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.
Files changed (76) hide show
  1. package/README.md +7 -11
  2. package/bin/z-schema +0 -0
  3. package/cjs/index.d.ts +192 -117
  4. package/cjs/index.js +949 -998
  5. package/{src/FormatValidators.ts → dist/format-validators.js} +97 -65
  6. package/dist/index.js +1 -1
  7. package/dist/json-schema.js +40 -0
  8. package/dist/{JsonValidation.js → json-validation.js} +75 -69
  9. package/dist/{Report.js → report.js} +35 -45
  10. package/dist/schema-cache.js +109 -0
  11. package/dist/schema-compiler.js +255 -0
  12. package/dist/{SchemaValidation.js → schema-validator.js} +153 -149
  13. package/dist/types/{Errors.d.ts → errors.d.ts} +2 -0
  14. package/dist/types/format-validators.d.ts +10 -0
  15. package/dist/types/index.d.ts +10 -1
  16. package/dist/types/json-schema.d.ts +50 -0
  17. package/dist/types/json-validation.d.ts +7 -0
  18. package/dist/types/{Report.d.ts → report.d.ts} +22 -23
  19. package/dist/types/schema-cache.d.ts +17 -0
  20. package/dist/types/schema-compiler.d.ts +16 -0
  21. package/dist/types/schema-validator.d.ts +10 -0
  22. package/dist/types/utils/array.d.ts +2 -0
  23. package/dist/types/utils/clone.d.ts +2 -0
  24. package/dist/types/utils/json.d.ts +7 -0
  25. package/dist/types/utils/symbols.d.ts +2 -0
  26. package/dist/types/utils/unicode.d.ts +14 -0
  27. package/dist/types/utils/uri.d.ts +4 -0
  28. package/dist/types/utils/what-is.d.ts +3 -0
  29. package/dist/types/z-schema.d.ts +75 -0
  30. package/dist/utils/array.js +27 -0
  31. package/dist/utils/clone.js +61 -0
  32. package/dist/utils/json.js +59 -0
  33. package/dist/utils/symbols.js +2 -0
  34. package/dist/utils/unicode.js +45 -0
  35. package/dist/utils/uri.js +15 -0
  36. package/dist/utils/what-is.js +29 -0
  37. package/dist/{ZSchema.js → z-schema.js} +66 -77
  38. package/package.json +8 -4
  39. package/src/{Errors.ts → errors.ts} +4 -0
  40. package/src/format-validators.ts +191 -0
  41. package/src/index.ts +12 -1
  42. package/src/json-schema.ts +97 -0
  43. package/src/{JsonValidation.ts → json-validation.ts} +137 -127
  44. package/src/{Report.ts → report.ts} +60 -70
  45. package/src/schema-cache.ts +122 -0
  46. package/src/schema-compiler.ts +300 -0
  47. package/src/{SchemaValidation.ts → schema-validator.ts} +213 -215
  48. package/src/utils/array.ts +29 -0
  49. package/src/utils/clone.ts +63 -0
  50. package/src/utils/json.ts +74 -0
  51. package/src/utils/symbols.ts +3 -0
  52. package/src/utils/unicode.ts +43 -0
  53. package/src/utils/uri.ts +18 -0
  54. package/src/utils/what-is.ts +46 -0
  55. package/src/{ZSchema.ts → z-schema.ts} +108 -113
  56. package/umd/ZSchema.js +949 -998
  57. package/umd/ZSchema.min.js +1 -1
  58. package/dist/FormatValidators.js +0 -136
  59. package/dist/SchemaCache.js +0 -173
  60. package/dist/SchemaCompilation.js +0 -259
  61. package/dist/Utils.js +0 -266
  62. package/dist/types/FormatValidators.d.ts +0 -12
  63. package/dist/types/JsonValidation.d.ts +0 -37
  64. package/dist/types/SchemaCache.d.ts +0 -26
  65. package/dist/types/SchemaCompilation.d.ts +0 -1
  66. package/dist/types/SchemaValidation.d.ts +0 -6
  67. package/dist/types/Utils.d.ts +0 -64
  68. package/dist/types/ZSchema.d.ts +0 -97
  69. package/src/SchemaCache.ts +0 -189
  70. package/src/SchemaCompilation.ts +0 -293
  71. package/src/Utils.ts +0 -286
  72. /package/dist/{Errors.js → errors.js} +0 -0
  73. /package/dist/schemas/{hyper-schema.json → draft-04-hyper-schema.json} +0 -0
  74. /package/dist/schemas/{schema.json → draft-04-schema.json} +0 -0
  75. /package/src/schemas/{hyper-schema.json → draft-04-hyper-schema.json} +0 -0
  76. /package/src/schemas/{schema.json → draft-04-schema.json} +0 -0
@@ -1,20 +1,34 @@
1
- import { FormatValidators } from './FormatValidators.js';
2
- import { Report } from './Report.js';
3
- import * as Utils from './Utils.js';
4
-
5
- const shouldSkipValidate = function (options, errors) {
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.includes(err);
16
+ !errors.some(function (err: any) {
17
+ return options.includeErrors!.includes(err);
12
18
  })
13
19
  );
14
20
  };
15
21
 
16
- export const JsonValidators = {
17
- multipleOf: function (report, schema, json) {
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 (Utils.whatIs((json * scale) / (schema.multipleOf * scale)) !== 'integer') {
29
- report.addError('MULTIPLE_OF', [json, schema.multipleOf], null, schema);
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], null, schema);
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], null, schema);
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], null, schema);
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], null, schema);
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 (Utils.ucs2decode(json).length > schema.maxLength) {
83
- report.addError('MAX_LENGTH', [json.length, schema.maxLength], null, schema);
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 (Utils.ucs2decode(json).length < schema.minLength) {
95
- report.addError('MIN_LENGTH', [json.length, schema.minLength], null, schema);
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, json], null, schema);
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', null, null, schema);
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], null, schema);
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], null, schema);
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 (Utils.isUniqueArray(json, matches) === false) {
165
- report.addError('ARRAY_UNIQUE', matches, null, schema);
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 (Utils.whatIs(json) !== 'object') {
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], null, schema);
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 (Utils.whatIs(json) !== 'object') {
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], null, schema);
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 (Utils.whatIs(json) !== 'object') {
214
+ if (!isObject(json)) {
201
215
  return;
202
216
  }
203
- let idx = schema.required.length;
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], null, schema);
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 (Utils.whatIs(json) !== 'object') {
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 = Utils.difference(s, p);
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
- let idx3 = this.options.assumeAdditional.length;
257
- if (idx3) {
258
- while (idx3--) {
259
- const io = s.indexOf(this.options.assumeAdditional[idx3]);
260
- if (io !== -1) {
261
- s.splice(io, 1);
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]], null, schema);
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 (Utils.whatIs(json) !== 'object') {
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 (Utils.whatIs(dependencyDefinition) === 'object') {
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], null, schema);
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.length;
331
+ idx = schema.enum!.length;
316
332
  while (idx--) {
317
- if (Utils.areEqual(json, schema.enum[idx])) {
333
+ if (areEqual(json, schema.enum![idx])) {
318
334
  match = true;
319
335
  break;
320
- } else if (Utils.areEqual(json, schema.enum[idx], { caseInsensitiveComparison: true })) {
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], null, schema);
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 = Utils.whatIs(json);
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], null, schema);
355
+ report.addError('INVALID_TYPE', [schema.type, jsonType], undefined, schema);
340
356
  }
341
357
  } else {
342
- if (schema.type.indexOf(jsonType) === -1 && (jsonType !== 'integer' || schema.type.indexOf('number') === -1)) {
343
- report.addError('INVALID_TYPE', [schema.type, jsonType], null, schema);
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.length;
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.length;
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.length;
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', null, null, schema);
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, json) === true) {
397
- report.addError('NOT_PASSED', null, null, schema);
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 formatValidatorFn = FormatValidators[schema.format];
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, Utils.whatIs(json)])) {
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 = Utils.clone(report.path);
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, json], null, schema);
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, json], null, schema);
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], null, schema);
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 = Utils.whatIs(schema);
555
+ const to = whatIs(schema);
545
556
  if (to !== 'object') {
546
- report.addError('SCHEMA_NOT_AN_OBJECT', [to], null, schema);
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], null, schema);
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 (jsonType === 'array') {
616
+ if (Array.isArray(json)) {
607
617
  recurseArray.call(this, report, schema, json);
608
- } else if (jsonType === 'object') {
618
+ } else if (isObject(json)) {
609
619
  recurseObject.call(this, report, schema, json);
610
620
  }
611
621
  }