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