z-schema 7.0.0 → 7.0.6
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 +7 -11
- package/bin/z-schema +0 -0
- package/cjs/index.d.ts +192 -117
- package/cjs/index.js +949 -998
- package/{src/FormatValidators.ts → dist/format-validators.js} +97 -65
- package/dist/index.js +1 -1
- package/dist/json-schema.js +40 -0
- package/dist/{JsonValidation.js → json-validation.js} +75 -69
- package/dist/{Report.js → report.js} +35 -45
- package/dist/schema-cache.js +109 -0
- package/dist/schema-compiler.js +255 -0
- package/dist/{SchemaValidation.js → schema-validator.js} +153 -149
- package/dist/types/{Errors.d.ts → errors.d.ts} +2 -0
- package/dist/types/format-validators.d.ts +10 -0
- package/dist/types/index.d.ts +10 -1
- package/dist/types/json-schema.d.ts +50 -0
- package/dist/types/json-validation.d.ts +7 -0
- package/dist/types/{Report.d.ts → report.d.ts} +22 -23
- package/dist/types/schema-cache.d.ts +17 -0
- package/dist/types/schema-compiler.d.ts +16 -0
- package/dist/types/schema-validator.d.ts +10 -0
- package/dist/types/utils/array.d.ts +2 -0
- package/dist/types/utils/clone.d.ts +2 -0
- package/dist/types/utils/json.d.ts +7 -0
- package/dist/types/utils/symbols.d.ts +2 -0
- package/dist/types/utils/unicode.d.ts +14 -0
- package/dist/types/utils/uri.d.ts +4 -0
- package/dist/types/utils/what-is.d.ts +3 -0
- package/dist/types/z-schema.d.ts +75 -0
- package/dist/utils/array.js +27 -0
- package/dist/utils/clone.js +61 -0
- package/dist/utils/json.js +59 -0
- package/dist/utils/symbols.js +2 -0
- package/dist/utils/unicode.js +45 -0
- package/dist/utils/uri.js +15 -0
- package/dist/utils/what-is.js +29 -0
- package/dist/{ZSchema.js → z-schema.js} +66 -77
- package/package.json +8 -4
- package/src/{Errors.ts → errors.ts} +4 -0
- package/src/format-validators.ts +191 -0
- package/src/index.ts +12 -1
- package/src/json-schema.ts +97 -0
- package/src/{JsonValidation.ts → json-validation.ts} +137 -127
- package/src/{Report.ts → report.ts} +60 -70
- package/src/schema-cache.ts +122 -0
- package/src/schema-compiler.ts +300 -0
- package/src/{SchemaValidation.ts → schema-validator.ts} +213 -215
- package/src/utils/array.ts +29 -0
- package/src/utils/clone.ts +63 -0
- package/src/utils/json.ts +74 -0
- package/src/utils/symbols.ts +3 -0
- package/src/utils/unicode.ts +43 -0
- package/src/utils/uri.ts +18 -0
- package/src/utils/what-is.ts +46 -0
- package/src/{ZSchema.ts → z-schema.ts} +108 -113
- package/umd/ZSchema.js +949 -998
- package/umd/ZSchema.min.js +1 -1
- package/dist/FormatValidators.js +0 -136
- package/dist/SchemaCache.js +0 -173
- package/dist/SchemaCompilation.js +0 -259
- package/dist/Utils.js +0 -266
- package/dist/types/FormatValidators.d.ts +0 -12
- package/dist/types/JsonValidation.d.ts +0 -37
- package/dist/types/SchemaCache.d.ts +0 -26
- package/dist/types/SchemaCompilation.d.ts +0 -1
- package/dist/types/SchemaValidation.d.ts +0 -6
- package/dist/types/Utils.d.ts +0 -64
- package/dist/types/ZSchema.d.ts +0 -97
- package/src/SchemaCache.ts +0 -189
- package/src/SchemaCompilation.ts +0 -293
- package/src/Utils.ts +0 -286
- /package/dist/{Errors.js → errors.js} +0 -0
- /package/dist/schemas/{hyper-schema.json → draft-04-hyper-schema.json} +0 -0
- /package/dist/schemas/{schema.json → draft-04-schema.json} +0 -0
- /package/src/schemas/{hyper-schema.json → draft-04-hyper-schema.json} +0 -0
- /package/src/schemas/{schema.json → draft-04-schema.json} +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
1
|
+
import { validate } from './json-validation.js';
|
|
2
|
+
import { Report } from './report.js';
|
|
3
|
+
import { isObject, whatIs } from './utils/what-is.js';
|
|
4
|
+
import { shallowClone } from './utils/clone.js';
|
|
5
|
+
import { isUniqueArray } from './utils/array.js';
|
|
6
|
+
import { isFormatSupported } from './format-validators.js';
|
|
5
7
|
const SchemaValidators = {
|
|
6
8
|
$ref: function (report, schema) {
|
|
7
9
|
// http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
|
|
@@ -57,7 +59,7 @@ const SchemaValidators = {
|
|
|
57
59
|
},
|
|
58
60
|
maxLength: function (report, schema) {
|
|
59
61
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.1
|
|
60
|
-
if (
|
|
62
|
+
if (whatIs(schema.maxLength) !== 'integer') {
|
|
61
63
|
report.addError('KEYWORD_TYPE_EXPECTED', ['maxLength', 'integer']);
|
|
62
64
|
}
|
|
63
65
|
else if (schema.maxLength < 0) {
|
|
@@ -66,7 +68,7 @@ const SchemaValidators = {
|
|
|
66
68
|
},
|
|
67
69
|
minLength: function (report, schema) {
|
|
68
70
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.1
|
|
69
|
-
if (
|
|
71
|
+
if (whatIs(schema.minLength) !== 'integer') {
|
|
70
72
|
report.addError('KEYWORD_TYPE_EXPECTED', ['minLength', 'integer']);
|
|
71
73
|
}
|
|
72
74
|
else if (schema.minLength < 0) {
|
|
@@ -89,30 +91,30 @@ const SchemaValidators = {
|
|
|
89
91
|
},
|
|
90
92
|
additionalItems: function (report, schema) {
|
|
91
93
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
|
|
92
|
-
const type =
|
|
94
|
+
const type = whatIs(schema.additionalItems);
|
|
93
95
|
if (type !== 'boolean' && type !== 'object') {
|
|
94
96
|
report.addError('KEYWORD_TYPE_EXPECTED', ['additionalItems', ['boolean', 'object']]);
|
|
95
97
|
}
|
|
96
|
-
else if (
|
|
98
|
+
else if (isObject(schema.additionalItems)) {
|
|
97
99
|
report.path.push('additionalItems');
|
|
98
|
-
validateSchema
|
|
100
|
+
this.validateSchema(report, schema.additionalItems);
|
|
99
101
|
report.path.pop();
|
|
100
102
|
}
|
|
101
103
|
},
|
|
102
104
|
items: function (report, schema) {
|
|
103
105
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
|
|
104
|
-
const type =
|
|
106
|
+
const type = whatIs(schema.items);
|
|
105
107
|
if (type === 'object') {
|
|
106
108
|
report.path.push('items');
|
|
107
|
-
validateSchema
|
|
109
|
+
this.validateSchema(report, schema.items);
|
|
108
110
|
report.path.pop();
|
|
109
111
|
}
|
|
110
|
-
else if (
|
|
112
|
+
else if (Array.isArray(schema.items)) {
|
|
111
113
|
let idx = schema.items.length;
|
|
112
114
|
while (idx--) {
|
|
113
115
|
report.path.push('items');
|
|
114
|
-
report.path.push(idx
|
|
115
|
-
validateSchema
|
|
116
|
+
report.path.push(idx);
|
|
117
|
+
this.validateSchema(report, schema.items[idx]);
|
|
116
118
|
report.path.pop();
|
|
117
119
|
report.path.pop();
|
|
118
120
|
}
|
|
@@ -140,7 +142,7 @@ const SchemaValidators = {
|
|
|
140
142
|
},
|
|
141
143
|
minItems: function (report, schema) {
|
|
142
144
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.1
|
|
143
|
-
if (
|
|
145
|
+
if (whatIs(schema.minItems) !== 'integer') {
|
|
144
146
|
report.addError('KEYWORD_TYPE_EXPECTED', ['minItems', 'integer']);
|
|
145
147
|
}
|
|
146
148
|
else if (schema.minItems < 0) {
|
|
@@ -155,7 +157,7 @@ const SchemaValidators = {
|
|
|
155
157
|
},
|
|
156
158
|
maxProperties: function (report, schema) {
|
|
157
159
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.1
|
|
158
|
-
if (
|
|
160
|
+
if (whatIs(schema.maxProperties) !== 'integer') {
|
|
159
161
|
report.addError('KEYWORD_TYPE_EXPECTED', ['maxProperties', 'integer']);
|
|
160
162
|
}
|
|
161
163
|
else if (schema.maxProperties < 0) {
|
|
@@ -164,7 +166,7 @@ const SchemaValidators = {
|
|
|
164
166
|
},
|
|
165
167
|
minProperties: function (report, schema) {
|
|
166
168
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.1
|
|
167
|
-
if (
|
|
169
|
+
if (whatIs(schema.minProperties) !== 'integer') {
|
|
168
170
|
report.addError('KEYWORD_TYPE_EXPECTED', ['minProperties', 'integer']);
|
|
169
171
|
}
|
|
170
172
|
else if (schema.minProperties < 0) {
|
|
@@ -173,7 +175,7 @@ const SchemaValidators = {
|
|
|
173
175
|
},
|
|
174
176
|
required: function (report, schema) {
|
|
175
177
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.1
|
|
176
|
-
if (
|
|
178
|
+
if (whatIs(schema.required) !== 'array') {
|
|
177
179
|
report.addError('KEYWORD_TYPE_EXPECTED', ['required', 'array']);
|
|
178
180
|
}
|
|
179
181
|
else if (schema.required.length === 0) {
|
|
@@ -186,36 +188,37 @@ const SchemaValidators = {
|
|
|
186
188
|
report.addError('KEYWORD_VALUE_TYPE', ['required', 'string']);
|
|
187
189
|
}
|
|
188
190
|
}
|
|
189
|
-
if (
|
|
191
|
+
if (isUniqueArray(schema.required) === false) {
|
|
190
192
|
report.addError('KEYWORD_MUST_BE', ['required', 'an array with unique items']);
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
195
|
},
|
|
194
196
|
additionalProperties: function (report, schema) {
|
|
195
197
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
|
|
196
|
-
const type =
|
|
198
|
+
const type = whatIs(schema.additionalProperties);
|
|
197
199
|
if (type !== 'boolean' && type !== 'object') {
|
|
198
200
|
report.addError('KEYWORD_TYPE_EXPECTED', ['additionalProperties', ['boolean', 'object']]);
|
|
199
201
|
}
|
|
200
|
-
else if (
|
|
202
|
+
else if (isObject(schema.additionalProperties)) {
|
|
201
203
|
report.path.push('additionalProperties');
|
|
202
|
-
validateSchema
|
|
204
|
+
this.validateSchema(report, schema.additionalProperties);
|
|
203
205
|
report.path.pop();
|
|
204
206
|
}
|
|
205
207
|
},
|
|
206
208
|
properties: function (report, schema) {
|
|
207
209
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
|
|
208
|
-
if (
|
|
210
|
+
if (whatIs(schema.properties) !== 'object') {
|
|
209
211
|
report.addError('KEYWORD_TYPE_EXPECTED', ['properties', 'object']);
|
|
210
212
|
return;
|
|
211
213
|
}
|
|
212
214
|
const keys = Object.keys(schema.properties);
|
|
213
215
|
let idx = keys.length;
|
|
214
216
|
while (idx--) {
|
|
215
|
-
const key = keys[idx]
|
|
217
|
+
const key = keys[idx];
|
|
218
|
+
const val = schema.properties[key];
|
|
216
219
|
report.path.push('properties');
|
|
217
220
|
report.path.push(key);
|
|
218
|
-
validateSchema
|
|
221
|
+
this.validateSchema(report, val);
|
|
219
222
|
report.path.pop();
|
|
220
223
|
report.path.pop();
|
|
221
224
|
}
|
|
@@ -234,7 +237,7 @@ const SchemaValidators = {
|
|
|
234
237
|
},
|
|
235
238
|
patternProperties: function (report, schema) {
|
|
236
239
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
|
|
237
|
-
if (
|
|
240
|
+
if (whatIs(schema.patternProperties) !== 'object') {
|
|
238
241
|
report.addError('KEYWORD_TYPE_EXPECTED', ['patternProperties', 'object']);
|
|
239
242
|
return;
|
|
240
243
|
}
|
|
@@ -249,8 +252,8 @@ const SchemaValidators = {
|
|
|
249
252
|
report.addError('KEYWORD_PATTERN', ['patternProperties', key]);
|
|
250
253
|
}
|
|
251
254
|
report.path.push('patternProperties');
|
|
252
|
-
report.path.push(key
|
|
253
|
-
validateSchema
|
|
255
|
+
report.path.push(key);
|
|
256
|
+
this.validateSchema(report, val);
|
|
254
257
|
report.path.pop();
|
|
255
258
|
report.path.pop();
|
|
256
259
|
}
|
|
@@ -261,18 +264,20 @@ const SchemaValidators = {
|
|
|
261
264
|
},
|
|
262
265
|
dependencies: function (report, schema) {
|
|
263
266
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.1
|
|
264
|
-
if (
|
|
267
|
+
if (whatIs(schema.dependencies) !== 'object') {
|
|
265
268
|
report.addError('KEYWORD_TYPE_EXPECTED', ['dependencies', 'object']);
|
|
266
269
|
}
|
|
267
270
|
else {
|
|
268
271
|
const keys = Object.keys(schema.dependencies);
|
|
269
272
|
let idx = keys.length;
|
|
270
273
|
while (idx--) {
|
|
271
|
-
const schemaKey = keys[idx]
|
|
274
|
+
const schemaKey = keys[idx];
|
|
275
|
+
const schemaDependency = schema.dependencies[schemaKey];
|
|
276
|
+
const type = whatIs(schemaDependency);
|
|
272
277
|
if (type === 'object') {
|
|
273
278
|
report.path.push('dependencies');
|
|
274
279
|
report.path.push(schemaKey);
|
|
275
|
-
validateSchema
|
|
280
|
+
this.validateSchema(report, schemaDependency);
|
|
276
281
|
report.path.pop();
|
|
277
282
|
report.path.pop();
|
|
278
283
|
}
|
|
@@ -286,7 +291,7 @@ const SchemaValidators = {
|
|
|
286
291
|
report.addError('KEYWORD_VALUE_TYPE', ['dependensices', 'string']);
|
|
287
292
|
}
|
|
288
293
|
}
|
|
289
|
-
if (
|
|
294
|
+
if (isUniqueArray(schemaDependency) === false) {
|
|
290
295
|
report.addError('KEYWORD_MUST_BE', ['dependencies', 'an array with unique items']);
|
|
291
296
|
}
|
|
292
297
|
}
|
|
@@ -304,21 +309,23 @@ const SchemaValidators = {
|
|
|
304
309
|
else if (schema.enum.length === 0) {
|
|
305
310
|
report.addError('KEYWORD_MUST_BE', ['enum', 'an array with at least one element']);
|
|
306
311
|
}
|
|
307
|
-
else if (
|
|
312
|
+
else if (isUniqueArray(schema.enum) === false) {
|
|
308
313
|
report.addError('KEYWORD_MUST_BE', ['enum', 'an array with unique elements']);
|
|
309
314
|
}
|
|
310
315
|
},
|
|
311
316
|
type: function (report, schema) {
|
|
312
317
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.1
|
|
313
|
-
const primitiveTypes = ['array', 'boolean', 'integer', 'number', 'null', 'object', 'string']
|
|
314
|
-
|
|
318
|
+
const primitiveTypes = ['array', 'boolean', 'integer', 'number', 'null', 'object', 'string'];
|
|
319
|
+
const primitiveTypeStr = primitiveTypes.join(',');
|
|
320
|
+
const isArray = Array.isArray(schema.type);
|
|
321
|
+
if (Array.isArray(schema.type)) {
|
|
315
322
|
let idx = schema.type.length;
|
|
316
323
|
while (idx--) {
|
|
317
324
|
if (primitiveTypes.indexOf(schema.type[idx]) === -1) {
|
|
318
325
|
report.addError('KEYWORD_TYPE_EXPECTED', ['type', primitiveTypeStr]);
|
|
319
326
|
}
|
|
320
327
|
}
|
|
321
|
-
if (
|
|
328
|
+
if (isUniqueArray(schema.type) === false) {
|
|
322
329
|
report.addError('KEYWORD_MUST_BE', ['type', 'an object with unique properties']);
|
|
323
330
|
}
|
|
324
331
|
}
|
|
@@ -405,8 +412,8 @@ const SchemaValidators = {
|
|
|
405
412
|
let idx = schema.allOf.length;
|
|
406
413
|
while (idx--) {
|
|
407
414
|
report.path.push('allOf');
|
|
408
|
-
report.path.push(idx
|
|
409
|
-
validateSchema
|
|
415
|
+
report.path.push(idx);
|
|
416
|
+
this.validateSchema(report, schema.allOf[idx]);
|
|
410
417
|
report.path.pop();
|
|
411
418
|
report.path.pop();
|
|
412
419
|
}
|
|
@@ -424,8 +431,8 @@ const SchemaValidators = {
|
|
|
424
431
|
let idx = schema.anyOf.length;
|
|
425
432
|
while (idx--) {
|
|
426
433
|
report.path.push('anyOf');
|
|
427
|
-
report.path.push(idx
|
|
428
|
-
validateSchema
|
|
434
|
+
report.path.push(idx);
|
|
435
|
+
this.validateSchema(report, schema.anyOf[idx]);
|
|
429
436
|
report.path.pop();
|
|
430
437
|
report.path.pop();
|
|
431
438
|
}
|
|
@@ -443,8 +450,8 @@ const SchemaValidators = {
|
|
|
443
450
|
let idx = schema.oneOf.length;
|
|
444
451
|
while (idx--) {
|
|
445
452
|
report.path.push('oneOf');
|
|
446
|
-
report.path.push(idx
|
|
447
|
-
validateSchema
|
|
453
|
+
report.path.push(idx);
|
|
454
|
+
this.validateSchema(report, schema.oneOf[idx]);
|
|
448
455
|
report.path.pop();
|
|
449
456
|
report.path.pop();
|
|
450
457
|
}
|
|
@@ -452,18 +459,18 @@ const SchemaValidators = {
|
|
|
452
459
|
},
|
|
453
460
|
not: function (report, schema) {
|
|
454
461
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.1
|
|
455
|
-
if (
|
|
462
|
+
if (whatIs(schema.not) !== 'object') {
|
|
456
463
|
report.addError('KEYWORD_TYPE_EXPECTED', ['not', 'object']);
|
|
457
464
|
}
|
|
458
465
|
else {
|
|
459
466
|
report.path.push('not');
|
|
460
|
-
validateSchema
|
|
467
|
+
this.validateSchema(report, schema.not);
|
|
461
468
|
report.path.pop();
|
|
462
469
|
}
|
|
463
470
|
},
|
|
464
471
|
definitions: function (report, schema) {
|
|
465
472
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.1
|
|
466
|
-
if (
|
|
473
|
+
if (whatIs(schema.definitions) !== 'object') {
|
|
467
474
|
report.addError('KEYWORD_TYPE_EXPECTED', ['definitions', 'object']);
|
|
468
475
|
}
|
|
469
476
|
else {
|
|
@@ -473,7 +480,7 @@ const SchemaValidators = {
|
|
|
473
480
|
const key = keys[idx], val = schema.definitions[key];
|
|
474
481
|
report.path.push('definitions');
|
|
475
482
|
report.path.push(key);
|
|
476
|
-
validateSchema
|
|
483
|
+
this.validateSchema(report, val);
|
|
477
484
|
report.path.pop();
|
|
478
485
|
report.path.pop();
|
|
479
486
|
}
|
|
@@ -484,7 +491,7 @@ const SchemaValidators = {
|
|
|
484
491
|
report.addError('KEYWORD_TYPE_EXPECTED', ['format', 'string']);
|
|
485
492
|
}
|
|
486
493
|
else {
|
|
487
|
-
if (
|
|
494
|
+
if (!isFormatSupported(schema.format) && this.options.ignoreUnknownFormats !== true) {
|
|
488
495
|
report.addError('UNKNOWN_FORMAT', [schema.format]);
|
|
489
496
|
}
|
|
490
497
|
}
|
|
@@ -507,125 +514,122 @@ const SchemaValidators = {
|
|
|
507
514
|
report.addError('KEYWORD_TYPE_EXPECTED', ['description', 'string']);
|
|
508
515
|
}
|
|
509
516
|
},
|
|
510
|
-
default: function (
|
|
517
|
+
default: function () {
|
|
511
518
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.2
|
|
512
519
|
// There are no restrictions placed on the value of this keyword.
|
|
513
520
|
},
|
|
514
521
|
};
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
*
|
|
520
|
-
* @returns {boolean}
|
|
521
|
-
*/
|
|
522
|
-
const validateArrayOfSchemas = function (report, arr) {
|
|
523
|
-
let idx = arr.length;
|
|
524
|
-
while (idx--) {
|
|
525
|
-
validateSchema.call(this, report, arr[idx]);
|
|
522
|
+
export class SchemaValidator {
|
|
523
|
+
validator;
|
|
524
|
+
constructor(validator) {
|
|
525
|
+
this.validator = validator;
|
|
526
526
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
*
|
|
531
|
-
* @param {Report} report
|
|
532
|
-
* @param {*} schema
|
|
533
|
-
*/
|
|
534
|
-
export function validateSchema(report, schema) {
|
|
535
|
-
report.commonErrorMessage = 'SCHEMA_VALIDATION_FAILED';
|
|
536
|
-
// if schema is an array, assume it's an array of schemas
|
|
537
|
-
if (Array.isArray(schema)) {
|
|
538
|
-
return validateArrayOfSchemas.call(this, report, schema);
|
|
527
|
+
get options() {
|
|
528
|
+
return this.validator.options;
|
|
539
529
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
530
|
+
validateArrayOfSchemas(report, arr) {
|
|
531
|
+
let idx = arr.length;
|
|
532
|
+
while (idx--) {
|
|
533
|
+
this.validateSchema(report, arr[idx]);
|
|
534
|
+
}
|
|
535
|
+
return report.isValid();
|
|
543
536
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
if (
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
537
|
+
validateSchema(report, schema) {
|
|
538
|
+
report.commonErrorMessage = 'SCHEMA_VALIDATION_FAILED';
|
|
539
|
+
// if schema is an array, assume it's an array of schemas
|
|
540
|
+
if (Array.isArray(schema)) {
|
|
541
|
+
return this.validateArrayOfSchemas(report, schema);
|
|
542
|
+
}
|
|
543
|
+
// do not revalidate schema that has already been validated once
|
|
544
|
+
if (schema.__$validated) {
|
|
545
|
+
return true;
|
|
546
|
+
}
|
|
547
|
+
// if $schema is present, this schema should validate against that $schema
|
|
548
|
+
const hasParentSchema = schema.$schema && schema.id !== schema.$schema;
|
|
549
|
+
if (hasParentSchema) {
|
|
550
|
+
if (schema.__$schemaResolved && schema.__$schemaResolved !== schema) {
|
|
551
|
+
const subReport = new Report(report);
|
|
552
|
+
const valid = validate.call(this.validator, subReport, schema.__$schemaResolved, schema);
|
|
553
|
+
if (valid === false) {
|
|
554
|
+
report.addError('PARENT_SCHEMA_VALIDATION_FAILED', undefined, subReport);
|
|
555
|
+
}
|
|
552
556
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
+
else {
|
|
558
|
+
if (this.validator.options.ignoreUnresolvableReferences !== true) {
|
|
559
|
+
report.addError('REF_UNRESOLVED', [schema.$schema]);
|
|
560
|
+
}
|
|
557
561
|
}
|
|
558
562
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
schemas = schemas.concat(schema.anyOf);
|
|
566
|
-
}
|
|
567
|
-
if (Array.isArray(schema.oneOf)) {
|
|
568
|
-
schemas = schemas.concat(schema.oneOf);
|
|
569
|
-
}
|
|
570
|
-
if (Array.isArray(schema.allOf)) {
|
|
571
|
-
schemas = schemas.concat(schema.allOf);
|
|
572
|
-
}
|
|
573
|
-
schemas.forEach(function (sch) {
|
|
574
|
-
if (!sch.type) {
|
|
575
|
-
sch.type = schema.type;
|
|
563
|
+
if (this.validator.options.noTypeless === true) {
|
|
564
|
+
// issue #36 - inherit type to anyOf, oneOf, allOf if noTypeless is defined
|
|
565
|
+
if (schema.type !== undefined) {
|
|
566
|
+
let schemas = [];
|
|
567
|
+
if (Array.isArray(schema.anyOf)) {
|
|
568
|
+
schemas = schemas.concat(schema.anyOf);
|
|
576
569
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
570
|
+
if (Array.isArray(schema.oneOf)) {
|
|
571
|
+
schemas = schemas.concat(schema.oneOf);
|
|
572
|
+
}
|
|
573
|
+
if (Array.isArray(schema.allOf)) {
|
|
574
|
+
schemas = schemas.concat(schema.allOf);
|
|
575
|
+
}
|
|
576
|
+
schemas.forEach(function (sch) {
|
|
577
|
+
if (!sch.type) {
|
|
578
|
+
sch.type = schema.type;
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
// end issue #36
|
|
583
|
+
if (schema.enum === undefined &&
|
|
584
|
+
schema.type === undefined &&
|
|
585
|
+
schema.anyOf === undefined &&
|
|
586
|
+
schema.oneOf === undefined &&
|
|
587
|
+
schema.not === undefined &&
|
|
588
|
+
schema.$ref === undefined) {
|
|
589
|
+
report.addError('KEYWORD_UNDEFINED_STRICT', ['type']);
|
|
590
|
+
}
|
|
598
591
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
592
|
+
const keys = Object.keys(schema);
|
|
593
|
+
let idx = keys.length;
|
|
594
|
+
while (idx--) {
|
|
595
|
+
const key = keys[idx];
|
|
596
|
+
if (key.indexOf('__') === 0) {
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
if (Object.prototype.hasOwnProperty.call(SchemaValidators, key)) {
|
|
600
|
+
SchemaValidators[key].call(this, report, schema);
|
|
601
|
+
}
|
|
602
|
+
else if (!hasParentSchema) {
|
|
603
|
+
if (this.validator.options.noExtraKeywords === true) {
|
|
604
|
+
report.addError('KEYWORD_UNEXPECTED', [key]);
|
|
605
|
+
}
|
|
602
606
|
}
|
|
603
607
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
608
|
+
if (this.validator.options.pedanticCheck === true) {
|
|
609
|
+
if (schema.enum) {
|
|
610
|
+
// break recursion
|
|
611
|
+
const tmpSchema = shallowClone(schema);
|
|
612
|
+
delete tmpSchema.enum;
|
|
613
|
+
delete tmpSchema.default;
|
|
614
|
+
report.path.push('enum');
|
|
615
|
+
idx = schema.enum.length;
|
|
616
|
+
while (idx--) {
|
|
617
|
+
report.path.push(idx);
|
|
618
|
+
validate.call(this.validator, report, tmpSchema, schema.enum[idx]);
|
|
619
|
+
report.path.pop();
|
|
620
|
+
}
|
|
621
|
+
report.path.pop();
|
|
622
|
+
}
|
|
623
|
+
if (schema.default) {
|
|
624
|
+
report.path.push('default');
|
|
625
|
+
validate.call(this.validator, report, schema, schema.default);
|
|
616
626
|
report.path.pop();
|
|
617
627
|
}
|
|
618
|
-
report.path.pop();
|
|
619
628
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
report.path.pop();
|
|
629
|
+
const isValid = report.isValid();
|
|
630
|
+
if (isValid) {
|
|
631
|
+
schema.__$validated = true;
|
|
624
632
|
}
|
|
633
|
+
return isValid;
|
|
625
634
|
}
|
|
626
|
-
const isValid = report.isValid();
|
|
627
|
-
if (isValid) {
|
|
628
|
-
schema.__$validated = true;
|
|
629
|
-
}
|
|
630
|
-
return isValid;
|
|
631
635
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type FormatValidatorFn = (input: unknown) => boolean;
|
|
2
|
+
export interface FormatValidatorsOptions {
|
|
3
|
+
strictUris?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function getFormatValidators(options?: FormatValidatorsOptions): Record<string, FormatValidatorFn>;
|
|
6
|
+
export declare function registerFormat(name: string, validatorFunction: FormatValidatorFn): void;
|
|
7
|
+
export declare function unregisterFormat(name: string): void;
|
|
8
|
+
export declare function getSupportedFormats(): string[];
|
|
9
|
+
export declare function isFormatSupported(name: string): boolean;
|
|
10
|
+
export declare function getRegisteredFormats(): string[];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
import { ZSchema } from './
|
|
1
|
+
import { ZSchema } from './z-schema.js';
|
|
2
|
+
export type * from './errors.js';
|
|
3
|
+
export type * from './format-validators.js';
|
|
4
|
+
export type * from './json-schema.js';
|
|
5
|
+
export type * from './json-validation.js';
|
|
6
|
+
export type * from './report.js';
|
|
7
|
+
export type * from './schema-cache.js';
|
|
8
|
+
export type * from './schema-compiler.js';
|
|
9
|
+
export type * from './schema-validator.js';
|
|
10
|
+
export type * from './z-schema.js';
|
|
2
11
|
export default ZSchema;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Reference } from './schema-compiler.js';
|
|
2
|
+
export interface JsonSchema {
|
|
3
|
+
$ref?: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
$schema?: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
default?: unknown;
|
|
9
|
+
definitions?: Record<string, JsonSchema>;
|
|
10
|
+
type?: string | string[];
|
|
11
|
+
properties?: Record<string, JsonSchema>;
|
|
12
|
+
patternProperties?: Record<string, JsonSchema>;
|
|
13
|
+
dependencies?: Record<string, string[]>;
|
|
14
|
+
multipleOf?: number;
|
|
15
|
+
minimum?: number;
|
|
16
|
+
exclusiveMinimum?: boolean;
|
|
17
|
+
maximum?: number;
|
|
18
|
+
exclusiveMaximum?: boolean;
|
|
19
|
+
minLength?: number;
|
|
20
|
+
maxLength?: number;
|
|
21
|
+
pattern?: string;
|
|
22
|
+
additionalItems?: boolean | JsonSchema;
|
|
23
|
+
items?: JsonSchema | JsonSchema[];
|
|
24
|
+
minItems?: number;
|
|
25
|
+
maxItems?: number;
|
|
26
|
+
uniqueItems?: boolean;
|
|
27
|
+
minProperties?: number;
|
|
28
|
+
maxProperties?: number;
|
|
29
|
+
required?: string[];
|
|
30
|
+
additionalProperties?: boolean | JsonSchema;
|
|
31
|
+
enum?: Array<unknown>;
|
|
32
|
+
format?: string;
|
|
33
|
+
allOf?: JsonSchema[];
|
|
34
|
+
anyOf?: JsonSchema[];
|
|
35
|
+
oneOf?: JsonSchema[];
|
|
36
|
+
not?: JsonSchema;
|
|
37
|
+
}
|
|
38
|
+
export type JsonSchemaType = 'array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string';
|
|
39
|
+
export interface ZSchemaInternalProperties {
|
|
40
|
+
__$compiled?: unknown;
|
|
41
|
+
__$missingReferences?: Reference[];
|
|
42
|
+
__$refResolved?: JsonSchema;
|
|
43
|
+
__$schemaResolved?: unknown;
|
|
44
|
+
__$validated?: boolean;
|
|
45
|
+
__$validationOptions?: unknown;
|
|
46
|
+
__$visited?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface JsonSchemaInternal extends JsonSchema, ZSchemaInternalProperties {
|
|
49
|
+
}
|
|
50
|
+
export declare const findId: (schema: JsonSchemaInternal, id: string) => JsonSchemaInternal | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Report } from './report.js';
|
|
2
|
+
import { JsonSchema, JsonSchemaInternal } from './json-schema.js';
|
|
3
|
+
import type { ZSchema } from './z-schema.js';
|
|
4
|
+
type JsonValidatorFn = (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) => void;
|
|
5
|
+
export declare const JsonValidators: Record<keyof JsonSchema, JsonValidatorFn>;
|
|
6
|
+
export declare function validate(this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown): boolean;
|
|
7
|
+
export {};
|