z-schema 9.0.1 → 10.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.
- package/README.md +123 -191
- package/cjs/index.d.ts +33 -9
- package/cjs/index.js +4799 -3984
- package/dist/errors.js +5 -0
- package/dist/format-validators.js +65 -0
- package/dist/json-schema-versions.js +5 -0
- package/dist/json-schema.js +11 -4
- package/dist/json-validation.js +151 -10
- package/dist/report.js +2 -3
- package/dist/schema-cache.js +23 -2
- package/dist/schema-compiler.js +25 -10
- package/dist/schema-validator.js +66 -45
- package/dist/schemas/draft-06-hyper-schema.json +132 -0
- package/dist/schemas/draft-06-links.json +43 -0
- package/dist/schemas/draft-06-schema.json +155 -0
- package/dist/types/errors.d.ts +4 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/json-schema-versions.d.ts +23 -0
- package/dist/types/json-schema.d.ts +5 -9
- package/dist/types/json-validation.d.ts +3 -3
- package/dist/types/report.d.ts +3 -3
- package/dist/types/schema-cache.d.ts +1 -1
- package/dist/types/schema-compiler.d.ts +1 -1
- package/dist/types/schema-validator.d.ts +1 -1
- package/dist/types/utils/what-is.d.ts +1 -0
- package/dist/types/z-schema-base.d.ts +1 -1
- package/dist/types/z-schema-options.d.ts +1 -1
- package/dist/types/z-schema-reader.d.ts +1 -1
- package/dist/types/z-schema-versions.d.ts +1 -0
- package/dist/types/z-schema.d.ts +10 -1
- package/dist/utils/schema-regex.js +4 -3
- package/dist/utils/what-is.js +4 -1
- package/dist/z-schema-base.js +4 -5
- package/dist/z-schema-options.js +3 -1
- package/dist/z-schema-versions.js +27 -0
- package/dist/z-schema.js +21 -7
- package/package.json +2 -2
- package/src/errors.ts +6 -0
- package/src/format-validators.ts +65 -0
- package/src/index.ts +2 -1
- package/src/json-schema-versions.ts +34 -0
- package/src/json-schema.ts +22 -16
- package/src/json-validation.ts +183 -13
- package/src/report.ts +5 -6
- package/src/schema-cache.ts +25 -3
- package/src/schema-compiler.ts +25 -11
- package/src/schema-validator.ts +128 -62
- package/src/schemas/draft-06-hyper-schema.json +133 -0
- package/src/schemas/draft-06-links.json +43 -0
- package/src/schemas/draft-06-schema.json +155 -0
- package/src/utils/schema-regex.ts +5 -3
- package/src/utils/what-is.ts +5 -1
- package/src/z-schema-base.ts +5 -6
- package/src/z-schema-options.ts +3 -2
- package/src/z-schema-reader.ts +1 -1
- package/src/z-schema-versions.ts +38 -0
- package/src/z-schema.ts +27 -11
- package/umd/ZSchema.js +5100 -4285
- package/umd/ZSchema.min.js +1 -1
package/src/schema-validator.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import type { JsonSchema, JsonSchemaInternal } from './json-schema.js';
|
|
1
|
+
import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
|
|
2
2
|
import type { ZSchemaBase } from './z-schema-base.js';
|
|
3
3
|
|
|
4
4
|
import { isFormatSupported } from './format-validators.js';
|
|
5
|
+
import { getId } from './json-schema.js';
|
|
5
6
|
import { validate } from './json-validation.js';
|
|
6
7
|
import { Report } from './report.js';
|
|
7
8
|
import { isUniqueArray } from './utils/array.js';
|
|
8
9
|
import { shallowClone } from './utils/clone.js';
|
|
9
10
|
import { compileSchemaRegex } from './utils/schema-regex.js';
|
|
10
|
-
import {
|
|
11
|
+
import { isInteger, isObject } from './utils/what-is.js';
|
|
11
12
|
|
|
12
13
|
const SchemaValidators = {
|
|
13
14
|
$ref: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
@@ -39,10 +40,28 @@ const SchemaValidators = {
|
|
|
39
40
|
},
|
|
40
41
|
exclusiveMaximum: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
41
42
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.1
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if (report.options.version === 'draft-04') {
|
|
44
|
+
if (typeof schema.exclusiveMaximum !== 'boolean') {
|
|
45
|
+
report.addError(
|
|
46
|
+
'KEYWORD_TYPE_EXPECTED',
|
|
47
|
+
['exclusiveMaximum', 'boolean'],
|
|
48
|
+
undefined,
|
|
49
|
+
schema,
|
|
50
|
+
'exclusiveMaximum'
|
|
51
|
+
);
|
|
52
|
+
} else if (schema.maximum === undefined) {
|
|
53
|
+
report.addError('KEYWORD_DEPENDENCY', ['exclusiveMaximum', 'maximum'], undefined, schema, 'exclusiveMaximum');
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
if (typeof schema.exclusiveMaximum !== 'boolean' && typeof schema.exclusiveMaximum !== 'number') {
|
|
57
|
+
report.addError(
|
|
58
|
+
'KEYWORD_TYPE_EXPECTED',
|
|
59
|
+
['exclusiveMaximum', ['boolean', 'number']],
|
|
60
|
+
undefined,
|
|
61
|
+
schema,
|
|
62
|
+
'exclusiveMaximum'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
46
65
|
}
|
|
47
66
|
},
|
|
48
67
|
minimum: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
@@ -52,26 +71,44 @@ const SchemaValidators = {
|
|
|
52
71
|
}
|
|
53
72
|
},
|
|
54
73
|
exclusiveMinimum: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
if (report.options.version === 'draft-04') {
|
|
75
|
+
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.1
|
|
76
|
+
if (typeof schema.exclusiveMinimum !== 'boolean') {
|
|
77
|
+
report.addError(
|
|
78
|
+
'KEYWORD_TYPE_EXPECTED',
|
|
79
|
+
['exclusiveMinimum', 'boolean'],
|
|
80
|
+
undefined,
|
|
81
|
+
schema,
|
|
82
|
+
'exclusiveMinimum'
|
|
83
|
+
);
|
|
84
|
+
} else if (schema.minimum === undefined) {
|
|
85
|
+
report.addError('KEYWORD_DEPENDENCY', ['exclusiveMinimum', 'minimum'], undefined, schema, 'exclusiveMinimum');
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (typeof schema.exclusiveMinimum !== 'boolean' && typeof schema.exclusiveMinimum !== 'number') {
|
|
89
|
+
report.addError(
|
|
90
|
+
'KEYWORD_TYPE_EXPECTED',
|
|
91
|
+
['exclusiveMinimum', ['boolean', 'number']],
|
|
92
|
+
undefined,
|
|
93
|
+
schema,
|
|
94
|
+
'exclusiveMinimum'
|
|
95
|
+
);
|
|
96
|
+
}
|
|
60
97
|
}
|
|
61
98
|
},
|
|
62
99
|
maxLength: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
63
100
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.1
|
|
64
|
-
if (
|
|
101
|
+
if (!isInteger(schema.maxLength)) {
|
|
65
102
|
report.addError('KEYWORD_TYPE_EXPECTED', ['maxLength', 'integer'], undefined, schema, 'maxLength');
|
|
66
|
-
} else if (schema.maxLength
|
|
103
|
+
} else if (schema.maxLength < 0) {
|
|
67
104
|
report.addError('KEYWORD_MUST_BE', ['maxLength', 'greater than, or equal to 0'], undefined, schema, 'maxLength');
|
|
68
105
|
}
|
|
69
106
|
},
|
|
70
107
|
minLength: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
71
108
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.1
|
|
72
|
-
if (
|
|
109
|
+
if (!isInteger(schema.minLength)) {
|
|
73
110
|
report.addError('KEYWORD_TYPE_EXPECTED', ['minLength', 'integer'], undefined, schema, 'minLength');
|
|
74
|
-
} else if (schema.minLength
|
|
111
|
+
} else if (schema.minLength < 0) {
|
|
75
112
|
report.addError('KEYWORD_MUST_BE', ['minLength', 'greater than, or equal to 0'], undefined, schema, 'minLength');
|
|
76
113
|
}
|
|
77
114
|
},
|
|
@@ -96,8 +133,7 @@ const SchemaValidators = {
|
|
|
96
133
|
},
|
|
97
134
|
additionalItems: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
98
135
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
|
|
99
|
-
|
|
100
|
-
if (type !== 'boolean' && type !== 'object') {
|
|
136
|
+
if (typeof schema.additionalItems !== 'boolean' && !isObject(schema.additionalItems)) {
|
|
101
137
|
report.addError(
|
|
102
138
|
'KEYWORD_TYPE_EXPECTED',
|
|
103
139
|
['additionalItems', ['boolean', 'object']],
|
|
@@ -113,12 +149,7 @@ const SchemaValidators = {
|
|
|
113
149
|
},
|
|
114
150
|
items: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
115
151
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.1
|
|
116
|
-
|
|
117
|
-
if (type === 'object') {
|
|
118
|
-
report.path.push('items');
|
|
119
|
-
this.validateSchema(report, schema.items!);
|
|
120
|
-
report.path.pop();
|
|
121
|
-
} else if (Array.isArray(schema.items)) {
|
|
152
|
+
if (Array.isArray(schema.items)) {
|
|
122
153
|
let idx = schema.items.length;
|
|
123
154
|
while (idx--) {
|
|
124
155
|
report.path.push('items');
|
|
@@ -127,8 +158,18 @@ const SchemaValidators = {
|
|
|
127
158
|
report.path.pop();
|
|
128
159
|
report.path.pop();
|
|
129
160
|
}
|
|
161
|
+
} else if (isObject(schema.items) || (report.options.version !== 'draft-04' && typeof schema.items === 'boolean')) {
|
|
162
|
+
report.path.push('items');
|
|
163
|
+
this.validateSchema(report, schema.items as JsonSchemaInternal);
|
|
164
|
+
report.path.pop();
|
|
130
165
|
} else {
|
|
131
|
-
report.addError(
|
|
166
|
+
report.addError(
|
|
167
|
+
'KEYWORD_TYPE_EXPECTED',
|
|
168
|
+
['items', report.options.version === 'draft-04' ? ['array', 'object'] : ['array', 'object', 'boolean']],
|
|
169
|
+
undefined,
|
|
170
|
+
schema,
|
|
171
|
+
'items'
|
|
172
|
+
);
|
|
132
173
|
}
|
|
133
174
|
|
|
134
175
|
// custom - strict mode
|
|
@@ -150,9 +191,9 @@ const SchemaValidators = {
|
|
|
150
191
|
},
|
|
151
192
|
minItems: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
152
193
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.1
|
|
153
|
-
if (
|
|
194
|
+
if (!isInteger(schema.minItems)) {
|
|
154
195
|
report.addError('KEYWORD_TYPE_EXPECTED', ['minItems', 'integer'], undefined, schema, 'minItems');
|
|
155
|
-
} else if (schema.minItems
|
|
196
|
+
} else if (schema.minItems < 0) {
|
|
156
197
|
report.addError('KEYWORD_MUST_BE', ['minItems', 'greater than, or equal to 0'], undefined, schema, 'minItems');
|
|
157
198
|
}
|
|
158
199
|
},
|
|
@@ -164,9 +205,9 @@ const SchemaValidators = {
|
|
|
164
205
|
},
|
|
165
206
|
maxProperties: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
166
207
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.1
|
|
167
|
-
if (
|
|
208
|
+
if (!isInteger(schema.maxProperties)) {
|
|
168
209
|
report.addError('KEYWORD_TYPE_EXPECTED', ['maxProperties', 'integer'], undefined, schema, 'maxProperties');
|
|
169
|
-
} else if (schema.maxProperties
|
|
210
|
+
} else if (schema.maxProperties < 0) {
|
|
170
211
|
report.addError(
|
|
171
212
|
'KEYWORD_MUST_BE',
|
|
172
213
|
['maxProperties', 'greater than, or equal to 0'],
|
|
@@ -178,9 +219,9 @@ const SchemaValidators = {
|
|
|
178
219
|
},
|
|
179
220
|
minProperties: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
180
221
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.1
|
|
181
|
-
if (
|
|
222
|
+
if (!isInteger(schema.minProperties)) {
|
|
182
223
|
report.addError('KEYWORD_TYPE_EXPECTED', ['minProperties', 'integer'], undefined, schema, 'minProperties');
|
|
183
|
-
} else if (schema.minProperties
|
|
224
|
+
} else if (schema.minProperties < 0) {
|
|
184
225
|
report.addError(
|
|
185
226
|
'KEYWORD_MUST_BE',
|
|
186
227
|
['minProperties', 'greater than, or equal to 0'],
|
|
@@ -192,9 +233,9 @@ const SchemaValidators = {
|
|
|
192
233
|
},
|
|
193
234
|
required: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
194
235
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.1
|
|
195
|
-
if (
|
|
236
|
+
if (!Array.isArray(schema.required)) {
|
|
196
237
|
report.addError('KEYWORD_TYPE_EXPECTED', ['required', 'array'], undefined, schema, 'required');
|
|
197
|
-
} else if (schema.required
|
|
238
|
+
} else if (report.options.version === 'draft-04' && schema.required.length === 0) {
|
|
198
239
|
report.addError(
|
|
199
240
|
'KEYWORD_MUST_BE',
|
|
200
241
|
['required', 'an array with at least one element'],
|
|
@@ -203,21 +244,20 @@ const SchemaValidators = {
|
|
|
203
244
|
'required'
|
|
204
245
|
);
|
|
205
246
|
} else {
|
|
206
|
-
let idx = schema.required
|
|
247
|
+
let idx = schema.required.length;
|
|
207
248
|
while (idx--) {
|
|
208
|
-
if (typeof schema.required
|
|
249
|
+
if (typeof schema.required[idx] !== 'string') {
|
|
209
250
|
report.addError('KEYWORD_VALUE_TYPE', ['required', 'string'], undefined, schema, 'required');
|
|
210
251
|
}
|
|
211
252
|
}
|
|
212
|
-
if (isUniqueArray(schema.required
|
|
253
|
+
if (isUniqueArray(schema.required) === false) {
|
|
213
254
|
report.addError('KEYWORD_MUST_BE', ['required', 'an array with unique items'], undefined, schema, 'required');
|
|
214
255
|
}
|
|
215
256
|
}
|
|
216
257
|
},
|
|
217
258
|
additionalProperties: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
218
259
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
|
|
219
|
-
|
|
220
|
-
if (type !== 'boolean' && type !== 'object') {
|
|
260
|
+
if (typeof schema.additionalProperties !== 'boolean' && !isObject(schema.additionalProperties)) {
|
|
221
261
|
report.addError(
|
|
222
262
|
'KEYWORD_TYPE_EXPECTED',
|
|
223
263
|
['additionalProperties', ['boolean', 'object']],
|
|
@@ -233,16 +273,16 @@ const SchemaValidators = {
|
|
|
233
273
|
},
|
|
234
274
|
properties: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
235
275
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
|
|
236
|
-
if (
|
|
276
|
+
if (!isObject(schema.properties)) {
|
|
237
277
|
report.addError('KEYWORD_TYPE_EXPECTED', ['properties', 'object'], undefined, schema, 'properties');
|
|
238
278
|
return;
|
|
239
279
|
}
|
|
240
280
|
|
|
241
|
-
const keys = Object.keys(schema.properties
|
|
281
|
+
const keys = Object.keys(schema.properties);
|
|
242
282
|
let idx = keys.length;
|
|
243
283
|
while (idx--) {
|
|
244
284
|
const key = keys[idx];
|
|
245
|
-
const val = schema.properties
|
|
285
|
+
const val = schema.properties[key];
|
|
246
286
|
report.path.push('properties');
|
|
247
287
|
report.path.push(key);
|
|
248
288
|
this.validateSchema(report, val);
|
|
@@ -265,17 +305,17 @@ const SchemaValidators = {
|
|
|
265
305
|
},
|
|
266
306
|
patternProperties: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
267
307
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.1
|
|
268
|
-
if (
|
|
308
|
+
if (!isObject(schema.patternProperties)) {
|
|
269
309
|
report.addError('KEYWORD_TYPE_EXPECTED', ['patternProperties', 'object'], undefined, schema, 'patternProperties');
|
|
270
310
|
return;
|
|
271
311
|
}
|
|
272
312
|
|
|
273
313
|
// Use shared regex compilation helper
|
|
274
|
-
const keys = Object.keys(schema.patternProperties
|
|
314
|
+
const keys = Object.keys(schema.patternProperties);
|
|
275
315
|
let idx = keys.length;
|
|
276
316
|
while (idx--) {
|
|
277
317
|
const key = keys[idx],
|
|
278
|
-
val = schema.patternProperties
|
|
318
|
+
val = schema.patternProperties[key];
|
|
279
319
|
const result = compileSchemaRegex(key);
|
|
280
320
|
if (!result.ok) {
|
|
281
321
|
report.addError(
|
|
@@ -300,32 +340,36 @@ const SchemaValidators = {
|
|
|
300
340
|
},
|
|
301
341
|
dependencies: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
302
342
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.1
|
|
303
|
-
if (
|
|
343
|
+
if (!isObject(schema.dependencies)) {
|
|
304
344
|
report.addError('KEYWORD_TYPE_EXPECTED', ['dependencies', 'object'], undefined, schema, 'dependencies');
|
|
305
345
|
} else {
|
|
306
|
-
const keys = Object.keys(schema.dependencies
|
|
346
|
+
const keys = Object.keys(schema.dependencies);
|
|
307
347
|
let idx = keys.length;
|
|
308
348
|
while (idx--) {
|
|
309
349
|
const schemaKey = keys[idx];
|
|
310
|
-
const schemaDependency = schema.dependencies
|
|
311
|
-
const
|
|
312
|
-
|
|
350
|
+
const schemaDependency = (schema.dependencies as Record<string, unknown>)[schemaKey];
|
|
351
|
+
const isSchemaDependency =
|
|
352
|
+
isObject(schemaDependency) ||
|
|
353
|
+
(report.options.version !== 'draft-04' && typeof schemaDependency === 'boolean');
|
|
354
|
+
|
|
355
|
+
if (isSchemaDependency) {
|
|
313
356
|
report.path.push('dependencies');
|
|
314
357
|
report.path.push(schemaKey);
|
|
315
|
-
this.validateSchema(report, schemaDependency as
|
|
358
|
+
this.validateSchema(report, schemaDependency as JsonSchemaInternal);
|
|
316
359
|
report.path.pop();
|
|
317
360
|
report.path.pop();
|
|
318
|
-
} else if (
|
|
319
|
-
|
|
320
|
-
|
|
361
|
+
} else if (Array.isArray(schemaDependency)) {
|
|
362
|
+
const depArray = schemaDependency as string[];
|
|
363
|
+
let idx2 = depArray.length;
|
|
364
|
+
if (report.options.version === 'draft-04' && idx2 === 0) {
|
|
321
365
|
report.addError('KEYWORD_MUST_BE', ['dependencies', 'not empty array'], undefined, schema, 'dependencies');
|
|
322
366
|
}
|
|
323
367
|
while (idx2--) {
|
|
324
|
-
if (typeof
|
|
368
|
+
if (typeof depArray[idx2] !== 'string') {
|
|
325
369
|
report.addError('KEYWORD_VALUE_TYPE', ['dependencies', 'string'], undefined, schema, 'dependencies');
|
|
326
370
|
}
|
|
327
371
|
}
|
|
328
|
-
if (isUniqueArray(
|
|
372
|
+
if (isUniqueArray(depArray) === false) {
|
|
329
373
|
report.addError(
|
|
330
374
|
'KEYWORD_MUST_BE',
|
|
331
375
|
['dependencies', 'an array with unique items'],
|
|
@@ -335,7 +379,13 @@ const SchemaValidators = {
|
|
|
335
379
|
);
|
|
336
380
|
}
|
|
337
381
|
} else {
|
|
338
|
-
report.addError(
|
|
382
|
+
report.addError(
|
|
383
|
+
'KEYWORD_VALUE_TYPE',
|
|
384
|
+
['dependencies', report.options.version === 'draft-04' ? 'object or array' : 'boolean, object or array'],
|
|
385
|
+
undefined,
|
|
386
|
+
schema,
|
|
387
|
+
'dependencies'
|
|
388
|
+
);
|
|
339
389
|
}
|
|
340
390
|
}
|
|
341
391
|
}
|
|
@@ -494,24 +544,36 @@ const SchemaValidators = {
|
|
|
494
544
|
},
|
|
495
545
|
not: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
496
546
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.1
|
|
497
|
-
|
|
498
|
-
|
|
547
|
+
const notSchema = schema.not;
|
|
548
|
+
const isValidNotSchema =
|
|
549
|
+
report.options.version === 'draft-04'
|
|
550
|
+
? isObject(notSchema)
|
|
551
|
+
: typeof notSchema === 'boolean' || isObject(notSchema);
|
|
552
|
+
|
|
553
|
+
if (!isValidNotSchema) {
|
|
554
|
+
report.addError(
|
|
555
|
+
'KEYWORD_TYPE_EXPECTED',
|
|
556
|
+
['not', report.options.version === 'draft-04' ? 'object' : ['boolean', 'object']],
|
|
557
|
+
undefined,
|
|
558
|
+
schema,
|
|
559
|
+
'not'
|
|
560
|
+
);
|
|
499
561
|
} else {
|
|
500
562
|
report.path.push('not');
|
|
501
|
-
this.validateSchema(report,
|
|
563
|
+
this.validateSchema(report, notSchema as JsonSchemaInternal);
|
|
502
564
|
report.path.pop();
|
|
503
565
|
}
|
|
504
566
|
},
|
|
505
567
|
definitions: function (this: SchemaValidator, report: Report, schema: JsonSchemaInternal) {
|
|
506
568
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.1
|
|
507
|
-
if (
|
|
569
|
+
if (!isObject(schema.definitions)) {
|
|
508
570
|
report.addError('KEYWORD_TYPE_EXPECTED', ['definitions', 'object'], undefined, schema, 'definitions');
|
|
509
571
|
} else {
|
|
510
|
-
const keys = Object.keys(schema.definitions
|
|
572
|
+
const keys = Object.keys(schema.definitions);
|
|
511
573
|
let idx = keys.length;
|
|
512
574
|
while (idx--) {
|
|
513
575
|
const key = keys[idx],
|
|
514
|
-
val = schema.definitions
|
|
576
|
+
val = schema.definitions[key];
|
|
515
577
|
report.path.push('definitions');
|
|
516
578
|
report.path.push(key);
|
|
517
579
|
this.validateSchema(report, val);
|
|
@@ -576,13 +638,17 @@ export class SchemaValidator {
|
|
|
576
638
|
return this.validateArrayOfSchemas(report, schema);
|
|
577
639
|
}
|
|
578
640
|
|
|
641
|
+
if (typeof schema === 'boolean') {
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
|
|
579
645
|
// do not revalidate schema that has already been validated once
|
|
580
646
|
if (schema.__$validated) {
|
|
581
647
|
return true;
|
|
582
648
|
}
|
|
583
649
|
|
|
584
650
|
// if $schema is present, this schema should validate against that $schema
|
|
585
|
-
const hasParentSchema = schema.$schema && schema
|
|
651
|
+
const hasParentSchema = schema.$schema && getId(schema) !== schema.$schema;
|
|
586
652
|
if (hasParentSchema) {
|
|
587
653
|
if (schema.__$schemaResolved && schema.__$schemaResolved !== schema) {
|
|
588
654
|
const subReport = new Report(report);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-06/hyper-schema#",
|
|
3
|
+
"$id": "http://json-schema.org/draft-06/hyper-schema#",
|
|
4
|
+
"title": "JSON Hyper-Schema",
|
|
5
|
+
"definitions": {
|
|
6
|
+
"schemaArray": {
|
|
7
|
+
"allOf": [
|
|
8
|
+
{ "$ref": "http://json-schema.org/draft-06/schema#/definitions/schemaArray" },
|
|
9
|
+
{
|
|
10
|
+
"items": { "$ref": "#" }
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"linkDescription": {
|
|
15
|
+
"title": "Link Description Object",
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": [ "href" ],
|
|
18
|
+
"properties": {
|
|
19
|
+
"href": {
|
|
20
|
+
"description": "a URI template, as defined by RFC 6570",
|
|
21
|
+
"type": "string",
|
|
22
|
+
"format": "uri-template"
|
|
23
|
+
},
|
|
24
|
+
"hrefSchema": {
|
|
25
|
+
"description": "a schema for validating user input to the URI template, where the input is in the form of a JSON object with property names matching variable names in \"href\"",
|
|
26
|
+
"allOf": [ {"$ref": "#"} ]
|
|
27
|
+
},
|
|
28
|
+
"rel": {
|
|
29
|
+
"description": "relation to the target resource of the link",
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"title": {
|
|
33
|
+
"description": "a title for the link",
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
"targetSchema": {
|
|
37
|
+
"description": "JSON Schema describing the link target",
|
|
38
|
+
"allOf": [ { "$ref": "#" } ]
|
|
39
|
+
},
|
|
40
|
+
"mediaType": {
|
|
41
|
+
"description": "media type (as defined by RFC 2046) describing the link target",
|
|
42
|
+
"type": "string"
|
|
43
|
+
},
|
|
44
|
+
"submissionEncType": {
|
|
45
|
+
"description": "The media type in which to submit data along with the request",
|
|
46
|
+
"type": "string",
|
|
47
|
+
"default": "application/json"
|
|
48
|
+
},
|
|
49
|
+
"submissionSchema": {
|
|
50
|
+
"description": "Schema describing the data to submit along with the request",
|
|
51
|
+
"allOf": [ { "$ref": "#" } ]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"allOf": [ { "$ref": "http://json-schema.org/draft-06/schema#" } ],
|
|
57
|
+
"properties": {
|
|
58
|
+
"additionalItems": {
|
|
59
|
+
"anyOf": [
|
|
60
|
+
{ "type": "boolean" },
|
|
61
|
+
{ "$ref": "#" }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"additionalProperties": {
|
|
65
|
+
"anyOf": [
|
|
66
|
+
{ "type": "boolean" },
|
|
67
|
+
{ "$ref": "#" }
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"additionalProperties": {
|
|
72
|
+
"anyOf": [
|
|
73
|
+
{ "$ref": "#" },
|
|
74
|
+
{ "type": "array" }
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"items": {
|
|
79
|
+
"anyOf": [
|
|
80
|
+
{ "$ref": "#" },
|
|
81
|
+
{ "$ref": "#/definitions/schemaArray" }
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"definitions": {
|
|
85
|
+
"additionalProperties": { "$ref": "#" }
|
|
86
|
+
},
|
|
87
|
+
"patternProperties": {
|
|
88
|
+
"additionalProperties": { "$ref": "#" }
|
|
89
|
+
},
|
|
90
|
+
"properties": {
|
|
91
|
+
"additionalProperties": { "$ref": "#" }
|
|
92
|
+
},
|
|
93
|
+
"allOf": { "$ref": "#/definitions/schemaArray" },
|
|
94
|
+
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
|
95
|
+
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
|
96
|
+
"not": { "$ref": "#" },
|
|
97
|
+
|
|
98
|
+
"contains": { "$ref": "#" },
|
|
99
|
+
"propertyNames": { "$ref": "#" },
|
|
100
|
+
"base": {
|
|
101
|
+
"description": "URI Template resolved as for the 'href' keyword in the Link Description Object. The resulting URI Reference is resolved against the current URI base and sets the new URI base for URI references within the instance.",
|
|
102
|
+
"type": "string"
|
|
103
|
+
},
|
|
104
|
+
"links": {
|
|
105
|
+
"type": "array",
|
|
106
|
+
"items": { "$ref": "#/definitions/linkDescription" }
|
|
107
|
+
},
|
|
108
|
+
"media": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"properties": {
|
|
111
|
+
"type": {
|
|
112
|
+
"description": "A media type, as described in RFC 2046",
|
|
113
|
+
"type": "string"
|
|
114
|
+
},
|
|
115
|
+
"binaryEncoding": {
|
|
116
|
+
"description": "A content encoding scheme, as described in RFC 2045",
|
|
117
|
+
"type": "string"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"readOnly": {
|
|
122
|
+
"description": "If true, indicates that the value of this property is controlled by the server.",
|
|
123
|
+
"type": "boolean",
|
|
124
|
+
"default": false
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"links": [
|
|
128
|
+
{
|
|
129
|
+
"rel": "self",
|
|
130
|
+
"href": "{+%24id}"
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-06/hyper-schema#",
|
|
3
|
+
"$id": "http://json-schema.org/draft-06/links#",
|
|
4
|
+
"title": "Link Description Object",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [ "href" ],
|
|
7
|
+
"properties": {
|
|
8
|
+
"href": {
|
|
9
|
+
"description": "a URI template, as defined by RFC 6570",
|
|
10
|
+
"type": "string",
|
|
11
|
+
"format": "uri-template"
|
|
12
|
+
},
|
|
13
|
+
"hrefSchema": {
|
|
14
|
+
"description": "a schema for validating user input to the URI template, where the input is in the form of a JSON object with property names matching variable names in \"href\"",
|
|
15
|
+
"allOf": [ {"$ref": "#"} ]
|
|
16
|
+
},
|
|
17
|
+
"rel": {
|
|
18
|
+
"description": "relation to the target resource of the link",
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"title": {
|
|
22
|
+
"description": "a title for the link",
|
|
23
|
+
"type": "string"
|
|
24
|
+
},
|
|
25
|
+
"targetSchema": {
|
|
26
|
+
"description": "JSON Schema describing the link target",
|
|
27
|
+
"allOf": [ { "$ref": "hyper-schema#" } ]
|
|
28
|
+
},
|
|
29
|
+
"mediaType": {
|
|
30
|
+
"description": "media type (as defined by RFC 2046) describing the link target",
|
|
31
|
+
"type": "string"
|
|
32
|
+
},
|
|
33
|
+
"submissionEncType": {
|
|
34
|
+
"description": "The media type in which to submit data along with the request",
|
|
35
|
+
"type": "string",
|
|
36
|
+
"default": "application/json"
|
|
37
|
+
},
|
|
38
|
+
"submissionSchema": {
|
|
39
|
+
"description": "Schema describing the data to submit along with the request",
|
|
40
|
+
"allOf": [ { "$ref": "hyper-schema#" } ]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|