z-schema 10.0.0 → 12.0.0

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 (138) hide show
  1. package/README.md +35 -17
  2. package/cjs/index.d.ts +345 -34
  3. package/cjs/index.js +4446 -1685
  4. package/dist/errors.js +5 -0
  5. package/dist/format-validators.js +131 -107
  6. package/dist/json-schema-versions.js +4 -1
  7. package/dist/json-schema.js +50 -16
  8. package/dist/json-validation.js +524 -669
  9. package/dist/report.js +37 -16
  10. package/dist/schema-cache.js +76 -18
  11. package/dist/schema-compiler.js +72 -47
  12. package/dist/schema-validator.js +117 -52
  13. package/dist/schemas/draft-07-schema.json +172 -0
  14. package/dist/schemas/draft-2019-09-meta-applicator.json +52 -0
  15. package/dist/schemas/draft-2019-09-meta-content.json +12 -0
  16. package/dist/schemas/draft-2019-09-meta-core.json +53 -0
  17. package/dist/schemas/draft-2019-09-meta-format.json +10 -0
  18. package/dist/schemas/draft-2019-09-meta-meta-data.json +32 -0
  19. package/dist/schemas/draft-2019-09-meta-validation.json +94 -0
  20. package/dist/schemas/draft-2019-09-schema.json +41 -0
  21. package/dist/schemas/draft-2020-12-meta-applicator.json +44 -0
  22. package/dist/schemas/draft-2020-12-meta-content.json +12 -0
  23. package/dist/schemas/draft-2020-12-meta-core.json +47 -0
  24. package/dist/schemas/draft-2020-12-meta-format-annotation.json +10 -0
  25. package/dist/schemas/draft-2020-12-meta-format-assertion.json +10 -0
  26. package/dist/schemas/draft-2020-12-meta-meta-data.json +32 -0
  27. package/dist/schemas/draft-2020-12-meta-unevaluated.json +11 -0
  28. package/dist/schemas/draft-2020-12-meta-validation.json +94 -0
  29. package/dist/schemas/draft-2020-12-schema.json +57 -0
  30. package/dist/types/errors.d.ts +4 -0
  31. package/dist/types/index.d.ts +2 -1
  32. package/dist/types/json-schema-versions.d.ts +128 -9
  33. package/dist/types/json-schema.d.ts +28 -11
  34. package/dist/types/json-validation.d.ts +2 -3
  35. package/dist/types/report.d.ts +14 -4
  36. package/dist/types/schema-cache.d.ts +7 -0
  37. package/dist/types/schema-compiler.d.ts +5 -3
  38. package/dist/types/schema-validator.d.ts +2 -2
  39. package/dist/types/utils/array.d.ts +8 -1
  40. package/dist/types/utils/base64.d.ts +2 -0
  41. package/dist/types/utils/clone.d.ts +1 -1
  42. package/dist/types/utils/date.d.ts +1 -0
  43. package/dist/types/utils/hostname.d.ts +2 -0
  44. package/dist/types/utils/json.d.ts +2 -1
  45. package/dist/types/utils/properties.d.ts +0 -1
  46. package/dist/types/utils/time.d.ts +12 -0
  47. package/dist/types/utils/unicode.d.ts +3 -12
  48. package/dist/types/validation/array.d.ts +12 -0
  49. package/dist/types/validation/combinators.d.ts +10 -0
  50. package/dist/types/validation/numeric.d.ts +8 -0
  51. package/dist/types/validation/object.d.ts +13 -0
  52. package/dist/types/validation/ref.d.ts +11 -0
  53. package/dist/types/validation/shared.d.ts +26 -0
  54. package/dist/types/validation/string.d.ts +9 -0
  55. package/dist/types/validation/type.d.ts +6 -0
  56. package/dist/types/z-schema-base.d.ts +39 -1
  57. package/dist/types/z-schema-options.d.ts +3 -0
  58. package/dist/types/z-schema.d.ts +144 -8
  59. package/dist/utils/array.js +49 -7
  60. package/dist/utils/base64.js +29 -0
  61. package/dist/utils/clone.js +13 -12
  62. package/dist/utils/date.js +21 -0
  63. package/dist/utils/hostname.js +146 -0
  64. package/dist/utils/json.js +11 -6
  65. package/dist/utils/properties.js +1 -6
  66. package/dist/utils/time.js +50 -0
  67. package/dist/utils/unicode.js +8 -41
  68. package/dist/utils/uri.js +1 -1
  69. package/dist/validation/array.js +128 -0
  70. package/dist/validation/combinators.js +107 -0
  71. package/dist/validation/numeric.js +97 -0
  72. package/dist/validation/object.js +238 -0
  73. package/dist/validation/ref.js +70 -0
  74. package/dist/validation/shared.js +136 -0
  75. package/dist/validation/string.js +178 -0
  76. package/dist/validation/type.js +55 -0
  77. package/dist/z-schema-base.js +52 -32
  78. package/dist/z-schema-options.js +12 -8
  79. package/dist/z-schema-versions.js +92 -9
  80. package/dist/z-schema.js +135 -38
  81. package/package.json +22 -8
  82. package/src/errors.ts +8 -0
  83. package/src/format-validators.ts +146 -105
  84. package/src/index.ts +10 -1
  85. package/src/json-schema-versions.ts +181 -11
  86. package/src/json-schema.ts +102 -35
  87. package/src/json-validation.ts +653 -724
  88. package/src/report.ts +42 -20
  89. package/src/schema-cache.ts +94 -18
  90. package/src/schema-compiler.ts +94 -51
  91. package/src/schema-validator.ts +132 -56
  92. package/src/schemas/draft-07-schema.json +172 -0
  93. package/src/schemas/draft-2019-09-meta-applicator.json +53 -0
  94. package/src/schemas/draft-2019-09-meta-content.json +14 -0
  95. package/src/schemas/draft-2019-09-meta-core.json +54 -0
  96. package/src/schemas/draft-2019-09-meta-format.json +11 -0
  97. package/src/schemas/draft-2019-09-meta-meta-data.json +34 -0
  98. package/src/schemas/draft-2019-09-meta-validation.json +95 -0
  99. package/src/schemas/draft-2019-09-schema.json +42 -0
  100. package/src/schemas/draft-2020-12-meta-applicator.json +45 -0
  101. package/src/schemas/draft-2020-12-meta-content.json +14 -0
  102. package/src/schemas/draft-2020-12-meta-core.json +48 -0
  103. package/src/schemas/draft-2020-12-meta-format-annotation.json +11 -0
  104. package/src/schemas/draft-2020-12-meta-format-assertion.json +11 -0
  105. package/src/schemas/draft-2020-12-meta-meta-data.json +34 -0
  106. package/src/schemas/draft-2020-12-meta-unevaluated.json +12 -0
  107. package/src/schemas/draft-2020-12-meta-validation.json +95 -0
  108. package/src/schemas/draft-2020-12-schema.json +58 -0
  109. package/src/utils/array.ts +51 -7
  110. package/src/utils/base64.ts +32 -0
  111. package/src/utils/clone.ts +16 -12
  112. package/src/utils/date.ts +23 -0
  113. package/src/utils/hostname.ts +174 -0
  114. package/src/utils/json.ts +15 -6
  115. package/src/utils/properties.ts +1 -7
  116. package/src/utils/time.ts +73 -0
  117. package/src/utils/unicode.ts +8 -39
  118. package/src/utils/uri.ts +1 -1
  119. package/src/validation/array.ts +158 -0
  120. package/src/validation/combinators.ts +132 -0
  121. package/src/validation/numeric.ts +120 -0
  122. package/src/validation/object.ts +318 -0
  123. package/src/validation/ref.ts +85 -0
  124. package/src/validation/shared.ts +191 -0
  125. package/src/validation/string.ts +224 -0
  126. package/src/validation/type.ts +66 -0
  127. package/src/z-schema-base.ts +54 -36
  128. package/src/z-schema-options.ts +15 -8
  129. package/src/z-schema-versions.ts +107 -12
  130. package/src/z-schema.ts +158 -42
  131. package/umd/ZSchema.js +4446 -1685
  132. package/umd/ZSchema.min.js +1 -1
  133. package/dist/schemas/draft-04-hyper-schema.json +0 -135
  134. package/dist/schemas/draft-06-hyper-schema.json +0 -132
  135. package/dist/schemas/draft-06-links.json +0 -43
  136. package/src/schemas/draft-04-hyper-schema.json +0 -136
  137. package/src/schemas/draft-06-hyper-schema.json +0 -133
  138. package/src/schemas/draft-06-links.json +0 -43
@@ -119,8 +119,7 @@ const SchemaValidators = {
119
119
  items: function (report, schema) {
120
120
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
121
121
  if (Array.isArray(schema.items)) {
122
- let idx = schema.items.length;
123
- while (idx--) {
122
+ for (let idx = 0; idx < schema.items.length; idx++) {
124
123
  report.path.push('items');
125
124
  report.path.push(idx);
126
125
  this.validateSchema(report, schema.items[idx]);
@@ -140,7 +139,7 @@ const SchemaValidators = {
140
139
  if (this.options.forceAdditional === true && schema.additionalItems === undefined && Array.isArray(schema.items)) {
141
140
  report.addError('KEYWORD_UNDEFINED_STRICT', ['additionalItems'], undefined, schema, 'additionalItems');
142
141
  }
143
- // custome - assume defined false mode
142
+ // custom - assume defined false mode
144
143
  if (this.options.assumeAdditional && schema.additionalItems === undefined && Array.isArray(schema.items)) {
145
144
  schema.additionalItems = false;
146
145
  }
@@ -196,9 +195,8 @@ const SchemaValidators = {
196
195
  report.addError('KEYWORD_MUST_BE', ['required', 'an array with at least one element'], undefined, schema, 'required');
197
196
  }
198
197
  else {
199
- let idx = schema.required.length;
200
- while (idx--) {
201
- if (typeof schema.required[idx] !== 'string') {
198
+ for (const item of schema.required) {
199
+ if (typeof item !== 'string') {
202
200
  report.addError('KEYWORD_VALUE_TYPE', ['required', 'string'], undefined, schema, 'required');
203
201
  }
204
202
  }
@@ -225,9 +223,7 @@ const SchemaValidators = {
225
223
  return;
226
224
  }
227
225
  const keys = Object.keys(schema.properties);
228
- let idx = keys.length;
229
- while (idx--) {
230
- const key = keys[idx];
226
+ for (const key of keys) {
231
227
  const val = schema.properties[key];
232
228
  report.path.push('properties');
233
229
  report.path.push(key);
@@ -239,7 +235,7 @@ const SchemaValidators = {
239
235
  if (this.options.forceAdditional === true && schema.additionalProperties === undefined) {
240
236
  report.addError('KEYWORD_UNDEFINED_STRICT', ['additionalProperties'], undefined, schema, 'additionalProperties');
241
237
  }
242
- // custome - assume defined false mode
238
+ // custom - assume defined false mode
243
239
  if (this.options.assumeAdditional && schema.additionalProperties === undefined) {
244
240
  schema.additionalProperties = false;
245
241
  }
@@ -256,9 +252,8 @@ const SchemaValidators = {
256
252
  }
257
253
  // Use shared regex compilation helper
258
254
  const keys = Object.keys(schema.patternProperties);
259
- let idx = keys.length;
260
- while (idx--) {
261
- const key = keys[idx], val = schema.patternProperties[key];
255
+ for (const key of keys) {
256
+ const val = schema.patternProperties[key];
262
257
  const result = compileSchemaRegex(key);
263
258
  if (!result.ok) {
264
259
  report.addError('KEYWORD_PATTERN', ['patternProperties', key, result.error.message], undefined, schema, 'patternProperties');
@@ -281,9 +276,7 @@ const SchemaValidators = {
281
276
  }
282
277
  else {
283
278
  const keys = Object.keys(schema.dependencies);
284
- let idx = keys.length;
285
- while (idx--) {
286
- const schemaKey = keys[idx];
279
+ for (const schemaKey of keys) {
287
280
  const schemaDependency = schema.dependencies[schemaKey];
288
281
  const isSchemaDependency = isObject(schemaDependency) ||
289
282
  (report.options.version !== 'draft-04' && typeof schemaDependency === 'boolean');
@@ -296,12 +289,11 @@ const SchemaValidators = {
296
289
  }
297
290
  else if (Array.isArray(schemaDependency)) {
298
291
  const depArray = schemaDependency;
299
- let idx2 = depArray.length;
300
- if (report.options.version === 'draft-04' && idx2 === 0) {
292
+ if (report.options.version === 'draft-04' && depArray.length === 0) {
301
293
  report.addError('KEYWORD_MUST_BE', ['dependencies', 'not empty array'], undefined, schema, 'dependencies');
302
294
  }
303
- while (idx2--) {
304
- if (typeof depArray[idx2] !== 'string') {
295
+ for (const dep of depArray) {
296
+ if (typeof dep !== 'string') {
305
297
  report.addError('KEYWORD_VALUE_TYPE', ['dependencies', 'string'], undefined, schema, 'dependencies');
306
298
  }
307
299
  }
@@ -333,9 +325,8 @@ const SchemaValidators = {
333
325
  const primitiveTypeStr = primitiveTypes.join(',');
334
326
  const isArray = Array.isArray(schema.type);
335
327
  if (Array.isArray(schema.type)) {
336
- let idx = schema.type.length;
337
- while (idx--) {
338
- if (primitiveTypes.indexOf(schema.type[idx]) === -1) {
328
+ for (const typeItem of schema.type) {
329
+ if (!primitiveTypes.includes(typeItem)) {
339
330
  report.addError('KEYWORD_TYPE_EXPECTED', ['type', primitiveTypeStr], undefined, schema, 'type');
340
331
  }
341
332
  }
@@ -344,7 +335,7 @@ const SchemaValidators = {
344
335
  }
345
336
  }
346
337
  else if (typeof schema.type === 'string') {
347
- if (primitiveTypes.indexOf(schema.type) === -1) {
338
+ if (!primitiveTypes.includes(schema.type)) {
348
339
  report.addError('KEYWORD_TYPE_EXPECTED', ['type', primitiveTypeStr], undefined, schema, 'type');
349
340
  }
350
341
  }
@@ -352,49 +343,49 @@ const SchemaValidators = {
352
343
  report.addError('KEYWORD_TYPE_EXPECTED', ['type', ['string', 'array']], undefined, schema, 'type');
353
344
  }
354
345
  if (this.options.noEmptyStrings === true) {
355
- if (schema.type === 'string' || (isArray && schema.type.indexOf('string') !== -1)) {
346
+ if (schema.type === 'string' || (isArray && schema.type.includes('string'))) {
356
347
  if (schema.minLength === undefined && schema.enum === undefined && schema.format === undefined) {
357
348
  schema.minLength = 1;
358
349
  }
359
350
  }
360
351
  }
361
352
  if (this.options.noEmptyArrays === true) {
362
- if (schema.type === 'array' || (isArray && schema.type.indexOf('array') !== -1)) {
353
+ if (schema.type === 'array' || (isArray && schema.type.includes('array'))) {
363
354
  if (schema.minItems === undefined) {
364
355
  schema.minItems = 1;
365
356
  }
366
357
  }
367
358
  }
368
359
  if (this.options.forceProperties === true) {
369
- if (schema.type === 'object' || (isArray && schema.type.indexOf('object') !== -1)) {
360
+ if (schema.type === 'object' || (isArray && schema.type.includes('object'))) {
370
361
  if (schema.properties === undefined && schema.patternProperties === undefined) {
371
362
  report.addError('KEYWORD_UNDEFINED_STRICT', ['properties'], undefined, schema, 'properties');
372
363
  }
373
364
  }
374
365
  }
375
366
  if (this.options.forceItems === true) {
376
- if (schema.type === 'array' || (isArray && schema.type.indexOf('array') !== -1)) {
367
+ if (schema.type === 'array' || (isArray && schema.type.includes('array'))) {
377
368
  if (schema.items === undefined) {
378
369
  report.addError('KEYWORD_UNDEFINED_STRICT', ['items'], undefined, schema, 'items');
379
370
  }
380
371
  }
381
372
  }
382
373
  if (this.options.forceMinItems === true) {
383
- if (schema.type === 'array' || (isArray && schema.type.indexOf('array') !== -1)) {
374
+ if (schema.type === 'array' || (isArray && schema.type.includes('array'))) {
384
375
  if (schema.minItems === undefined) {
385
376
  report.addError('KEYWORD_UNDEFINED_STRICT', ['minItems'], undefined, schema, 'minItems');
386
377
  }
387
378
  }
388
379
  }
389
380
  if (this.options.forceMaxItems === true) {
390
- if (schema.type === 'array' || (isArray && schema.type.indexOf('array') !== -1)) {
381
+ if (schema.type === 'array' || (isArray && schema.type.includes('array'))) {
391
382
  if (schema.maxItems === undefined) {
392
383
  report.addError('KEYWORD_UNDEFINED_STRICT', ['maxItems'], undefined, schema, 'maxItems');
393
384
  }
394
385
  }
395
386
  }
396
387
  if (this.options.forceMinLength === true) {
397
- if (schema.type === 'string' || (isArray && schema.type.indexOf('string') !== -1)) {
388
+ if (schema.type === 'string' || (isArray && schema.type.includes('string'))) {
398
389
  if (schema.minLength === undefined &&
399
390
  schema.format === undefined &&
400
391
  schema.enum === undefined &&
@@ -404,7 +395,7 @@ const SchemaValidators = {
404
395
  }
405
396
  }
406
397
  if (this.options.forceMaxLength === true) {
407
- if (schema.type === 'string' || (isArray && schema.type.indexOf('string') !== -1)) {
398
+ if (schema.type === 'string' || (isArray && schema.type.includes('string'))) {
408
399
  if (schema.maxLength === undefined &&
409
400
  schema.format === undefined &&
410
401
  schema.enum === undefined &&
@@ -423,8 +414,7 @@ const SchemaValidators = {
423
414
  report.addError('KEYWORD_MUST_BE', ['allOf', 'an array with at least one element'], undefined, schema, 'allOf');
424
415
  }
425
416
  else {
426
- let idx = schema.allOf.length;
427
- while (idx--) {
417
+ for (let idx = 0; idx < schema.allOf.length; idx++) {
428
418
  report.path.push('allOf');
429
419
  report.path.push(idx);
430
420
  this.validateSchema(report, schema.allOf[idx]);
@@ -442,8 +432,7 @@ const SchemaValidators = {
442
432
  report.addError('KEYWORD_MUST_BE', ['anyOf', 'an array with at least one element'], undefined, schema, 'anyOf');
443
433
  }
444
434
  else {
445
- let idx = schema.anyOf.length;
446
- while (idx--) {
435
+ for (let idx = 0; idx < schema.anyOf.length; idx++) {
447
436
  report.path.push('anyOf');
448
437
  report.path.push(idx);
449
438
  this.validateSchema(report, schema.anyOf[idx]);
@@ -461,8 +450,7 @@ const SchemaValidators = {
461
450
  report.addError('KEYWORD_MUST_BE', ['oneOf', 'an array with at least one element'], undefined, schema, 'oneOf');
462
451
  }
463
452
  else {
464
- let idx = schema.oneOf.length;
465
- while (idx--) {
453
+ for (let idx = 0; idx < schema.oneOf.length; idx++) {
466
454
  report.path.push('oneOf');
467
455
  report.path.push(idx);
468
456
  this.validateSchema(report, schema.oneOf[idx]);
@@ -486,6 +474,48 @@ const SchemaValidators = {
486
474
  report.path.pop();
487
475
  }
488
476
  },
477
+ if: function (report, schema) {
478
+ if (report.options.version !== 'draft-07') {
479
+ return;
480
+ }
481
+ const ifSchema = schema.if;
482
+ const isValidIfSchema = typeof ifSchema === 'boolean' || isObject(ifSchema);
483
+ if (!isValidIfSchema) {
484
+ report.addError('KEYWORD_TYPE_EXPECTED', ['if', ['boolean', 'object']], undefined, schema, 'if');
485
+ return;
486
+ }
487
+ report.path.push('if');
488
+ this.validateSchema(report, ifSchema);
489
+ report.path.pop();
490
+ },
491
+ then: function (report, schema) {
492
+ if (report.options.version !== 'draft-07') {
493
+ return;
494
+ }
495
+ const thenSchema = schema.then;
496
+ const isValidThenSchema = typeof thenSchema === 'boolean' || isObject(thenSchema);
497
+ if (!isValidThenSchema) {
498
+ report.addError('KEYWORD_TYPE_EXPECTED', ['then', ['boolean', 'object']], undefined, schema, 'then');
499
+ return;
500
+ }
501
+ report.path.push('then');
502
+ this.validateSchema(report, thenSchema);
503
+ report.path.pop();
504
+ },
505
+ else: function (report, schema) {
506
+ if (report.options.version !== 'draft-07') {
507
+ return;
508
+ }
509
+ const elseSchema = schema.else;
510
+ const isValidElseSchema = typeof elseSchema === 'boolean' || isObject(elseSchema);
511
+ if (!isValidElseSchema) {
512
+ report.addError('KEYWORD_TYPE_EXPECTED', ['else', ['boolean', 'object']], undefined, schema, 'else');
513
+ return;
514
+ }
515
+ report.path.push('else');
516
+ this.validateSchema(report, elseSchema);
517
+ report.path.pop();
518
+ },
489
519
  definitions: function (report, schema) {
490
520
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.1
491
521
  if (!isObject(schema.definitions)) {
@@ -493,9 +523,8 @@ const SchemaValidators = {
493
523
  }
494
524
  else {
495
525
  const keys = Object.keys(schema.definitions);
496
- let idx = keys.length;
497
- while (idx--) {
498
- const key = keys[idx], val = schema.definitions[key];
526
+ for (const key of keys) {
527
+ const val = schema.definitions[key];
499
528
  report.path.push('definitions');
500
529
  report.path.push(key);
501
530
  this.validateSchema(report, val);
@@ -504,16 +533,56 @@ const SchemaValidators = {
504
533
  }
505
534
  }
506
535
  },
536
+ $defs: function (report, schema) {
537
+ if (report.options.version !== 'draft2019-09' && report.options.version !== 'draft2020-12') {
538
+ return;
539
+ }
540
+ if (!isObject(schema.$defs)) {
541
+ report.addError('KEYWORD_TYPE_EXPECTED', ['$defs', 'object'], undefined, schema, '$defs');
542
+ return;
543
+ }
544
+ const keys = Object.keys(schema.$defs);
545
+ for (const key of keys) {
546
+ const val = schema.$defs[key];
547
+ report.path.push('$defs');
548
+ report.path.push(key);
549
+ this.validateSchema(report, val);
550
+ report.path.pop();
551
+ report.path.pop();
552
+ }
553
+ },
507
554
  format: function (report, schema) {
555
+ if (this.options.formatAssertions === false) {
556
+ return;
557
+ }
508
558
  if (typeof schema.format !== 'string') {
509
559
  report.addError('KEYWORD_TYPE_EXPECTED', ['format', 'string'], undefined, schema, 'format');
510
560
  }
511
561
  else {
512
- if (!isFormatSupported(schema.format, this.options.customFormats) && this.options.ignoreUnknownFormats !== true) {
562
+ const isModernDraft = this.options.version === 'draft2019-09' || this.options.version === 'draft2020-12';
563
+ if (!isFormatSupported(schema.format, this.options.customFormats) &&
564
+ this.options.ignoreUnknownFormats !== true &&
565
+ !isModernDraft) {
513
566
  report.addError('UNKNOWN_FORMAT', [schema.format], undefined, schema, 'format');
514
567
  }
515
568
  }
516
569
  },
570
+ contentEncoding: function (report, schema) {
571
+ if (report.options.version !== 'draft-07') {
572
+ return;
573
+ }
574
+ if (typeof schema.contentEncoding !== 'string') {
575
+ report.addError('KEYWORD_TYPE_EXPECTED', ['contentEncoding', 'string'], undefined, schema, 'contentEncoding');
576
+ }
577
+ },
578
+ contentMediaType: function (report, schema) {
579
+ if (report.options.version !== 'draft-07') {
580
+ return;
581
+ }
582
+ if (typeof schema.contentMediaType !== 'string') {
583
+ report.addError('KEYWORD_TYPE_EXPECTED', ['contentMediaType', 'string'], undefined, schema, 'contentMediaType');
584
+ }
585
+ },
517
586
  id: function (report, schema) {
518
587
  // http://json-schema.org/latest/json-schema-core.html#rfc.section.7.2
519
588
  if (typeof schema.id !== 'string') {
@@ -546,9 +615,8 @@ export class SchemaValidator {
546
615
  return this.validator.options;
547
616
  }
548
617
  validateArrayOfSchemas(report, arr) {
549
- let idx = arr.length;
550
- while (idx--) {
551
- this.validateSchema(report, arr[idx]);
618
+ for (const schema of arr) {
619
+ this.validateSchema(report, schema);
552
620
  }
553
621
  return report.isValid();
554
622
  }
@@ -611,13 +679,11 @@ export class SchemaValidator {
611
679
  }
612
680
  }
613
681
  const keys = Object.keys(schema);
614
- let idx = keys.length;
615
- while (idx--) {
616
- const key = keys[idx];
617
- if (key.indexOf('__') === 0) {
682
+ for (const key of keys) {
683
+ if (key.startsWith('__')) {
618
684
  continue;
619
685
  }
620
- if (Object.prototype.hasOwnProperty.call(SchemaValidators, key)) {
686
+ if (Object.hasOwn(SchemaValidators, key)) {
621
687
  SchemaValidators[key].call(this, report, schema);
622
688
  }
623
689
  else if (!hasParentSchema) {
@@ -633,8 +699,7 @@ export class SchemaValidator {
633
699
  delete tmpSchema.enum;
634
700
  delete tmpSchema.default;
635
701
  report.path.push('enum');
636
- idx = schema.enum.length;
637
- while (idx--) {
702
+ for (let idx = 0; idx < schema.enum.length; idx++) {
638
703
  report.path.push(idx);
639
704
  validate.call(this.validator, report, tmpSchema, schema.enum[idx]);
640
705
  report.path.pop();
@@ -0,0 +1,172 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "http://json-schema.org/draft-07/schema#",
4
+ "title": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "nonNegativeInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "nonNegativeIntegerDefault0": {
16
+ "allOf": [
17
+ { "$ref": "#/definitions/nonNegativeInteger" },
18
+ { "default": 0 }
19
+ ]
20
+ },
21
+ "simpleTypes": {
22
+ "enum": [
23
+ "array",
24
+ "boolean",
25
+ "integer",
26
+ "null",
27
+ "number",
28
+ "object",
29
+ "string"
30
+ ]
31
+ },
32
+ "stringArray": {
33
+ "type": "array",
34
+ "items": { "type": "string" },
35
+ "uniqueItems": true,
36
+ "default": []
37
+ }
38
+ },
39
+ "type": ["object", "boolean"],
40
+ "properties": {
41
+ "$id": {
42
+ "type": "string",
43
+ "format": "uri-reference"
44
+ },
45
+ "$schema": {
46
+ "type": "string",
47
+ "format": "uri"
48
+ },
49
+ "$ref": {
50
+ "type": "string",
51
+ "format": "uri-reference"
52
+ },
53
+ "$comment": {
54
+ "type": "string"
55
+ },
56
+ "title": {
57
+ "type": "string"
58
+ },
59
+ "description": {
60
+ "type": "string"
61
+ },
62
+ "default": true,
63
+ "readOnly": {
64
+ "type": "boolean",
65
+ "default": false
66
+ },
67
+ "writeOnly": {
68
+ "type": "boolean",
69
+ "default": false
70
+ },
71
+ "examples": {
72
+ "type": "array",
73
+ "items": true
74
+ },
75
+ "multipleOf": {
76
+ "type": "number",
77
+ "exclusiveMinimum": 0
78
+ },
79
+ "maximum": {
80
+ "type": "number"
81
+ },
82
+ "exclusiveMaximum": {
83
+ "type": "number"
84
+ },
85
+ "minimum": {
86
+ "type": "number"
87
+ },
88
+ "exclusiveMinimum": {
89
+ "type": "number"
90
+ },
91
+ "maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
92
+ "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
93
+ "pattern": {
94
+ "type": "string",
95
+ "format": "regex"
96
+ },
97
+ "additionalItems": { "$ref": "#" },
98
+ "items": {
99
+ "anyOf": [
100
+ { "$ref": "#" },
101
+ { "$ref": "#/definitions/schemaArray" }
102
+ ],
103
+ "default": true
104
+ },
105
+ "maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
106
+ "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
107
+ "uniqueItems": {
108
+ "type": "boolean",
109
+ "default": false
110
+ },
111
+ "contains": { "$ref": "#" },
112
+ "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
113
+ "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
114
+ "required": { "$ref": "#/definitions/stringArray" },
115
+ "additionalProperties": { "$ref": "#" },
116
+ "definitions": {
117
+ "type": "object",
118
+ "additionalProperties": { "$ref": "#" },
119
+ "default": {}
120
+ },
121
+ "properties": {
122
+ "type": "object",
123
+ "additionalProperties": { "$ref": "#" },
124
+ "default": {}
125
+ },
126
+ "patternProperties": {
127
+ "type": "object",
128
+ "additionalProperties": { "$ref": "#" },
129
+ "propertyNames": { "format": "regex" },
130
+ "default": {}
131
+ },
132
+ "dependencies": {
133
+ "type": "object",
134
+ "additionalProperties": {
135
+ "anyOf": [
136
+ { "$ref": "#" },
137
+ { "$ref": "#/definitions/stringArray" }
138
+ ]
139
+ }
140
+ },
141
+ "propertyNames": { "$ref": "#" },
142
+ "const": true,
143
+ "enum": {
144
+ "type": "array",
145
+ "items": true,
146
+ "minItems": 1,
147
+ "uniqueItems": true
148
+ },
149
+ "type": {
150
+ "anyOf": [
151
+ { "$ref": "#/definitions/simpleTypes" },
152
+ {
153
+ "type": "array",
154
+ "items": { "$ref": "#/definitions/simpleTypes" },
155
+ "minItems": 1,
156
+ "uniqueItems": true
157
+ }
158
+ ]
159
+ },
160
+ "format": { "type": "string" },
161
+ "contentMediaType": { "type": "string" },
162
+ "contentEncoding": { "type": "string" },
163
+ "if": { "$ref": "#" },
164
+ "then": { "$ref": "#" },
165
+ "else": { "$ref": "#" },
166
+ "allOf": { "$ref": "#/definitions/schemaArray" },
167
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
168
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
169
+ "not": { "$ref": "#" }
170
+ },
171
+ "default": true
172
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
3
+ "$id": "https://json-schema.org/draft/2019-09/meta/applicator",
4
+ "$recursiveAnchor": true,
5
+ "title": "Applicator vocabulary meta-schema",
6
+ "type": ["object", "boolean"],
7
+ "properties": {
8
+ "additionalItems": { "$recursiveRef": "#" },
9
+ "unevaluatedItems": { "$recursiveRef": "#" },
10
+ "items": {
11
+ "anyOf": [
12
+ { "$recursiveRef": "#" },
13
+ { "$ref": "#/$defs/schemaArray" }
14
+ ]
15
+ },
16
+ "contains": { "$recursiveRef": "#" },
17
+ "additionalProperties": { "$recursiveRef": "#" },
18
+ "unevaluatedProperties": { "$recursiveRef": "#" },
19
+ "properties": {
20
+ "type": "object",
21
+ "additionalProperties": { "$recursiveRef": "#" },
22
+ "default": {}
23
+ },
24
+ "patternProperties": {
25
+ "type": "object",
26
+ "additionalProperties": { "$recursiveRef": "#" },
27
+ "propertyNames": { "format": "regex" },
28
+ "default": {}
29
+ },
30
+ "dependentSchemas": {
31
+ "type": "object",
32
+ "additionalProperties": {
33
+ "$recursiveRef": "#"
34
+ }
35
+ },
36
+ "propertyNames": { "$recursiveRef": "#" },
37
+ "if": { "$recursiveRef": "#" },
38
+ "then": { "$recursiveRef": "#" },
39
+ "else": { "$recursiveRef": "#" },
40
+ "allOf": { "$ref": "#/$defs/schemaArray" },
41
+ "anyOf": { "$ref": "#/$defs/schemaArray" },
42
+ "oneOf": { "$ref": "#/$defs/schemaArray" },
43
+ "not": { "$recursiveRef": "#" }
44
+ },
45
+ "$defs": {
46
+ "schemaArray": {
47
+ "type": "array",
48
+ "minItems": 1,
49
+ "items": { "$recursiveRef": "#" }
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
3
+ "$id": "https://json-schema.org/draft/2019-09/meta/content",
4
+ "$recursiveAnchor": true,
5
+ "title": "Content vocabulary meta-schema",
6
+ "type": ["object", "boolean"],
7
+ "properties": {
8
+ "contentMediaType": { "type": "string" },
9
+ "contentEncoding": { "type": "string" },
10
+ "contentSchema": { "$recursiveRef": "#" }
11
+ }
12
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
3
+ "$id": "https://json-schema.org/draft/2019-09/meta/core",
4
+ "$recursiveAnchor": true,
5
+ "title": "Core vocabulary meta-schema",
6
+ "type": ["object", "boolean"],
7
+ "properties": {
8
+ "$id": {
9
+ "type": "string",
10
+ "format": "uri-reference",
11
+ "$comment": "Non-empty fragments not allowed.",
12
+ "pattern": "^[^#]*#?$"
13
+ },
14
+ "$schema": {
15
+ "type": "string",
16
+ "format": "uri"
17
+ },
18
+ "$anchor": {
19
+ "type": "string",
20
+ "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$"
21
+ },
22
+ "$ref": {
23
+ "type": "string",
24
+ "format": "uri-reference"
25
+ },
26
+ "$recursiveRef": {
27
+ "type": "string",
28
+ "format": "uri-reference"
29
+ },
30
+ "$recursiveAnchor": {
31
+ "type": "boolean",
32
+ "default": false
33
+ },
34
+ "$vocabulary": {
35
+ "type": "object",
36
+ "propertyNames": {
37
+ "type": "string",
38
+ "format": "uri"
39
+ },
40
+ "additionalProperties": {
41
+ "type": "boolean"
42
+ }
43
+ },
44
+ "$comment": {
45
+ "type": "string"
46
+ },
47
+ "$defs": {
48
+ "type": "object",
49
+ "additionalProperties": { "$recursiveRef": "#" },
50
+ "default": {}
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
3
+ "$id": "https://json-schema.org/draft/2019-09/meta/format",
4
+ "$recursiveAnchor": true,
5
+ "title": "Format vocabulary meta-schema",
6
+ "type": ["object", "boolean"],
7
+ "properties": {
8
+ "format": { "type": "string" }
9
+ }
10
+ }