Skip to content

Commit d0c14ff

Browse files
committed
docs, fix: deepRequired keyword
1 parent 6e49042 commit d0c14ff

File tree

3 files changed

+141
-22
lines changed

3 files changed

+141
-22
lines changed

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Custom JSON-Schema keywords for [ajv](https://github.com/epoberezkin/ajv) valida
1818
- [range and exclusiveRange](#range-and-exclusiverange)
1919
- [propertyNames](#propertynames)
2020
- [if/then/else](#ifthenelse)
21+
- [deepRequired](#deeprequired)
2122
- [regexp](#regexp)
2223
- [dynamicDefaults](#dynamicdefaults)
2324
- [License](#license)
@@ -168,6 +169,8 @@ These keywords allow to implement conditional validation. Their values should be
168169
If the data is valid according to the sub-schema in `if` keyword, then the result is equal to the result of data validation against the sub-schema in `then` keyword, otherwise - in `else` keyword (if `else` is absent, the validation succeeds).
169170

170171
```javascript
172+
require('ajv-keywords')(ajv, 'if');
173+
171174
var schema = {
172175
type: 'array',
173176
items: {
@@ -182,11 +185,47 @@ var schema = {
182185
var validItems = [ 2, 4, 6, 8, 10, 15, 20, 25 ]; // etc.
183186

184187
var invalidItems = [ 1, 3, 5, 11, 12 ]; // etc.
188+
189+
ajv.validate(schema, validItems); // true
190+
ajv.validate(schema, invalidItems); // false
185191
```
186192

187193
This keyword is [proposed](https://github.com/json-schema-org/json-schema-spec/issues/180) for the future version of JSON-Schema standard.
188194

189195

196+
### `deepRequired`
197+
198+
This keyword allows to check that some deep properties (identified by JSON pointers) are available. The value should be an array of JSON pointers to the data, starting from the current position in data.
199+
200+
```javascript
201+
var schema = {
202+
type: 'object',
203+
deepRequired: ["users/1/role"]
204+
};
205+
206+
var validData = {
207+
users: [
208+
{},
209+
{
210+
id: 123,
211+
role: 'admin'
212+
}
213+
]
214+
};
215+
216+
var invalidData = {
217+
users: [
218+
{},
219+
{
220+
id: 123
221+
}
222+
]
223+
};
224+
```
225+
226+
See [json-schema-org/json-schema-spec#203](https://github.com/json-schema-org/json-schema-spec/issues/203#issue-197211916) for an example of the equivalent schema without `deepRequired` keyword.
227+
228+
190229
### `regexp`
191230

192231
This keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags). The value of this keyword can be either a string (the result of `regexp.toString()`) or an object with the properties `pattern` and `flags` (the same strings that should be passed to RegExp constructor).

keywords/deepRequired.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = function defFunc(ajv) {
77
var expr = '';
88
for (var i=0; i<schema.length; i++) {
99
if (i) expr += ' && ';
10-
expr += '(' + getData(schema[i], it.dataLvl) + ' !== undefined)';
10+
expr += '(' + getData(schema[i], it.dataLevel) + ' !== undefined)';
1111
}
1212
return expr;
1313
}
@@ -24,12 +24,10 @@ function getData(jsonPointer, lvl) {
2424

2525
var expr = data;
2626
var segments = jsonPointer.split('/');
27-
for (var i=0; i<segments.length; i++) {
27+
for (var i=1; i<segments.length; i++) {
2828
var segment = segments[i];
29-
if (segment) {
30-
data += getProperty(unescapeJsonPointer(segment));
31-
expr += ' && ' + data;
32-
}
29+
data += getProperty(unescapeJsonPointer(segment));
30+
expr += ' && ' + data;
3331
}
3432
return expr;
3533
}

spec/tests/deepRequired.json

Lines changed: 98 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,48 +47,130 @@
4747
"description": "deepRequired keyword with items",
4848
"schema": {
4949
"type": "object",
50-
"deepRequired": [ "/foo/1/bar", "/foo/2/baz", "/quux/3" ]
50+
"properties": {
51+
"inside": {
52+
"type": "object",
53+
"deepRequired": [ "/foo/1/bar", "/foo/2/baz", "/quux/3" ]
54+
}
55+
}
5156
},
5257
"tests": [
5358
{
5459
"description": "object with all required properties/items is valid",
5560
"data": {
56-
"foo": [
57-
{},
58-
{ "bar": 1 },
59-
{ "baz": 2 }
60-
],
61-
"quux": [ 0, 1, 2, 3 ]
61+
"inside": {
62+
"foo": [
63+
{},
64+
{ "bar": 1 },
65+
{ "baz": 2 }
66+
],
67+
"quux": [ 0, 1, 2, 3 ]
68+
}
6269
},
6370
"valid": true
6471
},
6572
{
6673
"description": "object without any required properties is invalid",
6774
"data": {
68-
"foo": [{}, {}, {}],
69-
"quux": [0, 1, 2]
75+
"inside": {
76+
"foo": [{}, {}, {}],
77+
"quux": [0, 1, 2]
78+
}
7079
},
7180
"valid": false
7281
},
7382
{
7483
"description": "object with one required property is invalid",
7584
"data": {
76-
"quux": [ 0, 1, 2, 3 ]
85+
"inside": {
86+
"quux": [ 0, 1, 2, 3 ]
87+
}
7788
},
7889
"valid": false
7990
},
8091
{
8192
"description": "object with one required sub-property is invalid",
8293
"data": {
83-
"foo": [
84-
{},
85-
{ "bar": 1 },
86-
{}
87-
],
88-
"quux": [ 0, 1, 2, 3 ]
94+
"inside": {
95+
"foo": [
96+
{},
97+
{ "bar": 1 },
98+
{}
99+
],
100+
"quux": [ 0, 1, 2, 3 ]
101+
}
89102
},
90103
"valid": false
91104
}
92105
]
106+
},
107+
{
108+
"description": "deepRequired keyword with empty sub-properties",
109+
"schema": {
110+
"type": "array",
111+
"items": {
112+
"type": "object",
113+
"deepRequired": [ "/", "/foo/", "/bar//baz" ]
114+
}
115+
},
116+
"tests": [
117+
{
118+
"description": "object with required properties is valid",
119+
"data": [
120+
{
121+
"": 0,
122+
"foo": {
123+
"": 1
124+
},
125+
"bar": {
126+
"": {
127+
"baz": 2
128+
}
129+
}
130+
}
131+
],
132+
"valid": true
133+
},
134+
{
135+
"description": "object without any required properties is invalid",
136+
"data": [
137+
{
138+
"foo": {},
139+
"bar": {
140+
"": {}
141+
}
142+
}
143+
],
144+
"valid": false
145+
},
146+
{
147+
"description": "object with one required property is invalid",
148+
"data": [
149+
{
150+
"": 0,
151+
"foo": {},
152+
"bar": {
153+
"": {}
154+
}
155+
}
156+
],
157+
"valid": false
158+
},
159+
{
160+
"description": "object with one required sub-property is invalid",
161+
"data": [
162+
{
163+
"": 0,
164+
"foo": {
165+
"": 1
166+
},
167+
"bar": {
168+
"": {}
169+
}
170+
}
171+
],
172+
"valid": false
173+
}
174+
]
93175
}
94176
]

0 commit comments

Comments
 (0)