z-schema 6.0.2 → 7.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -134
- package/bin/z-schema +128 -124
- package/dist/Errors.js +50 -0
- package/dist/FormatValidators.js +136 -0
- package/{src → dist}/JsonValidation.js +184 -213
- package/dist/Report.js +220 -0
- package/{src → dist}/SchemaCache.js +67 -82
- package/{src → dist}/SchemaCompilation.js +89 -129
- package/dist/SchemaValidation.js +631 -0
- package/{src → dist}/Utils.js +96 -104
- package/dist/ZSchema-umd-min.js +1 -0
- package/dist/ZSchema-umd.js +13791 -0
- package/dist/ZSchema.cjs +13785 -0
- package/dist/ZSchema.js +366 -0
- package/dist/schemas/hyper-schema.json +156 -0
- package/dist/schemas/schema.json +151 -0
- package/dist/types/Errors.d.ts +44 -0
- package/dist/types/FormatValidators.d.ts +12 -0
- package/dist/types/JsonValidation.d.ts +37 -0
- package/dist/types/Report.d.ts +87 -0
- package/dist/types/SchemaCache.d.ts +26 -0
- package/dist/types/SchemaCompilation.d.ts +1 -0
- package/dist/types/SchemaValidation.d.ts +6 -0
- package/dist/types/Utils.d.ts +64 -0
- package/dist/types/ZSchema.d.ts +97 -0
- package/package.json +54 -43
- package/src/Errors.ts +56 -0
- package/src/FormatValidators.ts +136 -0
- package/src/JsonValidation.ts +624 -0
- package/src/Report.ts +337 -0
- package/src/SchemaCache.ts +189 -0
- package/src/SchemaCompilation.ts +293 -0
- package/src/SchemaValidation.ts +629 -0
- package/src/Utils.ts +286 -0
- package/src/ZSchema.ts +469 -0
- package/src/schemas/_ +0 -0
- package/dist/ZSchema-browser-min.js +0 -2
- package/dist/ZSchema-browser-min.js.map +0 -1
- package/dist/ZSchema-browser-test.js +0 -32247
- package/dist/ZSchema-browser.js +0 -12745
- package/index.d.ts +0 -175
- package/src/Errors.js +0 -60
- package/src/FormatValidators.js +0 -129
- package/src/Polyfills.js +0 -16
- package/src/Report.js +0 -299
- package/src/SchemaValidation.js +0 -619
- package/src/ZSchema.js +0 -409
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# z-schema validator
|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/js/z-schema)
|
|
4
|
-
|
|
5
|
-
[](https://travis-ci.org/zaggino/z-schema)
|
|
4
|
+
|
|
6
5
|
[](https://coveralls.io/r/zaggino/z-schema)
|
|
7
6
|
|
|
8
7
|
[](https://greenkeeper.io/)
|
|
@@ -26,11 +25,12 @@ Validator will try to perform sync validation when possible for speed, but suppo
|
|
|
26
25
|
## Development:
|
|
27
26
|
|
|
28
27
|
These repository has several submodules and should be cloned as follows:
|
|
29
|
-
|
|
28
|
+
|
|
29
|
+
> git clone **--recursive** https://github.com/zaggino/z-schema.git
|
|
30
30
|
|
|
31
31
|
## CLI:
|
|
32
32
|
|
|
33
|
-
```
|
|
33
|
+
```bash
|
|
34
34
|
npm install --global z-schema
|
|
35
35
|
z-schema --help
|
|
36
36
|
z-schema mySchema.json
|
|
@@ -41,7 +41,7 @@ z-schema --strictMode mySchema.json myJson.json
|
|
|
41
41
|
## NodeJS:
|
|
42
42
|
|
|
43
43
|
```javascript
|
|
44
|
-
|
|
44
|
+
import ZSchema from 'z-schema';
|
|
45
45
|
var options = ... // see below for possible option values
|
|
46
46
|
var validator = new ZSchema(options);
|
|
47
47
|
```
|
|
@@ -65,21 +65,27 @@ validator.validate(json, schema, function (err, valid) {
|
|
|
65
65
|
});
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
## CommonJs
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
import ZSchema from 'z-schema/dist/ZSchema.cjs';
|
|
72
|
+
```
|
|
73
|
+
|
|
68
74
|
## Browser:
|
|
69
75
|
|
|
70
76
|
```html
|
|
71
|
-
<script type="text/javascript" src="../dist/ZSchema-
|
|
77
|
+
<script type="text/javascript" src="../dist/ZSchema-umd-min.js"></script>
|
|
72
78
|
<script type="text/javascript">
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
var validator = new ZSchema();
|
|
80
|
+
var valid = validator.validate('string', { type: 'string' });
|
|
81
|
+
console.log(valid);
|
|
76
82
|
</script>
|
|
77
83
|
```
|
|
78
84
|
|
|
79
85
|
## Remote references and schemas:
|
|
80
86
|
|
|
81
87
|
In case you have some remote references in your schemas, you have to download those schemas before using validator.
|
|
82
|
-
Otherwise you'll get
|
|
88
|
+
Otherwise you'll get `UNRESOLVABLE_REFERENCE` error when trying to compile a schema.
|
|
83
89
|
|
|
84
90
|
```javascript
|
|
85
91
|
var validator = new ZSchema();
|
|
@@ -109,8 +115,8 @@ If you're able to load schemas synchronously, you can use `ZSchema.setSchemaRead
|
|
|
109
115
|
|
|
110
116
|
```javascript
|
|
111
117
|
ZSchema.setSchemaReader(function (uri) {
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
var someFilename = path.resolve(__dirname, '..', 'schemas', uri + '.json');
|
|
119
|
+
return JSON.parse(fs.readFileSync(someFilename, 'utf8'));
|
|
114
120
|
});
|
|
115
121
|
```
|
|
116
122
|
|
|
@@ -146,7 +152,7 @@ ZSchema.setSchemaReader(function (uri) {
|
|
|
146
152
|
In case you don't want to split your schema into multiple schemas using reference for any reason, you can use option schemaPath when validating:
|
|
147
153
|
|
|
148
154
|
```javascript
|
|
149
|
-
var valid = validator.validate(cars, schema, { schemaPath:
|
|
155
|
+
var valid = validator.validate(cars, schema, { schemaPath: 'definitions.car.definitions.cars' });
|
|
150
156
|
```
|
|
151
157
|
|
|
152
158
|
See more details in the [test](/test/spec/schemaPathSpec.js).
|
|
@@ -157,38 +163,35 @@ You can use validator to compile an array of schemas that have references betwee
|
|
|
157
163
|
|
|
158
164
|
```javascript
|
|
159
165
|
var schemas = [
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
},
|
|
167
|
-
required: ["firstName", "lastName"]
|
|
166
|
+
{
|
|
167
|
+
id: 'personDetails',
|
|
168
|
+
type: 'object',
|
|
169
|
+
properties: {
|
|
170
|
+
firstName: { type: 'string' },
|
|
171
|
+
lastName: { type: 'string' },
|
|
168
172
|
},
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
required: ['firstName', 'lastName'],
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: 'addressDetails',
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: {
|
|
179
|
+
street: { type: 'string' },
|
|
180
|
+
city: { type: 'string' },
|
|
177
181
|
},
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
182
|
+
required: ['street', 'city'],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: 'personWithAddress',
|
|
186
|
+
allOf: [{ $ref: 'personDetails' }, { $ref: 'addressDetails' }],
|
|
187
|
+
},
|
|
185
188
|
];
|
|
186
189
|
|
|
187
190
|
var data = {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
firstName: 'Martin',
|
|
192
|
+
lastName: 'Zagora',
|
|
193
|
+
street: 'George St',
|
|
194
|
+
city: 'Sydney',
|
|
192
195
|
};
|
|
193
196
|
|
|
194
197
|
var validator = new ZSchema();
|
|
@@ -207,28 +210,31 @@ var valid = validator.validate(data, schemas[2]);
|
|
|
207
210
|
You can register any format of your own. Your sync validator function should always respond with a boolean:
|
|
208
211
|
|
|
209
212
|
```javascript
|
|
210
|
-
ZSchema.registerFormat(
|
|
211
|
-
|
|
213
|
+
ZSchema.registerFormat('xstring', function (str) {
|
|
214
|
+
return str === 'xxx';
|
|
212
215
|
});
|
|
213
216
|
```
|
|
214
217
|
|
|
215
218
|
Async format validators are also supported, they should accept two arguments, value and a callback to which they need to respond:
|
|
216
219
|
|
|
217
220
|
```javascript
|
|
218
|
-
ZSchema.registerFormat(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
ZSchema.registerFormat('xstring', function (str, callback) {
|
|
222
|
+
setTimeout(function () {
|
|
223
|
+
callback(str === 'xxx');
|
|
224
|
+
}, 1);
|
|
222
225
|
});
|
|
223
226
|
```
|
|
227
|
+
|
|
224
228
|
## Helper method to check the formats that have been registered
|
|
229
|
+
|
|
225
230
|
```javascript
|
|
226
231
|
var registeredFormats = ZSchema.getRegisteredFormats();
|
|
227
232
|
//registeredFormats will now contain an array of all formats that have been registered with z-schema
|
|
228
233
|
```
|
|
234
|
+
|
|
229
235
|
## Automatic downloading of remote schemas
|
|
230
236
|
|
|
231
|
-
Automatic downloading of remote schemas was removed from version
|
|
237
|
+
Automatic downloading of remote schemas was removed from version `3.x` but is still possible with a bit of extra code,
|
|
232
238
|
see [this test](test/spec/AutomaticSchemaLoadingSpec.js) for more information on this.
|
|
233
239
|
|
|
234
240
|
## Prefill default values to object using format
|
|
@@ -236,16 +242,16 @@ see [this test](test/spec/AutomaticSchemaLoadingSpec.js) for more information on
|
|
|
236
242
|
Using format, you can pre-fill values of your choosing into the objects like this:
|
|
237
243
|
|
|
238
244
|
```javascript
|
|
239
|
-
ZSchema.registerFormat(
|
|
240
|
-
|
|
241
|
-
|
|
245
|
+
ZSchema.registerFormat('fillHello', function (obj) {
|
|
246
|
+
obj.hello = 'world';
|
|
247
|
+
return true;
|
|
242
248
|
});
|
|
243
249
|
|
|
244
250
|
var data = {};
|
|
245
251
|
|
|
246
252
|
var schema = {
|
|
247
|
-
|
|
248
|
-
|
|
253
|
+
type: 'object',
|
|
254
|
+
format: 'fillHello',
|
|
249
255
|
};
|
|
250
256
|
|
|
251
257
|
validator.validate(data, schema);
|
|
@@ -257,51 +263,51 @@ validator.validate(data, schema);
|
|
|
257
263
|
## asyncTimeout
|
|
258
264
|
|
|
259
265
|
Defines a time limit, which should be used when waiting for async tasks like async format validators to perform their validation,
|
|
260
|
-
before the validation fails with an
|
|
266
|
+
before the validation fails with an `ASYNC_TIMEOUT` error.
|
|
261
267
|
|
|
262
268
|
```javascript
|
|
263
269
|
var validator = new ZSchema({
|
|
264
|
-
|
|
270
|
+
asyncTimeout: 2000,
|
|
265
271
|
});
|
|
266
272
|
```
|
|
267
273
|
|
|
268
274
|
## noEmptyArrays
|
|
269
275
|
|
|
270
|
-
When true, validator will assume that minimum count of items in any
|
|
276
|
+
When true, validator will assume that minimum count of items in any `array` is 1, except when `minItems: 0` is explicitly defined.
|
|
271
277
|
|
|
272
278
|
```javascript
|
|
273
279
|
var validator = new ZSchema({
|
|
274
|
-
|
|
280
|
+
noEmptyArrays: true,
|
|
275
281
|
});
|
|
276
282
|
```
|
|
277
283
|
|
|
278
284
|
## noEmptyStrings
|
|
279
285
|
|
|
280
|
-
When true, validator will assume that minimum length of any string to pass type
|
|
286
|
+
When true, validator will assume that minimum length of any string to pass type `string` validation is 1, except when `minLength: 0` is explicitly defined.
|
|
281
287
|
|
|
282
288
|
```javascript
|
|
283
289
|
var validator = new ZSchema({
|
|
284
|
-
|
|
290
|
+
noEmptyStrings: true,
|
|
285
291
|
});
|
|
286
292
|
```
|
|
287
293
|
|
|
288
294
|
## noTypeless
|
|
289
295
|
|
|
290
|
-
When true, validator will fail validation for schemas that don't specify a
|
|
296
|
+
When true, validator will fail validation for schemas that don't specify a `type` of object that they expect.
|
|
291
297
|
|
|
292
298
|
```javascript
|
|
293
299
|
var validator = new ZSchema({
|
|
294
|
-
|
|
300
|
+
noTypeless: true,
|
|
295
301
|
});
|
|
296
302
|
```
|
|
297
303
|
|
|
298
304
|
## noExtraKeywords
|
|
299
305
|
|
|
300
|
-
When true, validator will fail for schemas that use keywords not defined in JSON Schema specification and doesn't provide a parent schema in
|
|
306
|
+
When true, validator will fail for schemas that use keywords not defined in JSON Schema specification and doesn't provide a parent schema in `$schema` property to validate the schema.
|
|
301
307
|
|
|
302
308
|
```javascript
|
|
303
309
|
var validator = new ZSchema({
|
|
304
|
-
|
|
310
|
+
noExtraKeywords: true,
|
|
305
311
|
});
|
|
306
312
|
```
|
|
307
313
|
|
|
@@ -311,7 +317,7 @@ When true, validator assumes that additionalItems/additionalProperties are defin
|
|
|
311
317
|
|
|
312
318
|
```javascript
|
|
313
319
|
var validator = new ZSchema({
|
|
314
|
-
|
|
320
|
+
assumeAdditional: true,
|
|
315
321
|
});
|
|
316
322
|
```
|
|
317
323
|
|
|
@@ -319,7 +325,7 @@ When an array, validator assumes that additionalItems/additionalProperties are d
|
|
|
319
325
|
|
|
320
326
|
```javascript
|
|
321
327
|
var validator = new ZSchema({
|
|
322
|
-
|
|
328
|
+
assumeAdditional: ['$ref'],
|
|
323
329
|
});
|
|
324
330
|
```
|
|
325
331
|
|
|
@@ -329,74 +335,73 @@ When true, validator doesn't validate schemas where additionalItems/additionalPr
|
|
|
329
335
|
|
|
330
336
|
```javascript
|
|
331
337
|
var validator = new ZSchema({
|
|
332
|
-
|
|
338
|
+
forceAdditional: true,
|
|
333
339
|
});
|
|
334
340
|
```
|
|
335
341
|
|
|
336
342
|
## forceItems
|
|
337
343
|
|
|
338
|
-
When true, validator doesn't validate schemas where
|
|
344
|
+
When true, validator doesn't validate schemas where `items` are not defined for `array` type schemas.
|
|
339
345
|
This is to avoid passing anything through an array definition.
|
|
340
346
|
|
|
341
347
|
```javascript
|
|
342
348
|
var validator = new ZSchema({
|
|
343
|
-
|
|
349
|
+
forceItems: true,
|
|
344
350
|
});
|
|
345
351
|
```
|
|
346
352
|
|
|
347
353
|
## forceMinItems
|
|
348
354
|
|
|
349
|
-
When true, validator doesn't validate schemas where
|
|
355
|
+
When true, validator doesn't validate schemas where `minItems` is not defined for `array` type schemas.
|
|
350
356
|
This is to avoid passing zero-length arrays which application doesn't expect to handle.
|
|
351
357
|
|
|
352
358
|
```javascript
|
|
353
359
|
var validator = new ZSchema({
|
|
354
|
-
|
|
360
|
+
forceMinItems: true,
|
|
355
361
|
});
|
|
356
362
|
```
|
|
357
363
|
|
|
358
364
|
## forceMaxItems
|
|
359
365
|
|
|
360
|
-
When true, validator doesn't validate schemas where
|
|
366
|
+
When true, validator doesn't validate schemas where `maxItems` is not defined for `array` type schemas.
|
|
361
367
|
This is to avoid passing arrays with unlimited count of elements which application doesn't expect to handle.
|
|
362
368
|
|
|
363
369
|
```javascript
|
|
364
370
|
var validator = new ZSchema({
|
|
365
|
-
|
|
371
|
+
forceMaxItems: true,
|
|
366
372
|
});
|
|
367
373
|
```
|
|
368
374
|
|
|
369
375
|
## forceMinLength
|
|
370
376
|
|
|
371
|
-
When true, validator doesn't validate schemas where
|
|
377
|
+
When true, validator doesn't validate schemas where `minLength` is not defined for `string` type schemas.
|
|
372
378
|
This is to avoid passing zero-length strings which application doesn't expect to handle.
|
|
373
379
|
|
|
374
380
|
```javascript
|
|
375
381
|
var validator = new ZSchema({
|
|
376
|
-
|
|
382
|
+
forceMinLength: true,
|
|
377
383
|
});
|
|
378
384
|
```
|
|
379
385
|
|
|
380
|
-
|
|
381
386
|
## forceMaxLength
|
|
382
387
|
|
|
383
|
-
When true, validator doesn't validate schemas where
|
|
388
|
+
When true, validator doesn't validate schemas where `maxLength` is not defined for `string` type schemas.
|
|
384
389
|
This is to avoid passing extremly large strings which application doesn't expect to handle.
|
|
385
390
|
|
|
386
391
|
```javascript
|
|
387
392
|
var validator = new ZSchema({
|
|
388
|
-
|
|
393
|
+
forceMaxLength: true,
|
|
389
394
|
});
|
|
390
395
|
```
|
|
391
396
|
|
|
392
397
|
## forceProperties
|
|
393
398
|
|
|
394
|
-
When true, validator doesn't validate schemas where
|
|
399
|
+
When true, validator doesn't validate schemas where `properties` or `patternProperties` is not defined for `object` type schemas.
|
|
395
400
|
This is to avoid having objects with unexpected properties in application.
|
|
396
401
|
|
|
397
402
|
```javascript
|
|
398
403
|
var validator = new ZSchema({
|
|
399
|
-
|
|
404
|
+
forceProperties: true,
|
|
400
405
|
});
|
|
401
406
|
```
|
|
402
407
|
|
|
@@ -406,26 +411,27 @@ When true, validator doesn't end with error when a remote reference is unreachab
|
|
|
406
411
|
|
|
407
412
|
```javascript
|
|
408
413
|
var validator = new ZSchema({
|
|
409
|
-
|
|
414
|
+
ignoreUnresolvableReferences: true,
|
|
410
415
|
});
|
|
411
416
|
```
|
|
417
|
+
|
|
412
418
|
## enumCaseInsensitiveComparison
|
|
413
419
|
|
|
414
|
-
When true, validator will return a
|
|
420
|
+
When true, validator will return a `ENUM_CASE_MISMATCH` when the enum values mismatch only in case.
|
|
415
421
|
|
|
416
422
|
```javascript
|
|
417
423
|
var validator = new ZSchema({
|
|
418
|
-
|
|
424
|
+
enumCaseInsensitiveComparison: true,
|
|
419
425
|
});
|
|
420
426
|
```
|
|
421
427
|
|
|
422
428
|
## strictUris
|
|
423
429
|
|
|
424
|
-
When true, all strings of format
|
|
430
|
+
When true, all strings of format `uri` must be an absolute URIs and not only URI references. See more details in [this issue](https://github.com/zaggino/z-schema/issues/18).
|
|
425
431
|
|
|
426
432
|
```javascript
|
|
427
433
|
var validator = new ZSchema({
|
|
428
|
-
|
|
434
|
+
strictUris: true,
|
|
429
435
|
});
|
|
430
436
|
```
|
|
431
437
|
|
|
@@ -435,20 +441,20 @@ Strict mode of z-schema is currently equal to the following:
|
|
|
435
441
|
|
|
436
442
|
```javascript
|
|
437
443
|
if (this.options.strictMode === true) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
444
|
+
this.options.forceAdditional = true;
|
|
445
|
+
this.options.forceItems = true;
|
|
446
|
+
this.options.forceMaxLength = true;
|
|
447
|
+
this.options.forceProperties = true;
|
|
448
|
+
this.options.noExtraKeywords = true;
|
|
449
|
+
this.options.noTypeless = true;
|
|
450
|
+
this.options.noEmptyStrings = true;
|
|
451
|
+
this.options.noEmptyArrays = true;
|
|
446
452
|
}
|
|
447
453
|
```
|
|
448
454
|
|
|
449
455
|
```javascript
|
|
450
456
|
var validator = new ZSchema({
|
|
451
|
-
|
|
457
|
+
strictMode: true,
|
|
452
458
|
});
|
|
453
459
|
```
|
|
454
460
|
|
|
@@ -459,7 +465,7 @@ When true, will stop validation after the first error is found:
|
|
|
459
465
|
|
|
460
466
|
```javascript
|
|
461
467
|
var validator = new ZSchema({
|
|
462
|
-
|
|
468
|
+
breakOnFirstError: true,
|
|
463
469
|
});
|
|
464
470
|
```
|
|
465
471
|
|
|
@@ -469,21 +475,21 @@ Report error paths as an array of path segments instead of a string:
|
|
|
469
475
|
|
|
470
476
|
```javascript
|
|
471
477
|
var validator = new ZSchema({
|
|
472
|
-
|
|
478
|
+
reportPathAsArray: true,
|
|
473
479
|
});
|
|
474
480
|
```
|
|
475
481
|
|
|
476
482
|
## ignoreUnknownFormats
|
|
477
483
|
|
|
478
484
|
By default, z-schema reports all unknown formats, formats not defined by JSON Schema and not registered using
|
|
479
|
-
`ZSchema.registerFormat`, as an error.
|
|
485
|
+
`ZSchema.registerFormat`, as an error. But the
|
|
480
486
|
[JSON Schema specification](http://json-schema.org/latest/json-schema-validation.html#anchor106) says that validator
|
|
481
|
-
implementations
|
|
487
|
+
implementations _"they SHOULD offer an option to disable validation"_ for `format`. That being said, setting this
|
|
482
488
|
option to `true` will disable treating unknown formats as errlrs
|
|
483
489
|
|
|
484
490
|
```javascript
|
|
485
491
|
var validator = new ZSchema({
|
|
486
|
-
|
|
492
|
+
ignoreUnknownFormats: true,
|
|
487
493
|
});
|
|
488
494
|
```
|
|
489
495
|
|
|
@@ -494,7 +500,7 @@ By default, z-schema reports all errors. If interested only in a subset of the e
|
|
|
494
500
|
```javascript
|
|
495
501
|
var validator = new ZSchema();
|
|
496
502
|
// will only execute validation for "INVALID_TYPE" error.
|
|
497
|
-
validator.validate(json, schema, {includeErrors: [
|
|
503
|
+
validator.validate(json, schema, { includeErrors: ['INVALID_TYPE'] });
|
|
498
504
|
```
|
|
499
505
|
|
|
500
506
|
## customValidator
|
|
@@ -505,83 +511,97 @@ Register function to be called as part of validation process on every subshema e
|
|
|
505
511
|
|
|
506
512
|
Let's make a real-life example with this feature.
|
|
507
513
|
Imagine you have number of transactions:
|
|
514
|
+
|
|
508
515
|
```json
|
|
509
516
|
{
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
517
|
+
"fromId": 1034834329,
|
|
518
|
+
"toId": 1034834543,
|
|
519
|
+
"amount": 200
|
|
513
520
|
}
|
|
514
521
|
```
|
|
522
|
+
|
|
515
523
|
So you write the schema:
|
|
524
|
+
|
|
516
525
|
```json
|
|
517
526
|
{
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
527
|
+
"type": "object",
|
|
528
|
+
"properties": {
|
|
529
|
+
"fromId": {
|
|
530
|
+
"type": "integer"
|
|
531
|
+
},
|
|
532
|
+
"toId": {
|
|
533
|
+
"type": "integer"
|
|
534
|
+
},
|
|
535
|
+
"amount": {
|
|
536
|
+
"type": "number"
|
|
529
537
|
}
|
|
538
|
+
}
|
|
530
539
|
}
|
|
531
540
|
```
|
|
541
|
+
|
|
532
542
|
But how to check that `fromId` and `toId` are never equal.
|
|
533
543
|
In JSON Schema Draft4 there is no possibility to do this.
|
|
534
544
|
Actually, it's easy to just write validation code for such simple payloads.
|
|
535
545
|
But what if you have to do the same check for many objects in different places of JSON payload.
|
|
536
546
|
One solution is to add custom keyword `uniqueProperties` with array of property names as a value. So in our schema we would need to add:
|
|
547
|
+
|
|
537
548
|
```json
|
|
538
549
|
"uniqueProperties": [
|
|
539
550
|
"fromId",
|
|
540
551
|
"toId"
|
|
541
552
|
]
|
|
542
553
|
```
|
|
554
|
+
|
|
543
555
|
To teach `z-schema` about this new keyword we need to write handler for it:
|
|
556
|
+
|
|
544
557
|
```javascript
|
|
545
558
|
function customValidatorFn(report, schema, json) {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
559
|
+
// check if our custom property is present
|
|
560
|
+
if (Array.isArray(schema.uniqueProperties)) {
|
|
561
|
+
var seenValues = [];
|
|
562
|
+
schema.uniqueProperties.forEach(function (prop) {
|
|
563
|
+
var value = json[prop];
|
|
564
|
+
if (typeof value !== 'undefined') {
|
|
565
|
+
if (seenValues.indexOf(value) !== -1) {
|
|
566
|
+
// report error back to z-schema core
|
|
567
|
+
report.addCustomError(
|
|
568
|
+
'NON_UNIQUE_PROPERTY_VALUE',
|
|
569
|
+
'Property "{0}" has non-unique value: {1}',
|
|
570
|
+
[prop, value],
|
|
571
|
+
null,
|
|
572
|
+
schema.description
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
seenValues.push(value);
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
}
|
|
562
579
|
}
|
|
563
580
|
|
|
564
581
|
var validator = new ZSchema({
|
|
565
|
-
|
|
566
|
-
|
|
582
|
+
// register our custom validator inside z-schema
|
|
583
|
+
customValidator: customValidatorFn,
|
|
567
584
|
});
|
|
568
585
|
```
|
|
586
|
+
|
|
569
587
|
Let's test it:
|
|
588
|
+
|
|
570
589
|
```javascript
|
|
571
590
|
var data = {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
591
|
+
fromId: 1034834346,
|
|
592
|
+
toId: 1034834346,
|
|
593
|
+
amount: 50,
|
|
575
594
|
};
|
|
576
595
|
|
|
577
596
|
validator.validate(data, schema);
|
|
578
|
-
console.log(validator.getLastErrors())
|
|
597
|
+
console.log(validator.getLastErrors());
|
|
579
598
|
//[ { code: 'NON_UNIQUE_PROPERTY_VALUE',
|
|
580
599
|
// params: [ 'toId', 1034834346 ],
|
|
581
600
|
// message: 'Property "toId" has non-unique value: 1034834346',
|
|
582
601
|
// path: '#/',
|
|
583
602
|
// schemaId: undefined } ]
|
|
584
603
|
```
|
|
604
|
+
|
|
585
605
|
**Note:** before creating your own keywords you should consider all compatibility issues.
|
|
586
606
|
|
|
587
607
|
# Benchmarks
|