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,20 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { Report } from './report.js';
|
|
2
|
+
import { isObject, whatIs } from './utils/what-is.js';
|
|
3
|
+
import { ucs2decode } from './utils/unicode.js';
|
|
4
|
+
import { difference, isUniqueArray } from './utils/array.js';
|
|
5
|
+
import { areEqual } from './utils/json.js';
|
|
6
|
+
import { shallowClone } from './utils/clone.js';
|
|
7
|
+
import { JsonSchema, JsonSchemaInternal } from './json-schema.js';
|
|
8
|
+
import type { ValidateOptions, ZSchema } from './z-schema.js';
|
|
9
|
+
import { getFormatValidators } from './format-validators.js';
|
|
10
|
+
|
|
11
|
+
const shouldSkipValidate = function (options: ValidateOptions, errors: any) {
|
|
6
12
|
return (
|
|
7
13
|
options &&
|
|
8
14
|
Array.isArray(options.includeErrors) &&
|
|
9
15
|
options.includeErrors.length > 0 &&
|
|
10
|
-
!errors.some(function (err) {
|
|
11
|
-
return options.includeErrors
|
|
16
|
+
!errors.some(function (err: any) {
|
|
17
|
+
return options.includeErrors!.includes(err);
|
|
12
18
|
})
|
|
13
19
|
);
|
|
14
20
|
};
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
type JsonValidatorFn = (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) => void;
|
|
23
|
+
|
|
24
|
+
export const JsonValidators: Record<keyof JsonSchema, JsonValidatorFn> = {
|
|
25
|
+
id: () => {},
|
|
26
|
+
$ref: () => {},
|
|
27
|
+
$schema: () => {},
|
|
28
|
+
title: () => {},
|
|
29
|
+
description: () => {},
|
|
30
|
+
default: () => {},
|
|
31
|
+
multipleOf: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
18
32
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.1.2
|
|
19
33
|
if (shouldSkipValidate(this.validateOptions, ['MULTIPLE_OF'])) {
|
|
20
34
|
return;
|
|
@@ -25,11 +39,11 @@ export const JsonValidators = {
|
|
|
25
39
|
|
|
26
40
|
const stringMultipleOf = String(schema.multipleOf);
|
|
27
41
|
const scale = Math.pow(10, stringMultipleOf.length - stringMultipleOf.indexOf('.') - 1);
|
|
28
|
-
if (
|
|
29
|
-
report.addError('MULTIPLE_OF', [json, schema.multipleOf],
|
|
42
|
+
if (whatIs((json * scale) / (schema.multipleOf! * scale)) !== 'integer') {
|
|
43
|
+
report.addError('MULTIPLE_OF', [json, schema.multipleOf!], undefined, schema);
|
|
30
44
|
}
|
|
31
45
|
},
|
|
32
|
-
maximum: function (report, schema, json) {
|
|
46
|
+
maximum: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
33
47
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.2
|
|
34
48
|
if (shouldSkipValidate(this.validateOptions, ['MAXIMUM', 'MAXIMUM_EXCLUSIVE'])) {
|
|
35
49
|
return;
|
|
@@ -38,19 +52,19 @@ export const JsonValidators = {
|
|
|
38
52
|
return;
|
|
39
53
|
}
|
|
40
54
|
if (schema.exclusiveMaximum !== true) {
|
|
41
|
-
if (json > schema.maximum) {
|
|
42
|
-
report.addError('MAXIMUM', [json, schema.maximum],
|
|
55
|
+
if (json > schema.maximum!) {
|
|
56
|
+
report.addError('MAXIMUM', [json, schema.maximum!], undefined, schema);
|
|
43
57
|
}
|
|
44
58
|
} else {
|
|
45
|
-
if (json >= schema.maximum) {
|
|
46
|
-
report.addError('MAXIMUM_EXCLUSIVE', [json, schema.maximum],
|
|
59
|
+
if (json >= schema.maximum!) {
|
|
60
|
+
report.addError('MAXIMUM_EXCLUSIVE', [json, schema.maximum!], undefined, schema);
|
|
47
61
|
}
|
|
48
62
|
}
|
|
49
63
|
},
|
|
50
64
|
exclusiveMaximum: function () {
|
|
51
65
|
// covered in maximum
|
|
52
66
|
},
|
|
53
|
-
minimum: function (report, schema, json) {
|
|
67
|
+
minimum: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
54
68
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.2
|
|
55
69
|
if (shouldSkipValidate(this.validateOptions, ['MINIMUM', 'MINIMUM_EXCLUSIVE'])) {
|
|
56
70
|
return;
|
|
@@ -59,19 +73,19 @@ export const JsonValidators = {
|
|
|
59
73
|
return;
|
|
60
74
|
}
|
|
61
75
|
if (schema.exclusiveMinimum !== true) {
|
|
62
|
-
if (json < schema.minimum) {
|
|
63
|
-
report.addError('MINIMUM', [json, schema.minimum],
|
|
76
|
+
if (json < schema.minimum!) {
|
|
77
|
+
report.addError('MINIMUM', [json, schema.minimum!], undefined, schema);
|
|
64
78
|
}
|
|
65
79
|
} else {
|
|
66
|
-
if (json <= schema.minimum) {
|
|
67
|
-
report.addError('MINIMUM_EXCLUSIVE', [json, schema.minimum],
|
|
80
|
+
if (json <= schema.minimum!) {
|
|
81
|
+
report.addError('MINIMUM_EXCLUSIVE', [json, schema.minimum!], undefined, schema);
|
|
68
82
|
}
|
|
69
83
|
}
|
|
70
84
|
},
|
|
71
85
|
exclusiveMinimum: function () {
|
|
72
86
|
// covered in minimum
|
|
73
87
|
},
|
|
74
|
-
maxLength: function (report, schema, json) {
|
|
88
|
+
maxLength: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
75
89
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.2
|
|
76
90
|
if (shouldSkipValidate(this.validateOptions, ['MAX_LENGTH'])) {
|
|
77
91
|
return;
|
|
@@ -79,11 +93,11 @@ export const JsonValidators = {
|
|
|
79
93
|
if (typeof json !== 'string') {
|
|
80
94
|
return;
|
|
81
95
|
}
|
|
82
|
-
if (
|
|
83
|
-
report.addError('MAX_LENGTH', [json.length, schema.maxLength],
|
|
96
|
+
if (ucs2decode(json).length > schema.maxLength!) {
|
|
97
|
+
report.addError('MAX_LENGTH', [json.length, schema.maxLength!], undefined, schema);
|
|
84
98
|
}
|
|
85
99
|
},
|
|
86
|
-
minLength: function (report, schema, json) {
|
|
100
|
+
minLength: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
87
101
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.2
|
|
88
102
|
if (shouldSkipValidate(this.validateOptions, ['MIN_LENGTH'])) {
|
|
89
103
|
return;
|
|
@@ -91,11 +105,11 @@ export const JsonValidators = {
|
|
|
91
105
|
if (typeof json !== 'string') {
|
|
92
106
|
return;
|
|
93
107
|
}
|
|
94
|
-
if (
|
|
95
|
-
report.addError('MIN_LENGTH', [json.length, schema.minLength],
|
|
108
|
+
if (ucs2decode(json).length < schema.minLength!) {
|
|
109
|
+
report.addError('MIN_LENGTH', [json.length, schema.minLength!], undefined, schema);
|
|
96
110
|
}
|
|
97
111
|
},
|
|
98
|
-
pattern: function (report, schema, json) {
|
|
112
|
+
pattern: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
99
113
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3.2
|
|
100
114
|
if (shouldSkipValidate(this.validateOptions, ['PATTERN'])) {
|
|
101
115
|
return;
|
|
@@ -103,11 +117,11 @@ export const JsonValidators = {
|
|
|
103
117
|
if (typeof json !== 'string') {
|
|
104
118
|
return;
|
|
105
119
|
}
|
|
106
|
-
if (RegExp(schema.pattern).test(json) === false) {
|
|
107
|
-
report.addError('PATTERN', [schema.pattern
|
|
120
|
+
if (RegExp(schema.pattern!).test(json) === false) {
|
|
121
|
+
report.addError('PATTERN', [schema.pattern!, json], undefined, schema);
|
|
108
122
|
}
|
|
109
123
|
},
|
|
110
|
-
additionalItems: function (report, schema, json) {
|
|
124
|
+
additionalItems: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
111
125
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.2
|
|
112
126
|
if (shouldSkipValidate(this.validateOptions, ['ARRAY_ADDITIONAL_ITEMS'])) {
|
|
113
127
|
return;
|
|
@@ -119,15 +133,15 @@ export const JsonValidators = {
|
|
|
119
133
|
// the json is valid if its size is less than, or equal to, the size of "items".
|
|
120
134
|
if (schema.additionalItems === false && Array.isArray(schema.items)) {
|
|
121
135
|
if (json.length > schema.items.length) {
|
|
122
|
-
report.addError('ARRAY_ADDITIONAL_ITEMS',
|
|
136
|
+
report.addError('ARRAY_ADDITIONAL_ITEMS', undefined, undefined, schema);
|
|
123
137
|
}
|
|
124
138
|
}
|
|
125
139
|
},
|
|
126
140
|
items: function () {
|
|
127
|
-
/*report, schema, json*/
|
|
141
|
+
/*report: Report, schema: JsonSchemaInternal, json: unknown*/
|
|
128
142
|
// covered in additionalItems
|
|
129
143
|
},
|
|
130
|
-
maxItems: function (report, schema, json) {
|
|
144
|
+
maxItems: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
131
145
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.2.2
|
|
132
146
|
if (shouldSkipValidate(this.validateOptions, ['ARRAY_LENGTH_LONG'])) {
|
|
133
147
|
return;
|
|
@@ -135,11 +149,11 @@ export const JsonValidators = {
|
|
|
135
149
|
if (!Array.isArray(json)) {
|
|
136
150
|
return;
|
|
137
151
|
}
|
|
138
|
-
if (json.length > schema.maxItems) {
|
|
139
|
-
report.addError('ARRAY_LENGTH_LONG', [json.length, schema.maxItems],
|
|
152
|
+
if (json.length > schema.maxItems!) {
|
|
153
|
+
report.addError('ARRAY_LENGTH_LONG', [json.length, schema.maxItems!], undefined, schema);
|
|
140
154
|
}
|
|
141
155
|
},
|
|
142
|
-
minItems: function (report, schema, json) {
|
|
156
|
+
minItems: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
143
157
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.2
|
|
144
158
|
if (shouldSkipValidate(this.validateOptions, ['ARRAY_LENGTH_SHORT'])) {
|
|
145
159
|
return;
|
|
@@ -147,11 +161,11 @@ export const JsonValidators = {
|
|
|
147
161
|
if (!Array.isArray(json)) {
|
|
148
162
|
return;
|
|
149
163
|
}
|
|
150
|
-
if (json.length < schema.minItems) {
|
|
151
|
-
report.addError('ARRAY_LENGTH_SHORT', [json.length, schema.minItems],
|
|
164
|
+
if (json.length < schema.minItems!) {
|
|
165
|
+
report.addError('ARRAY_LENGTH_SHORT', [json.length, schema.minItems!], undefined, schema);
|
|
152
166
|
}
|
|
153
167
|
},
|
|
154
|
-
uniqueItems: function (report, schema, json) {
|
|
168
|
+
uniqueItems: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
155
169
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.4.2
|
|
156
170
|
if (shouldSkipValidate(this.validateOptions, ['ARRAY_UNIQUE'])) {
|
|
157
171
|
return;
|
|
@@ -160,72 +174,72 @@ export const JsonValidators = {
|
|
|
160
174
|
return;
|
|
161
175
|
}
|
|
162
176
|
if (schema.uniqueItems === true) {
|
|
163
|
-
const matches = [];
|
|
164
|
-
if (
|
|
165
|
-
report.addError('ARRAY_UNIQUE', matches,
|
|
177
|
+
const matches: any[] = [];
|
|
178
|
+
if (isUniqueArray(json, matches) === false) {
|
|
179
|
+
report.addError('ARRAY_UNIQUE', matches, undefined, schema);
|
|
166
180
|
}
|
|
167
181
|
}
|
|
168
182
|
},
|
|
169
|
-
maxProperties: function (report, schema, json) {
|
|
183
|
+
maxProperties: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
170
184
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.1.2
|
|
171
185
|
if (shouldSkipValidate(this.validateOptions, ['OBJECT_PROPERTIES_MAXIMUM'])) {
|
|
172
186
|
return;
|
|
173
187
|
}
|
|
174
|
-
if (
|
|
188
|
+
if (!isObject(json)) {
|
|
175
189
|
return;
|
|
176
190
|
}
|
|
177
191
|
const keysCount = Object.keys(json).length;
|
|
178
|
-
if (keysCount > schema.maxProperties) {
|
|
179
|
-
report.addError('OBJECT_PROPERTIES_MAXIMUM', [keysCount, schema.maxProperties],
|
|
192
|
+
if (keysCount > schema.maxProperties!) {
|
|
193
|
+
report.addError('OBJECT_PROPERTIES_MAXIMUM', [keysCount, schema.maxProperties!], undefined, schema);
|
|
180
194
|
}
|
|
181
195
|
},
|
|
182
|
-
minProperties: function (report, schema, json) {
|
|
196
|
+
minProperties: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
183
197
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.2.2
|
|
184
198
|
if (shouldSkipValidate(this.validateOptions, ['OBJECT_PROPERTIES_MINIMUM'])) {
|
|
185
199
|
return;
|
|
186
200
|
}
|
|
187
|
-
if (
|
|
201
|
+
if (!isObject(json)) {
|
|
188
202
|
return;
|
|
189
203
|
}
|
|
190
204
|
const keysCount = Object.keys(json).length;
|
|
191
|
-
if (keysCount < schema.minProperties) {
|
|
192
|
-
report.addError('OBJECT_PROPERTIES_MINIMUM', [keysCount, schema.minProperties],
|
|
205
|
+
if (keysCount < schema.minProperties!) {
|
|
206
|
+
report.addError('OBJECT_PROPERTIES_MINIMUM', [keysCount, schema.minProperties!], undefined, schema);
|
|
193
207
|
}
|
|
194
208
|
},
|
|
195
|
-
required: function (report, schema, json) {
|
|
209
|
+
required: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
196
210
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.3.2
|
|
197
211
|
if (shouldSkipValidate(this.validateOptions, ['OBJECT_MISSING_REQUIRED_PROPERTY'])) {
|
|
198
212
|
return;
|
|
199
213
|
}
|
|
200
|
-
if (
|
|
214
|
+
if (!isObject(json)) {
|
|
201
215
|
return;
|
|
202
216
|
}
|
|
203
|
-
let idx = schema.required
|
|
217
|
+
let idx = schema.required!.length;
|
|
204
218
|
while (idx--) {
|
|
205
|
-
const requiredPropertyName = schema.required[idx];
|
|
219
|
+
const requiredPropertyName = schema.required![idx];
|
|
206
220
|
if (json[requiredPropertyName] === undefined) {
|
|
207
|
-
report.addError('OBJECT_MISSING_REQUIRED_PROPERTY', [requiredPropertyName],
|
|
221
|
+
report.addError('OBJECT_MISSING_REQUIRED_PROPERTY', [requiredPropertyName], undefined, schema);
|
|
208
222
|
}
|
|
209
223
|
}
|
|
210
224
|
},
|
|
211
|
-
additionalProperties: function (report, schema, json) {
|
|
225
|
+
additionalProperties: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
212
226
|
// covered in properties and patternProperties
|
|
213
227
|
if (schema.properties === undefined && schema.patternProperties === undefined) {
|
|
214
228
|
return JsonValidators.properties.call(this, report, schema, json);
|
|
215
229
|
}
|
|
216
230
|
},
|
|
217
|
-
patternProperties: function (report, schema, json) {
|
|
231
|
+
patternProperties: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
218
232
|
// covered in properties
|
|
219
233
|
if (schema.properties === undefined) {
|
|
220
234
|
return JsonValidators.properties.call(this, report, schema, json);
|
|
221
235
|
}
|
|
222
236
|
},
|
|
223
|
-
properties: function (report, schema, json) {
|
|
237
|
+
properties: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
224
238
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.4.2
|
|
225
239
|
if (shouldSkipValidate(this.validateOptions, ['OBJECT_ADDITIONAL_PROPERTIES'])) {
|
|
226
240
|
return;
|
|
227
241
|
}
|
|
228
|
-
if (
|
|
242
|
+
if (!isObject(json)) {
|
|
229
243
|
return;
|
|
230
244
|
}
|
|
231
245
|
const properties = schema.properties !== undefined ? schema.properties : {};
|
|
@@ -238,7 +252,7 @@ export const JsonValidators = {
|
|
|
238
252
|
// The property set from "patternProperties".
|
|
239
253
|
const pp = Object.keys(patternProperties);
|
|
240
254
|
// remove from "s" all elements of "p", if any;
|
|
241
|
-
s =
|
|
255
|
+
s = difference(s, p);
|
|
242
256
|
// for each regex in "pp", remove all elements of "s" which this regex matches.
|
|
243
257
|
let idx = pp.length;
|
|
244
258
|
while (idx--) {
|
|
@@ -253,71 +267,73 @@ export const JsonValidators = {
|
|
|
253
267
|
// Validation of the json succeeds if, after these two steps, set "s" is empty.
|
|
254
268
|
if (s.length > 0) {
|
|
255
269
|
// assumeAdditional can be an array of allowed properties
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
if (Array.isArray(this.options.assumeAdditional)) {
|
|
271
|
+
let idx3 = this.options.assumeAdditional.length;
|
|
272
|
+
if (idx3) {
|
|
273
|
+
while (idx3--) {
|
|
274
|
+
const io = s.indexOf(this.options.assumeAdditional[idx3]);
|
|
275
|
+
if (io !== -1) {
|
|
276
|
+
s.splice(io, 1);
|
|
277
|
+
}
|
|
262
278
|
}
|
|
263
279
|
}
|
|
264
280
|
}
|
|
265
281
|
let idx4 = s.length;
|
|
266
282
|
if (idx4) {
|
|
267
283
|
while (idx4--) {
|
|
268
|
-
report.addError('OBJECT_ADDITIONAL_PROPERTIES', [s[idx4]],
|
|
284
|
+
report.addError('OBJECT_ADDITIONAL_PROPERTIES', [s[idx4]], undefined, schema);
|
|
269
285
|
}
|
|
270
286
|
}
|
|
271
287
|
}
|
|
272
288
|
}
|
|
273
289
|
},
|
|
274
|
-
dependencies: function (report, schema, json) {
|
|
290
|
+
dependencies: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
275
291
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.4.5.2
|
|
276
292
|
if (shouldSkipValidate(this.validateOptions, ['OBJECT_DEPENDENCY_KEY'])) {
|
|
277
293
|
return;
|
|
278
294
|
}
|
|
279
|
-
if (
|
|
295
|
+
if (!isObject(json)) {
|
|
280
296
|
return;
|
|
281
297
|
}
|
|
282
298
|
|
|
283
|
-
const keys = Object.keys(schema.dependencies);
|
|
299
|
+
const keys = Object.keys(schema.dependencies!);
|
|
284
300
|
let idx = keys.length;
|
|
285
301
|
|
|
286
302
|
while (idx--) {
|
|
287
303
|
// iterate all dependencies
|
|
288
304
|
const dependencyName = keys[idx];
|
|
289
305
|
if (json[dependencyName]) {
|
|
290
|
-
const dependencyDefinition = schema.dependencies[dependencyName];
|
|
291
|
-
if (
|
|
292
|
-
// if dependency is a schema, validate against this schema
|
|
293
|
-
validate.call(this, report, dependencyDefinition, json);
|
|
294
|
-
} else {
|
|
306
|
+
const dependencyDefinition = schema.dependencies![dependencyName];
|
|
307
|
+
if (Array.isArray(dependencyDefinition)) {
|
|
295
308
|
// Array
|
|
296
309
|
// if dependency is an array, object needs to have all properties in this array
|
|
297
310
|
let idx2 = dependencyDefinition.length;
|
|
298
311
|
while (idx2--) {
|
|
299
312
|
const requiredPropertyName = dependencyDefinition[idx2];
|
|
300
313
|
if (json[requiredPropertyName] === undefined) {
|
|
301
|
-
report.addError('OBJECT_DEPENDENCY_KEY', [requiredPropertyName, dependencyName],
|
|
314
|
+
report.addError('OBJECT_DEPENDENCY_KEY', [requiredPropertyName, dependencyName], undefined, schema);
|
|
302
315
|
}
|
|
303
316
|
}
|
|
317
|
+
} else {
|
|
318
|
+
// if dependency is a schema, validate against this schema
|
|
319
|
+
validate.call(this, report, dependencyDefinition, json);
|
|
304
320
|
}
|
|
305
321
|
}
|
|
306
322
|
}
|
|
307
323
|
},
|
|
308
|
-
enum: function (report, schema, json) {
|
|
324
|
+
enum: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
309
325
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.2
|
|
310
326
|
if (shouldSkipValidate(this.validateOptions, ['ENUM_CASE_MISMATCH', 'ENUM_MISMATCH'])) {
|
|
311
327
|
return;
|
|
312
328
|
}
|
|
313
329
|
let match = false,
|
|
314
330
|
caseInsensitiveMatch = false,
|
|
315
|
-
idx = schema.enum
|
|
331
|
+
idx = schema.enum!.length;
|
|
316
332
|
while (idx--) {
|
|
317
|
-
if (
|
|
333
|
+
if (areEqual(json, schema.enum![idx])) {
|
|
318
334
|
match = true;
|
|
319
335
|
break;
|
|
320
|
-
} else if (
|
|
336
|
+
} else if (areEqual(json, schema.enum![idx], { caseInsensitiveComparison: true })) {
|
|
321
337
|
caseInsensitiveMatch = true;
|
|
322
338
|
}
|
|
323
339
|
}
|
|
@@ -325,61 +341,61 @@ export const JsonValidators = {
|
|
|
325
341
|
if (match === false) {
|
|
326
342
|
const error =
|
|
327
343
|
caseInsensitiveMatch && this.options.enumCaseInsensitiveComparison ? 'ENUM_CASE_MISMATCH' : 'ENUM_MISMATCH';
|
|
328
|
-
report.addError(error, [json],
|
|
344
|
+
report.addError(error, [JSON.stringify(json)], undefined, schema);
|
|
329
345
|
}
|
|
330
346
|
},
|
|
331
|
-
type: function (report, schema, json) {
|
|
347
|
+
type: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
332
348
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2
|
|
333
349
|
if (shouldSkipValidate(this.validateOptions, ['INVALID_TYPE'])) {
|
|
334
350
|
return;
|
|
335
351
|
}
|
|
336
|
-
const jsonType =
|
|
352
|
+
const jsonType = whatIs(json);
|
|
337
353
|
if (typeof schema.type === 'string') {
|
|
338
354
|
if (jsonType !== schema.type && (jsonType !== 'integer' || schema.type !== 'number')) {
|
|
339
|
-
report.addError('INVALID_TYPE', [schema.type, jsonType],
|
|
355
|
+
report.addError('INVALID_TYPE', [schema.type, jsonType], undefined, schema);
|
|
340
356
|
}
|
|
341
357
|
} else {
|
|
342
|
-
if (schema.type
|
|
343
|
-
report.addError('INVALID_TYPE', [schema.type, jsonType],
|
|
358
|
+
if (schema.type!.indexOf(jsonType) === -1 && (jsonType !== 'integer' || schema.type!.indexOf('number') === -1)) {
|
|
359
|
+
report.addError('INVALID_TYPE', [JSON.stringify(schema.type), jsonType], undefined, schema);
|
|
344
360
|
}
|
|
345
361
|
}
|
|
346
362
|
},
|
|
347
|
-
allOf: function (report, schema, json) {
|
|
363
|
+
allOf: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
348
364
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.3.2
|
|
349
|
-
let idx = schema.allOf
|
|
365
|
+
let idx = schema.allOf!.length;
|
|
350
366
|
while (idx--) {
|
|
351
|
-
const validateResult = validate.call(this, report, schema.allOf[idx], json);
|
|
367
|
+
const validateResult = validate.call(this, report, schema.allOf![idx], json);
|
|
352
368
|
if (this.options.breakOnFirstError && validateResult === false) {
|
|
353
369
|
break;
|
|
354
370
|
}
|
|
355
371
|
}
|
|
356
372
|
},
|
|
357
|
-
anyOf: function (report, schema, json) {
|
|
373
|
+
anyOf: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
358
374
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.4.2
|
|
359
375
|
const subReports = [];
|
|
360
376
|
let passed = false;
|
|
361
|
-
let idx = schema.anyOf
|
|
377
|
+
let idx = schema.anyOf!.length;
|
|
362
378
|
|
|
363
379
|
while (idx-- && passed === false) {
|
|
364
380
|
const subReport = new Report(report);
|
|
365
381
|
subReports.push(subReport);
|
|
366
|
-
passed = validate.call(this, subReport, schema.anyOf[idx], json);
|
|
382
|
+
passed = validate.call(this, subReport, schema.anyOf![idx], json);
|
|
367
383
|
}
|
|
368
384
|
|
|
369
385
|
if (passed === false) {
|
|
370
386
|
report.addError('ANY_OF_MISSING', undefined, subReports, schema);
|
|
371
387
|
}
|
|
372
388
|
},
|
|
373
|
-
oneOf: function (report, schema, json) {
|
|
389
|
+
oneOf: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
374
390
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.5.2
|
|
375
391
|
let passes = 0;
|
|
376
392
|
const subReports = [];
|
|
377
|
-
let idx = schema.oneOf
|
|
393
|
+
let idx = schema.oneOf!.length;
|
|
378
394
|
|
|
379
395
|
while (idx--) {
|
|
380
396
|
const subReport = new Report(report, { maxErrors: 1 });
|
|
381
397
|
subReports.push(subReport);
|
|
382
|
-
if (validate.call(this, subReport, schema.oneOf[idx], json) === true) {
|
|
398
|
+
if (validate.call(this, subReport, schema.oneOf![idx], json) === true) {
|
|
383
399
|
passes++;
|
|
384
400
|
}
|
|
385
401
|
}
|
|
@@ -387,55 +403,56 @@ export const JsonValidators = {
|
|
|
387
403
|
if (passes === 0) {
|
|
388
404
|
report.addError('ONE_OF_MISSING', undefined, subReports, schema);
|
|
389
405
|
} else if (passes > 1) {
|
|
390
|
-
report.addError('ONE_OF_MULTIPLE',
|
|
406
|
+
report.addError('ONE_OF_MULTIPLE', undefined, undefined, schema);
|
|
391
407
|
}
|
|
392
408
|
},
|
|
393
|
-
not: function (report, schema, json) {
|
|
409
|
+
not: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
394
410
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.2
|
|
395
411
|
const subReport = new Report(report);
|
|
396
|
-
if (validate.call(this, subReport, schema.not
|
|
397
|
-
report.addError('NOT_PASSED',
|
|
412
|
+
if (validate.call(this, subReport, schema.not!, json) === true) {
|
|
413
|
+
report.addError('NOT_PASSED', undefined, undefined, schema);
|
|
398
414
|
}
|
|
399
415
|
},
|
|
400
416
|
definitions: function () {
|
|
401
|
-
/*report, schema, json*/
|
|
417
|
+
/*report: Report, schema: JsonSchemaInternal, json: unknown*/
|
|
402
418
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.7.2
|
|
403
419
|
// nothing to do here
|
|
404
420
|
},
|
|
405
|
-
format: function (report, schema, json) {
|
|
421
|
+
format: function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown) {
|
|
406
422
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.7.2
|
|
407
|
-
const
|
|
423
|
+
const formatValidators = getFormatValidators(this.options);
|
|
424
|
+
const formatValidatorFn = formatValidators[schema.format!];
|
|
408
425
|
if (typeof formatValidatorFn === 'function') {
|
|
409
426
|
if (shouldSkipValidate(this.validateOptions, ['INVALID_FORMAT'])) {
|
|
410
427
|
return;
|
|
411
428
|
}
|
|
412
|
-
if (report.hasError('INVALID_TYPE', [schema.type,
|
|
429
|
+
if (report.hasError('INVALID_TYPE', [schema.type, whatIs(json)])) {
|
|
413
430
|
return;
|
|
414
431
|
}
|
|
415
432
|
if (formatValidatorFn.length === 2) {
|
|
416
433
|
// async - need to clone the path here, because it will change by the time async function reports back
|
|
417
|
-
const pathBeforeAsync =
|
|
434
|
+
const pathBeforeAsync = shallowClone(report.path);
|
|
418
435
|
report.addAsyncTask(formatValidatorFn, [json], function (result) {
|
|
419
436
|
if (result !== true) {
|
|
420
437
|
const backup = report.path;
|
|
421
438
|
report.path = pathBeforeAsync;
|
|
422
|
-
report.addError('INVALID_FORMAT', [schema.format
|
|
439
|
+
report.addError('INVALID_FORMAT', [schema.format!, JSON.stringify(json)], undefined, schema);
|
|
423
440
|
report.path = backup;
|
|
424
441
|
}
|
|
425
442
|
});
|
|
426
443
|
} else {
|
|
427
444
|
// sync
|
|
428
445
|
if (formatValidatorFn.call(this, json) !== true) {
|
|
429
|
-
report.addError('INVALID_FORMAT', [schema.format
|
|
446
|
+
report.addError('INVALID_FORMAT', [schema.format!, JSON.stringify(json)], undefined, schema);
|
|
430
447
|
}
|
|
431
448
|
}
|
|
432
449
|
} else if (this.options.ignoreUnknownFormats !== true) {
|
|
433
|
-
report.addError('UNKNOWN_FORMAT', [schema.format],
|
|
450
|
+
report.addError('UNKNOWN_FORMAT', [schema.format!], undefined, schema);
|
|
434
451
|
}
|
|
435
452
|
},
|
|
436
453
|
};
|
|
437
454
|
|
|
438
|
-
const recurseArray = function (report, schema, json) {
|
|
455
|
+
const recurseArray = function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: Array<unknown>) {
|
|
439
456
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.8.2
|
|
440
457
|
|
|
441
458
|
let idx = json.length;
|
|
@@ -471,7 +488,7 @@ const recurseArray = function (report, schema, json) {
|
|
|
471
488
|
}
|
|
472
489
|
};
|
|
473
490
|
|
|
474
|
-
const recurseObject = function (report, schema, json) {
|
|
491
|
+
const recurseObject = function (this: ZSchema, report: Report, schema: JsonSchemaInternal, json: Record<any, any>) {
|
|
475
492
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.8.3
|
|
476
493
|
|
|
477
494
|
// If "additionalProperties" is absent, it is considered present with an empty schema as a value.
|
|
@@ -500,7 +517,7 @@ const recurseObject = function (report, schema, json) {
|
|
|
500
517
|
|
|
501
518
|
// 1. If set "p" contains value "m", then the corresponding schema in "properties" is added to "s".
|
|
502
519
|
if (p.indexOf(m) !== -1) {
|
|
503
|
-
s.push(schema.properties[m]);
|
|
520
|
+
s.push(schema.properties![m]);
|
|
504
521
|
}
|
|
505
522
|
|
|
506
523
|
// 2. For each regex in "pp", if it matches "m" successfully, the corresponding schema in "patternProperties" is added to "s".
|
|
@@ -508,7 +525,7 @@ const recurseObject = function (report, schema, json) {
|
|
|
508
525
|
while (idx2--) {
|
|
509
526
|
const regexString = pp[idx2];
|
|
510
527
|
if (RegExp(regexString).test(m) === true) {
|
|
511
|
-
s.push(schema.patternProperties[regexString]);
|
|
528
|
+
s.push(schema.patternProperties![regexString]);
|
|
512
529
|
}
|
|
513
530
|
}
|
|
514
531
|
|
|
@@ -531,24 +548,18 @@ const recurseObject = function (report, schema, json) {
|
|
|
531
548
|
}
|
|
532
549
|
};
|
|
533
550
|
|
|
534
|
-
|
|
535
|
-
*
|
|
536
|
-
* @param {Report} report
|
|
537
|
-
* @param {*} schema
|
|
538
|
-
* @param {*} json
|
|
539
|
-
*/
|
|
540
|
-
export function validate(report, schema, json) {
|
|
551
|
+
export function validate(this: ZSchema, report: Report, schema: JsonSchemaInternal, json: unknown): boolean {
|
|
541
552
|
report.commonErrorMessage = 'JSON_OBJECT_VALIDATION_FAILED';
|
|
542
553
|
|
|
543
554
|
// check if schema is an object
|
|
544
|
-
const to =
|
|
555
|
+
const to = whatIs(schema);
|
|
545
556
|
if (to !== 'object') {
|
|
546
|
-
report.addError('SCHEMA_NOT_AN_OBJECT', [to],
|
|
557
|
+
report.addError('SCHEMA_NOT_AN_OBJECT', [to], undefined, schema);
|
|
547
558
|
return false;
|
|
548
559
|
}
|
|
549
560
|
|
|
550
561
|
// check if schema is empty, everything is valid against empty schema
|
|
551
|
-
let keys = Object.keys(schema)
|
|
562
|
+
let keys = Object.keys(schema) as Array<keyof JsonSchema>;
|
|
552
563
|
if (keys.length === 0) {
|
|
553
564
|
return true;
|
|
554
565
|
}
|
|
@@ -566,13 +577,13 @@ export function validate(report, schema, json) {
|
|
|
566
577
|
let maxRefs = 99;
|
|
567
578
|
while (schema.$ref && maxRefs > 0) {
|
|
568
579
|
if (!schema.__$refResolved) {
|
|
569
|
-
report.addError('REF_UNRESOLVED', [schema.$ref],
|
|
580
|
+
report.addError('REF_UNRESOLVED', [schema.$ref], undefined, schema);
|
|
570
581
|
break;
|
|
571
582
|
} else if (schema.__$refResolved === schema) {
|
|
572
583
|
break;
|
|
573
584
|
} else {
|
|
574
585
|
schema = schema.__$refResolved;
|
|
575
|
-
keys = Object.keys(schema)
|
|
586
|
+
keys = Object.keys(schema) as Array<keyof JsonSchema>;
|
|
576
587
|
}
|
|
577
588
|
maxRefs--;
|
|
578
589
|
}
|
|
@@ -582,7 +593,6 @@ export function validate(report, schema, json) {
|
|
|
582
593
|
}
|
|
583
594
|
|
|
584
595
|
// type checking first
|
|
585
|
-
const jsonType = Utils.whatIs(json);
|
|
586
596
|
if (schema.type) {
|
|
587
597
|
keys.splice(keys.indexOf('type'), 1);
|
|
588
598
|
JsonValidators.type.call(this, report, schema, json);
|
|
@@ -603,9 +613,9 @@ export function validate(report, schema, json) {
|
|
|
603
613
|
}
|
|
604
614
|
|
|
605
615
|
if (report.errors.length === 0 || this.options.breakOnFirstError === false) {
|
|
606
|
-
if (
|
|
616
|
+
if (Array.isArray(json)) {
|
|
607
617
|
recurseArray.call(this, report, schema, json);
|
|
608
|
-
} else if (
|
|
618
|
+
} else if (isObject(json)) {
|
|
609
619
|
recurseObject.call(this, report, schema, json);
|
|
610
620
|
}
|
|
611
621
|
}
|