z-schema 12.2.0 → 12.3.1
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 +2 -2
- package/bin/z-schema +1 -1
- package/cjs/{index.js → index.cjs} +696 -687
- package/cjs/{index.d.ts → index.d.cts} +47 -26
- package/dist/{errors.d.mts → errors.d.ts} +2 -2
- package/dist/{errors.mjs → errors.js} +1 -2
- package/dist/{format-validators.mjs → format-validators.js} +43 -36
- package/dist/{index.d.mts → index.d.ts} +9 -9
- package/dist/{index.mjs → index.js} +3 -3
- package/dist/{json-schema-versions.d.mts → json-schema-versions.d.ts} +34 -3
- package/dist/{json-schema.d.mts → json-schema.d.ts} +7 -7
- package/dist/{json-schema.mjs → json-schema.js} +7 -12
- package/dist/{json-validation.mjs → json-validation.js} +143 -127
- package/dist/{report.d.mts → report.d.ts} +7 -8
- package/dist/{report.mjs → report.js} +28 -31
- package/dist/{schema-cache.d.mts → schema-cache.d.ts} +4 -4
- package/dist/{schema-cache.mjs → schema-cache.js} +10 -11
- package/dist/{schema-compiler.d.mts → schema-compiler.d.ts} +4 -4
- package/dist/{schema-compiler.mjs → schema-compiler.js} +95 -77
- package/dist/{schema-validator.d.mts → schema-validator.d.ts} +5 -5
- package/dist/{schema-validator.mjs → schema-validator.js} +138 -166
- package/dist/utils/{array.mjs → array.js} +4 -3
- package/dist/utils/{base64.mjs → base64.js} +3 -2
- package/dist/utils/{clone.mjs → clone.js} +18 -20
- package/dist/utils/{hostname.mjs → hostname.js} +19 -22
- package/dist/utils/{json.mjs → json.js} +11 -7
- package/dist/utils/{schema-regex.mjs → schema-regex.js} +5 -5
- package/dist/utils/{time.mjs → time.js} +5 -5
- package/dist/utils/unicode.js +22 -0
- package/dist/utils/{what-is.mjs → what-is.js} +1 -2
- package/dist/validation/{array.mjs → array.js} +18 -20
- package/dist/validation/{combinators.mjs → combinators.js} +16 -16
- package/dist/validation/{numeric.mjs → numeric.js} +11 -11
- package/dist/validation/{object.mjs → object.js} +35 -34
- package/dist/validation/{ref.mjs → ref.js} +4 -4
- package/dist/validation/{shared.mjs → shared.js} +12 -11
- package/dist/validation/{string.mjs → string.js} +32 -32
- package/dist/validation/type.js +34 -0
- package/dist/{z-schema-base.d.mts → z-schema-base.d.ts} +11 -12
- package/dist/{z-schema-base.mjs → z-schema-base.js} +45 -40
- package/dist/{z-schema-options.d.mts → z-schema-options.d.ts} +3 -3
- package/dist/{z-schema-options.mjs → z-schema-options.js} +4 -4
- package/dist/{z-schema-reader.d.mts → z-schema-reader.d.ts} +1 -1
- package/dist/{z-schema-versions.mjs → z-schema-versions.js} +21 -21
- package/dist/{z-schema.d.mts → z-schema.d.ts} +5 -13
- package/dist/{z-schema.mjs → z-schema.js} +37 -47
- package/package.json +22 -23
- package/src/errors.ts +1 -2
- package/src/format-validators.ts +139 -59
- package/src/json-schema-versions.ts +56 -2
- package/src/json-schema.ts +10 -9
- package/src/json-validation.ts +189 -146
- package/src/report.ts +37 -49
- package/src/schema-cache.ts +13 -13
- package/src/schema-compiler.ts +170 -117
- package/src/schema-validator.ts +239 -238
- package/src/utils/array.ts +9 -6
- package/src/utils/base64.ts +13 -2
- package/src/utils/clone.ts +28 -30
- package/src/utils/date.ts +6 -3
- package/src/utils/hostname.ts +27 -27
- package/src/utils/json.ts +16 -9
- package/src/utils/properties.ts +2 -2
- package/src/utils/schema-regex.ts +4 -4
- package/src/utils/time.ts +5 -5
- package/src/utils/unicode.ts +12 -5
- package/src/utils/what-is.ts +1 -5
- package/src/validation/array.ts +24 -22
- package/src/validation/combinators.ts +14 -14
- package/src/validation/numeric.ts +14 -28
- package/src/validation/object.ts +32 -36
- package/src/validation/ref.ts +5 -6
- package/src/validation/shared.ts +22 -21
- package/src/validation/string.ts +29 -39
- package/src/validation/type.ts +17 -17
- package/src/z-schema-base.ts +49 -38
- package/src/z-schema-options.ts +4 -3
- package/src/z-schema.ts +35 -45
- package/umd/ZSchema.js +711 -695
- package/umd/ZSchema.min.js +2 -2
- package/umd/package.json +3 -0
- package/dist/utils/unicode.mjs +0 -12
- package/dist/validation/type.mjs +0 -32
- /package/dist/{format-validators.d.mts → format-validators.d.ts} +0 -0
- /package/dist/{json-schema-versions.mjs → json-schema-versions.js} +0 -0
- /package/dist/schemas/{draft-04-schema.mjs → draft-04-schema.js} +0 -0
- /package/dist/schemas/{draft-06-schema.mjs → draft-06-schema.js} +0 -0
- /package/dist/schemas/{draft-07-schema.mjs → draft-07-schema.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-applicator.mjs → draft-2019-09-meta-applicator.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-content.mjs → draft-2019-09-meta-content.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-core.mjs → draft-2019-09-meta-core.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-format.mjs → draft-2019-09-meta-format.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-meta-data.mjs → draft-2019-09-meta-meta-data.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-validation.mjs → draft-2019-09-meta-validation.js} +0 -0
- /package/dist/schemas/{draft-2019-09-schema.mjs → draft-2019-09-schema.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-applicator.mjs → draft-2020-12-meta-applicator.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-content.mjs → draft-2020-12-meta-content.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-core.mjs → draft-2020-12-meta-core.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-format-annotation.mjs → draft-2020-12-meta-format-annotation.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-format-assertion.mjs → draft-2020-12-meta-format-assertion.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-meta-data.mjs → draft-2020-12-meta-meta-data.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-unevaluated.mjs → draft-2020-12-meta-unevaluated.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-validation.mjs → draft-2020-12-meta-validation.js} +0 -0
- /package/dist/schemas/{draft-2020-12-schema.mjs → draft-2020-12-schema.js} +0 -0
- /package/dist/utils/{constants.mjs → constants.js} +0 -0
- /package/dist/utils/{date.mjs → date.js} +0 -0
- /package/dist/utils/{properties.mjs → properties.js} +0 -0
- /package/dist/utils/{symbols.mjs → symbols.js} +0 -0
- /package/dist/utils/{uri.mjs → uri.js} +0 -0
- /package/dist/{z-schema-reader.mjs → z-schema-reader.js} +0 -0
|
@@ -25,26 +25,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
//#endregion
|
|
27
27
|
let validator_lib_isEmail_js = require("validator/lib/isEmail.js");
|
|
28
|
-
validator_lib_isEmail_js = __toESM(validator_lib_isEmail_js);
|
|
28
|
+
validator_lib_isEmail_js = __toESM(validator_lib_isEmail_js, 1);
|
|
29
29
|
let validator_lib_isIP_js = require("validator/lib/isIP.js");
|
|
30
|
-
validator_lib_isIP_js = __toESM(validator_lib_isIP_js);
|
|
30
|
+
validator_lib_isIP_js = __toESM(validator_lib_isIP_js, 1);
|
|
31
31
|
let validator_lib_isURL_js = require("validator/lib/isURL.js");
|
|
32
|
-
validator_lib_isURL_js = __toESM(validator_lib_isURL_js);
|
|
32
|
+
validator_lib_isURL_js = __toESM(validator_lib_isURL_js, 1);
|
|
33
33
|
let punycode_punycode_js = require("punycode/punycode.js");
|
|
34
|
-
punycode_punycode_js = __toESM(punycode_punycode_js);
|
|
34
|
+
punycode_punycode_js = __toESM(punycode_punycode_js, 1);
|
|
35
35
|
let safe_regex2 = require("safe-regex2");
|
|
36
|
-
safe_regex2 = __toESM(safe_regex2);
|
|
37
|
-
//#region src/utils/uri.ts
|
|
38
|
-
const getQueryPath = (uri) => {
|
|
39
|
-
const io = uri.indexOf("#");
|
|
40
|
-
return io === -1 ? void 0 : uri.slice(io + 1);
|
|
41
|
-
};
|
|
42
|
-
const getRemotePath = (uri) => {
|
|
43
|
-
const io = uri.indexOf("#");
|
|
44
|
-
return io === -1 ? uri : uri.slice(0, io);
|
|
45
|
-
};
|
|
46
|
-
const isAbsoluteUri = (uri) => /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(uri);
|
|
47
|
-
//#endregion
|
|
36
|
+
safe_regex2 = __toESM(safe_regex2, 1);
|
|
48
37
|
//#region src/utils/constants.ts
|
|
49
38
|
/**
|
|
50
39
|
* Maximum allowed value for {@link ZSchemaOptions.asyncTimeout} in milliseconds.
|
|
@@ -60,6 +49,17 @@ const MAX_ASYNC_TIMEOUT = 6e4;
|
|
|
60
49
|
*/
|
|
61
50
|
const MAX_SCHEMA_REGEX_LENGTH = 1e4;
|
|
62
51
|
//#endregion
|
|
52
|
+
//#region src/utils/uri.ts
|
|
53
|
+
const getQueryPath = (uri) => {
|
|
54
|
+
const io = uri.indexOf("#");
|
|
55
|
+
return io === -1 ? void 0 : uri.slice(io + 1);
|
|
56
|
+
};
|
|
57
|
+
const getRemotePath = (uri) => {
|
|
58
|
+
const io = uri.indexOf("#");
|
|
59
|
+
return io === -1 ? uri : uri.slice(0, io);
|
|
60
|
+
};
|
|
61
|
+
const isAbsoluteUri = (uri) => /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(uri);
|
|
62
|
+
//#endregion
|
|
63
63
|
//#region src/utils/what-is.ts
|
|
64
64
|
const whatIs = (what) => {
|
|
65
65
|
if (typeof what === "object") {
|
|
@@ -68,8 +68,7 @@ const whatIs = (what) => {
|
|
|
68
68
|
return "object";
|
|
69
69
|
}
|
|
70
70
|
if (typeof what === "number") {
|
|
71
|
-
if (Number.isFinite(what))
|
|
72
|
-
else return "number";
|
|
71
|
+
if (Number.isFinite(what)) return what % 1 === 0 ? "integer" : "number";
|
|
73
72
|
if (Number.isNaN(what)) return "not-a-number";
|
|
74
73
|
return "unknown-number";
|
|
75
74
|
}
|
|
@@ -81,18 +80,12 @@ function isObject(value) {
|
|
|
81
80
|
function isInteger(value) {
|
|
82
81
|
return typeof value === "number" && Number.isFinite(value) && value % 1 === 0;
|
|
83
82
|
}
|
|
84
|
-
|
|
85
|
-
//#region src/json-schema.ts
|
|
86
|
-
/**
|
|
87
|
-
* Keywords whose values are not JSON Schema sub-schemas and must not be
|
|
88
|
-
* traversed during schema walking (id collection, reference collection, etc.).
|
|
89
|
-
*/
|
|
90
|
-
const NON_SCHEMA_KEYWORDS = [
|
|
83
|
+
const NON_SCHEMA_KEYWORDS_SET = new Set([
|
|
91
84
|
"enum",
|
|
92
85
|
"const",
|
|
93
86
|
"default",
|
|
94
87
|
"examples"
|
|
95
|
-
];
|
|
88
|
+
]);
|
|
96
89
|
/** Returns true if the key is an internal z-schema property (prefixed with `__$`). */
|
|
97
90
|
const isInternalKey = (key) => key.startsWith("__$");
|
|
98
91
|
const getId = (schema) => {
|
|
@@ -113,7 +106,7 @@ const findId = (schema, id, targetBaseUri, currentBaseUri, maxDepth = 100, _dept
|
|
|
113
106
|
} catch {}
|
|
114
107
|
}
|
|
115
108
|
if (!targetBaseUri || nextBaseUri === targetBaseUri) {
|
|
116
|
-
if (schemaId && (schemaId === id || schemaId
|
|
109
|
+
if (schemaId && (schemaId === id || schemaId.startsWith("#") && schemaId.slice(1) === id)) return schema;
|
|
117
110
|
if (schema.$anchor === id || schema.$dynamicAnchor === id) return schema;
|
|
118
111
|
}
|
|
119
112
|
let result;
|
|
@@ -125,7 +118,7 @@ const findId = (schema, id, targetBaseUri, currentBaseUri, maxDepth = 100, _dept
|
|
|
125
118
|
const keys = Object.keys(schema);
|
|
126
119
|
for (let i = keys.length - 1; i >= 0; i--) {
|
|
127
120
|
const k = keys[i];
|
|
128
|
-
if (isInternalKey(k) ||
|
|
121
|
+
if (isInternalKey(k) || NON_SCHEMA_KEYWORDS_SET.has(k)) continue;
|
|
129
122
|
result = findId(schema[k], id, targetBaseUri, nextBaseUri, maxDepth, _depth + 1);
|
|
130
123
|
if (result) return result;
|
|
131
124
|
}
|
|
@@ -186,11 +179,10 @@ const Errors = {
|
|
|
186
179
|
MAX_RECURSION_DEPTH_EXCEEDED: "Maximum recursion depth ({0}) exceeded. If your schema or data is deeply nested and valid, increase the maxRecursionDepth option."
|
|
187
180
|
};
|
|
188
181
|
var ValidateError = class extends Error {
|
|
189
|
-
name;
|
|
182
|
+
name = "ValidateError";
|
|
190
183
|
details;
|
|
191
184
|
constructor(message, details) {
|
|
192
185
|
super(message);
|
|
193
|
-
this.name = "z-schema validation error";
|
|
194
186
|
this.details = details;
|
|
195
187
|
}
|
|
196
188
|
};
|
|
@@ -211,49 +203,48 @@ function copyProp(from, to, key, fn) {
|
|
|
211
203
|
//#region src/utils/clone.ts
|
|
212
204
|
const shallowClone = (src) => {
|
|
213
205
|
if (src == null || typeof src !== "object") return src;
|
|
214
|
-
let res;
|
|
215
206
|
if (Array.isArray(src)) {
|
|
216
|
-
res = [];
|
|
207
|
+
const res = [];
|
|
217
208
|
for (let i = 0; i < src.length; i++) res[i] = src[i];
|
|
218
|
-
|
|
219
|
-
res = {};
|
|
220
|
-
const keys = Object.keys(src).sort();
|
|
221
|
-
for (const key of keys) copyProp(src, res, key);
|
|
209
|
+
return res;
|
|
222
210
|
}
|
|
211
|
+
const res = {};
|
|
212
|
+
const keys = Object.keys(src).sort();
|
|
213
|
+
for (let i = 0; i < keys.length; i++) copyProp(src, res, keys[i]);
|
|
223
214
|
return res;
|
|
224
215
|
};
|
|
225
216
|
const deepClone = (src, maxDepth = 100) => {
|
|
226
217
|
let vidx = 0;
|
|
227
218
|
const visited = /* @__PURE__ */ new Map();
|
|
228
219
|
const cloned = [];
|
|
229
|
-
const cloneDeepInner = (
|
|
230
|
-
if (typeof
|
|
220
|
+
const cloneDeepInner = (node, _depth) => {
|
|
221
|
+
if (typeof node !== "object" || node === null) return node;
|
|
231
222
|
if (_depth >= maxDepth) throw new Error(`Maximum recursion depth (${maxDepth}) exceeded in deepClone. If your schema or data is deeply nested and valid, increase the maxRecursionDepth option.`);
|
|
232
|
-
|
|
233
|
-
const cidx = visited.get(src);
|
|
223
|
+
const cidx = visited.get(node);
|
|
234
224
|
if (cidx !== void 0) return cloned[cidx];
|
|
235
|
-
visited.set(
|
|
236
|
-
if (Array.isArray(
|
|
237
|
-
res = [];
|
|
238
|
-
cloned.push(res);
|
|
239
|
-
for (let i = 0; i < src.length; i++) res[i] = cloneDeepInner(src[i], _depth + 1);
|
|
240
|
-
} else {
|
|
241
|
-
res = {};
|
|
225
|
+
visited.set(node, vidx++);
|
|
226
|
+
if (Array.isArray(node)) {
|
|
227
|
+
const res = [];
|
|
242
228
|
cloned.push(res);
|
|
243
|
-
|
|
244
|
-
|
|
229
|
+
for (let i = 0; i < node.length; i++) res[i] = cloneDeepInner(node[i], _depth + 1);
|
|
230
|
+
return res;
|
|
245
231
|
}
|
|
232
|
+
const res = {};
|
|
233
|
+
cloned.push(res);
|
|
234
|
+
const keys = Object.keys(node).sort();
|
|
235
|
+
for (let i = 0; i < keys.length; i++) copyProp(node, res, keys[i], (v) => cloneDeepInner(v, _depth + 1));
|
|
246
236
|
return res;
|
|
247
237
|
};
|
|
248
238
|
return cloneDeepInner(src, 0);
|
|
249
239
|
};
|
|
250
240
|
//#endregion
|
|
251
241
|
//#region src/utils/json.ts
|
|
242
|
+
const sortedKeys = (obj) => Object.keys(obj).sort();
|
|
252
243
|
const areEqual = (json1, json2, options, _depth = 0) => {
|
|
253
244
|
const caseInsensitiveComparison = options?.caseInsensitiveComparison || false;
|
|
254
245
|
const maxDepth = options?.maxDepth ?? 100;
|
|
255
246
|
if (json1 === json2) return true;
|
|
256
|
-
if (caseInsensitiveComparison
|
|
247
|
+
if (caseInsensitiveComparison && typeof json1 === "string" && typeof json2 === "string" && json1.toUpperCase() === json2.toUpperCase()) return true;
|
|
257
248
|
if (_depth >= maxDepth) throw new Error(`Maximum recursion depth (${maxDepth}) exceeded in areEqual. If your data is deeply nested and valid, increase the maxRecursionDepth option.`);
|
|
258
249
|
let i, len;
|
|
259
250
|
if (Array.isArray(json1) && Array.isArray(json2)) {
|
|
@@ -271,13 +262,16 @@ const areEqual = (json1, json2, options, _depth = 0) => {
|
|
|
271
262
|
}
|
|
272
263
|
return false;
|
|
273
264
|
};
|
|
274
|
-
const decodeJSONPointer = (str) =>
|
|
275
|
-
return decodeURIComponent(str).replace(/~[0-1]/g, (x) => x === "~1" ? "/" : "~");
|
|
276
|
-
};
|
|
277
|
-
const sortedKeys = (obj) => Object.keys(obj).sort();
|
|
265
|
+
const decodeJSONPointer = (str) => decodeURIComponent(str).replaceAll(/~[0-1]/g, (x) => x === "~1" ? "/" : "~");
|
|
278
266
|
const get = (obj, path) => {
|
|
279
267
|
if (typeof path === "string") path = path.split(".");
|
|
280
|
-
|
|
268
|
+
let acc = obj;
|
|
269
|
+
for (let i = 0; i < path.length; i++) {
|
|
270
|
+
const key = path[i];
|
|
271
|
+
if (acc && acc[key] !== void 0) acc = acc[key];
|
|
272
|
+
else return;
|
|
273
|
+
}
|
|
274
|
+
return acc;
|
|
281
275
|
};
|
|
282
276
|
//#endregion
|
|
283
277
|
//#region src/utils/symbols.ts
|
|
@@ -307,8 +301,8 @@ var Report = class Report {
|
|
|
307
301
|
if (parentOrOptions instanceof Report) {
|
|
308
302
|
this.reportOptions = reportOptionsOrValidate || {};
|
|
309
303
|
this.validateOptions = validateOptions || parentOrOptions.validateOptions;
|
|
310
|
-
this.__$recursiveAnchorStack =
|
|
311
|
-
this.__$dynamicScopeStack =
|
|
304
|
+
this.__$recursiveAnchorStack = parentOrOptions.__$recursiveAnchorStack.slice();
|
|
305
|
+
this.__$dynamicScopeStack = parentOrOptions.__$dynamicScopeStack.slice();
|
|
312
306
|
this.__validationResultCache = parentOrOptions.__validationResultCache;
|
|
313
307
|
} else {
|
|
314
308
|
this.reportOptions = {};
|
|
@@ -391,30 +385,24 @@ var Report = class Report {
|
|
|
391
385
|
setTimeout(checkTimeout, ASYNC_TIMEOUT_POLL_MS);
|
|
392
386
|
}
|
|
393
387
|
getPath(returnPathAsString) {
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
path = path.concat(this.path);
|
|
397
|
-
if (returnPathAsString !== true) return "#/" + path.map(function(segment) {
|
|
388
|
+
const path = this.parentReport ? this.parentReport.path.concat(this.path) : this.path.slice();
|
|
389
|
+
if (returnPathAsString !== true) return `#/${path.map((segment) => {
|
|
398
390
|
segment = segment.toString();
|
|
399
|
-
if (isAbsoluteUri(segment)) return
|
|
400
|
-
return segment.
|
|
401
|
-
}).join("/")
|
|
391
|
+
if (isAbsoluteUri(segment)) return `uri(${segment})`;
|
|
392
|
+
return segment.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
393
|
+
}).join("/")}`;
|
|
402
394
|
return path;
|
|
403
395
|
}
|
|
404
396
|
getSchemaPath() {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
schemaPath = schemaPath.concat(this.schemaPath);
|
|
408
|
-
return schemaPath;
|
|
397
|
+
if (this.parentReport) return this.parentReport.schemaPath.concat(this.schemaPath);
|
|
398
|
+
return this.schemaPath.slice();
|
|
409
399
|
}
|
|
410
400
|
getSchemaId() {
|
|
411
401
|
if (!this.rootSchema) return;
|
|
412
|
-
|
|
413
|
-
if (this.parentReport) path = path.concat(this.parentReport.path);
|
|
414
|
-
path = path.concat(this.path);
|
|
402
|
+
const path = this.parentReport ? this.parentReport.path.concat(this.path) : this.path.slice();
|
|
415
403
|
while (path.length > 0) {
|
|
416
404
|
const obj = get(this.rootSchema, path);
|
|
417
|
-
if (obj && obj.id) return obj.id;
|
|
405
|
+
if (isObject(obj) && typeof obj.id === "string") return obj.id;
|
|
418
406
|
path.pop();
|
|
419
407
|
}
|
|
420
408
|
return this.rootSchema.id;
|
|
@@ -437,11 +425,11 @@ var Report = class Report {
|
|
|
437
425
|
}
|
|
438
426
|
addCustomError(errorCode, errorMessage, params, subReports, schema, keyword) {
|
|
439
427
|
if (typeof this.reportOptions.maxErrors === "number" && this.errors.length >= this.reportOptions.maxErrors) return;
|
|
440
|
-
if (!errorMessage) throw new Error(
|
|
441
|
-
params
|
|
428
|
+
if (!errorMessage) throw new Error(`No errorMessage known for code ${errorCode}`);
|
|
429
|
+
params ||= [];
|
|
442
430
|
for (let idx = 0; idx < params.length; idx++) {
|
|
443
431
|
const param = params[idx] === null || isObject(params[idx]) ? JSON.stringify(params[idx]) : params[idx];
|
|
444
|
-
errorMessage = errorMessage.replace(
|
|
432
|
+
errorMessage = errorMessage.replace(`{${idx}}`, param.toString());
|
|
445
433
|
}
|
|
446
434
|
const err = {
|
|
447
435
|
code: errorCode,
|
|
@@ -450,10 +438,10 @@ var Report = class Report {
|
|
|
450
438
|
path: this.getPath(this.options.reportPathAsArray),
|
|
451
439
|
schemaPath: this.getSchemaPath(),
|
|
452
440
|
schemaId: this.getSchemaId(),
|
|
453
|
-
keyword
|
|
441
|
+
keyword,
|
|
442
|
+
[schemaSymbol]: schema,
|
|
443
|
+
[jsonSymbol]: this.getJson()
|
|
454
444
|
};
|
|
455
|
-
err[schemaSymbol] = schema;
|
|
456
|
-
err[jsonSymbol] = this.getJson();
|
|
457
445
|
if (schema && typeof schema === "string") err.description = schema;
|
|
458
446
|
else if (schema && typeof schema === "object") {
|
|
459
447
|
if (schema.title) err.title = schema.title;
|
|
@@ -462,7 +450,10 @@ var Report = class Report {
|
|
|
462
450
|
if (subReports != null) {
|
|
463
451
|
if (!Array.isArray(subReports)) subReports = [subReports];
|
|
464
452
|
err.inner = [];
|
|
465
|
-
for (
|
|
453
|
+
for (let si = 0; si < subReports.length; si++) {
|
|
454
|
+
const errs = subReports[si].errors;
|
|
455
|
+
for (let ei = 0; ei < errs.length; ei++) err.inner.push(errs[ei]);
|
|
456
|
+
}
|
|
466
457
|
if (err.inner.length === 0) err.inner = void 0;
|
|
467
458
|
}
|
|
468
459
|
if (Array.isArray(this.validateOptions.excludeErrors) && this.validateOptions.excludeErrors.includes(errorCode)) return;
|
|
@@ -512,7 +503,7 @@ const normalizeOptions = (options) => {
|
|
|
512
503
|
let normalized;
|
|
513
504
|
if (typeof options === "object") {
|
|
514
505
|
let keys = Object.keys(options);
|
|
515
|
-
for (const key of keys) if (defaultOptions[key] === void 0) throw new Error(
|
|
506
|
+
for (const key of keys) if (defaultOptions[key] === void 0) throw new Error(`Unexpected option passed to constructor: ${key}`);
|
|
516
507
|
keys = Object.keys(defaultOptions);
|
|
517
508
|
for (const key of keys) if (options[key] === void 0) options[key] = shallowClone(defaultOptions[key]);
|
|
518
509
|
normalized = options;
|
|
@@ -540,7 +531,7 @@ function getSafeRemotePath(uri) {
|
|
|
540
531
|
}
|
|
541
532
|
const getEffectiveId = (schema) => {
|
|
542
533
|
let id = getId(schema);
|
|
543
|
-
if ((!id || !isAbsoluteUri(id)) && typeof schema.id === "string" && isAbsoluteUri(schema.id)) id = schema
|
|
534
|
+
if ((!id || !isAbsoluteUri(id)) && typeof schema.id === "string" && isAbsoluteUri(schema.id)) ({id} = schema);
|
|
544
535
|
return id;
|
|
545
536
|
};
|
|
546
537
|
/**
|
|
@@ -549,9 +540,7 @@ const getEffectiveId = (schema) => {
|
|
|
549
540
|
* the instance `validator.setRemoteReference()` (instance cache).
|
|
550
541
|
*/
|
|
551
542
|
function prepareRemoteSchema(schema, uri, validationOptions, maxCloneDepth) {
|
|
552
|
-
|
|
553
|
-
if (typeof schema === "string") _schema = JSON.parse(schema);
|
|
554
|
-
else _schema = deepClone(schema, maxCloneDepth);
|
|
543
|
+
const _schema = typeof schema === "string" ? JSON.parse(schema) : deepClone(schema, maxCloneDepth);
|
|
555
544
|
if (!_schema.id) _schema.id = uri;
|
|
556
545
|
if (validationOptions) _schema.__$validationOptions = normalizeOptions(validationOptions);
|
|
557
546
|
return _schema;
|
|
@@ -559,6 +548,7 @@ function prepareRemoteSchema(schema, uri, validationOptions, maxCloneDepth) {
|
|
|
559
548
|
var SchemaCache = class SchemaCache {
|
|
560
549
|
static global_cache = Object.create(null);
|
|
561
550
|
cache = Object.create(null);
|
|
551
|
+
validator;
|
|
562
552
|
constructor(validator) {
|
|
563
553
|
this.validator = validator;
|
|
564
554
|
}
|
|
@@ -635,7 +625,7 @@ var SchemaCache = class SchemaCache {
|
|
|
635
625
|
usesAncestorReport = true;
|
|
636
626
|
} else {
|
|
637
627
|
remoteReport = new Report(report);
|
|
638
|
-
const noCache = result.id && isAbsoluteUri(result.id)
|
|
628
|
+
const noCache = !(result.id && isAbsoluteUri(result.id));
|
|
639
629
|
if (this.validator.sc.compileSchema(remoteReport, result, { noCache })) {
|
|
640
630
|
const savedOptions = this.validator.options;
|
|
641
631
|
try {
|
|
@@ -1688,13 +1678,16 @@ const isValidRfc3339Date = (year, month, day) => {
|
|
|
1688
1678
|
};
|
|
1689
1679
|
//#endregion
|
|
1690
1680
|
//#region src/utils/hostname.ts
|
|
1691
|
-
const IDN_SEPARATOR_REGEX = /[\u3002\
|
|
1692
|
-
const IDN_SEPARATOR_TEST_REGEX = /[\u3002\
|
|
1681
|
+
const IDN_SEPARATOR_REGEX = /[\u3002\uFF0E\uFF61]/g;
|
|
1682
|
+
const IDN_SEPARATOR_TEST_REGEX = /[\u3002\uFF0E\uFF61]/;
|
|
1693
1683
|
const splitHostnameLabels = (hostname) => {
|
|
1694
1684
|
if (hostname.length === 0 || hostname.length > 255) return null;
|
|
1695
1685
|
if (hostname.startsWith(".") || hostname.endsWith(".")) return null;
|
|
1696
1686
|
const labels = hostname.split(".");
|
|
1697
|
-
|
|
1687
|
+
for (let i = 0; i < labels.length; i++) {
|
|
1688
|
+
const len = labels[i].length;
|
|
1689
|
+
if (len === 0 || len > 63) return null;
|
|
1690
|
+
}
|
|
1698
1691
|
return labels;
|
|
1699
1692
|
};
|
|
1700
1693
|
const isAsciiHostnameLabel = (label) => /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label);
|
|
@@ -1705,7 +1698,7 @@ const toUnicodeLabel = (label) => {
|
|
|
1705
1698
|
if (!/^xn--/i.test(label)) return label;
|
|
1706
1699
|
try {
|
|
1707
1700
|
return punycode_punycode_js.default.toUnicode(label.toLowerCase());
|
|
1708
|
-
} catch
|
|
1701
|
+
} catch {
|
|
1709
1702
|
return null;
|
|
1710
1703
|
}
|
|
1711
1704
|
};
|
|
@@ -1713,34 +1706,27 @@ const isValidIdnUnicodeLabel = (label) => {
|
|
|
1713
1706
|
if (label.startsWith("-") || label.endsWith("-")) return false;
|
|
1714
1707
|
if (label.length >= 4 && label[2] === "-" && label[3] === "-" && !/^xn--/i.test(label)) return false;
|
|
1715
1708
|
if (/^\p{M}/u.test(label)) return false;
|
|
1716
|
-
if (/[\
|
|
1709
|
+
if (/[\u302E\u302F\u0640\u07FA]/u.test(label)) return false;
|
|
1717
1710
|
for (let idx = 0; idx < label.length; idx++) {
|
|
1718
1711
|
const char = label[idx];
|
|
1719
|
-
if (char === "·")
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
if (char === "
|
|
1723
|
-
if (idx === label.length - 1 || !isGreek(label[idx + 1])) return false;
|
|
1724
|
-
}
|
|
1725
|
-
if (char === "׳" || char === "״") {
|
|
1726
|
-
if (idx === 0 || !isHebrew(label[idx - 1])) return false;
|
|
1727
|
-
}
|
|
1728
|
-
if (char === "") {
|
|
1729
|
-
if (idx === 0 || label[idx - 1] !== "्") return false;
|
|
1730
|
-
}
|
|
1712
|
+
if (char === "·" && (idx === 0 || idx === label.length - 1 || label[idx - 1] !== "l" || label[idx + 1] !== "l")) return false;
|
|
1713
|
+
if (char === "͵" && (idx === label.length - 1 || !isGreek(label[idx + 1]))) return false;
|
|
1714
|
+
if ((char === "׳" || char === "״") && (idx === 0 || !isHebrew(label[idx - 1]))) return false;
|
|
1715
|
+
if (char === "" && (idx === 0 || label[idx - 1] !== "्")) return false;
|
|
1731
1716
|
}
|
|
1732
|
-
if (label.includes("・") && !hasCjkKanaOrHan(label.
|
|
1717
|
+
if (label.includes("・") && !hasCjkKanaOrHan(label.replaceAll("・", ""))) return false;
|
|
1733
1718
|
const hasArabicIndic = /[\u0660-\u0669]/.test(label);
|
|
1734
|
-
const hasExtendedArabicIndic = /[\
|
|
1719
|
+
const hasExtendedArabicIndic = /[\u06F0-\u06F9]/.test(label);
|
|
1735
1720
|
if (hasArabicIndic && hasExtendedArabicIndic) return false;
|
|
1736
1721
|
return true;
|
|
1737
1722
|
};
|
|
1738
1723
|
const isValidHostname = (hostname) => {
|
|
1739
|
-
if (IDN_SEPARATOR_TEST_REGEX.test(hostname) || /[^\
|
|
1724
|
+
if (IDN_SEPARATOR_TEST_REGEX.test(hostname) || /[^\u0000-\u007F]/.test(hostname)) return false;
|
|
1740
1725
|
if (validator_lib_isIP_js.default.default(hostname, 4)) return false;
|
|
1741
1726
|
const labels = splitHostnameLabels(hostname);
|
|
1742
1727
|
if (labels === null) return false;
|
|
1743
|
-
for (
|
|
1728
|
+
for (let i = 0; i < labels.length; i++) {
|
|
1729
|
+
const label = labels[i];
|
|
1744
1730
|
if (!isAsciiHostnameLabel(label)) return false;
|
|
1745
1731
|
if (/^xn--/i.test(label)) {
|
|
1746
1732
|
const unicodeLabel = toUnicodeLabel(label);
|
|
@@ -1752,7 +1738,8 @@ const isValidHostname = (hostname) => {
|
|
|
1752
1738
|
const isValidIdnHostname = (hostname) => {
|
|
1753
1739
|
const labels = splitHostnameLabels(hostname.replace(IDN_SEPARATOR_REGEX, "."));
|
|
1754
1740
|
if (labels === null) return false;
|
|
1755
|
-
for (
|
|
1741
|
+
for (let i = 0; i < labels.length; i++) {
|
|
1742
|
+
const label = labels[i];
|
|
1756
1743
|
const unicodeLabel = toUnicodeLabel(label);
|
|
1757
1744
|
if (unicodeLabel === null || !isValidIdnUnicodeLabel(unicodeLabel)) return false;
|
|
1758
1745
|
}
|
|
@@ -1773,9 +1760,9 @@ const RFC3339_TIME_REGEX = /^([0-9]{2}):([0-9]{2}):([0-9]{2})(\.[0-9]+)?(z|([+-]
|
|
|
1773
1760
|
const parseRfc3339Time = (time) => {
|
|
1774
1761
|
const matches = RFC3339_TIME_REGEX.exec(time);
|
|
1775
1762
|
if (matches === null) return null;
|
|
1776
|
-
const hour = parseInt(matches[1], 10);
|
|
1777
|
-
const minute = parseInt(matches[2], 10);
|
|
1778
|
-
const second = parseInt(matches[3], 10);
|
|
1763
|
+
const hour = Number.parseInt(matches[1], 10);
|
|
1764
|
+
const minute = Number.parseInt(matches[2], 10);
|
|
1765
|
+
const second = Number.parseInt(matches[3], 10);
|
|
1779
1766
|
if (hour > 23 || minute > 59 || second > 60) return null;
|
|
1780
1767
|
let utcHour = hour;
|
|
1781
1768
|
let utcMinute = minute;
|
|
@@ -1783,8 +1770,8 @@ const parseRfc3339Time = (time) => {
|
|
|
1783
1770
|
const offsetMatches = /^([+-])([0-9]{2}):([0-9]{2})$/.exec(matches[5]);
|
|
1784
1771
|
if (offsetMatches === null) return null;
|
|
1785
1772
|
const offsetSign = offsetMatches[1];
|
|
1786
|
-
const offsetHour = parseInt(offsetMatches[2], 10);
|
|
1787
|
-
const offsetMinute = parseInt(offsetMatches[3], 10);
|
|
1773
|
+
const offsetHour = Number.parseInt(offsetMatches[2], 10);
|
|
1774
|
+
const offsetMinute = Number.parseInt(offsetMatches[3], 10);
|
|
1788
1775
|
if (offsetHour > 23 || offsetMinute > 59) return null;
|
|
1789
1776
|
const utc = toUtcTime(hour, minute, offsetSign, offsetHour, offsetMinute);
|
|
1790
1777
|
utcHour = utc.hour;
|
|
@@ -1805,17 +1792,18 @@ const dateValidator = (date) => {
|
|
|
1805
1792
|
if (typeof date !== "string") return true;
|
|
1806
1793
|
const matches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(date);
|
|
1807
1794
|
if (matches === null) return false;
|
|
1808
|
-
return isValidRfc3339Date(parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3], 10));
|
|
1795
|
+
return isValidRfc3339Date(Number.parseInt(matches[1], 10), Number.parseInt(matches[2], 10), Number.parseInt(matches[3], 10));
|
|
1809
1796
|
};
|
|
1810
1797
|
const dateTimeValidator = (dateTime) => {
|
|
1811
1798
|
if (typeof dateTime !== "string") return true;
|
|
1812
|
-
|
|
1813
|
-
if (
|
|
1814
|
-
|
|
1815
|
-
const
|
|
1799
|
+
let tIdx = dateTime.indexOf("T");
|
|
1800
|
+
if (tIdx === -1) tIdx = dateTime.indexOf("t");
|
|
1801
|
+
if (tIdx === -1) return false;
|
|
1802
|
+
const datePart = dateTime.slice(0, tIdx);
|
|
1803
|
+
const timePart = dateTime.slice(tIdx + 1);
|
|
1816
1804
|
const dateMatches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(datePart);
|
|
1817
1805
|
if (dateMatches === null) return false;
|
|
1818
|
-
if (!isValidRfc3339Date(parseInt(dateMatches[1], 10), parseInt(dateMatches[2], 10), parseInt(dateMatches[3], 10))) return false;
|
|
1806
|
+
if (!isValidRfc3339Date(Number.parseInt(dateMatches[1], 10), Number.parseInt(dateMatches[2], 10), Number.parseInt(dateMatches[3], 10))) return false;
|
|
1819
1807
|
return parseRfc3339Time(timePart) !== null;
|
|
1820
1808
|
};
|
|
1821
1809
|
const emailValidator = (email) => {
|
|
@@ -1844,26 +1832,26 @@ const ipv6Validator = (ipv6) => {
|
|
|
1844
1832
|
if (ipv6.includes("%")) return false;
|
|
1845
1833
|
return validator_lib_isIP_js.default.default(ipv6, 6);
|
|
1846
1834
|
};
|
|
1835
|
+
const INVALID_REGEX_ESCAPES = new Set(["a"]);
|
|
1847
1836
|
const regexValidator = (input) => {
|
|
1848
1837
|
if (typeof input !== "string") return true;
|
|
1849
|
-
const invalidEscapes = new Set(["a"]);
|
|
1850
1838
|
for (let idx = 0; idx < input.length; idx++) {
|
|
1851
1839
|
if (input[idx] !== "\\") continue;
|
|
1852
1840
|
idx++;
|
|
1853
1841
|
if (idx >= input.length) return false;
|
|
1854
1842
|
const escaped = input[idx];
|
|
1855
|
-
if (
|
|
1843
|
+
if (INVALID_REGEX_ESCAPES.has(escaped)) return false;
|
|
1856
1844
|
}
|
|
1857
1845
|
try {
|
|
1858
|
-
RegExp(input);
|
|
1846
|
+
new RegExp(input);
|
|
1859
1847
|
return true;
|
|
1860
|
-
} catch
|
|
1848
|
+
} catch {
|
|
1861
1849
|
return false;
|
|
1862
1850
|
}
|
|
1863
1851
|
};
|
|
1864
1852
|
const durationValidator = (input) => {
|
|
1865
1853
|
if (typeof input !== "string") return true;
|
|
1866
|
-
if (!/^P[\
|
|
1854
|
+
if (!/^P[\u0000-\u007F]*$/.test(input)) return false;
|
|
1867
1855
|
if (!input.startsWith("P")) return false;
|
|
1868
1856
|
const body = input.slice(1);
|
|
1869
1857
|
if (body.length === 0) return false;
|
|
@@ -1873,7 +1861,7 @@ const durationValidator = (input) => {
|
|
|
1873
1861
|
const datePart = parts[0];
|
|
1874
1862
|
const timePart = parts.length === 2 ? parts[1] : void 0;
|
|
1875
1863
|
if (datePart.length > 0 && !/^(?:\d+Y(?:\d+M(?:\d+D)?)?|\d+M(?:\d+D)?|\d+D)$/.test(datePart)) return false;
|
|
1876
|
-
const hasDateComponent =
|
|
1864
|
+
const hasDateComponent = datePart.length > 0;
|
|
1877
1865
|
let hasTimeComponent = false;
|
|
1878
1866
|
if (timePart !== void 0) {
|
|
1879
1867
|
if (timePart.length === 0) return false;
|
|
@@ -1888,32 +1876,31 @@ const uuidValidator = (input) => {
|
|
|
1888
1876
|
return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(input);
|
|
1889
1877
|
};
|
|
1890
1878
|
const strictUriValidator = (uri) => typeof uri !== "string" || validator_lib_isURL_js.default.default(uri);
|
|
1879
|
+
const isHexChar = (c) => c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
|
|
1891
1880
|
const hasValidPercentEncoding = (str) => {
|
|
1892
|
-
for (let i = 0; i < str.length; i++) if (str[i] === "%")
|
|
1893
|
-
if (i + 2 >= str.length || !/[0-9a-fA-F]/.test(str[i + 1]) || !/[0-9a-fA-F]/.test(str[i + 2])) return false;
|
|
1894
|
-
}
|
|
1881
|
+
for (let i = 0; i < str.length; i++) if (str[i] === "%" && (i + 2 >= str.length || !isHexChar(str.charCodeAt(i + 1)) || !isHexChar(str.charCodeAt(i + 2)))) return false;
|
|
1895
1882
|
return true;
|
|
1896
1883
|
};
|
|
1897
|
-
const uriValidator =
|
|
1884
|
+
const uriValidator = (uri) => {
|
|
1898
1885
|
if (typeof uri !== "string") return true;
|
|
1899
|
-
if (/[^\
|
|
1886
|
+
if (/[^\u0000-\u007F]/.test(uri)) return false;
|
|
1900
1887
|
if (!hasValidPercentEncoding(uri)) return false;
|
|
1901
|
-
const match =
|
|
1888
|
+
const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):\/\/([^/?#]*)/.exec(uri);
|
|
1902
1889
|
if (match) {
|
|
1903
1890
|
const authority = match[2];
|
|
1904
1891
|
const atIndex = authority.indexOf("@");
|
|
1905
1892
|
if (atIndex > 0) {
|
|
1906
|
-
const userinfo = authority.
|
|
1893
|
+
const userinfo = authority.slice(0, atIndex);
|
|
1907
1894
|
if (userinfo.includes("[") || userinfo.includes("]")) return false;
|
|
1908
1895
|
}
|
|
1909
|
-
let hostPort = atIndex
|
|
1896
|
+
let hostPort = atIndex === -1 ? authority : authority.slice(atIndex + 1);
|
|
1910
1897
|
if (hostPort.startsWith("[")) {
|
|
1911
1898
|
const bracketEnd = hostPort.indexOf("]");
|
|
1912
|
-
if (bracketEnd
|
|
1899
|
+
if (bracketEnd !== -1) hostPort = hostPort.slice(bracketEnd + 1);
|
|
1913
1900
|
}
|
|
1914
1901
|
const colonIndex = hostPort.lastIndexOf(":");
|
|
1915
|
-
if (colonIndex
|
|
1916
|
-
const port = hostPort.
|
|
1902
|
+
if (colonIndex !== -1) {
|
|
1903
|
+
const port = hostPort.slice(colonIndex + 1);
|
|
1917
1904
|
if (port.length > 0 && !/^\d+$/.test(port)) return false;
|
|
1918
1905
|
}
|
|
1919
1906
|
}
|
|
@@ -1921,7 +1908,7 @@ const uriValidator = function(uri) {
|
|
|
1921
1908
|
};
|
|
1922
1909
|
const uriReferenceValidator = (uri) => {
|
|
1923
1910
|
if (typeof uri !== "string") return true;
|
|
1924
|
-
if (/[^\
|
|
1911
|
+
if (/[^\u0000-\u007F]/.test(uri)) return false;
|
|
1925
1912
|
return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/.test(uri);
|
|
1926
1913
|
};
|
|
1927
1914
|
const uriTemplateValidator = (uri) => {
|
|
@@ -1952,20 +1939,20 @@ const jsonPointerValidator = (pointer) => {
|
|
|
1952
1939
|
if (typeof pointer !== "string") return true;
|
|
1953
1940
|
if (pointer === "") return true;
|
|
1954
1941
|
if (!/^(?:\/[^/]*)+$/.test(pointer)) return false;
|
|
1955
|
-
const tokens = pointer.split("/")
|
|
1956
|
-
for (
|
|
1942
|
+
const tokens = pointer.split("/");
|
|
1943
|
+
for (let i = 1; i < tokens.length; i++) if (!hasValidTildeEscapes(tokens[i])) return false;
|
|
1957
1944
|
return true;
|
|
1958
1945
|
};
|
|
1959
1946
|
const relativeJsonPointerValidator = (pointer) => {
|
|
1960
1947
|
if (typeof pointer !== "string") return true;
|
|
1961
|
-
const match =
|
|
1948
|
+
const match = /^(0|[1-9]\d*)(.*)$/.exec(pointer);
|
|
1962
1949
|
if (!match) return false;
|
|
1963
1950
|
const suffix = match[2];
|
|
1964
1951
|
if (suffix === "" || suffix === "#") return true;
|
|
1965
1952
|
if (!suffix.startsWith("/")) return false;
|
|
1966
1953
|
if (!/^(?:\/[^/]*)+$/.test(suffix)) return false;
|
|
1967
|
-
const tokens = suffix.split("/")
|
|
1968
|
-
for (
|
|
1954
|
+
const tokens = suffix.split("/");
|
|
1955
|
+
for (let i = 1; i < tokens.length; i++) if (!hasValidTildeEscapes(tokens[i])) return false;
|
|
1969
1956
|
return true;
|
|
1970
1957
|
};
|
|
1971
1958
|
const timeValidator = (time) => {
|
|
@@ -1986,7 +1973,7 @@ const iriValidator = (iri) => {
|
|
|
1986
1973
|
try {
|
|
1987
1974
|
new URL(iri);
|
|
1988
1975
|
return true;
|
|
1989
|
-
} catch
|
|
1976
|
+
} catch {
|
|
1990
1977
|
return false;
|
|
1991
1978
|
}
|
|
1992
1979
|
};
|
|
@@ -2023,9 +2010,16 @@ function getFormatValidators(options) {
|
|
|
2023
2010
|
...inbuiltValidators,
|
|
2024
2011
|
...options?.strictUris ? { uri: strictUriValidator } : {},
|
|
2025
2012
|
...customValidators,
|
|
2026
|
-
...options?.customFormats
|
|
2013
|
+
...options?.customFormats
|
|
2027
2014
|
};
|
|
2028
2015
|
}
|
|
2016
|
+
function resolveFormatValidator(name, options) {
|
|
2017
|
+
const custom = options?.customFormats;
|
|
2018
|
+
if (custom && Object.hasOwn(custom, name)) return custom[name];
|
|
2019
|
+
if (Object.hasOwn(customValidators, name)) return customValidators[name];
|
|
2020
|
+
if (options?.strictUris && name === "uri") return strictUriValidator;
|
|
2021
|
+
return inbuiltValidators[name];
|
|
2022
|
+
}
|
|
2029
2023
|
function registerFormat(name, validatorFunction) {
|
|
2030
2024
|
customValidators[name] = validatorFunction;
|
|
2031
2025
|
}
|
|
@@ -2074,12 +2068,12 @@ function compileSchemaRegex(pattern) {
|
|
|
2074
2068
|
ok: true,
|
|
2075
2069
|
value: new RegExp(pattern, "u")
|
|
2076
2070
|
};
|
|
2077
|
-
} catch (
|
|
2071
|
+
} catch (error) {
|
|
2078
2072
|
return {
|
|
2079
2073
|
ok: false,
|
|
2080
2074
|
error: {
|
|
2081
2075
|
pattern,
|
|
2082
|
-
message:
|
|
2076
|
+
message: error instanceof Error ? error.message : "Invalid regular expression"
|
|
2083
2077
|
}
|
|
2084
2078
|
};
|
|
2085
2079
|
}
|
|
@@ -2088,12 +2082,12 @@ function compileSchemaRegex(pattern) {
|
|
|
2088
2082
|
ok: true,
|
|
2089
2083
|
value: new RegExp(pattern)
|
|
2090
2084
|
};
|
|
2091
|
-
} catch (
|
|
2085
|
+
} catch (error) {
|
|
2092
2086
|
return {
|
|
2093
2087
|
ok: false,
|
|
2094
2088
|
error: {
|
|
2095
2089
|
pattern,
|
|
2096
|
-
message:
|
|
2090
|
+
message: error instanceof Error ? error.message : "Invalid regular expression"
|
|
2097
2091
|
}
|
|
2098
2092
|
};
|
|
2099
2093
|
}
|
|
@@ -2122,7 +2116,7 @@ const isUniqueArray = (arr, indexes, maxDepth) => {
|
|
|
2122
2116
|
const seen = /* @__PURE__ */ new Set();
|
|
2123
2117
|
for (let i = 0; i < l; i++) {
|
|
2124
2118
|
const v = arr[i];
|
|
2125
|
-
const key = typeof v
|
|
2119
|
+
const key = `${typeof v}:${String(v)}`;
|
|
2126
2120
|
if (seen.has(key)) {
|
|
2127
2121
|
if (indexes) for (let j = 0; j < i; j++) {
|
|
2128
2122
|
const prev = arr[j];
|
|
@@ -2137,7 +2131,8 @@ const isUniqueArray = (arr, indexes, maxDepth) => {
|
|
|
2137
2131
|
}
|
|
2138
2132
|
return true;
|
|
2139
2133
|
}
|
|
2140
|
-
|
|
2134
|
+
const eqOpts = { maxDepth };
|
|
2135
|
+
for (let i = 0; i < l; i++) for (let j = i + 1; j < l; j++) if (areEqual(arr[i], arr[j], eqOpts)) {
|
|
2141
2136
|
if (indexes) indexes.push(i, j);
|
|
2142
2137
|
return false;
|
|
2143
2138
|
}
|
|
@@ -2152,11 +2147,7 @@ const difference = (bigSet, subSet) => {
|
|
|
2152
2147
|
};
|
|
2153
2148
|
//#endregion
|
|
2154
2149
|
//#region src/validation/shared.ts
|
|
2155
|
-
const shouldSkipValidate =
|
|
2156
|
-
return options && Array.isArray(options.includeErrors) && options.includeErrors.length > 0 && !errors.some(function(err) {
|
|
2157
|
-
return options.includeErrors.includes(err);
|
|
2158
|
-
});
|
|
2159
|
-
};
|
|
2150
|
+
const shouldSkipValidate = (options, errors) => options && Array.isArray(options.includeErrors) && options.includeErrors.length > 0 && !errors.some((err) => options.includeErrors.includes(err));
|
|
2160
2151
|
const supportsDependentKeywords = (schema, version) => {
|
|
2161
2152
|
if (typeof schema.$schema === "string") return !/draft-04|draft-06|draft-07/.test(schema.$schema);
|
|
2162
2153
|
return !(version === "draft-04" || version === "draft-06" || version === "draft-07");
|
|
@@ -2196,7 +2187,7 @@ const isValidationVocabularyEnabled = (schema, report, version) => {
|
|
|
2196
2187
|
const metaSchema = currentSchemaMeta || rootSchemaMeta;
|
|
2197
2188
|
if (!metaSchema || typeof metaSchema !== "object" || !isObject(metaSchema.$vocabulary)) return true;
|
|
2198
2189
|
const vocabulary = metaSchema.$vocabulary;
|
|
2199
|
-
if (Object.hasOwn(vocabulary, VOCAB_VALIDATION_2019_09) || Object.hasOwn(vocabulary, VOCAB_VALIDATION_2020_12)) return vocabulary[VOCAB_VALIDATION_2019_09]
|
|
2190
|
+
if (Object.hasOwn(vocabulary, VOCAB_VALIDATION_2019_09) || Object.hasOwn(vocabulary, VOCAB_VALIDATION_2020_12)) return vocabulary[VOCAB_VALIDATION_2019_09] || vocabulary[VOCAB_VALIDATION_2020_12];
|
|
2200
2191
|
return false;
|
|
2201
2192
|
};
|
|
2202
2193
|
/**
|
|
@@ -2212,8 +2203,8 @@ const isFormatAssertionVocabEnabled = (schema, report, version) => {
|
|
|
2212
2203
|
const metaSchema = currentSchemaMeta || rootSchemaMeta;
|
|
2213
2204
|
if (!metaSchema || typeof metaSchema !== "object" || !isObject(metaSchema.$vocabulary)) return false;
|
|
2214
2205
|
const vocabulary = metaSchema.$vocabulary;
|
|
2215
|
-
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_ASSERTION_2020_12)) return vocabulary[VOCAB_FORMAT_ASSERTION_2020_12]
|
|
2216
|
-
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_2019_09)) return vocabulary[VOCAB_FORMAT_2019_09]
|
|
2206
|
+
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_ASSERTION_2020_12)) return vocabulary[VOCAB_FORMAT_ASSERTION_2020_12];
|
|
2207
|
+
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_2019_09)) return vocabulary[VOCAB_FORMAT_2019_09];
|
|
2217
2208
|
return false;
|
|
2218
2209
|
};
|
|
2219
2210
|
function cacheValidationResult(report, schema, json, passed) {
|
|
@@ -2237,9 +2228,14 @@ function getCachedValidationResult(report, schema, json) {
|
|
|
2237
2228
|
*/
|
|
2238
2229
|
function deferOrRunSync(report, subReports, decisionFn) {
|
|
2239
2230
|
const asyncTasksBefore = report.asyncTasks.length;
|
|
2240
|
-
for (
|
|
2231
|
+
for (let i = 0; i < subReports.length; i++) {
|
|
2232
|
+
const tasks = subReports[i].asyncTasks;
|
|
2233
|
+
for (let j = 0; j < tasks.length; j++) report.asyncTasks.push(tasks[j]);
|
|
2234
|
+
}
|
|
2241
2235
|
if (report.asyncTasks.length > asyncTasksBefore) report.addAsyncTaskWithPath((callback) => {
|
|
2242
|
-
setTimeout(() =>
|
|
2236
|
+
setTimeout(() => {
|
|
2237
|
+
callback(null);
|
|
2238
|
+
}, 0);
|
|
2243
2239
|
}, [], () => {
|
|
2244
2240
|
decisionFn();
|
|
2245
2241
|
});
|
|
@@ -2247,35 +2243,33 @@ function deferOrRunSync(report, subReports, decisionFn) {
|
|
|
2247
2243
|
}
|
|
2248
2244
|
//#endregion
|
|
2249
2245
|
//#region src/validation/array.ts
|
|
2250
|
-
function additionalItemsValidator(report, schema, json) {
|
|
2251
|
-
if (shouldSkipValidate(
|
|
2246
|
+
function additionalItemsValidator(ctx, report, schema, json) {
|
|
2247
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_ADDITIONAL_ITEMS"])) return;
|
|
2252
2248
|
if (!Array.isArray(json)) return;
|
|
2253
|
-
if (schema.additionalItems === false && Array.isArray(schema.items))
|
|
2254
|
-
if (json.length > schema.items.length) report.addError("ARRAY_ADDITIONAL_ITEMS", void 0, void 0, schema, "additionalItems");
|
|
2255
|
-
}
|
|
2249
|
+
if (schema.additionalItems === false && Array.isArray(schema.items) && json.length > schema.items.length) report.addError("ARRAY_ADDITIONAL_ITEMS", void 0, void 0, schema, "additionalItems");
|
|
2256
2250
|
}
|
|
2257
2251
|
function itemsValidator() {}
|
|
2258
2252
|
function prefixItemsValidator() {}
|
|
2259
|
-
function maxItemsValidator(report, schema, json) {
|
|
2260
|
-
if (shouldSkipValidate(
|
|
2253
|
+
function maxItemsValidator(ctx, report, schema, json) {
|
|
2254
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_LENGTH_LONG"])) return;
|
|
2261
2255
|
if (!Array.isArray(json)) return;
|
|
2262
2256
|
if (json.length > schema.maxItems) report.addError("ARRAY_LENGTH_LONG", [json.length, schema.maxItems], void 0, schema, "maxItems");
|
|
2263
2257
|
}
|
|
2264
|
-
function minItemsValidator(report, schema, json) {
|
|
2265
|
-
if (shouldSkipValidate(
|
|
2258
|
+
function minItemsValidator(ctx, report, schema, json) {
|
|
2259
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_LENGTH_SHORT"])) return;
|
|
2266
2260
|
if (!Array.isArray(json)) return;
|
|
2267
2261
|
if (json.length < schema.minItems) report.addError("ARRAY_LENGTH_SHORT", [json.length, schema.minItems], void 0, schema, "minItems");
|
|
2268
2262
|
}
|
|
2269
|
-
function uniqueItemsValidator(report, schema, json) {
|
|
2270
|
-
if (shouldSkipValidate(
|
|
2263
|
+
function uniqueItemsValidator(ctx, report, schema, json) {
|
|
2264
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_UNIQUE"])) return;
|
|
2271
2265
|
if (!Array.isArray(json)) return;
|
|
2272
2266
|
if (schema.uniqueItems === true) {
|
|
2273
2267
|
const matches = [];
|
|
2274
|
-
if (isUniqueArray(json, matches,
|
|
2268
|
+
if (!isUniqueArray(json, matches, ctx.options.maxRecursionDepth)) report.addError("ARRAY_UNIQUE", matches, void 0, schema, "uniqueItems");
|
|
2275
2269
|
}
|
|
2276
2270
|
}
|
|
2277
|
-
function containsValidator(report, schema, json) {
|
|
2278
|
-
if (shouldSkipValidate(
|
|
2271
|
+
function containsValidator(ctx, report, schema, json) {
|
|
2272
|
+
if (shouldSkipValidate(ctx.validateOptions, ["CONTAINS"])) return;
|
|
2279
2273
|
if (!Array.isArray(json)) return;
|
|
2280
2274
|
const containsSchema = schema.contains;
|
|
2281
2275
|
if (containsSchema === void 0) return;
|
|
@@ -2284,16 +2278,16 @@ function containsValidator(report, schema, json) {
|
|
|
2284
2278
|
for (let idx = 0; idx < json.length; idx++) {
|
|
2285
2279
|
const subReport = new Report_(report);
|
|
2286
2280
|
subReports.push(subReport);
|
|
2287
|
-
|
|
2281
|
+
ctx._jsonValidate(subReport, containsSchema, json[idx]);
|
|
2288
2282
|
cacheValidationResult(report, containsSchema, json[idx], subReport.errors.length === 0);
|
|
2289
2283
|
}
|
|
2290
2284
|
const addContainsErrorIfNeeded = () => {
|
|
2291
2285
|
let matchingItems = 0;
|
|
2292
|
-
for (
|
|
2293
|
-
const supportsContainsBounds =
|
|
2286
|
+
for (let i = 0; i < subReports.length; i++) if (subReports[i].errors.length === 0) matchingItems += 1;
|
|
2287
|
+
const supportsContainsBounds = ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12";
|
|
2294
2288
|
const minContains = supportsContainsBounds && typeof schema.minContains === "number" ? schema.minContains ?? 1 : 1;
|
|
2295
2289
|
const maxContains = supportsContainsBounds && typeof schema.maxContains === "number" ? schema.maxContains : void 0;
|
|
2296
|
-
if (!(matchingItems >= minContains) || !(maxContains === void 0 || matchingItems <= maxContains)) report.addError("CONTAINS", void 0, subReports, schema
|
|
2290
|
+
if (!(matchingItems >= minContains) || !(maxContains === void 0 || matchingItems <= maxContains)) report.addError("CONTAINS", void 0, subReports, schema);
|
|
2297
2291
|
};
|
|
2298
2292
|
deferOrRunSync(report, subReports, addContainsErrorIfNeeded);
|
|
2299
2293
|
}
|
|
@@ -2301,18 +2295,18 @@ function maxContainsValidator() {}
|
|
|
2301
2295
|
function minContainsValidator() {}
|
|
2302
2296
|
//#endregion
|
|
2303
2297
|
//#region src/validation/combinators.ts
|
|
2304
|
-
function allOfValidator(report, schema, json) {
|
|
2298
|
+
function allOfValidator(ctx, report, schema, json) {
|
|
2305
2299
|
for (let i = 0; i < schema.allOf.length; i++) {
|
|
2306
|
-
const validateResult =
|
|
2307
|
-
if (
|
|
2300
|
+
const validateResult = ctx._jsonValidate(report, schema.allOf[i], json);
|
|
2301
|
+
if (ctx.options.breakOnFirstError && !validateResult) break;
|
|
2308
2302
|
}
|
|
2309
2303
|
}
|
|
2310
|
-
function anyOfValidator(report, schema, json) {
|
|
2304
|
+
function anyOfValidator(ctx, report, schema, json) {
|
|
2311
2305
|
const subReports = [];
|
|
2312
2306
|
for (let i = 0; i < schema.anyOf.length; i++) {
|
|
2313
2307
|
const subReport = new Report(report);
|
|
2314
2308
|
subReports.push(subReport);
|
|
2315
|
-
|
|
2309
|
+
ctx._jsonValidate(subReport, schema.anyOf[i], json);
|
|
2316
2310
|
cacheValidationResult(report, schema.anyOf[i], json, subReport.errors.length === 0);
|
|
2317
2311
|
}
|
|
2318
2312
|
deferOrRunSync(report, subReports, () => {
|
|
@@ -2321,15 +2315,15 @@ function anyOfValidator(report, schema, json) {
|
|
|
2321
2315
|
passed = true;
|
|
2322
2316
|
break;
|
|
2323
2317
|
}
|
|
2324
|
-
if (passed
|
|
2318
|
+
if (!passed) report.addError("ANY_OF_MISSING", void 0, subReports, schema, "anyOf");
|
|
2325
2319
|
});
|
|
2326
2320
|
}
|
|
2327
|
-
function oneOfValidator(report, schema, json) {
|
|
2321
|
+
function oneOfValidator(ctx, report, schema, json) {
|
|
2328
2322
|
const subReports = [];
|
|
2329
2323
|
for (let i = 0; i < schema.oneOf.length; i++) {
|
|
2330
2324
|
const subReport = new Report(report);
|
|
2331
2325
|
subReports.push(subReport);
|
|
2332
|
-
|
|
2326
|
+
ctx._jsonValidate(subReport, schema.oneOf[i], json);
|
|
2333
2327
|
cacheValidationResult(report, schema.oneOf[i], json, subReport.errors.length === 0);
|
|
2334
2328
|
}
|
|
2335
2329
|
deferOrRunSync(report, subReports, () => {
|
|
@@ -2339,77 +2333,77 @@ function oneOfValidator(report, schema, json) {
|
|
|
2339
2333
|
else if (passes > 1) report.addError("ONE_OF_MULTIPLE", void 0, void 0, schema, "oneOf");
|
|
2340
2334
|
});
|
|
2341
2335
|
}
|
|
2342
|
-
function notValidator(report, schema, json) {
|
|
2336
|
+
function notValidator(ctx, report, schema, json) {
|
|
2343
2337
|
const subReport = new Report(report);
|
|
2344
|
-
if (
|
|
2338
|
+
if (ctx._jsonValidate(subReport, schema.not, json)) report.addError("NOT_PASSED", void 0, void 0, schema, "not");
|
|
2345
2339
|
}
|
|
2346
|
-
function ifValidator(report, schema, json) {
|
|
2347
|
-
if (
|
|
2340
|
+
function ifValidator(ctx, report, schema, json) {
|
|
2341
|
+
if (ctx.options.version === "draft-04" || ctx.options.version === "draft-06") return;
|
|
2348
2342
|
const conditionSchema = schema.if;
|
|
2349
2343
|
const thenSchema = schema.then;
|
|
2350
2344
|
const elseSchema = schema.else;
|
|
2351
2345
|
if (conditionSchema === void 0 || thenSchema === void 0 && elseSchema === void 0) return;
|
|
2352
2346
|
const conditionReport = new Report(report);
|
|
2353
|
-
|
|
2347
|
+
ctx._jsonValidate(conditionReport, conditionSchema, json);
|
|
2354
2348
|
cacheValidationResult(report, conditionSchema, json, conditionReport.errors.length === 0);
|
|
2355
2349
|
const branchSchema = conditionReport.errors.length === 0 ? thenSchema : elseSchema;
|
|
2356
2350
|
if (branchSchema === void 0) return;
|
|
2357
|
-
|
|
2351
|
+
ctx._jsonValidate(report, branchSchema, json);
|
|
2358
2352
|
}
|
|
2359
2353
|
function thenValidator() {}
|
|
2360
2354
|
function elseValidator() {}
|
|
2361
2355
|
//#endregion
|
|
2362
2356
|
//#region src/validation/numeric.ts
|
|
2363
|
-
function multipleOfValidator(report, schema, json) {
|
|
2364
|
-
if (shouldSkipValidate(
|
|
2357
|
+
function multipleOfValidator(ctx, report, schema, json) {
|
|
2358
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MULTIPLE_OF"])) return;
|
|
2365
2359
|
if (typeof json !== "number") return;
|
|
2366
2360
|
const result = json / schema.multipleOf;
|
|
2367
2361
|
if (!Number.isFinite(result) || Math.abs(result - Math.round(result)) >= 1e-10) report.addError("MULTIPLE_OF", [json, schema.multipleOf], void 0, schema, "multipleOf");
|
|
2368
2362
|
}
|
|
2369
|
-
function maximumValidator(report, schema, json) {
|
|
2370
|
-
if (shouldSkipValidate(
|
|
2363
|
+
function maximumValidator(ctx, report, schema, json) {
|
|
2364
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MAXIMUM", "MAXIMUM_EXCLUSIVE"])) return;
|
|
2371
2365
|
if (typeof json !== "number") return;
|
|
2372
2366
|
if (schema.exclusiveMaximum !== true) {
|
|
2373
2367
|
if (json > schema.maximum) report.addError("MAXIMUM", [json, schema.maximum], void 0, schema, "maximum");
|
|
2374
2368
|
} else if (json >= schema.maximum) report.addError("MAXIMUM_EXCLUSIVE", [json, schema.maximum], void 0, schema, "maximum");
|
|
2375
2369
|
}
|
|
2376
|
-
function exclusiveMaximumValidator(report, schema, json) {
|
|
2370
|
+
function exclusiveMaximumValidator(ctx, report, schema, json) {
|
|
2377
2371
|
if (typeof schema.exclusiveMaximum === "number") {
|
|
2378
|
-
if (shouldSkipValidate(
|
|
2372
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MAXIMUM_EXCLUSIVE"])) return;
|
|
2379
2373
|
if (typeof json !== "number") return;
|
|
2380
2374
|
if (json >= schema.exclusiveMaximum) report.addError("MAXIMUM_EXCLUSIVE", [json, schema.exclusiveMaximum], void 0, schema, "exclusiveMaximum");
|
|
2381
2375
|
}
|
|
2382
2376
|
}
|
|
2383
|
-
function minimumValidator(report, schema, json) {
|
|
2384
|
-
if (shouldSkipValidate(
|
|
2377
|
+
function minimumValidator(ctx, report, schema, json) {
|
|
2378
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MINIMUM", "MINIMUM_EXCLUSIVE"])) return;
|
|
2385
2379
|
if (typeof json !== "number") return;
|
|
2386
2380
|
if (schema.exclusiveMinimum !== true) {
|
|
2387
2381
|
if (json < schema.minimum) report.addError("MINIMUM", [json, schema.minimum], void 0, schema, "minimum");
|
|
2388
2382
|
} else if (json <= schema.minimum) report.addError("MINIMUM_EXCLUSIVE", [json, schema.minimum], void 0, schema, "minimum");
|
|
2389
2383
|
}
|
|
2390
|
-
function exclusiveMinimumValidator(report, schema, json) {
|
|
2384
|
+
function exclusiveMinimumValidator(ctx, report, schema, json) {
|
|
2391
2385
|
if (typeof schema.exclusiveMinimum === "number") {
|
|
2392
|
-
if (shouldSkipValidate(
|
|
2386
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MINIMUM_EXCLUSIVE"])) return;
|
|
2393
2387
|
if (typeof json !== "number") return;
|
|
2394
2388
|
if (json <= schema.exclusiveMinimum) report.addError("MINIMUM_EXCLUSIVE", [json, schema.exclusiveMinimum], void 0, schema, "exclusiveMinimum");
|
|
2395
2389
|
}
|
|
2396
2390
|
}
|
|
2397
2391
|
//#endregion
|
|
2398
2392
|
//#region src/validation/object.ts
|
|
2399
|
-
function maxPropertiesValidator(report, schema, json) {
|
|
2400
|
-
if (shouldSkipValidate(
|
|
2393
|
+
function maxPropertiesValidator(ctx, report, schema, json) {
|
|
2394
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_PROPERTIES_MAXIMUM"])) return;
|
|
2401
2395
|
if (!isObject(json)) return;
|
|
2402
2396
|
const keysCount = Object.keys(json).length;
|
|
2403
2397
|
if (keysCount > schema.maxProperties) report.addError("OBJECT_PROPERTIES_MAXIMUM", [keysCount, schema.maxProperties], void 0, schema, "maxProperties");
|
|
2404
2398
|
}
|
|
2405
|
-
function minPropertiesValidator(report, schema, json) {
|
|
2406
|
-
if (shouldSkipValidate(
|
|
2399
|
+
function minPropertiesValidator(ctx, report, schema, json) {
|
|
2400
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_PROPERTIES_MINIMUM"])) return;
|
|
2407
2401
|
if (!isObject(json)) return;
|
|
2408
2402
|
const keysCount = Object.keys(json).length;
|
|
2409
2403
|
if (keysCount < schema.minProperties) report.addError("OBJECT_PROPERTIES_MINIMUM", [keysCount, schema.minProperties], void 0, schema, "minProperties");
|
|
2410
2404
|
}
|
|
2411
|
-
function requiredValidator(report, schema, json) {
|
|
2412
|
-
if (shouldSkipValidate(
|
|
2405
|
+
function requiredValidator(ctx, report, schema, json) {
|
|
2406
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_MISSING_REQUIRED_PROPERTY"])) return;
|
|
2413
2407
|
if (!isObject(json)) return;
|
|
2414
2408
|
const idx = schema.required.length;
|
|
2415
2409
|
for (let i = 0; i < idx; i++) {
|
|
@@ -2417,30 +2411,31 @@ function requiredValidator(report, schema, json) {
|
|
|
2417
2411
|
if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_MISSING_REQUIRED_PROPERTY", [requiredPropertyName], void 0, schema, "required");
|
|
2418
2412
|
}
|
|
2419
2413
|
}
|
|
2420
|
-
function additionalPropertiesValidator(report, schema, json) {
|
|
2421
|
-
if (schema.properties === void 0 && schema.patternProperties === void 0)
|
|
2414
|
+
function additionalPropertiesValidator(ctx, report, schema, json) {
|
|
2415
|
+
if (schema.properties === void 0 && schema.patternProperties === void 0) propertiesValidator(ctx, report, schema, json);
|
|
2422
2416
|
}
|
|
2423
|
-
function patternPropertiesValidator(report, schema, json) {
|
|
2424
|
-
if (schema.properties === void 0)
|
|
2417
|
+
function patternPropertiesValidator(ctx, report, schema, json) {
|
|
2418
|
+
if (schema.properties === void 0) propertiesValidator(ctx, report, schema, json);
|
|
2425
2419
|
}
|
|
2426
|
-
function propertiesValidator(report, schema, json) {
|
|
2427
|
-
if (shouldSkipValidate(
|
|
2420
|
+
function propertiesValidator(ctx, report, schema, json) {
|
|
2421
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_ADDITIONAL_PROPERTIES"])) return;
|
|
2428
2422
|
if (!isObject(json)) return;
|
|
2429
|
-
const properties = schema.properties
|
|
2430
|
-
const patternProperties = schema.patternProperties
|
|
2423
|
+
const properties = schema.properties === void 0 ? {} : schema.properties;
|
|
2424
|
+
const patternProperties = schema.patternProperties === void 0 ? {} : schema.patternProperties;
|
|
2431
2425
|
if (schema.additionalProperties === false) {
|
|
2432
2426
|
let s = Object.keys(json);
|
|
2433
2427
|
const p = Object.keys(properties);
|
|
2434
2428
|
const pp = Object.keys(patternProperties);
|
|
2435
2429
|
s = difference(s, p);
|
|
2436
|
-
for (
|
|
2430
|
+
for (let i = 0; i < pp.length; i++) {
|
|
2431
|
+
const ppKey = pp[i];
|
|
2437
2432
|
const result = compileSchemaRegex(ppKey);
|
|
2438
2433
|
if (!result.ok) continue;
|
|
2439
2434
|
const regExp = result.value;
|
|
2440
|
-
for (let idx2 = s.length - 1; idx2 >= 0; idx2--) if (regExp.test(s[idx2])
|
|
2435
|
+
for (let idx2 = s.length - 1; idx2 >= 0; idx2--) if (regExp.test(s[idx2])) s.splice(idx2, 1);
|
|
2441
2436
|
}
|
|
2442
2437
|
if (s.length > 0) {
|
|
2443
|
-
if (Array.isArray(
|
|
2438
|
+
if (Array.isArray(ctx.options.assumeAdditional)) for (const allowed of ctx.options.assumeAdditional) {
|
|
2444
2439
|
const io = s.indexOf(allowed);
|
|
2445
2440
|
if (io !== -1) s.splice(io, 1);
|
|
2446
2441
|
}
|
|
@@ -2448,29 +2443,29 @@ function propertiesValidator(report, schema, json) {
|
|
|
2448
2443
|
}
|
|
2449
2444
|
}
|
|
2450
2445
|
}
|
|
2451
|
-
function dependenciesValidator(report, schema, json) {
|
|
2452
|
-
if (shouldSkipValidate(
|
|
2446
|
+
function dependenciesValidator(ctx, report, schema, json) {
|
|
2447
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_DEPENDENCY_KEY"])) return;
|
|
2453
2448
|
if (!isObject(json)) return;
|
|
2454
2449
|
const keys = Object.keys(schema.dependencies);
|
|
2455
2450
|
for (const dependencyName of keys) if (Object.hasOwn(json, dependencyName)) {
|
|
2456
2451
|
const dependencyDefinition = schema.dependencies[dependencyName];
|
|
2457
2452
|
if (Array.isArray(dependencyDefinition)) {
|
|
2458
2453
|
for (const requiredPropertyName of dependencyDefinition) if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], void 0, schema, "dependencies");
|
|
2459
|
-
} else
|
|
2454
|
+
} else ctx._jsonValidate(report, dependencyDefinition, json);
|
|
2460
2455
|
}
|
|
2461
2456
|
}
|
|
2462
|
-
function dependentSchemasValidator(report, schema, json) {
|
|
2463
|
-
if (!supportsDependentKeywords(schema,
|
|
2457
|
+
function dependentSchemasValidator(ctx, report, schema, json) {
|
|
2458
|
+
if (!supportsDependentKeywords(schema, ctx.options.version)) return;
|
|
2464
2459
|
if (!isObject(json) || !isObject(schema.dependentSchemas)) return;
|
|
2465
2460
|
const keys = Object.keys(schema.dependentSchemas);
|
|
2466
2461
|
for (const dependencyName of keys) if (Object.hasOwn(json, dependencyName)) {
|
|
2467
2462
|
const dependencySchema = schema.dependentSchemas[dependencyName];
|
|
2468
|
-
|
|
2463
|
+
ctx._jsonValidate(report, dependencySchema, json);
|
|
2469
2464
|
}
|
|
2470
2465
|
}
|
|
2471
|
-
function dependentRequiredValidator(report, schema, json) {
|
|
2472
|
-
if (!supportsDependentKeywords(schema,
|
|
2473
|
-
if (shouldSkipValidate(
|
|
2466
|
+
function dependentRequiredValidator(ctx, report, schema, json) {
|
|
2467
|
+
if (!supportsDependentKeywords(schema, ctx.options.version)) return;
|
|
2468
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_DEPENDENCY_KEY"])) return;
|
|
2474
2469
|
if (!isObject(json) || !isObject(schema.dependentRequired)) return;
|
|
2475
2470
|
const keys = Object.keys(schema.dependentRequired);
|
|
2476
2471
|
for (const dependencyName of keys) {
|
|
@@ -2480,8 +2475,8 @@ function dependentRequiredValidator(report, schema, json) {
|
|
|
2480
2475
|
for (const requiredPropertyName of requiredProperties) if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], void 0, schema, "dependentRequired");
|
|
2481
2476
|
}
|
|
2482
2477
|
}
|
|
2483
|
-
function propertyNamesValidator(report, schema, json) {
|
|
2484
|
-
if (shouldSkipValidate(
|
|
2478
|
+
function propertyNamesValidator(ctx, report, schema, json) {
|
|
2479
|
+
if (shouldSkipValidate(ctx.validateOptions, ["PROPERTY_NAMES"])) return;
|
|
2485
2480
|
if (!isObject(json)) return;
|
|
2486
2481
|
const propertyNamesSchema = schema.propertyNames;
|
|
2487
2482
|
if (propertyNamesSchema === void 0) return;
|
|
@@ -2491,10 +2486,10 @@ function propertyNamesValidator(report, schema, json) {
|
|
|
2491
2486
|
for (const key of keys) {
|
|
2492
2487
|
const subReport = new Report_(report);
|
|
2493
2488
|
subReports.push(subReport);
|
|
2494
|
-
|
|
2489
|
+
ctx._jsonValidate(subReport, propertyNamesSchema, key);
|
|
2495
2490
|
}
|
|
2496
2491
|
const addPropertyNameErrors = () => {
|
|
2497
|
-
for (let idx = 0; idx < keys.length; idx++) if (subReports[idx].errors.length > 0) report.addError("PROPERTY_NAMES", [keys[idx]], subReports[idx], schema
|
|
2492
|
+
for (let idx = 0; idx < keys.length; idx++) if (subReports[idx].errors.length > 0) report.addError("PROPERTY_NAMES", [keys[idx]], subReports[idx], schema);
|
|
2498
2493
|
};
|
|
2499
2494
|
deferOrRunSync(report, subReports, addPropertyNameErrors);
|
|
2500
2495
|
}
|
|
@@ -2504,7 +2499,7 @@ const getDynamicRefAnchorName = (dynamicRef) => {
|
|
|
2504
2499
|
const hashIdx = dynamicRef.indexOf("#");
|
|
2505
2500
|
if (hashIdx === -1) return;
|
|
2506
2501
|
const fragment = dynamicRef.slice(hashIdx + 1);
|
|
2507
|
-
if (!fragment || fragment
|
|
2502
|
+
if (!fragment || fragment.startsWith("/")) return;
|
|
2508
2503
|
return fragment;
|
|
2509
2504
|
};
|
|
2510
2505
|
const findDynamicAnchorInScope = (scopeSchema, anchorName) => {
|
|
@@ -2531,7 +2526,7 @@ const resolveRecursiveRef = (schema, recursiveAnchorStack) => {
|
|
|
2531
2526
|
*/
|
|
2532
2527
|
const resolveDynamicRef = (schema, dynamicScopeStack) => {
|
|
2533
2528
|
const resolved = schema.__$dynamicRefResolved;
|
|
2534
|
-
if (
|
|
2529
|
+
if (resolved === void 0 || !schema.$dynamicRef) return resolved;
|
|
2535
2530
|
let target = resolved;
|
|
2536
2531
|
const anchorName = getDynamicRefAnchorName(schema.$dynamicRef);
|
|
2537
2532
|
if (anchorName && typeof target === "object" && target.$dynamicAnchor === anchorName) for (let scopeIdx = 0; scopeIdx < dynamicScopeStack.length; scopeIdx++) {
|
|
@@ -2558,8 +2553,9 @@ const decodeBase64 = (value) => {
|
|
|
2558
2553
|
} catch {
|
|
2559
2554
|
return;
|
|
2560
2555
|
}
|
|
2561
|
-
|
|
2562
|
-
|
|
2556
|
+
const bufferCtor = globalThis.Buffer;
|
|
2557
|
+
if (bufferCtor !== void 0) try {
|
|
2558
|
+
return bufferCtor.from(value, "base64").toString("utf-8");
|
|
2563
2559
|
} catch {
|
|
2564
2560
|
return;
|
|
2565
2561
|
}
|
|
@@ -2568,27 +2564,37 @@ const decodeBase64 = (value) => {
|
|
|
2568
2564
|
//#region src/utils/unicode.ts
|
|
2569
2565
|
/**
|
|
2570
2566
|
* Returns the number of Unicode code points in the string.
|
|
2571
|
-
* Uses
|
|
2567
|
+
* Uses a surrogate-aware charCodeAt scan (equivalent to the string iterator)
|
|
2568
|
+
* that counts a surrogate pair as one code point and lone surrogates as one each.
|
|
2572
2569
|
*/
|
|
2573
2570
|
function unicodeLength(str) {
|
|
2574
|
-
let count =
|
|
2575
|
-
for (
|
|
2571
|
+
let count = str.length;
|
|
2572
|
+
for (let i = 0; i < str.length - 1; i++) {
|
|
2573
|
+
const hi = str.charCodeAt(i);
|
|
2574
|
+
if (hi >= 55296 && hi <= 56319) {
|
|
2575
|
+
const lo = str.charCodeAt(i + 1);
|
|
2576
|
+
if (lo >= 56320 && lo <= 57343) {
|
|
2577
|
+
count--;
|
|
2578
|
+
i++;
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2576
2582
|
return count;
|
|
2577
2583
|
}
|
|
2578
2584
|
//#endregion
|
|
2579
2585
|
//#region src/validation/string.ts
|
|
2580
|
-
function minLengthValidator(report, schema, json) {
|
|
2581
|
-
if (shouldSkipValidate(
|
|
2586
|
+
function minLengthValidator(ctx, report, schema, json) {
|
|
2587
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MIN_LENGTH"])) return;
|
|
2582
2588
|
if (typeof json !== "string") return;
|
|
2583
2589
|
if (unicodeLength(json) < schema.minLength) report.addError("MIN_LENGTH", [json.length, schema.minLength], void 0, schema, "minLength");
|
|
2584
2590
|
}
|
|
2585
|
-
function maxLengthValidator(report, schema, json) {
|
|
2586
|
-
if (shouldSkipValidate(
|
|
2591
|
+
function maxLengthValidator(ctx, report, schema, json) {
|
|
2592
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MAX_LENGTH"])) return;
|
|
2587
2593
|
if (typeof json !== "string") return;
|
|
2588
2594
|
if (unicodeLength(json) > schema.maxLength) report.addError("MAX_LENGTH", [json.length, schema.maxLength], void 0, schema, "maxLength");
|
|
2589
2595
|
}
|
|
2590
|
-
function patternValidator(report, schema, json) {
|
|
2591
|
-
if (shouldSkipValidate(
|
|
2596
|
+
function patternValidator(ctx, report, schema, json) {
|
|
2597
|
+
if (shouldSkipValidate(ctx.validateOptions, ["PATTERN"])) return;
|
|
2592
2598
|
if (typeof json !== "string") return;
|
|
2593
2599
|
const result = compileSchemaRegex(schema.pattern);
|
|
2594
2600
|
if (!result.ok) {
|
|
@@ -2601,46 +2607,46 @@ function patternValidator(report, schema, json) {
|
|
|
2601
2607
|
}
|
|
2602
2608
|
if (!result.value.test(json)) report.addError("PATTERN", [schema.pattern, json], void 0, schema, "pattern");
|
|
2603
2609
|
}
|
|
2604
|
-
function formatValidator(report, schema, json) {
|
|
2605
|
-
if (
|
|
2606
|
-
if (
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
const isModernDraft = this.options.version === "draft2019-09" || this.options.version === "draft2020-12";
|
|
2610
|
-
const formatValidatorFn = getFormatValidators(this.options)[schema.format];
|
|
2610
|
+
function formatValidator(ctx, report, schema, json) {
|
|
2611
|
+
if (ctx.options.formatAssertions === false) return;
|
|
2612
|
+
if (ctx.options.formatAssertions === true && !isFormatAssertionVocabEnabled(schema, report, ctx.options.version)) return;
|
|
2613
|
+
const isModernDraft = ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12";
|
|
2614
|
+
const formatValidatorFn = resolveFormatValidator(schema.format, ctx.options);
|
|
2611
2615
|
if (typeof formatValidatorFn === "function") {
|
|
2612
|
-
if (shouldSkipValidate(
|
|
2616
|
+
if (shouldSkipValidate(ctx.validateOptions, ["INVALID_FORMAT"])) return;
|
|
2613
2617
|
if (report.hasError("INVALID_TYPE", [schema.type, whatIs(json)])) return;
|
|
2614
|
-
if (formatValidatorFn.length === 2) report.addAsyncTaskWithPath(formatValidatorFn, [json],
|
|
2618
|
+
if (formatValidatorFn.length === 2) report.addAsyncTaskWithPath(formatValidatorFn, [json], (result) => {
|
|
2615
2619
|
if (result !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
2616
2620
|
});
|
|
2617
2621
|
else {
|
|
2618
|
-
const result = formatValidatorFn.call(
|
|
2622
|
+
const result = formatValidatorFn.call(ctx, json);
|
|
2619
2623
|
if (result instanceof Promise) {
|
|
2620
2624
|
const promiseResult = result;
|
|
2621
2625
|
report.addAsyncTaskWithPath(async (callback) => {
|
|
2622
2626
|
try {
|
|
2623
2627
|
callback(await promiseResult);
|
|
2624
|
-
} catch
|
|
2628
|
+
} catch {
|
|
2625
2629
|
callback(false);
|
|
2626
2630
|
}
|
|
2627
|
-
}, [],
|
|
2631
|
+
}, [], (resolvedResult) => {
|
|
2628
2632
|
if (resolvedResult !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
2629
2633
|
});
|
|
2630
|
-
} else if (result
|
|
2634
|
+
} else if (!result) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
2631
2635
|
}
|
|
2632
|
-
} else if (
|
|
2636
|
+
} else if (ctx.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
2633
2637
|
}
|
|
2634
|
-
function contentEncodingValidator(report, schema, json) {
|
|
2635
|
-
if (
|
|
2638
|
+
function contentEncodingValidator(ctx, report, schema, json) {
|
|
2639
|
+
if (ctx.options.version !== "draft-07") return;
|
|
2636
2640
|
if (typeof json !== "string") return;
|
|
2637
|
-
|
|
2641
|
+
const { contentEncoding } = schema;
|
|
2642
|
+
if (contentEncoding !== "base64") return;
|
|
2638
2643
|
if (!isValidBase64(json)) report.addError("INVALID_FORMAT", ["contentEncoding:base64", JSON.stringify(json)], void 0, schema, "contentEncoding");
|
|
2639
2644
|
}
|
|
2640
|
-
function contentMediaTypeValidator(report, schema, json) {
|
|
2641
|
-
if (
|
|
2645
|
+
function contentMediaTypeValidator(ctx, report, schema, json) {
|
|
2646
|
+
if (ctx.options.version !== "draft-07") return;
|
|
2642
2647
|
if (typeof json !== "string") return;
|
|
2643
|
-
|
|
2648
|
+
const { contentMediaType } = schema;
|
|
2649
|
+
if (contentMediaType !== "application/json") return;
|
|
2644
2650
|
let payload = json;
|
|
2645
2651
|
if (schema.contentEncoding === "base64") {
|
|
2646
2652
|
const decoded = decodeBase64(json);
|
|
@@ -2658,38 +2664,40 @@ function contentMediaTypeValidator(report, schema, json) {
|
|
|
2658
2664
|
}
|
|
2659
2665
|
//#endregion
|
|
2660
2666
|
//#region src/validation/type.ts
|
|
2661
|
-
function typeValidator(report, schema, json) {
|
|
2662
|
-
if (shouldSkipValidate(
|
|
2667
|
+
function typeValidator(ctx, report, schema, json) {
|
|
2668
|
+
if (shouldSkipValidate(ctx.validateOptions, ["INVALID_TYPE"])) return;
|
|
2663
2669
|
const jsonType = whatIs(json);
|
|
2664
2670
|
if (typeof schema.type === "string") {
|
|
2665
2671
|
if (jsonType !== schema.type && (jsonType !== "integer" || schema.type !== "number")) report.addError("INVALID_TYPE", [schema.type, jsonType], void 0, schema, "type");
|
|
2666
2672
|
} else if (!schema.type.includes(jsonType) && (jsonType !== "integer" || !schema.type.includes("number"))) report.addError("INVALID_TYPE", [JSON.stringify(schema.type), jsonType], void 0, schema, "type");
|
|
2667
2673
|
}
|
|
2668
|
-
function enumValidator(report, schema, json) {
|
|
2669
|
-
if (shouldSkipValidate(
|
|
2670
|
-
|
|
2671
|
-
|
|
2674
|
+
function enumValidator(ctx, report, schema, json) {
|
|
2675
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ENUM_CASE_MISMATCH", "ENUM_MISMATCH"])) return;
|
|
2676
|
+
const eqOpts = { maxDepth: ctx.options.maxRecursionDepth };
|
|
2677
|
+
const eqOptsCI = {
|
|
2678
|
+
caseInsensitiveComparison: true,
|
|
2679
|
+
maxDepth: ctx.options.maxRecursionDepth
|
|
2680
|
+
};
|
|
2681
|
+
let caseInsensitiveMatch = false, match = false;
|
|
2682
|
+
for (const enumVal of schema.enum) if (areEqual(json, enumVal, eqOpts)) {
|
|
2672
2683
|
match = true;
|
|
2673
2684
|
break;
|
|
2674
|
-
} else if (areEqual(json, enumVal,
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
})) caseInsensitiveMatch = true;
|
|
2678
|
-
if (match === false) {
|
|
2679
|
-
const error = caseInsensitiveMatch && this.options.enumCaseInsensitiveComparison ? "ENUM_CASE_MISMATCH" : "ENUM_MISMATCH";
|
|
2685
|
+
} else if (areEqual(json, enumVal, eqOptsCI)) caseInsensitiveMatch = true;
|
|
2686
|
+
if (!match) {
|
|
2687
|
+
const error = caseInsensitiveMatch && ctx.options.enumCaseInsensitiveComparison ? "ENUM_CASE_MISMATCH" : "ENUM_MISMATCH";
|
|
2680
2688
|
report.addError(error, [JSON.stringify(json)], void 0, schema, "enum");
|
|
2681
2689
|
}
|
|
2682
2690
|
}
|
|
2683
|
-
function constValidator(report, schema, json) {
|
|
2691
|
+
function constValidator(ctx, report, schema, json) {
|
|
2684
2692
|
const constValue = schema.const;
|
|
2685
|
-
if (areEqual(json, constValue, { maxDepth:
|
|
2693
|
+
if (!areEqual(json, constValue, { maxDepth: ctx.options.maxRecursionDepth })) report.addError("CONST", [JSON.stringify(constValue)], void 0, schema);
|
|
2686
2694
|
}
|
|
2687
2695
|
//#endregion
|
|
2688
2696
|
//#region src/json-validation.ts
|
|
2689
|
-
function collectEvaluated(args) {
|
|
2697
|
+
function collectEvaluated(ctx, args) {
|
|
2690
2698
|
const { report, currentSchema, json, mode, depth } = args;
|
|
2691
2699
|
if (!currentSchema || typeof currentSchema === "boolean") return /* @__PURE__ */ new Set();
|
|
2692
|
-
if (depth > (
|
|
2700
|
+
if (depth > (ctx.options.maxRecursionDepth ?? 100)) {
|
|
2693
2701
|
report.addError("COLLECT_EVALUATED_DEPTH_EXCEEDED", [depth]);
|
|
2694
2702
|
return /* @__PURE__ */ new Set();
|
|
2695
2703
|
}
|
|
@@ -2700,7 +2708,7 @@ function collectEvaluated(args) {
|
|
|
2700
2708
|
return false;
|
|
2701
2709
|
};
|
|
2702
2710
|
const recurse = (subSchema) => {
|
|
2703
|
-
if (mode === "items") return collectEvaluated
|
|
2711
|
+
if (mode === "items") return collectEvaluated(ctx, {
|
|
2704
2712
|
report,
|
|
2705
2713
|
currentSchema: subSchema,
|
|
2706
2714
|
json,
|
|
@@ -2708,7 +2716,7 @@ function collectEvaluated(args) {
|
|
|
2708
2716
|
jsonArr: args.jsonArr,
|
|
2709
2717
|
depth: depth + 1
|
|
2710
2718
|
});
|
|
2711
|
-
return collectEvaluated
|
|
2719
|
+
return collectEvaluated(ctx, {
|
|
2712
2720
|
report,
|
|
2713
2721
|
currentSchema: subSchema,
|
|
2714
2722
|
json,
|
|
@@ -2718,7 +2726,7 @@ function collectEvaluated(args) {
|
|
|
2718
2726
|
});
|
|
2719
2727
|
};
|
|
2720
2728
|
if (mode === "items") {
|
|
2721
|
-
const jsonArr = args
|
|
2729
|
+
const { jsonArr } = args;
|
|
2722
2730
|
if (Array.isArray(currentSchema.prefixItems)) {
|
|
2723
2731
|
const len = Math.min(currentSchema.prefixItems.length, jsonArr.length);
|
|
2724
2732
|
for (let i = 0; i < len; i++) evaluated.add(i);
|
|
@@ -2734,104 +2742,102 @@ function collectEvaluated(args) {
|
|
|
2734
2742
|
let passed = getCachedValidationResult(report, currentSchema.contains, jsonArr[i]);
|
|
2735
2743
|
if (passed === void 0) {
|
|
2736
2744
|
const subReport = new Report(report);
|
|
2737
|
-
validate
|
|
2745
|
+
validate(ctx, subReport, currentSchema.contains, jsonArr[i]);
|
|
2738
2746
|
passed = subReport.errors.length === 0;
|
|
2739
2747
|
}
|
|
2740
2748
|
if (passed) evaluated.add(i);
|
|
2741
2749
|
}
|
|
2742
2750
|
if (currentSchema.unevaluatedItems === true) return "all";
|
|
2743
2751
|
} else {
|
|
2744
|
-
const jsonData = args
|
|
2752
|
+
const { jsonData } = args;
|
|
2745
2753
|
if (isObject(currentSchema.properties)) {
|
|
2746
|
-
|
|
2754
|
+
const propKeysCE = Object.keys(currentSchema.properties);
|
|
2755
|
+
for (let i = 0; i < propKeysCE.length; i++) {
|
|
2756
|
+
const key = propKeysCE[i];
|
|
2757
|
+
if (Object.hasOwn(jsonData, key)) evaluated.add(key);
|
|
2758
|
+
}
|
|
2747
2759
|
}
|
|
2748
2760
|
if (isObject(currentSchema.patternProperties)) for (const pattern of Object.keys(currentSchema.patternProperties)) {
|
|
2749
2761
|
const result = compileSchemaRegex(pattern);
|
|
2750
2762
|
if (result.ok) {
|
|
2751
|
-
|
|
2763
|
+
const jdKeys = Object.keys(jsonData);
|
|
2764
|
+
for (let i = 0; i < jdKeys.length; i++) if (result.value.test(jdKeys[i])) evaluated.add(jdKeys[i]);
|
|
2752
2765
|
}
|
|
2753
2766
|
}
|
|
2754
2767
|
if (currentSchema.additionalProperties !== void 0) {
|
|
2755
|
-
const
|
|
2768
|
+
const propKeySet = new Set(isObject(currentSchema.properties) ? Object.keys(currentSchema.properties) : []);
|
|
2756
2769
|
const patternRegexes = [];
|
|
2757
2770
|
if (isObject(currentSchema.patternProperties)) for (const pattern of Object.keys(currentSchema.patternProperties)) {
|
|
2758
2771
|
const result = compileSchemaRegex(pattern);
|
|
2759
2772
|
if (result.ok) patternRegexes.push(result.value);
|
|
2760
2773
|
}
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2774
|
+
const apKeys = Object.keys(jsonData);
|
|
2775
|
+
for (let i = 0; i < apKeys.length; i++) {
|
|
2776
|
+
const key = apKeys[i];
|
|
2777
|
+
if (propKeySet.has(key)) continue;
|
|
2778
|
+
let matchedPattern = false;
|
|
2779
|
+
for (let pi = 0; pi < patternRegexes.length; pi++) if (patternRegexes[pi].test(key)) {
|
|
2780
|
+
matchedPattern = true;
|
|
2781
|
+
break;
|
|
2782
|
+
}
|
|
2783
|
+
if (matchedPattern) continue;
|
|
2764
2784
|
evaluated.add(key);
|
|
2765
2785
|
}
|
|
2766
2786
|
}
|
|
2767
2787
|
if (isObject(currentSchema.dependentSchemas)) {
|
|
2768
|
-
for (const [depKey, depSchema] of Object.entries(currentSchema.dependentSchemas)) if (Object.hasOwn(jsonData, depKey))
|
|
2769
|
-
if (merge(recurse(depSchema))) return "all";
|
|
2770
|
-
}
|
|
2788
|
+
for (const [depKey, depSchema] of Object.entries(currentSchema.dependentSchemas)) if (Object.hasOwn(jsonData, depKey) && merge(recurse(depSchema))) return "all";
|
|
2771
2789
|
}
|
|
2772
2790
|
if (currentSchema.unevaluatedProperties === true) return "all";
|
|
2773
2791
|
}
|
|
2774
2792
|
if (Array.isArray(currentSchema.allOf)) {
|
|
2775
|
-
for (
|
|
2793
|
+
for (let i = 0; i < currentSchema.allOf.length; i++) if (merge(recurse(currentSchema.allOf[i]))) return "all";
|
|
2776
2794
|
}
|
|
2777
|
-
if (Array.isArray(currentSchema.anyOf)) for (
|
|
2795
|
+
if (Array.isArray(currentSchema.anyOf)) for (let i = 0; i < currentSchema.anyOf.length; i++) {
|
|
2796
|
+
const subSchema = currentSchema.anyOf[i];
|
|
2778
2797
|
let passed = getCachedValidationResult(report, subSchema, json);
|
|
2779
2798
|
if (passed === void 0) {
|
|
2780
2799
|
const subReport = new Report(report);
|
|
2781
|
-
validate
|
|
2800
|
+
validate(ctx, subReport, subSchema, json);
|
|
2782
2801
|
passed = subReport.errors.length === 0;
|
|
2783
2802
|
}
|
|
2784
|
-
if (passed)
|
|
2785
|
-
if (merge(recurse(subSchema))) return "all";
|
|
2786
|
-
}
|
|
2803
|
+
if (passed && merge(recurse(subSchema))) return "all";
|
|
2787
2804
|
}
|
|
2788
|
-
if (Array.isArray(currentSchema.oneOf)) for (
|
|
2805
|
+
if (Array.isArray(currentSchema.oneOf)) for (let i = 0; i < currentSchema.oneOf.length; i++) {
|
|
2806
|
+
const subSchema = currentSchema.oneOf[i];
|
|
2789
2807
|
let passed = getCachedValidationResult(report, subSchema, json);
|
|
2790
2808
|
if (passed === void 0) {
|
|
2791
2809
|
const subReport = new Report(report);
|
|
2792
|
-
validate
|
|
2810
|
+
validate(ctx, subReport, subSchema, json);
|
|
2793
2811
|
passed = subReport.errors.length === 0;
|
|
2794
2812
|
}
|
|
2795
|
-
if (passed)
|
|
2796
|
-
if (merge(recurse(subSchema))) return "all";
|
|
2797
|
-
}
|
|
2813
|
+
if (passed && merge(recurse(subSchema))) return "all";
|
|
2798
2814
|
}
|
|
2799
2815
|
if (currentSchema.if !== void 0) {
|
|
2800
2816
|
let condPassed = getCachedValidationResult(report, currentSchema.if, json);
|
|
2801
2817
|
if (condPassed === void 0) {
|
|
2802
2818
|
const condReport = new Report(report);
|
|
2803
|
-
validate
|
|
2819
|
+
validate(ctx, condReport, currentSchema.if, json);
|
|
2804
2820
|
condPassed = condReport.errors.length === 0;
|
|
2805
2821
|
}
|
|
2806
2822
|
if (condPassed) {
|
|
2807
2823
|
if (merge(recurse(currentSchema.if))) return "all";
|
|
2808
|
-
if (currentSchema.then !== void 0)
|
|
2809
|
-
|
|
2810
|
-
}
|
|
2811
|
-
} else if (currentSchema.else !== void 0) {
|
|
2812
|
-
if (merge(recurse(currentSchema.else))) return "all";
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
2815
|
-
if (currentSchema.__$refResolved && currentSchema.__$refResolved !== currentSchema) {
|
|
2816
|
-
if (merge(recurse(currentSchema.__$refResolved))) return "all";
|
|
2824
|
+
if (currentSchema.then !== void 0 && merge(recurse(currentSchema.then))) return "all";
|
|
2825
|
+
} else if (currentSchema.else !== void 0 && merge(recurse(currentSchema.else))) return "all";
|
|
2817
2826
|
}
|
|
2827
|
+
if (currentSchema.__$refResolved && currentSchema.__$refResolved !== currentSchema && merge(recurse(currentSchema.__$refResolved))) return "all";
|
|
2818
2828
|
const recursiveTarget = resolveRecursiveRef(currentSchema, report.__$recursiveAnchorStack);
|
|
2819
|
-
if (recursiveTarget && recursiveTarget !== currentSchema)
|
|
2820
|
-
if (merge(recurse(recursiveTarget))) return "all";
|
|
2821
|
-
}
|
|
2829
|
+
if (recursiveTarget && recursiveTarget !== currentSchema && merge(recurse(recursiveTarget))) return "all";
|
|
2822
2830
|
const dynamicTarget = resolveDynamicRef(currentSchema, report.__$dynamicScopeStack);
|
|
2823
|
-
if (dynamicTarget && dynamicTarget !== currentSchema)
|
|
2824
|
-
if (merge(recurse(dynamicTarget))) return "all";
|
|
2825
|
-
}
|
|
2831
|
+
if (dynamicTarget && dynamicTarget !== currentSchema && merge(recurse(dynamicTarget))) return "all";
|
|
2826
2832
|
return evaluated;
|
|
2827
2833
|
}
|
|
2828
|
-
function unevaluatedItemsValidator(report, schema, json) {
|
|
2834
|
+
function unevaluatedItemsValidator(ctx, report, schema, json) {
|
|
2829
2835
|
if (!Array.isArray(json)) return;
|
|
2830
2836
|
if (schema.unevaluatedItems === true) return;
|
|
2831
2837
|
const unevalSchema = schema.unevaluatedItems;
|
|
2832
2838
|
if (unevalSchema === void 0) return;
|
|
2833
2839
|
if (json.length === 0) return;
|
|
2834
|
-
const evaluatedItems = collectEvaluated
|
|
2840
|
+
const evaluatedItems = collectEvaluated(ctx, {
|
|
2835
2841
|
report,
|
|
2836
2842
|
currentSchema: schema,
|
|
2837
2843
|
json,
|
|
@@ -2844,23 +2850,24 @@ function unevaluatedItemsValidator(report, schema, json) {
|
|
|
2844
2850
|
for (let i = 0; i < json.length; i++) if (!evaluatedItems.has(i)) unevaluatedIndices.push(i);
|
|
2845
2851
|
if (unevaluatedIndices.length === 0) return;
|
|
2846
2852
|
if (unevalSchema === false) report.addError("ARRAY_UNEVALUATED_ITEMS", void 0, void 0, schema, "unevaluatedItems");
|
|
2847
|
-
else for (
|
|
2853
|
+
else for (let i = 0; i < unevaluatedIndices.length; i++) {
|
|
2854
|
+
const idx = unevaluatedIndices[i];
|
|
2848
2855
|
const subReport = new Report(report);
|
|
2849
|
-
validate
|
|
2856
|
+
validate(ctx, subReport, unevalSchema, json[idx]);
|
|
2850
2857
|
if (subReport.errors.length > 0) {
|
|
2851
2858
|
report.addError("ARRAY_UNEVALUATED_ITEMS", void 0, void 0, schema, "unevaluatedItems");
|
|
2852
2859
|
break;
|
|
2853
2860
|
}
|
|
2854
2861
|
}
|
|
2855
2862
|
}
|
|
2856
|
-
function unevaluatedPropertiesValidator(report, schema, json) {
|
|
2863
|
+
function unevaluatedPropertiesValidator(ctx, report, schema, json) {
|
|
2857
2864
|
if (!isObject(json)) return;
|
|
2858
2865
|
if (schema.unevaluatedProperties === true) return;
|
|
2859
2866
|
const unevalSchema = schema.unevaluatedProperties;
|
|
2860
2867
|
if (unevalSchema === void 0) return;
|
|
2861
2868
|
const allKeys = Object.keys(json);
|
|
2862
2869
|
if (allKeys.length === 0) return;
|
|
2863
|
-
const evaluatedProperties = collectEvaluated
|
|
2870
|
+
const evaluatedProperties = collectEvaluated(ctx, {
|
|
2864
2871
|
report,
|
|
2865
2872
|
currentSchema: schema,
|
|
2866
2873
|
json,
|
|
@@ -2869,32 +2876,35 @@ function unevaluatedPropertiesValidator(report, schema, json) {
|
|
|
2869
2876
|
depth: 0
|
|
2870
2877
|
});
|
|
2871
2878
|
if (evaluatedProperties === "all") return;
|
|
2872
|
-
const unevaluatedKeys =
|
|
2879
|
+
const unevaluatedKeys = [];
|
|
2880
|
+
for (let i = 0; i < allKeys.length; i++) if (!evaluatedProperties.has(allKeys[i])) unevaluatedKeys.push(allKeys[i]);
|
|
2873
2881
|
if (unevaluatedKeys.length === 0) return;
|
|
2874
2882
|
if (unevalSchema === false) report.addError("OBJECT_UNEVALUATED_PROPERTIES", [unevaluatedKeys.join(", ")], void 0, schema, "unevaluatedProperties");
|
|
2875
|
-
else for (
|
|
2883
|
+
else for (let i = 0; i < unevaluatedKeys.length; i++) {
|
|
2884
|
+
const key = unevaluatedKeys[i];
|
|
2876
2885
|
const subReport = new Report(report);
|
|
2877
|
-
validate
|
|
2886
|
+
validate(ctx, subReport, unevalSchema, json[key]);
|
|
2878
2887
|
if (subReport.errors.length > 0) report.addError("OBJECT_UNEVALUATED_PROPERTIES", [key], void 0, schema, "unevaluatedProperties");
|
|
2879
2888
|
}
|
|
2880
2889
|
}
|
|
2881
2890
|
function definitionsValidator() {}
|
|
2891
|
+
const noopValidator = () => {};
|
|
2882
2892
|
const JsonValidators = {
|
|
2883
|
-
id:
|
|
2884
|
-
$id:
|
|
2885
|
-
$ref:
|
|
2886
|
-
$schema:
|
|
2887
|
-
$dynamicAnchor:
|
|
2888
|
-
$dynamicRef:
|
|
2889
|
-
$anchor:
|
|
2890
|
-
$defs:
|
|
2891
|
-
$vocabulary:
|
|
2892
|
-
$recursiveAnchor:
|
|
2893
|
-
$recursiveRef:
|
|
2894
|
-
examples:
|
|
2895
|
-
title:
|
|
2896
|
-
description:
|
|
2897
|
-
default:
|
|
2893
|
+
id: noopValidator,
|
|
2894
|
+
$id: noopValidator,
|
|
2895
|
+
$ref: noopValidator,
|
|
2896
|
+
$schema: noopValidator,
|
|
2897
|
+
$dynamicAnchor: noopValidator,
|
|
2898
|
+
$dynamicRef: noopValidator,
|
|
2899
|
+
$anchor: noopValidator,
|
|
2900
|
+
$defs: noopValidator,
|
|
2901
|
+
$vocabulary: noopValidator,
|
|
2902
|
+
$recursiveAnchor: noopValidator,
|
|
2903
|
+
$recursiveRef: noopValidator,
|
|
2904
|
+
examples: noopValidator,
|
|
2905
|
+
title: noopValidator,
|
|
2906
|
+
description: noopValidator,
|
|
2907
|
+
default: noopValidator,
|
|
2898
2908
|
type: typeValidator,
|
|
2899
2909
|
enum: enumValidator,
|
|
2900
2910
|
const: constValidator,
|
|
@@ -2939,18 +2949,18 @@ const JsonValidators = {
|
|
|
2939
2949
|
else: elseValidator,
|
|
2940
2950
|
definitions: definitionsValidator
|
|
2941
2951
|
};
|
|
2942
|
-
|
|
2952
|
+
function recurseArray(ctx, report, schema, json) {
|
|
2943
2953
|
const schemaUri = typeof schema.$schema === "string" ? schema.$schema : void 0;
|
|
2944
|
-
const prefixItems = (schemaUri === "https://json-schema.org/draft/2020-12/schema" || !schemaUri &&
|
|
2954
|
+
const prefixItems = (schemaUri === "https://json-schema.org/draft/2020-12/schema" || !schemaUri && ctx.options.version === "draft2020-12") && Array.isArray(schema.prefixItems) ? schema.prefixItems : void 0;
|
|
2945
2955
|
if (prefixItems) {
|
|
2946
2956
|
for (let idx = 0; idx < json.length; idx++) if (idx < prefixItems.length) {
|
|
2947
2957
|
report.path.push(idx);
|
|
2948
|
-
validate
|
|
2958
|
+
validate(ctx, report, prefixItems[idx], json[idx]);
|
|
2949
2959
|
report.path.pop();
|
|
2950
2960
|
} else if (schema.items !== void 0 && !Array.isArray(schema.items)) {
|
|
2951
2961
|
report.path.push(idx);
|
|
2952
2962
|
report.schemaPath.push("items");
|
|
2953
|
-
validate
|
|
2963
|
+
validate(ctx, report, schema.items, json[idx]);
|
|
2954
2964
|
report.schemaPath.pop();
|
|
2955
2965
|
report.path.pop();
|
|
2956
2966
|
}
|
|
@@ -2959,50 +2969,56 @@ const recurseArray = function(report, schema, json) {
|
|
|
2959
2969
|
if (Array.isArray(schema.items)) {
|
|
2960
2970
|
for (let idx = 0; idx < json.length; idx++) if (idx < schema.items.length) {
|
|
2961
2971
|
report.path.push(idx);
|
|
2962
|
-
validate
|
|
2972
|
+
validate(ctx, report, schema.items[idx], json[idx]);
|
|
2963
2973
|
report.path.pop();
|
|
2964
2974
|
} else if (typeof schema.additionalItems === "object") {
|
|
2965
2975
|
report.path.push(idx);
|
|
2966
|
-
validate
|
|
2976
|
+
validate(ctx, report, schema.additionalItems, json[idx]);
|
|
2967
2977
|
report.path.pop();
|
|
2968
2978
|
}
|
|
2969
2979
|
} else if (typeof schema.items === "object" || typeof schema.items === "boolean") for (let idx = 0; idx < json.length; idx++) {
|
|
2970
2980
|
report.path.push(idx);
|
|
2971
2981
|
report.schemaPath.push("items");
|
|
2972
|
-
validate
|
|
2982
|
+
validate(ctx, report, schema.items, json[idx]);
|
|
2973
2983
|
report.schemaPath.pop();
|
|
2974
2984
|
report.path.pop();
|
|
2975
2985
|
}
|
|
2976
|
-
}
|
|
2977
|
-
|
|
2978
|
-
let additionalProperties = schema
|
|
2986
|
+
}
|
|
2987
|
+
function recurseObject(ctx, report, schema, json) {
|
|
2988
|
+
let { additionalProperties } = schema;
|
|
2979
2989
|
if (additionalProperties === true || additionalProperties === void 0) additionalProperties = {};
|
|
2980
2990
|
const p = schema.properties ? Object.keys(schema.properties) : [];
|
|
2981
2991
|
const pp = schema.patternProperties ? Object.keys(schema.patternProperties) : [];
|
|
2982
2992
|
const keys = Object.keys(json);
|
|
2993
|
+
const ppCompiled = [];
|
|
2994
|
+
for (let i = 0; i < pp.length; i++) {
|
|
2995
|
+
const r = compileSchemaRegex(pp[i]);
|
|
2996
|
+
if (r.ok) ppCompiled.push({
|
|
2997
|
+
key: pp[i],
|
|
2998
|
+
re: r.value
|
|
2999
|
+
});
|
|
3000
|
+
}
|
|
2983
3001
|
for (const m of keys) {
|
|
2984
3002
|
const propertyValue = json[m];
|
|
3003
|
+
const isProp = p.includes(m);
|
|
2985
3004
|
const s = [];
|
|
2986
|
-
if (
|
|
2987
|
-
for (
|
|
2988
|
-
const result = compileSchemaRegex(regexString);
|
|
2989
|
-
if (result.ok && result.value.test(m) === true) s.push(schema.patternProperties[regexString]);
|
|
2990
|
-
}
|
|
3005
|
+
if (isProp) s.push(schema.properties[m]);
|
|
3006
|
+
for (let i = 0; i < ppCompiled.length; i++) if (ppCompiled[i].re.test(m)) s.push(schema.patternProperties[ppCompiled[i].key]);
|
|
2991
3007
|
if (s.length === 0 && additionalProperties !== false) s.push(additionalProperties);
|
|
2992
3008
|
for (const schema_s of s) {
|
|
2993
3009
|
report.path.push(m);
|
|
2994
|
-
if (
|
|
3010
|
+
if (isProp) {
|
|
2995
3011
|
report.schemaPath.push("properties");
|
|
2996
3012
|
report.schemaPath.push(m);
|
|
2997
3013
|
} else report.schemaPath.push("additionalProperties");
|
|
2998
|
-
validate
|
|
3014
|
+
validate(ctx, report, schema_s, propertyValue);
|
|
2999
3015
|
report.path.pop();
|
|
3000
3016
|
report.schemaPath.pop();
|
|
3001
|
-
if (
|
|
3017
|
+
if (isProp) report.schemaPath.pop();
|
|
3002
3018
|
}
|
|
3003
3019
|
}
|
|
3004
|
-
}
|
|
3005
|
-
function validate(report, schema, json) {
|
|
3020
|
+
}
|
|
3021
|
+
function validate(ctx, report, schema, json) {
|
|
3006
3022
|
report.commonErrorMessage = "JSON_OBJECT_VALIDATION_FAILED";
|
|
3007
3023
|
if (schema === true) return true;
|
|
3008
3024
|
if (schema === false) {
|
|
@@ -3026,7 +3042,7 @@ function validate(report, schema, json) {
|
|
|
3026
3042
|
let pushedDynamicScope = false;
|
|
3027
3043
|
const schemaId = getId(schema);
|
|
3028
3044
|
const dynamicScopeEntry = schema.__$resourceRoot || (isRoot || typeof schemaId === "string" ? schema : void 0);
|
|
3029
|
-
if (dynamicScopeEntry && dynamicScopeStack
|
|
3045
|
+
if (dynamicScopeEntry && dynamicScopeStack.at(-1) !== dynamicScopeEntry) {
|
|
3030
3046
|
dynamicScopeStack.push(dynamicScopeEntry);
|
|
3031
3047
|
pushedDynamicScope = true;
|
|
3032
3048
|
}
|
|
@@ -3034,10 +3050,11 @@ function validate(report, schema, json) {
|
|
|
3034
3050
|
recursiveAnchorStack.push(schema);
|
|
3035
3051
|
pushedRecursiveAnchor = true;
|
|
3036
3052
|
}
|
|
3037
|
-
if (schema.$ref !== void 0) if (
|
|
3038
|
-
if (
|
|
3039
|
-
else
|
|
3040
|
-
|
|
3053
|
+
if (schema.$ref !== void 0) if (ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12") {
|
|
3054
|
+
if (schema.__$refResolved) validate(ctx, report, schema.__$refResolved, json);
|
|
3055
|
+
else report.addError("REF_UNRESOLVED", [schema.$ref], void 0, schema);
|
|
3056
|
+
const refIdx = keys.indexOf("$ref");
|
|
3057
|
+
if (refIdx !== -1) keys.splice(refIdx, 1);
|
|
3041
3058
|
} else {
|
|
3042
3059
|
let maxRefs = 99;
|
|
3043
3060
|
while (schema.$ref && maxRefs > 0) {
|
|
@@ -3055,58 +3072,65 @@ function validate(report, schema, json) {
|
|
|
3055
3072
|
report.schemaPath = [];
|
|
3056
3073
|
}
|
|
3057
3074
|
if (schema.$recursiveRef !== void 0) {
|
|
3058
|
-
if (
|
|
3075
|
+
if (ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12") {
|
|
3059
3076
|
const recursiveRefTarget = resolveRecursiveRef(schema, recursiveAnchorStack);
|
|
3060
|
-
if (
|
|
3061
|
-
else
|
|
3062
|
-
|
|
3077
|
+
if (recursiveRefTarget) validate(ctx, report, recursiveRefTarget, json);
|
|
3078
|
+
else report.addError("REF_UNRESOLVED", [schema.$recursiveRef], void 0, schema);
|
|
3079
|
+
const recursiveRefIdx = keys.indexOf("$recursiveRef");
|
|
3080
|
+
if (recursiveRefIdx !== -1) keys.splice(recursiveRefIdx, 1);
|
|
3063
3081
|
}
|
|
3064
3082
|
}
|
|
3065
3083
|
if (schema.$dynamicRef !== void 0) {
|
|
3066
|
-
if (
|
|
3084
|
+
if (ctx.options.version === "draft2020-12") {
|
|
3067
3085
|
const dynamicRefTarget = resolveDynamicRef(schema, dynamicScopeStack);
|
|
3068
|
-
if (
|
|
3069
|
-
else validate
|
|
3070
|
-
|
|
3086
|
+
if (dynamicRefTarget === void 0) report.addError("REF_UNRESOLVED", [schema.$dynamicRef], void 0, schema);
|
|
3087
|
+
else validate(ctx, report, dynamicRefTarget, json);
|
|
3088
|
+
const dynamicRefIdx = keys.indexOf("$dynamicRef");
|
|
3089
|
+
if (dynamicRefIdx !== -1) keys.splice(dynamicRefIdx, 1);
|
|
3071
3090
|
}
|
|
3072
3091
|
}
|
|
3073
|
-
const validationVocabularyEnabled = isValidationVocabularyEnabled(schema, report,
|
|
3074
|
-
if (!validationVocabularyEnabled)
|
|
3092
|
+
const validationVocabularyEnabled = isValidationVocabularyEnabled(schema, report, ctx.options.version);
|
|
3093
|
+
if (!validationVocabularyEnabled) {
|
|
3094
|
+
let wi = 0;
|
|
3095
|
+
for (let ri = 0; ri < keys.length; ri++) if (!VALIDATION_VOCAB_KEYWORDS.has(keys[ri])) keys[wi++] = keys[ri];
|
|
3096
|
+
keys.length = wi;
|
|
3097
|
+
}
|
|
3075
3098
|
if (validationVocabularyEnabled && schema.type) {
|
|
3076
3099
|
keys.splice(keys.indexOf("type"), 1);
|
|
3077
3100
|
report.schemaPath.push("type");
|
|
3078
|
-
JsonValidators.type
|
|
3101
|
+
JsonValidators.type(ctx, report, schema, json);
|
|
3079
3102
|
report.schemaPath.pop();
|
|
3080
|
-
if (report.errors.length &&
|
|
3103
|
+
if (report.errors.length && ctx.options.breakOnFirstError) {
|
|
3081
3104
|
if (pushedRecursiveAnchor) recursiveAnchorStack.pop();
|
|
3082
3105
|
if (pushedDynamicScope) dynamicScopeStack.pop();
|
|
3083
3106
|
return false;
|
|
3084
3107
|
}
|
|
3085
3108
|
}
|
|
3086
3109
|
const deferredUnevaluatedKeys = [];
|
|
3087
|
-
for (
|
|
3110
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3111
|
+
const key = keys[i];
|
|
3088
3112
|
if (key === "unevaluatedItems" || key === "unevaluatedProperties") {
|
|
3089
3113
|
deferredUnevaluatedKeys.push(key);
|
|
3090
3114
|
continue;
|
|
3091
3115
|
}
|
|
3092
3116
|
const validator = JsonValidators[key];
|
|
3093
3117
|
if (validator) {
|
|
3094
|
-
validator
|
|
3095
|
-
if (report.errors.length &&
|
|
3118
|
+
validator(ctx, report, schema, json);
|
|
3119
|
+
if (report.errors.length && ctx.options.breakOnFirstError) break;
|
|
3096
3120
|
}
|
|
3097
3121
|
}
|
|
3098
|
-
if (deferredUnevaluatedKeys.length > 0 && !(report.errors.length > 0 &&
|
|
3099
|
-
const validator = JsonValidators[
|
|
3122
|
+
if (deferredUnevaluatedKeys.length > 0 && !(report.errors.length > 0 && ctx.options.breakOnFirstError)) for (let i = 0; i < deferredUnevaluatedKeys.length; i++) {
|
|
3123
|
+
const validator = JsonValidators[deferredUnevaluatedKeys[i]];
|
|
3100
3124
|
if (validator) {
|
|
3101
|
-
validator
|
|
3102
|
-
if (report.errors.length &&
|
|
3125
|
+
validator(ctx, report, schema, json);
|
|
3126
|
+
if (report.errors.length && ctx.options.breakOnFirstError) break;
|
|
3103
3127
|
}
|
|
3104
3128
|
}
|
|
3105
|
-
if (report.errors.length === 0 ||
|
|
3106
|
-
if (Array.isArray(json)) recurseArray
|
|
3107
|
-
else if (isObject(json)) recurseObject
|
|
3129
|
+
if (report.errors.length === 0 || ctx.options.breakOnFirstError === false) {
|
|
3130
|
+
if (Array.isArray(json)) recurseArray(ctx, report, schema, json);
|
|
3131
|
+
else if (isObject(json)) recurseObject(ctx, report, schema, json);
|
|
3108
3132
|
}
|
|
3109
|
-
if (typeof
|
|
3133
|
+
if (typeof ctx.options.customValidator === "function") ctx.options.customValidator.call(ctx, report, schema, json);
|
|
3110
3134
|
if (pushedRecursiveAnchor) recursiveAnchorStack.pop();
|
|
3111
3135
|
if (pushedDynamicScope) dynamicScopeStack.pop();
|
|
3112
3136
|
if (isRoot) report.rootSchema = void 0;
|
|
@@ -3123,14 +3147,14 @@ function setSchemaReader(schemaReader) {
|
|
|
3123
3147
|
}
|
|
3124
3148
|
//#endregion
|
|
3125
3149
|
//#region src/schema-compiler.ts
|
|
3126
|
-
const UNSAFE_TARGETS = [
|
|
3150
|
+
const UNSAFE_TARGETS = new Set([
|
|
3127
3151
|
Object.prototype,
|
|
3128
3152
|
Function.prototype,
|
|
3129
3153
|
Array.prototype
|
|
3130
|
-
];
|
|
3154
|
+
]);
|
|
3131
3155
|
/** Returns true if `obj` is a built-in prototype that must not be mutated. */
|
|
3132
3156
|
function isUnsafeTarget(obj) {
|
|
3133
|
-
return UNSAFE_TARGETS.
|
|
3157
|
+
return UNSAFE_TARGETS.has(obj);
|
|
3134
3158
|
}
|
|
3135
3159
|
/** Safely assign a property on `obj`, refusing prototype-polluting keys. */
|
|
3136
3160
|
function safeSetProperty(obj, key, value) {
|
|
@@ -3143,35 +3167,78 @@ function safeDeleteProperty(obj, key) {
|
|
|
3143
3167
|
if (isUnsafeTarget(obj)) return;
|
|
3144
3168
|
if (key !== "__proto__" && key !== "constructor" && key !== "prototype") delete obj[key];
|
|
3145
3169
|
}
|
|
3170
|
+
const resolveReference = (base, ref) => {
|
|
3171
|
+
if (isAbsoluteUri(ref)) return ref;
|
|
3172
|
+
const baseStr = base ?? "";
|
|
3173
|
+
if (ref.startsWith("#")) {
|
|
3174
|
+
const hashIndex = baseStr.indexOf("#");
|
|
3175
|
+
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + ref;
|
|
3176
|
+
}
|
|
3177
|
+
if (!baseStr) return ref;
|
|
3178
|
+
const hashIndex = baseStr.indexOf("#");
|
|
3179
|
+
const baseNoFrag = hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex);
|
|
3180
|
+
if (isAbsoluteUri(baseNoFrag)) try {
|
|
3181
|
+
return new URL(ref, baseNoFrag).toString();
|
|
3182
|
+
} catch {}
|
|
3183
|
+
let baseDir = baseNoFrag;
|
|
3184
|
+
if (!baseDir.endsWith("/")) {
|
|
3185
|
+
const lastSlash = baseDir.lastIndexOf("/");
|
|
3186
|
+
baseDir = lastSlash === -1 ? "" : baseDir.slice(0, lastSlash + 1);
|
|
3187
|
+
}
|
|
3188
|
+
return baseDir + ref;
|
|
3189
|
+
};
|
|
3190
|
+
const isSimpleIdentifier = (id) => !id.startsWith("#") && !id.includes("/") && !id.includes(".") && !id.includes("#");
|
|
3191
|
+
const resolveIdScope = (base, id) => {
|
|
3192
|
+
if (isAbsoluteUri(id)) return id;
|
|
3193
|
+
const baseStr = base ?? "";
|
|
3194
|
+
if (isSimpleIdentifier(id)) {
|
|
3195
|
+
const hashIndex = baseStr.indexOf("#");
|
|
3196
|
+
return `${hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)}#${id}`;
|
|
3197
|
+
}
|
|
3198
|
+
return resolveReference(base, id);
|
|
3199
|
+
};
|
|
3200
|
+
const resolveSchemaScopeId = (base, schema, id) => {
|
|
3201
|
+
if (typeof schema.$id === "string") return resolveReference(base, id);
|
|
3202
|
+
return resolveIdScope(base, id);
|
|
3203
|
+
};
|
|
3146
3204
|
const collectIds = (obj, maxDepth = 100) => {
|
|
3147
3205
|
const ids = [];
|
|
3148
3206
|
function walk(node, scope, _depth = 0) {
|
|
3149
3207
|
if (typeof node !== "object" || node == null) return;
|
|
3208
|
+
const schemaNode = node;
|
|
3150
3209
|
if (_depth >= maxDepth) throw new Error(`Maximum recursion depth (${maxDepth}) exceeded in collectIds. If your schema is deeply nested and valid, increase the maxRecursionDepth option.`);
|
|
3151
3210
|
let addedScope = false;
|
|
3152
|
-
const nodeId = getId(
|
|
3211
|
+
const nodeId = getId(schemaNode);
|
|
3153
3212
|
if (typeof nodeId === "string") {
|
|
3154
3213
|
let type = isAbsoluteUri(nodeId) ? "absolute" : "relative";
|
|
3155
3214
|
if (scope.length === 0) type = "root";
|
|
3156
3215
|
const id = {
|
|
3157
3216
|
id: nodeId,
|
|
3158
3217
|
type,
|
|
3159
|
-
obj:
|
|
3218
|
+
obj: schemaNode
|
|
3160
3219
|
};
|
|
3161
3220
|
if (type === "absolute" || type === "root" && isAbsoluteUri(nodeId)) id.absoluteUri = nodeId;
|
|
3162
|
-
else if (type === "root" && typeof
|
|
3221
|
+
else if (type === "root" && typeof schemaNode.id === "string" && isAbsoluteUri(schemaNode.id) && schemaNode.id !== nodeId) id.absoluteUri = resolveSchemaScopeId(schemaNode.id, schemaNode, nodeId);
|
|
3163
3222
|
else if (type === "relative") {
|
|
3164
|
-
|
|
3165
|
-
|
|
3223
|
+
let absoluteParent;
|
|
3224
|
+
for (let i = scope.length - 1; i >= 0; i--) {
|
|
3225
|
+
const sc = scope[i];
|
|
3226
|
+
if (sc.type === "absolute" || sc.type === "root" && sc.absoluteUri) {
|
|
3227
|
+
absoluteParent = sc;
|
|
3228
|
+
break;
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
id.absoluteParent = absoluteParent;
|
|
3232
|
+
if (id.absoluteParent) id.absoluteUri = resolveSchemaScopeId(id.absoluteParent.absoluteUri || id.absoluteParent.id, schemaNode, id.id);
|
|
3166
3233
|
}
|
|
3167
3234
|
ids.push(id);
|
|
3168
3235
|
scope.push(id);
|
|
3169
3236
|
addedScope = true;
|
|
3170
3237
|
}
|
|
3171
3238
|
if (Array.isArray(node)) for (const item of node) walk(item, scope, _depth + 1);
|
|
3172
|
-
else for (const key of Object.keys(
|
|
3173
|
-
if (isInternalKey(key) ||
|
|
3174
|
-
walk(
|
|
3239
|
+
else for (const key of Object.keys(schemaNode)) {
|
|
3240
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
3241
|
+
walk(schemaNode[key], scope, _depth + 1);
|
|
3175
3242
|
}
|
|
3176
3243
|
if (addedScope) scope.pop();
|
|
3177
3244
|
}
|
|
@@ -3179,42 +3246,42 @@ const collectIds = (obj, maxDepth = 100) => {
|
|
|
3179
3246
|
return ids;
|
|
3180
3247
|
};
|
|
3181
3248
|
const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _depth = 0) => {
|
|
3182
|
-
results
|
|
3183
|
-
scope
|
|
3184
|
-
path
|
|
3185
|
-
options
|
|
3249
|
+
results ||= [];
|
|
3250
|
+
scope ||= [];
|
|
3251
|
+
path ||= [];
|
|
3252
|
+
options ||= {};
|
|
3186
3253
|
if (typeof obj !== "object" || obj === null) return results;
|
|
3187
3254
|
if (_depth >= maxDepth) throw new Error(`Maximum recursion depth (${maxDepth}) exceeded in collectReferences. If your schema is deeply nested and valid, increase the maxRecursionDepth option.`);
|
|
3188
|
-
const hasRef = typeof obj.$ref === "string" &&
|
|
3255
|
+
const hasRef = typeof obj.$ref === "string" && obj.__$refResolved === void 0;
|
|
3189
3256
|
let addedScope = false;
|
|
3190
3257
|
const isRootScope = scope.length === 0;
|
|
3191
3258
|
let scopeId = getId(obj);
|
|
3192
3259
|
if (typeof obj.id === "string" && isAbsoluteUri(obj.id) && (!scopeId || !isAbsoluteUri(scopeId))) scopeId = obj.id;
|
|
3193
3260
|
if (typeof scopeId === "string" && (isRootScope || !hasRef || options.useRefObjectScope === true)) {
|
|
3194
|
-
const base = scope.length > 0 ? scope
|
|
3261
|
+
const base = scope.length > 0 ? scope.at(-1) : void 0;
|
|
3195
3262
|
scope.push(resolveSchemaScopeId(base, obj, scopeId));
|
|
3196
3263
|
addedScope = true;
|
|
3197
3264
|
}
|
|
3198
3265
|
if (hasRef) results.push({
|
|
3199
|
-
ref: resolveReference(scope
|
|
3266
|
+
ref: resolveReference(scope.at(-1), obj.$ref),
|
|
3200
3267
|
key: "$ref",
|
|
3201
3268
|
obj,
|
|
3202
3269
|
path: path.slice(0)
|
|
3203
3270
|
});
|
|
3204
|
-
if (typeof obj.$recursiveRef === "string" &&
|
|
3205
|
-
ref: resolveReference(scope
|
|
3271
|
+
if (typeof obj.$recursiveRef === "string" && obj.__$recursiveRefResolved === void 0) results.push({
|
|
3272
|
+
ref: resolveReference(scope.at(-1), obj.$recursiveRef),
|
|
3206
3273
|
key: "$recursiveRef",
|
|
3207
3274
|
obj,
|
|
3208
3275
|
path: path.slice(0)
|
|
3209
3276
|
});
|
|
3210
|
-
if (typeof obj.$dynamicRef === "string" &&
|
|
3211
|
-
ref: resolveReference(scope
|
|
3277
|
+
if (typeof obj.$dynamicRef === "string" && obj.__$dynamicRefResolved === void 0) results.push({
|
|
3278
|
+
ref: resolveReference(scope.at(-1), obj.$dynamicRef),
|
|
3212
3279
|
key: "$dynamicRef",
|
|
3213
3280
|
obj,
|
|
3214
3281
|
path: path.slice(0)
|
|
3215
3282
|
});
|
|
3216
|
-
if (typeof obj.$schema === "string" &&
|
|
3217
|
-
ref: resolveReference(scope
|
|
3283
|
+
if (typeof obj.$schema === "string" && obj.__$schemaResolved === void 0) results.push({
|
|
3284
|
+
ref: resolveReference(scope.at(-1), obj.$schema),
|
|
3218
3285
|
key: "$schema",
|
|
3219
3286
|
obj,
|
|
3220
3287
|
path: path.slice(0)
|
|
@@ -3227,7 +3294,7 @@ const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _
|
|
|
3227
3294
|
else {
|
|
3228
3295
|
const keys = Object.keys(obj);
|
|
3229
3296
|
for (const key of keys) {
|
|
3230
|
-
if (isInternalKey(key) ||
|
|
3297
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
3231
3298
|
path.push(key);
|
|
3232
3299
|
collectReferences(obj[key], results, scope, path, options, maxDepth, _depth + 1);
|
|
3233
3300
|
path.pop();
|
|
@@ -3236,41 +3303,8 @@ const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _
|
|
|
3236
3303
|
if (addedScope) scope.pop();
|
|
3237
3304
|
return results;
|
|
3238
3305
|
};
|
|
3239
|
-
const resolveReference = (base, ref) => {
|
|
3240
|
-
if (isAbsoluteUri(ref)) return ref;
|
|
3241
|
-
const baseStr = base ?? "";
|
|
3242
|
-
if (ref[0] === "#") {
|
|
3243
|
-
const hashIndex = baseStr.indexOf("#");
|
|
3244
|
-
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + ref;
|
|
3245
|
-
}
|
|
3246
|
-
if (!baseStr) return ref;
|
|
3247
|
-
const hashIndex = baseStr.indexOf("#");
|
|
3248
|
-
const baseNoFrag = hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex);
|
|
3249
|
-
if (isAbsoluteUri(baseNoFrag)) try {
|
|
3250
|
-
return new URL(ref, baseNoFrag).toString();
|
|
3251
|
-
} catch {}
|
|
3252
|
-
let baseDir = baseNoFrag;
|
|
3253
|
-
if (!baseDir.endsWith("/")) {
|
|
3254
|
-
const lastSlash = baseDir.lastIndexOf("/");
|
|
3255
|
-
baseDir = lastSlash === -1 ? "" : baseDir.slice(0, lastSlash + 1);
|
|
3256
|
-
}
|
|
3257
|
-
return baseDir + ref;
|
|
3258
|
-
};
|
|
3259
|
-
const isSimpleIdentifier = (id) => id[0] !== "#" && !id.includes("/") && !id.includes(".") && !id.includes("#");
|
|
3260
|
-
const resolveIdScope = (base, id) => {
|
|
3261
|
-
if (isAbsoluteUri(id)) return id;
|
|
3262
|
-
const baseStr = base ?? "";
|
|
3263
|
-
if (isSimpleIdentifier(id)) {
|
|
3264
|
-
const hashIndex = baseStr.indexOf("#");
|
|
3265
|
-
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + "#" + id;
|
|
3266
|
-
}
|
|
3267
|
-
return resolveReference(base, id);
|
|
3268
|
-
};
|
|
3269
|
-
const resolveSchemaScopeId = (base, schema, id) => {
|
|
3270
|
-
if (typeof schema.$id === "string") return resolveReference(base, id);
|
|
3271
|
-
return resolveIdScope(base, id);
|
|
3272
|
-
};
|
|
3273
3306
|
var SchemaCompiler = class {
|
|
3307
|
+
validator;
|
|
3274
3308
|
constructor(validator) {
|
|
3275
3309
|
this.validator = validator;
|
|
3276
3310
|
}
|
|
@@ -3288,19 +3322,19 @@ var SchemaCompiler = class {
|
|
|
3288
3322
|
report.commonErrorMessage = "SCHEMA_COMPILATION_FAILED";
|
|
3289
3323
|
if (typeof schema === "string") {
|
|
3290
3324
|
const loadedSchema = this.validator.scache.getSchemaByUri(report, schema);
|
|
3291
|
-
if (
|
|
3325
|
+
if (loadedSchema === void 0) {
|
|
3292
3326
|
report.addError("SCHEMA_NOT_REACHABLE", [schema]);
|
|
3293
3327
|
return false;
|
|
3294
3328
|
}
|
|
3295
3329
|
schema = loadedSchema;
|
|
3296
3330
|
}
|
|
3297
3331
|
if (Array.isArray(schema)) {
|
|
3298
|
-
if (!options?.noCache) schema.
|
|
3332
|
+
if (!options?.noCache) for (let i = 0; i < schema.length; i++) this.collectAndCacheIds(schema[i]);
|
|
3299
3333
|
return this.compileArrayOfSchemas(report, schema);
|
|
3300
3334
|
} else if (typeof schema === "boolean") return true;
|
|
3301
|
-
|
|
3335
|
+
if (!options?.noCache) this.collectAndCacheIds(schema);
|
|
3302
3336
|
const canMutateSchemaObject = schema !== Object.prototype && schema !== Function.prototype && schema !== Array.prototype;
|
|
3303
|
-
if (canMutateSchemaObject && schema.__$compiled && schema.id && this.validator.scache.checkCacheForUri(schema.id)
|
|
3337
|
+
if (canMutateSchemaObject && schema.__$compiled && schema.id && !this.validator.scache.checkCacheForUri(schema.id)) schema.__$compiled = void 0;
|
|
3304
3338
|
if (schema.__$compiled) return true;
|
|
3305
3339
|
if (canMutateSchemaObject && !schema.$schema && this.validator.options.version !== "none") schema.$schema = this.validator.getDefaultSchemaId();
|
|
3306
3340
|
if (schema.id && typeof schema.id === "string" && !options?.noCache) this.validator.scache.cacheSchemaByUri(schema.id, schema);
|
|
@@ -3315,7 +3349,7 @@ var SchemaCompiler = class {
|
|
|
3315
3349
|
const refs = collectReferences(schema, void 0, void 0, void 0, { useRefObjectScope }, this.validator.options.maxRecursionDepth);
|
|
3316
3350
|
for (const refObj of refs) {
|
|
3317
3351
|
let response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
3318
|
-
if (
|
|
3352
|
+
if (response === void 0) {
|
|
3319
3353
|
const schemaReader = getSchemaReader();
|
|
3320
3354
|
if (schemaReader) {
|
|
3321
3355
|
const remotePath = getRemotePath(refObj.ref);
|
|
@@ -3323,23 +3357,24 @@ var SchemaCompiler = class {
|
|
|
3323
3357
|
if (s) {
|
|
3324
3358
|
s.id = remotePath;
|
|
3325
3359
|
const subreport = new Report(report);
|
|
3326
|
-
if (
|
|
3327
|
-
else
|
|
3360
|
+
if (this.compileSchema(subreport, s)) response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
3361
|
+
else for (let i = 0; i < subreport.errors.length; i++) report.errors.push(subreport.errors[i]);
|
|
3328
3362
|
}
|
|
3329
3363
|
}
|
|
3330
3364
|
}
|
|
3331
|
-
if (
|
|
3365
|
+
if (response === void 0) {
|
|
3332
3366
|
const hasNotValid = report.hasError("REMOTE_NOT_VALID", [refObj.ref]);
|
|
3333
3367
|
const isAbsolute = isAbsoluteUri(refObj.ref);
|
|
3334
3368
|
let isDownloaded = false;
|
|
3335
3369
|
const ignoreUnresolvableRemotes = this.validator.options.ignoreUnresolvableReferences === true;
|
|
3336
3370
|
if (isAbsolute) isDownloaded = this.validator.scache.checkCacheForUri(refObj.ref);
|
|
3337
3371
|
if (hasNotValid) {} else if (ignoreUnresolvableRemotes && isAbsolute) {} else if (isDownloaded) {} else {
|
|
3338
|
-
|
|
3372
|
+
const pathLen = refObj.path.length;
|
|
3373
|
+
for (let i = 0; i < pathLen; i++) report.path.push(refObj.path[i]);
|
|
3339
3374
|
report.addError("UNRESOLVABLE_REFERENCE", [refObj.ref]);
|
|
3340
|
-
report.path
|
|
3375
|
+
report.path.length -= pathLen;
|
|
3341
3376
|
if (isValidExceptReferences && canMutateSchemaObject && !isUnsafeTarget(schema)) {
|
|
3342
|
-
schema.__$missingReferences
|
|
3377
|
+
schema.__$missingReferences ||= [];
|
|
3343
3378
|
schema.__$missingReferences.push(refObj);
|
|
3344
3379
|
}
|
|
3345
3380
|
}
|
|
@@ -3354,13 +3389,20 @@ var SchemaCompiler = class {
|
|
|
3354
3389
|
compileArrayOfSchemas(report, arr) {
|
|
3355
3390
|
let compiled = 0, lastLoopCompiled;
|
|
3356
3391
|
do {
|
|
3357
|
-
|
|
3392
|
+
let wi = 0;
|
|
3393
|
+
for (let ri = 0; ri < report.errors.length; ri++) if (report.errors[ri].code !== "UNRESOLVABLE_REFERENCE") report.errors[wi++] = report.errors[ri];
|
|
3394
|
+
report.errors.length = wi;
|
|
3358
3395
|
lastLoopCompiled = compiled;
|
|
3359
3396
|
compiled = this.compileArrayOfSchemasLoop(report, arr);
|
|
3397
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
3398
|
+
for (let i = 0; i < arr.length; i++) {
|
|
3399
|
+
const schemaId = arr[i].id;
|
|
3400
|
+
if (schemaId && !idMap.has(schemaId)) idMap.set(schemaId, arr[i]);
|
|
3401
|
+
}
|
|
3360
3402
|
for (const sch of arr) if (sch.__$missingReferences) {
|
|
3361
3403
|
for (let idx2 = sch.__$missingReferences.length - 1; idx2 >= 0; idx2--) {
|
|
3362
3404
|
const refObj = sch.__$missingReferences[idx2];
|
|
3363
|
-
const response =
|
|
3405
|
+
const response = idMap.get(refObj.ref);
|
|
3364
3406
|
if (response) {
|
|
3365
3407
|
safeSetProperty(refObj.obj, `__${refObj.key}Resolved`, response);
|
|
3366
3408
|
sch.__$missingReferences.splice(idx2, 1);
|
|
@@ -3376,62 +3418,74 @@ var SchemaCompiler = class {
|
|
|
3376
3418
|
for (const schema of arr) {
|
|
3377
3419
|
const report = new Report(mainReport);
|
|
3378
3420
|
if (this.compileSchema(report, schema)) compiledCount++;
|
|
3379
|
-
|
|
3421
|
+
for (let i = 0; i < report.errors.length; i++) mainReport.errors.push(report.errors[i]);
|
|
3380
3422
|
}
|
|
3381
3423
|
return compiledCount;
|
|
3382
3424
|
}
|
|
3383
3425
|
};
|
|
3384
3426
|
//#endregion
|
|
3385
3427
|
//#region src/schema-validator.ts
|
|
3428
|
+
const PRIMITIVE_TYPES = [
|
|
3429
|
+
"array",
|
|
3430
|
+
"boolean",
|
|
3431
|
+
"integer",
|
|
3432
|
+
"number",
|
|
3433
|
+
"null",
|
|
3434
|
+
"object",
|
|
3435
|
+
"string"
|
|
3436
|
+
];
|
|
3437
|
+
const PRIMITIVE_TYPE_STR = PRIMITIVE_TYPES.join(",");
|
|
3438
|
+
const PRIMITIVE_TYPES_SET = new Set(PRIMITIVE_TYPES);
|
|
3386
3439
|
const SchemaValidators = {
|
|
3387
|
-
$ref
|
|
3440
|
+
$ref(report, schema) {
|
|
3388
3441
|
if (typeof schema.$ref !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["$ref", "string"], void 0, schema, "$ref");
|
|
3389
3442
|
},
|
|
3390
|
-
$schema
|
|
3443
|
+
$schema(report, schema) {
|
|
3391
3444
|
if (typeof schema.$schema !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["$schema", "string"], void 0, schema, "$schema");
|
|
3392
3445
|
},
|
|
3393
|
-
multipleOf
|
|
3446
|
+
multipleOf(report, schema) {
|
|
3394
3447
|
if (typeof schema.multipleOf !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["multipleOf", "number"], void 0, schema, "multipleOf");
|
|
3395
3448
|
else if (schema.multipleOf <= 0) report.addError("KEYWORD_MUST_BE", ["multipleOf", "strictly greater than 0"], void 0, schema, "multipleOf");
|
|
3396
3449
|
},
|
|
3397
|
-
maximum
|
|
3450
|
+
maximum(report, schema) {
|
|
3398
3451
|
if (typeof schema.maximum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["maximum", "number"], void 0, schema, "maximum");
|
|
3399
3452
|
},
|
|
3400
|
-
exclusiveMaximum
|
|
3453
|
+
exclusiveMaximum(report, schema) {
|
|
3401
3454
|
if (report.options.version === "draft-04") {
|
|
3402
3455
|
if (typeof schema.exclusiveMaximum !== "boolean") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMaximum", "boolean"], void 0, schema, "exclusiveMaximum");
|
|
3403
3456
|
else if (schema.maximum === void 0) report.addError("KEYWORD_DEPENDENCY", ["exclusiveMaximum", "maximum"], void 0, schema, "exclusiveMaximum");
|
|
3404
3457
|
} else if (typeof schema.exclusiveMaximum !== "boolean" && typeof schema.exclusiveMaximum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMaximum", ["boolean", "number"]], void 0, schema, "exclusiveMaximum");
|
|
3405
3458
|
},
|
|
3406
|
-
minimum
|
|
3459
|
+
minimum(report, schema) {
|
|
3407
3460
|
if (typeof schema.minimum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["minimum", "number"], void 0, schema, "minimum");
|
|
3408
3461
|
},
|
|
3409
|
-
exclusiveMinimum
|
|
3462
|
+
exclusiveMinimum(report, schema) {
|
|
3410
3463
|
if (report.options.version === "draft-04") {
|
|
3411
3464
|
if (typeof schema.exclusiveMinimum !== "boolean") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMinimum", "boolean"], void 0, schema, "exclusiveMinimum");
|
|
3412
3465
|
else if (schema.minimum === void 0) report.addError("KEYWORD_DEPENDENCY", ["exclusiveMinimum", "minimum"], void 0, schema, "exclusiveMinimum");
|
|
3413
3466
|
} else if (typeof schema.exclusiveMinimum !== "boolean" && typeof schema.exclusiveMinimum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMinimum", ["boolean", "number"]], void 0, schema, "exclusiveMinimum");
|
|
3414
3467
|
},
|
|
3415
|
-
maxLength
|
|
3468
|
+
maxLength(report, schema) {
|
|
3416
3469
|
if (!isInteger(schema.maxLength)) report.addError("KEYWORD_TYPE_EXPECTED", ["maxLength", "integer"], void 0, schema, "maxLength");
|
|
3417
3470
|
else if (schema.maxLength < 0) report.addError("KEYWORD_MUST_BE", ["maxLength", "greater than, or equal to 0"], void 0, schema, "maxLength");
|
|
3418
3471
|
},
|
|
3419
|
-
minLength
|
|
3472
|
+
minLength(report, schema) {
|
|
3420
3473
|
if (!isInteger(schema.minLength)) report.addError("KEYWORD_TYPE_EXPECTED", ["minLength", "integer"], void 0, schema, "minLength");
|
|
3421
3474
|
else if (schema.minLength < 0) report.addError("KEYWORD_MUST_BE", ["minLength", "greater than, or equal to 0"], void 0, schema, "minLength");
|
|
3422
3475
|
},
|
|
3423
|
-
pattern
|
|
3424
|
-
if (typeof schema.pattern !== "string")
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
if (!result.ok) report.addError("KEYWORD_PATTERN", [
|
|
3428
|
-
"pattern",
|
|
3429
|
-
schema.pattern,
|
|
3430
|
-
result.error.message
|
|
3431
|
-
], void 0, schema, "pattern");
|
|
3476
|
+
pattern(report, schema) {
|
|
3477
|
+
if (typeof schema.pattern !== "string") {
|
|
3478
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["pattern", "string"], void 0, schema, "pattern");
|
|
3479
|
+
return;
|
|
3432
3480
|
}
|
|
3481
|
+
const result = compileSchemaRegex(schema.pattern);
|
|
3482
|
+
if (!result.ok) report.addError("KEYWORD_PATTERN", [
|
|
3483
|
+
"pattern",
|
|
3484
|
+
schema.pattern,
|
|
3485
|
+
result.error.message
|
|
3486
|
+
], void 0, schema, "pattern");
|
|
3433
3487
|
},
|
|
3434
|
-
additionalItems
|
|
3488
|
+
additionalItems(report, schema) {
|
|
3435
3489
|
if (typeof schema.additionalItems !== "boolean" && !isObject(schema.additionalItems)) report.addError("KEYWORD_TYPE_EXPECTED", ["additionalItems", ["boolean", "object"]], void 0, schema, "additionalItems");
|
|
3436
3490
|
else if (isObject(schema.additionalItems)) {
|
|
3437
3491
|
report.path.push("additionalItems");
|
|
@@ -3439,7 +3493,7 @@ const SchemaValidators = {
|
|
|
3439
3493
|
report.path.pop();
|
|
3440
3494
|
}
|
|
3441
3495
|
},
|
|
3442
|
-
items
|
|
3496
|
+
items(report, schema) {
|
|
3443
3497
|
if (Array.isArray(schema.items)) for (let idx = 0; idx < schema.items.length; idx++) {
|
|
3444
3498
|
report.path.push("items");
|
|
3445
3499
|
report.path.push(idx);
|
|
@@ -3459,34 +3513,34 @@ const SchemaValidators = {
|
|
|
3459
3513
|
if (this.options.forceAdditional === true && schema.additionalItems === void 0 && Array.isArray(schema.items)) report.addError("KEYWORD_UNDEFINED_STRICT", ["additionalItems"], void 0, schema, "additionalItems");
|
|
3460
3514
|
if (this.options.assumeAdditional && schema.additionalItems === void 0 && Array.isArray(schema.items)) schema.additionalItems = false;
|
|
3461
3515
|
},
|
|
3462
|
-
maxItems
|
|
3516
|
+
maxItems(report, schema) {
|
|
3463
3517
|
if (typeof schema.maxItems !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["maxItems", "integer"], void 0, schema, "maxItems");
|
|
3464
3518
|
else if (schema.maxItems < 0) report.addError("KEYWORD_MUST_BE", ["maxItems", "greater than, or equal to 0"], void 0, schema, "maxItems");
|
|
3465
3519
|
},
|
|
3466
|
-
minItems
|
|
3520
|
+
minItems(report, schema) {
|
|
3467
3521
|
if (!isInteger(schema.minItems)) report.addError("KEYWORD_TYPE_EXPECTED", ["minItems", "integer"], void 0, schema, "minItems");
|
|
3468
3522
|
else if (schema.minItems < 0) report.addError("KEYWORD_MUST_BE", ["minItems", "greater than, or equal to 0"], void 0, schema, "minItems");
|
|
3469
3523
|
},
|
|
3470
|
-
uniqueItems
|
|
3524
|
+
uniqueItems(report, schema) {
|
|
3471
3525
|
if (typeof schema.uniqueItems !== "boolean") report.addError("KEYWORD_TYPE_EXPECTED", ["uniqueItems", "boolean"], void 0, schema, "uniqueItems");
|
|
3472
3526
|
},
|
|
3473
|
-
maxProperties
|
|
3527
|
+
maxProperties(report, schema) {
|
|
3474
3528
|
if (!isInteger(schema.maxProperties)) report.addError("KEYWORD_TYPE_EXPECTED", ["maxProperties", "integer"], void 0, schema, "maxProperties");
|
|
3475
3529
|
else if (schema.maxProperties < 0) report.addError("KEYWORD_MUST_BE", ["maxProperties", "greater than, or equal to 0"], void 0, schema, "maxProperties");
|
|
3476
3530
|
},
|
|
3477
|
-
minProperties
|
|
3531
|
+
minProperties(report, schema) {
|
|
3478
3532
|
if (!isInteger(schema.minProperties)) report.addError("KEYWORD_TYPE_EXPECTED", ["minProperties", "integer"], void 0, schema, "minProperties");
|
|
3479
3533
|
else if (schema.minProperties < 0) report.addError("KEYWORD_MUST_BE", ["minProperties", "greater than, or equal to 0"], void 0, schema, "minProperties");
|
|
3480
3534
|
},
|
|
3481
|
-
required
|
|
3535
|
+
required(report, schema) {
|
|
3482
3536
|
if (!Array.isArray(schema.required)) report.addError("KEYWORD_TYPE_EXPECTED", ["required", "array"], void 0, schema, "required");
|
|
3483
3537
|
else if (report.options.version === "draft-04" && schema.required.length === 0) report.addError("KEYWORD_MUST_BE", ["required", "an array with at least one element"], void 0, schema, "required");
|
|
3484
3538
|
else {
|
|
3485
3539
|
for (const item of schema.required) if (typeof item !== "string") report.addError("KEYWORD_VALUE_TYPE", ["required", "string"], void 0, schema, "required");
|
|
3486
|
-
if (isUniqueArray(schema.required)
|
|
3540
|
+
if (!isUniqueArray(schema.required)) report.addError("KEYWORD_MUST_BE", ["required", "an array with unique items"], void 0, schema, "required");
|
|
3487
3541
|
}
|
|
3488
3542
|
},
|
|
3489
|
-
additionalProperties
|
|
3543
|
+
additionalProperties(report, schema) {
|
|
3490
3544
|
if (typeof schema.additionalProperties !== "boolean" && !isObject(schema.additionalProperties)) report.addError("KEYWORD_TYPE_EXPECTED", ["additionalProperties", ["boolean", "object"]], void 0, schema, "additionalProperties");
|
|
3491
3545
|
else if (isObject(schema.additionalProperties)) {
|
|
3492
3546
|
report.path.push("additionalProperties");
|
|
@@ -3494,7 +3548,7 @@ const SchemaValidators = {
|
|
|
3494
3548
|
report.path.pop();
|
|
3495
3549
|
}
|
|
3496
3550
|
},
|
|
3497
|
-
properties
|
|
3551
|
+
properties(report, schema) {
|
|
3498
3552
|
if (!isObject(schema.properties)) {
|
|
3499
3553
|
report.addError("KEYWORD_TYPE_EXPECTED", ["properties", "object"], void 0, schema, "properties");
|
|
3500
3554
|
return;
|
|
@@ -3512,7 +3566,7 @@ const SchemaValidators = {
|
|
|
3512
3566
|
if (this.options.assumeAdditional && schema.additionalProperties === void 0) schema.additionalProperties = false;
|
|
3513
3567
|
if (this.options.forceProperties === true && keys.length === 0) report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["properties"], void 0, schema, "properties");
|
|
3514
3568
|
},
|
|
3515
|
-
patternProperties
|
|
3569
|
+
patternProperties(report, schema) {
|
|
3516
3570
|
if (!isObject(schema.patternProperties)) {
|
|
3517
3571
|
report.addError("KEYWORD_TYPE_EXPECTED", ["patternProperties", "object"], void 0, schema, "patternProperties");
|
|
3518
3572
|
return;
|
|
@@ -3534,93 +3588,52 @@ const SchemaValidators = {
|
|
|
3534
3588
|
}
|
|
3535
3589
|
if (this.options.forceProperties === true && keys.length === 0) report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["patternProperties"], void 0, schema, "patternProperties");
|
|
3536
3590
|
},
|
|
3537
|
-
dependencies
|
|
3538
|
-
if (!isObject(schema.dependencies))
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3591
|
+
dependencies(report, schema) {
|
|
3592
|
+
if (!isObject(schema.dependencies)) {
|
|
3593
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["dependencies", "object"], void 0, schema, "dependencies");
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
const keys = Object.keys(schema.dependencies);
|
|
3597
|
+
for (const schemaKey of keys) {
|
|
3598
|
+
const schemaDependency = schema.dependencies[schemaKey];
|
|
3599
|
+
if (isObject(schemaDependency) || report.options.version !== "draft-04" && typeof schemaDependency === "boolean") {
|
|
3600
|
+
report.path.push("dependencies");
|
|
3601
|
+
report.path.push(schemaKey);
|
|
3602
|
+
this.validateSchema(report, schemaDependency);
|
|
3603
|
+
report.path.pop();
|
|
3604
|
+
report.path.pop();
|
|
3605
|
+
} else if (Array.isArray(schemaDependency)) {
|
|
3606
|
+
const depArray = schemaDependency;
|
|
3607
|
+
if (report.options.version === "draft-04" && depArray.length === 0) report.addError("KEYWORD_MUST_BE", ["dependencies", "not empty array"], void 0, schema, "dependencies");
|
|
3608
|
+
for (const dep of depArray) if (typeof dep !== "string") report.addError("KEYWORD_VALUE_TYPE", ["dependencies", "string"], void 0, schema, "dependencies");
|
|
3609
|
+
if (!isUniqueArray(depArray)) report.addError("KEYWORD_MUST_BE", ["dependencies", "an array with unique items"], void 0, schema, "dependencies");
|
|
3610
|
+
} else report.addError("KEYWORD_VALUE_TYPE", ["dependencies", report.options.version === "draft-04" ? "object or array" : "boolean, object or array"], void 0, schema, "dependencies");
|
|
3556
3611
|
}
|
|
3557
3612
|
},
|
|
3558
|
-
enum
|
|
3559
|
-
if (Array.isArray(schema.enum)
|
|
3613
|
+
enum(report, schema) {
|
|
3614
|
+
if (!Array.isArray(schema.enum)) report.addError("KEYWORD_TYPE_EXPECTED", ["enum", "array"], void 0, schema, "enum");
|
|
3560
3615
|
else if (schema.enum.length === 0) report.addError("KEYWORD_MUST_BE", ["enum", "an array with at least one element"], void 0, schema, "enum");
|
|
3561
|
-
else if (isUniqueArray(schema.enum)
|
|
3616
|
+
else if (!isUniqueArray(schema.enum)) report.addError("KEYWORD_MUST_BE", ["enum", "an array with unique elements"], void 0, schema, "enum");
|
|
3562
3617
|
},
|
|
3563
|
-
type
|
|
3564
|
-
const primitiveTypes = [
|
|
3565
|
-
"array",
|
|
3566
|
-
"boolean",
|
|
3567
|
-
"integer",
|
|
3568
|
-
"number",
|
|
3569
|
-
"null",
|
|
3570
|
-
"object",
|
|
3571
|
-
"string"
|
|
3572
|
-
];
|
|
3573
|
-
const primitiveTypeStr = primitiveTypes.join(",");
|
|
3618
|
+
type(report, schema) {
|
|
3574
3619
|
const isArray = Array.isArray(schema.type);
|
|
3575
3620
|
if (Array.isArray(schema.type)) {
|
|
3576
|
-
for (const typeItem of schema.type) if (!
|
|
3577
|
-
if (isUniqueArray(schema.type)
|
|
3621
|
+
for (const typeItem of schema.type) if (!PRIMITIVE_TYPES_SET.has(typeItem)) report.addError("KEYWORD_TYPE_EXPECTED", ["type", PRIMITIVE_TYPE_STR], void 0, schema, "type");
|
|
3622
|
+
if (!isUniqueArray(schema.type)) report.addError("KEYWORD_MUST_BE", ["type", "an object with unique properties"], void 0, schema, "type");
|
|
3578
3623
|
} else if (typeof schema.type === "string") {
|
|
3579
|
-
if (!
|
|
3624
|
+
if (!PRIMITIVE_TYPES_SET.has(schema.type)) report.addError("KEYWORD_TYPE_EXPECTED", ["type", PRIMITIVE_TYPE_STR], void 0, schema, "type");
|
|
3580
3625
|
} else report.addError("KEYWORD_TYPE_EXPECTED", ["type", ["string", "array"]], void 0, schema, "type");
|
|
3581
|
-
if (this.options.noEmptyStrings === true)
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
if (this.options.
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
}
|
|
3590
|
-
}
|
|
3591
|
-
if (this.options.forceProperties === true) {
|
|
3592
|
-
if (schema.type === "object" || isArray && schema.type.includes("object")) {
|
|
3593
|
-
if (schema.properties === void 0 && schema.patternProperties === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["properties"], void 0, schema, "properties");
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
if (this.options.forceItems === true) {
|
|
3597
|
-
if (schema.type === "array" || isArray && schema.type.includes("array")) {
|
|
3598
|
-
if (schema.items === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["items"], void 0, schema, "items");
|
|
3599
|
-
}
|
|
3600
|
-
}
|
|
3601
|
-
if (this.options.forceMinItems === true) {
|
|
3602
|
-
if (schema.type === "array" || isArray && schema.type.includes("array")) {
|
|
3603
|
-
if (schema.minItems === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["minItems"], void 0, schema, "minItems");
|
|
3604
|
-
}
|
|
3605
|
-
}
|
|
3606
|
-
if (this.options.forceMaxItems === true) {
|
|
3607
|
-
if (schema.type === "array" || isArray && schema.type.includes("array")) {
|
|
3608
|
-
if (schema.maxItems === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["maxItems"], void 0, schema, "maxItems");
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
if (this.options.forceMinLength === true) {
|
|
3612
|
-
if (schema.type === "string" || isArray && schema.type.includes("string")) {
|
|
3613
|
-
if (schema.minLength === void 0 && schema.format === void 0 && schema.enum === void 0 && schema.pattern === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["minLength"], void 0, schema, "minLength");
|
|
3614
|
-
}
|
|
3615
|
-
}
|
|
3616
|
-
if (this.options.forceMaxLength === true) {
|
|
3617
|
-
if (schema.type === "string" || isArray && schema.type.includes("string")) {
|
|
3618
|
-
if (schema.maxLength === void 0 && schema.format === void 0 && schema.enum === void 0 && schema.pattern === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["maxLength"], void 0, schema, "maxLength");
|
|
3619
|
-
}
|
|
3620
|
-
}
|
|
3626
|
+
if (this.options.noEmptyStrings === true && (schema.type === "string" || isArray && schema.type.includes("string")) && schema.minLength === void 0 && schema.enum === void 0 && schema.format === void 0) schema.minLength = 1;
|
|
3627
|
+
if (this.options.noEmptyArrays === true && (schema.type === "array" || isArray && schema.type.includes("array")) && schema.minItems === void 0) schema.minItems = 1;
|
|
3628
|
+
if (this.options.forceProperties === true && (schema.type === "object" || isArray && schema.type.includes("object")) && schema.properties === void 0 && schema.patternProperties === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["properties"], void 0, schema, "properties");
|
|
3629
|
+
if (this.options.forceItems === true && (schema.type === "array" || isArray && schema.type.includes("array")) && schema.items === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["items"], void 0, schema, "items");
|
|
3630
|
+
if (this.options.forceMinItems === true && (schema.type === "array" || isArray && schema.type.includes("array")) && schema.minItems === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["minItems"], void 0, schema, "minItems");
|
|
3631
|
+
if (this.options.forceMaxItems === true && (schema.type === "array" || isArray && schema.type.includes("array")) && schema.maxItems === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["maxItems"], void 0, schema, "maxItems");
|
|
3632
|
+
if (this.options.forceMinLength === true && (schema.type === "string" || isArray && schema.type.includes("string")) && schema.minLength === void 0 && schema.format === void 0 && schema.enum === void 0 && schema.pattern === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["minLength"], void 0, schema, "minLength");
|
|
3633
|
+
if (this.options.forceMaxLength === true && (schema.type === "string" || isArray && schema.type.includes("string")) && schema.maxLength === void 0 && schema.format === void 0 && schema.enum === void 0 && schema.pattern === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["maxLength"], void 0, schema, "maxLength");
|
|
3621
3634
|
},
|
|
3622
|
-
allOf
|
|
3623
|
-
if (Array.isArray(schema.allOf)
|
|
3635
|
+
allOf(report, schema) {
|
|
3636
|
+
if (!Array.isArray(schema.allOf)) report.addError("KEYWORD_TYPE_EXPECTED", ["allOf", "array"], void 0, schema, "allOf");
|
|
3624
3637
|
else if (schema.allOf.length === 0) report.addError("KEYWORD_MUST_BE", ["allOf", "an array with at least one element"], void 0, schema, "allOf");
|
|
3625
3638
|
else for (let idx = 0; idx < schema.allOf.length; idx++) {
|
|
3626
3639
|
report.path.push("allOf");
|
|
@@ -3630,8 +3643,8 @@ const SchemaValidators = {
|
|
|
3630
3643
|
report.path.pop();
|
|
3631
3644
|
}
|
|
3632
3645
|
},
|
|
3633
|
-
anyOf
|
|
3634
|
-
if (Array.isArray(schema.anyOf)
|
|
3646
|
+
anyOf(report, schema) {
|
|
3647
|
+
if (!Array.isArray(schema.anyOf)) report.addError("KEYWORD_TYPE_EXPECTED", ["anyOf", "array"], void 0, schema, "anyOf");
|
|
3635
3648
|
else if (schema.anyOf.length === 0) report.addError("KEYWORD_MUST_BE", ["anyOf", "an array with at least one element"], void 0, schema, "anyOf");
|
|
3636
3649
|
else for (let idx = 0; idx < schema.anyOf.length; idx++) {
|
|
3637
3650
|
report.path.push("anyOf");
|
|
@@ -3641,8 +3654,8 @@ const SchemaValidators = {
|
|
|
3641
3654
|
report.path.pop();
|
|
3642
3655
|
}
|
|
3643
3656
|
},
|
|
3644
|
-
oneOf
|
|
3645
|
-
if (Array.isArray(schema.oneOf)
|
|
3657
|
+
oneOf(report, schema) {
|
|
3658
|
+
if (!Array.isArray(schema.oneOf)) report.addError("KEYWORD_TYPE_EXPECTED", ["oneOf", "array"], void 0, schema, "oneOf");
|
|
3646
3659
|
else if (schema.oneOf.length === 0) report.addError("KEYWORD_MUST_BE", ["oneOf", "an array with at least one element"], void 0, schema, "oneOf");
|
|
3647
3660
|
else for (let idx = 0; idx < schema.oneOf.length; idx++) {
|
|
3648
3661
|
report.path.push("oneOf");
|
|
@@ -3652,16 +3665,17 @@ const SchemaValidators = {
|
|
|
3652
3665
|
report.path.pop();
|
|
3653
3666
|
}
|
|
3654
3667
|
},
|
|
3655
|
-
not
|
|
3668
|
+
not(report, schema) {
|
|
3656
3669
|
const notSchema = schema.not;
|
|
3657
|
-
if (!(report.options.version === "draft-04" ? isObject(notSchema) : typeof notSchema === "boolean" || isObject(notSchema)))
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
this.validateSchema(report, notSchema);
|
|
3661
|
-
report.path.pop();
|
|
3670
|
+
if (!(report.options.version === "draft-04" ? isObject(notSchema) : typeof notSchema === "boolean" || isObject(notSchema))) {
|
|
3671
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["not", report.options.version === "draft-04" ? "object" : ["boolean", "object"]], void 0, schema, "not");
|
|
3672
|
+
return;
|
|
3662
3673
|
}
|
|
3674
|
+
report.path.push("not");
|
|
3675
|
+
this.validateSchema(report, notSchema);
|
|
3676
|
+
report.path.pop();
|
|
3663
3677
|
},
|
|
3664
|
-
if
|
|
3678
|
+
if(report, schema) {
|
|
3665
3679
|
if (report.options.version !== "draft-07") return;
|
|
3666
3680
|
const ifSchema = schema.if;
|
|
3667
3681
|
if (!(typeof ifSchema === "boolean" || isObject(ifSchema))) {
|
|
@@ -3672,7 +3686,7 @@ const SchemaValidators = {
|
|
|
3672
3686
|
this.validateSchema(report, ifSchema);
|
|
3673
3687
|
report.path.pop();
|
|
3674
3688
|
},
|
|
3675
|
-
then
|
|
3689
|
+
then(report, schema) {
|
|
3676
3690
|
if (report.options.version !== "draft-07") return;
|
|
3677
3691
|
const thenSchema = schema.then;
|
|
3678
3692
|
if (!(typeof thenSchema === "boolean" || isObject(thenSchema))) {
|
|
@@ -3683,7 +3697,7 @@ const SchemaValidators = {
|
|
|
3683
3697
|
this.validateSchema(report, thenSchema);
|
|
3684
3698
|
report.path.pop();
|
|
3685
3699
|
},
|
|
3686
|
-
else
|
|
3700
|
+
else(report, schema) {
|
|
3687
3701
|
if (report.options.version !== "draft-07") return;
|
|
3688
3702
|
const elseSchema = schema.else;
|
|
3689
3703
|
if (!(typeof elseSchema === "boolean" || isObject(elseSchema))) {
|
|
@@ -3694,21 +3708,22 @@ const SchemaValidators = {
|
|
|
3694
3708
|
this.validateSchema(report, elseSchema);
|
|
3695
3709
|
report.path.pop();
|
|
3696
3710
|
},
|
|
3697
|
-
definitions
|
|
3698
|
-
if (!isObject(schema.definitions))
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3711
|
+
definitions(report, schema) {
|
|
3712
|
+
if (!isObject(schema.definitions)) {
|
|
3713
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["definitions", "object"], void 0, schema, "definitions");
|
|
3714
|
+
return;
|
|
3715
|
+
}
|
|
3716
|
+
const keys = Object.keys(schema.definitions);
|
|
3717
|
+
for (const key of keys) {
|
|
3718
|
+
const val = schema.definitions[key];
|
|
3719
|
+
report.path.push("definitions");
|
|
3720
|
+
report.path.push(key);
|
|
3721
|
+
this.validateSchema(report, val);
|
|
3722
|
+
report.path.pop();
|
|
3723
|
+
report.path.pop();
|
|
3709
3724
|
}
|
|
3710
3725
|
},
|
|
3711
|
-
$defs
|
|
3726
|
+
$defs(report, schema) {
|
|
3712
3727
|
if (report.options.version !== "draft2019-09" && report.options.version !== "draft2020-12") return;
|
|
3713
3728
|
if (!isObject(schema.$defs)) {
|
|
3714
3729
|
report.addError("KEYWORD_TYPE_EXPECTED", ["$defs", "object"], void 0, schema, "$defs");
|
|
@@ -3724,34 +3739,36 @@ const SchemaValidators = {
|
|
|
3724
3739
|
report.path.pop();
|
|
3725
3740
|
}
|
|
3726
3741
|
},
|
|
3727
|
-
format
|
|
3742
|
+
format(report, schema) {
|
|
3728
3743
|
if (this.options.formatAssertions === false) return;
|
|
3729
|
-
if (typeof schema.format !== "string")
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
if (!isFormatSupported(schema.format, this.options.customFormats) && this.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
3744
|
+
if (typeof schema.format !== "string") {
|
|
3745
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["format", "string"], void 0, schema, "format");
|
|
3746
|
+
return;
|
|
3733
3747
|
}
|
|
3748
|
+
const isModernDraft = this.options.version === "draft2019-09" || this.options.version === "draft2020-12";
|
|
3749
|
+
if (!isFormatSupported(schema.format, this.options.customFormats) && this.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
3734
3750
|
},
|
|
3735
|
-
contentEncoding
|
|
3751
|
+
contentEncoding(report, schema) {
|
|
3736
3752
|
if (report.options.version !== "draft-07") return;
|
|
3737
3753
|
if (typeof schema.contentEncoding !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["contentEncoding", "string"], void 0, schema, "contentEncoding");
|
|
3738
3754
|
},
|
|
3739
|
-
contentMediaType
|
|
3755
|
+
contentMediaType(report, schema) {
|
|
3740
3756
|
if (report.options.version !== "draft-07") return;
|
|
3741
3757
|
if (typeof schema.contentMediaType !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["contentMediaType", "string"], void 0, schema, "contentMediaType");
|
|
3742
3758
|
},
|
|
3743
|
-
id
|
|
3759
|
+
id(report, schema) {
|
|
3744
3760
|
if (typeof schema.id !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["id", "string"], void 0, schema, "id");
|
|
3745
3761
|
},
|
|
3746
|
-
title
|
|
3762
|
+
title(report, schema) {
|
|
3747
3763
|
if (typeof schema.title !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["title", "string"], void 0, schema, "title");
|
|
3748
3764
|
},
|
|
3749
|
-
description
|
|
3765
|
+
description(report, schema) {
|
|
3750
3766
|
if (typeof schema.description !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["description", "string"], void 0, schema, "description");
|
|
3751
3767
|
},
|
|
3752
|
-
default
|
|
3768
|
+
default() {}
|
|
3753
3769
|
};
|
|
3754
3770
|
var SchemaValidator = class {
|
|
3771
|
+
validator;
|
|
3755
3772
|
constructor(validator) {
|
|
3756
3773
|
this.validator = validator;
|
|
3757
3774
|
}
|
|
@@ -3771,18 +3788,17 @@ var SchemaValidator = class {
|
|
|
3771
3788
|
if (hasParentSchema) {
|
|
3772
3789
|
if (schema.__$schemaResolved && schema.__$schemaResolved !== schema) {
|
|
3773
3790
|
const subReport = new Report(report);
|
|
3774
|
-
if (validate
|
|
3791
|
+
if (!validate(this.validator, subReport, schema.__$schemaResolved, schema)) report.addError("PARENT_SCHEMA_VALIDATION_FAILED", void 0, subReport, schema, "$schema");
|
|
3775
3792
|
} else if (this.validator.options.ignoreUnresolvableReferences !== true) report.addError("REF_UNRESOLVED", [schema.$schema], void 0, schema, "$schema");
|
|
3776
3793
|
}
|
|
3777
3794
|
if (this.validator.options.noTypeless === true) {
|
|
3778
3795
|
if (schema.type !== void 0) {
|
|
3779
|
-
|
|
3780
|
-
if (Array.isArray(schema.anyOf)) schemas = schemas.concat(schema.anyOf);
|
|
3781
|
-
if (Array.isArray(schema.oneOf)) schemas = schemas.concat(schema.oneOf);
|
|
3782
|
-
if (Array.isArray(schema.allOf)) schemas = schemas.concat(schema.allOf);
|
|
3783
|
-
schemas.forEach(function(sch) {
|
|
3796
|
+
const inheritType = (sch) => {
|
|
3784
3797
|
if (!sch.type) sch.type = schema.type;
|
|
3785
|
-
}
|
|
3798
|
+
};
|
|
3799
|
+
if (Array.isArray(schema.anyOf)) for (let i = 0; i < schema.anyOf.length; i++) inheritType(schema.anyOf[i]);
|
|
3800
|
+
if (Array.isArray(schema.oneOf)) for (let i = 0; i < schema.oneOf.length; i++) inheritType(schema.oneOf[i]);
|
|
3801
|
+
if (Array.isArray(schema.allOf)) for (let i = 0; i < schema.allOf.length; i++) inheritType(schema.allOf[i]);
|
|
3786
3802
|
}
|
|
3787
3803
|
if (schema.enum === void 0 && schema.type === void 0 && schema.anyOf === void 0 && schema.oneOf === void 0 && schema.not === void 0 && schema.$ref === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["type"], void 0, schema, "type");
|
|
3788
3804
|
}
|
|
@@ -3790,9 +3806,7 @@ var SchemaValidator = class {
|
|
|
3790
3806
|
for (const key of keys) {
|
|
3791
3807
|
if (key.startsWith("__")) continue;
|
|
3792
3808
|
if (Object.hasOwn(SchemaValidators, key)) SchemaValidators[key].call(this, report, schema);
|
|
3793
|
-
else if (!hasParentSchema)
|
|
3794
|
-
if (this.validator.options.noExtraKeywords === true) report.addError("KEYWORD_UNEXPECTED", [key], void 0, schema, void 0);
|
|
3795
|
-
}
|
|
3809
|
+
else if (!hasParentSchema && this.validator.options.noExtraKeywords === true) report.addError("KEYWORD_UNEXPECTED", [key], void 0, schema);
|
|
3796
3810
|
}
|
|
3797
3811
|
if (this.validator.options.pedanticCheck === true) {
|
|
3798
3812
|
if (schema.enum) {
|
|
@@ -3802,14 +3816,14 @@ var SchemaValidator = class {
|
|
|
3802
3816
|
report.path.push("enum");
|
|
3803
3817
|
for (let idx = 0; idx < schema.enum.length; idx++) {
|
|
3804
3818
|
report.path.push(idx);
|
|
3805
|
-
validate
|
|
3819
|
+
validate(this.validator, report, tmpSchema, schema.enum[idx]);
|
|
3806
3820
|
report.path.pop();
|
|
3807
3821
|
}
|
|
3808
3822
|
report.path.pop();
|
|
3809
3823
|
}
|
|
3810
3824
|
if (schema.default) {
|
|
3811
3825
|
report.path.push("default");
|
|
3812
|
-
validate
|
|
3826
|
+
validate(this.validator, report, schema, schema.default);
|
|
3813
3827
|
report.path.pop();
|
|
3814
3828
|
}
|
|
3815
3829
|
}
|
|
@@ -3846,7 +3860,7 @@ var ZSchemaBase = class {
|
|
|
3846
3860
|
* create a circular dependency).
|
|
3847
3861
|
*/
|
|
3848
3862
|
_jsonValidate(report, schema, json) {
|
|
3849
|
-
return validate
|
|
3863
|
+
return validate(this, report, schema, json);
|
|
3850
3864
|
}
|
|
3851
3865
|
getDefaultSchemaId() {
|
|
3852
3866
|
return this.options.version && this.options.version !== "none" ? VERSION_SCHEMA_URL_MAPPING[this.options.version] : VERSION_SCHEMA_URL_MAPPING[defaultOptions.version];
|
|
@@ -3859,9 +3873,9 @@ var ZSchemaBase = class {
|
|
|
3859
3873
|
if (!options) options = {};
|
|
3860
3874
|
this.validateOptions = options;
|
|
3861
3875
|
if (typeof schema !== "string" && typeof schema !== "boolean" && !isObject(schema)) {
|
|
3862
|
-
const e = /* @__PURE__ */ new Error(
|
|
3876
|
+
const e = /* @__PURE__ */ new Error(`Invalid .validate call - schema must be a string or object but ${whatIs(schema)} was passed!`);
|
|
3863
3877
|
if (callback) {
|
|
3864
|
-
setTimeout(
|
|
3878
|
+
setTimeout(() => {
|
|
3865
3879
|
callback(e, false);
|
|
3866
3880
|
}, 0);
|
|
3867
3881
|
return;
|
|
@@ -3876,9 +3890,9 @@ var ZSchemaBase = class {
|
|
|
3876
3890
|
const schemaName = schema;
|
|
3877
3891
|
_schema = this.scache.getSchema(report, schemaName);
|
|
3878
3892
|
if (!_schema) {
|
|
3879
|
-
const e = /* @__PURE__ */ new Error(
|
|
3893
|
+
const e = /* @__PURE__ */ new Error(`Schema with id '${schemaName}' wasn't found in the validator cache!`);
|
|
3880
3894
|
if (callback) {
|
|
3881
|
-
setTimeout(
|
|
3895
|
+
setTimeout(() => {
|
|
3882
3896
|
callback(e, false);
|
|
3883
3897
|
}, 0);
|
|
3884
3898
|
return;
|
|
@@ -3896,9 +3910,9 @@ var ZSchemaBase = class {
|
|
|
3896
3910
|
report.rootSchema = _schema;
|
|
3897
3911
|
_schema = get(_schema, options.schemaPath);
|
|
3898
3912
|
if (!_schema) {
|
|
3899
|
-
const e = /* @__PURE__ */ new Error(
|
|
3913
|
+
const e = /* @__PURE__ */ new Error(`Schema path '${options.schemaPath}' wasn't found in the schema!`);
|
|
3900
3914
|
if (callback) {
|
|
3901
|
-
setTimeout(
|
|
3915
|
+
setTimeout(() => {
|
|
3902
3916
|
callback(e, false);
|
|
3903
3917
|
}, 0);
|
|
3904
3918
|
return;
|
|
@@ -3906,7 +3920,7 @@ var ZSchemaBase = class {
|
|
|
3906
3920
|
throw e;
|
|
3907
3921
|
}
|
|
3908
3922
|
}
|
|
3909
|
-
if (!foundError) validate
|
|
3923
|
+
if (!foundError) validate(this, report, _schema, json);
|
|
3910
3924
|
if (callback) {
|
|
3911
3925
|
report.processAsyncTasks(this.options.asyncTimeout, callback);
|
|
3912
3926
|
return;
|
|
@@ -3977,8 +3991,8 @@ var ZSchemaBase = class {
|
|
|
3977
3991
|
if (!err) return [];
|
|
3978
3992
|
const details = err.details || [];
|
|
3979
3993
|
const missingRefs = [];
|
|
3980
|
-
function collect(
|
|
3981
|
-
for (const detail of
|
|
3994
|
+
function collect(items) {
|
|
3995
|
+
for (const detail of items) {
|
|
3982
3996
|
if (detail.code === "UNRESOLVABLE_REFERENCE" || detail.code === "SCHEMA_NOT_REACHABLE") missingRefs.push(detail.params[0]);
|
|
3983
3997
|
if (detail.inner) collect(detail.inner);
|
|
3984
3998
|
}
|
|
@@ -3994,9 +4008,13 @@ var ZSchemaBase = class {
|
|
|
3994
4008
|
getMissingRemoteReferences(err) {
|
|
3995
4009
|
const missingReferences = this.getMissingReferences(err);
|
|
3996
4010
|
const missingRemoteReferences = [];
|
|
4011
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3997
4012
|
for (const ref of missingReferences) {
|
|
3998
4013
|
const remoteReference = getRemotePath(ref);
|
|
3999
|
-
if (remoteReference && !
|
|
4014
|
+
if (remoteReference && !seen.has(remoteReference)) {
|
|
4015
|
+
seen.add(remoteReference);
|
|
4016
|
+
missingRemoteReferences.push(remoteReference);
|
|
4017
|
+
}
|
|
4000
4018
|
}
|
|
4001
4019
|
return missingRemoteReferences;
|
|
4002
4020
|
}
|
|
@@ -4009,24 +4027,25 @@ var ZSchemaBase = class {
|
|
|
4009
4027
|
getResolvedSchema(schemaId) {
|
|
4010
4028
|
const report = new Report(this.options);
|
|
4011
4029
|
const schema = this.scache.getSchemaByUri(report, schemaId);
|
|
4012
|
-
if (!schema) return
|
|
4030
|
+
if (!schema) return;
|
|
4013
4031
|
const clonedSchema = deepClone(schema, this.options.maxRecursionDepth);
|
|
4014
4032
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
4015
|
-
const cleanup =
|
|
4016
|
-
|
|
4017
|
-
const typeOf = whatIs(schema);
|
|
4033
|
+
const cleanup = (node) => {
|
|
4034
|
+
const typeOf = whatIs(node);
|
|
4018
4035
|
if (typeOf !== "object" && typeOf !== "array") return;
|
|
4019
|
-
if (visited.has(
|
|
4020
|
-
visited.add(
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
const
|
|
4024
|
-
|
|
4025
|
-
delete
|
|
4026
|
-
|
|
4036
|
+
if (visited.has(node)) return;
|
|
4037
|
+
visited.add(node);
|
|
4038
|
+
const schemaNode = node;
|
|
4039
|
+
if (schemaNode.$ref && schemaNode.__$refResolved) {
|
|
4040
|
+
const from = schemaNode.__$refResolved;
|
|
4041
|
+
const to = schemaNode;
|
|
4042
|
+
delete schemaNode.$ref;
|
|
4043
|
+
delete schemaNode.__$refResolved;
|
|
4044
|
+
for (const key in from) if (Object.hasOwn(from, key)) copyProp(from, to, key);
|
|
4027
4045
|
}
|
|
4028
|
-
|
|
4029
|
-
|
|
4046
|
+
const record = node;
|
|
4047
|
+
for (const key in record) if (Object.hasOwn(record, key)) if (isInternalKey(key)) delete record[key];
|
|
4048
|
+
else cleanup(record[key]);
|
|
4030
4049
|
};
|
|
4031
4050
|
cleanup(clonedSchema);
|
|
4032
4051
|
return clonedSchema;
|
|
@@ -4035,24 +4054,20 @@ var ZSchemaBase = class {
|
|
|
4035
4054
|
//#endregion
|
|
4036
4055
|
//#region src/z-schema.ts
|
|
4037
4056
|
var ZSchema = class ZSchema extends ZSchemaBase {
|
|
4038
|
-
/** @internal Use ZSchema.create() instead. */
|
|
4039
|
-
constructor(options, token) {
|
|
4040
|
-
super(options, token);
|
|
4041
|
-
}
|
|
4042
4057
|
/**
|
|
4043
4058
|
* Register a global format validator available to all instances.
|
|
4044
4059
|
* @param name - The format name (e.g. `'email'`, `'date'`).
|
|
4045
4060
|
* @param validatorFunction - A sync or async function `(value: unknown) => boolean | Promise<boolean>`.
|
|
4046
4061
|
*/
|
|
4047
4062
|
static registerFormat(name, validatorFunction) {
|
|
4048
|
-
|
|
4063
|
+
registerFormat(name, validatorFunction);
|
|
4049
4064
|
}
|
|
4050
4065
|
/**
|
|
4051
4066
|
* Remove a globally registered format validator.
|
|
4052
4067
|
* @param name - The format name to unregister.
|
|
4053
4068
|
*/
|
|
4054
4069
|
static unregisterFormat(name) {
|
|
4055
|
-
|
|
4070
|
+
unregisterFormat(name);
|
|
4056
4071
|
}
|
|
4057
4072
|
/** Returns the names of all globally registered format validators. */
|
|
4058
4073
|
static getRegisteredFormats() {
|
|
@@ -4081,7 +4096,7 @@ var ZSchema = class ZSchema extends ZSchemaBase {
|
|
|
4081
4096
|
* @param schemaReader - A function `(uri: string) => JsonSchema | undefined`, or `undefined` to clear.
|
|
4082
4097
|
*/
|
|
4083
4098
|
static setSchemaReader(schemaReader) {
|
|
4084
|
-
|
|
4099
|
+
setSchemaReader(schemaReader);
|
|
4085
4100
|
}
|
|
4086
4101
|
static schemaSymbol = schemaSymbol;
|
|
4087
4102
|
static jsonSymbol = jsonSymbol;
|
|
@@ -4117,10 +4132,10 @@ var ZSchema = class ZSchema extends ZSchemaBase {
|
|
|
4117
4132
|
try {
|
|
4118
4133
|
this._validate(json, schema, options ?? {});
|
|
4119
4134
|
return { valid: true };
|
|
4120
|
-
} catch (
|
|
4135
|
+
} catch (error) {
|
|
4121
4136
|
return {
|
|
4122
4137
|
valid: false,
|
|
4123
|
-
err
|
|
4138
|
+
err: error
|
|
4124
4139
|
};
|
|
4125
4140
|
}
|
|
4126
4141
|
}
|
|
@@ -4135,9 +4150,12 @@ var ZSchema = class ZSchema extends ZSchemaBase {
|
|
|
4135
4150
|
validateAsync(json, schema, options) {
|
|
4136
4151
|
return new Promise((resolve, reject) => {
|
|
4137
4152
|
try {
|
|
4138
|
-
this._validate(json, schema, options || {}, (err, valid) =>
|
|
4139
|
-
|
|
4140
|
-
|
|
4153
|
+
this._validate(json, schema, options || {}, (err, valid) => {
|
|
4154
|
+
if (err || !valid) reject(err ?? /* @__PURE__ */ new Error("Validation failed"));
|
|
4155
|
+
else resolve(valid);
|
|
4156
|
+
});
|
|
4157
|
+
} catch (error) {
|
|
4158
|
+
reject(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
4141
4159
|
}
|
|
4142
4160
|
});
|
|
4143
4161
|
}
|
|
@@ -4158,10 +4176,10 @@ var ZSchema = class ZSchema extends ZSchemaBase {
|
|
|
4158
4176
|
err
|
|
4159
4177
|
});
|
|
4160
4178
|
});
|
|
4161
|
-
} catch (
|
|
4179
|
+
} catch (error) {
|
|
4162
4180
|
resolve({
|
|
4163
4181
|
valid: false,
|
|
4164
|
-
err
|
|
4182
|
+
err: error
|
|
4165
4183
|
});
|
|
4166
4184
|
}
|
|
4167
4185
|
});
|
|
@@ -4184,10 +4202,10 @@ var ZSchema = class ZSchema extends ZSchemaBase {
|
|
|
4184
4202
|
try {
|
|
4185
4203
|
this._validateSchema(schemaOrArr);
|
|
4186
4204
|
return { valid: true };
|
|
4187
|
-
} catch (
|
|
4205
|
+
} catch (error) {
|
|
4188
4206
|
return {
|
|
4189
4207
|
valid: false,
|
|
4190
|
-
err
|
|
4208
|
+
err: error
|
|
4191
4209
|
};
|
|
4192
4210
|
}
|
|
4193
4211
|
}
|
|
@@ -4197,10 +4215,6 @@ var ZSchema = class ZSchema extends ZSchemaBase {
|
|
|
4197
4215
|
* Created via `ZSchema.create({ safe: true })`.
|
|
4198
4216
|
*/
|
|
4199
4217
|
var ZSchemaSafe = class extends ZSchemaBase {
|
|
4200
|
-
/** @internal Use ZSchema.create() instead. */
|
|
4201
|
-
constructor(options, token) {
|
|
4202
|
-
super(options, token);
|
|
4203
|
-
}
|
|
4204
4218
|
/**
|
|
4205
4219
|
* Validate JSON data against a schema.
|
|
4206
4220
|
* @param json - The data to validate.
|
|
@@ -4212,10 +4226,10 @@ var ZSchemaSafe = class extends ZSchemaBase {
|
|
|
4212
4226
|
try {
|
|
4213
4227
|
this._validate(json, schema, options);
|
|
4214
4228
|
return { valid: true };
|
|
4215
|
-
} catch (
|
|
4229
|
+
} catch (error) {
|
|
4216
4230
|
return {
|
|
4217
4231
|
valid: false,
|
|
4218
|
-
err
|
|
4232
|
+
err: error
|
|
4219
4233
|
};
|
|
4220
4234
|
}
|
|
4221
4235
|
}
|
|
@@ -4228,10 +4242,10 @@ var ZSchemaSafe = class extends ZSchemaBase {
|
|
|
4228
4242
|
try {
|
|
4229
4243
|
this._validateSchema(schemaOrArr);
|
|
4230
4244
|
return { valid: true };
|
|
4231
|
-
} catch (
|
|
4245
|
+
} catch (error) {
|
|
4232
4246
|
return {
|
|
4233
4247
|
valid: false,
|
|
4234
|
-
err
|
|
4248
|
+
err: error
|
|
4235
4249
|
};
|
|
4236
4250
|
}
|
|
4237
4251
|
}
|
|
@@ -4241,10 +4255,6 @@ var ZSchemaSafe = class extends ZSchemaBase {
|
|
|
4241
4255
|
* Created via `ZSchema.create({ async: true })`.
|
|
4242
4256
|
*/
|
|
4243
4257
|
var ZSchemaAsync = class extends ZSchemaBase {
|
|
4244
|
-
/** @internal Use ZSchema.create() instead. */
|
|
4245
|
-
constructor(options, token) {
|
|
4246
|
-
super(options, token);
|
|
4247
|
-
}
|
|
4248
4258
|
/**
|
|
4249
4259
|
* Validate JSON data against a schema asynchronously.
|
|
4250
4260
|
* @param json - The data to validate.
|
|
@@ -4256,9 +4266,12 @@ var ZSchemaAsync = class extends ZSchemaBase {
|
|
|
4256
4266
|
validate(json, schema, options = {}) {
|
|
4257
4267
|
return new Promise((resolve, reject) => {
|
|
4258
4268
|
try {
|
|
4259
|
-
this._validate(json, schema, options, (err, valid) =>
|
|
4260
|
-
|
|
4261
|
-
|
|
4269
|
+
this._validate(json, schema, options, (err, valid) => {
|
|
4270
|
+
if (err || !valid) reject(err ?? /* @__PURE__ */ new Error("Validation failed"));
|
|
4271
|
+
else resolve(valid);
|
|
4272
|
+
});
|
|
4273
|
+
} catch (error) {
|
|
4274
|
+
reject(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
4262
4275
|
}
|
|
4263
4276
|
});
|
|
4264
4277
|
}
|
|
@@ -4277,10 +4290,6 @@ var ZSchemaAsync = class extends ZSchemaBase {
|
|
|
4277
4290
|
* Created via `ZSchema.create({ async: true, safe: true })`.
|
|
4278
4291
|
*/
|
|
4279
4292
|
var ZSchemaAsyncSafe = class extends ZSchemaBase {
|
|
4280
|
-
/** @internal Use ZSchema.create() instead. */
|
|
4281
|
-
constructor(options, token) {
|
|
4282
|
-
super(options, token);
|
|
4283
|
-
}
|
|
4284
4293
|
/**
|
|
4285
4294
|
* Validate JSON data against a schema asynchronously.
|
|
4286
4295
|
* The promise always resolves (never rejects).
|
|
@@ -4298,10 +4307,10 @@ var ZSchemaAsyncSafe = class extends ZSchemaBase {
|
|
|
4298
4307
|
err
|
|
4299
4308
|
});
|
|
4300
4309
|
});
|
|
4301
|
-
} catch (
|
|
4310
|
+
} catch (error) {
|
|
4302
4311
|
resolve({
|
|
4303
4312
|
valid: false,
|
|
4304
|
-
err
|
|
4313
|
+
err: error
|
|
4305
4314
|
});
|
|
4306
4315
|
}
|
|
4307
4316
|
});
|
|
@@ -4315,10 +4324,10 @@ var ZSchemaAsyncSafe = class extends ZSchemaBase {
|
|
|
4315
4324
|
try {
|
|
4316
4325
|
this._validateSchema(schemaOrArr);
|
|
4317
4326
|
return { valid: true };
|
|
4318
|
-
} catch (
|
|
4327
|
+
} catch (error) {
|
|
4319
4328
|
return {
|
|
4320
4329
|
valid: false,
|
|
4321
|
-
err
|
|
4330
|
+
err: error
|
|
4322
4331
|
};
|
|
4323
4332
|
}
|
|
4324
4333
|
}
|