z-schema 12.2.0 → 12.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/z-schema +1 -1
- package/cjs/{index.js → index.cjs} +838 -707
- 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} +60 -43
- 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} +6 -5
- package/dist/{json-validation.mjs → json-validation.js} +144 -127
- package/dist/{report.d.mts → report.d.ts} +8 -9
- package/dist/{report.mjs → report.js} +28 -31
- package/dist/{schema-cache.d.mts → schema-cache.d.ts} +5 -5
- 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} +101 -79
- 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.js +176 -0
- package/dist/utils/{json.mjs → json.js} +13 -8
- package/dist/utils/{schema-regex.mjs → schema-regex.js} +5 -5
- package/dist/utils/{time.mjs → time.js} +8 -8
- 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} +5 -5
- package/dist/validation/{shared.mjs → shared.js} +15 -12
- package/dist/validation/{string.mjs → string.js} +35 -35
- 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} +5 -5
- 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} +38 -48
- package/package.json +24 -25
- package/src/errors.ts +1 -2
- package/src/format-validators.ts +173 -67
- 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 +257 -31
- 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 +8 -7
- 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 +36 -42
- 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 +853 -715
- package/umd/ZSchema.min.js +2 -2
- package/umd/package.json +3 -0
- package/dist/utils/hostname.mjs +0 -75
- 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
package/umd/ZSchema.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
10
|
var __getProtoOf = Object.getPrototypeOf;
|
|
11
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
12
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
13
13
|
var __copyProps = (to, from, except, desc) => {
|
|
14
14
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
15
15
|
key = keys[i];
|
|
@@ -25,17 +25,6 @@
|
|
|
25
25
|
enumerable: true
|
|
26
26
|
}) : target, mod));
|
|
27
27
|
//#endregion
|
|
28
|
-
//#region src/utils/uri.ts
|
|
29
|
-
const getQueryPath = (uri) => {
|
|
30
|
-
const io = uri.indexOf("#");
|
|
31
|
-
return io === -1 ? void 0 : uri.slice(io + 1);
|
|
32
|
-
};
|
|
33
|
-
const getRemotePath = (uri) => {
|
|
34
|
-
const io = uri.indexOf("#");
|
|
35
|
-
return io === -1 ? uri : uri.slice(0, io);
|
|
36
|
-
};
|
|
37
|
-
const isAbsoluteUri = (uri) => /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(uri);
|
|
38
|
-
//#endregion
|
|
39
28
|
//#region src/utils/constants.ts
|
|
40
29
|
/**
|
|
41
30
|
* Maximum allowed value for {@link ZSchemaOptions.asyncTimeout} in milliseconds.
|
|
@@ -51,6 +40,17 @@
|
|
|
51
40
|
*/
|
|
52
41
|
const MAX_SCHEMA_REGEX_LENGTH = 1e4;
|
|
53
42
|
//#endregion
|
|
43
|
+
//#region src/utils/uri.ts
|
|
44
|
+
const getQueryPath = (uri) => {
|
|
45
|
+
const io = uri.indexOf("#");
|
|
46
|
+
return io === -1 ? void 0 : uri.slice(io + 1);
|
|
47
|
+
};
|
|
48
|
+
const getRemotePath = (uri) => {
|
|
49
|
+
const io = uri.indexOf("#");
|
|
50
|
+
return io === -1 ? uri : uri.slice(0, io);
|
|
51
|
+
};
|
|
52
|
+
const isAbsoluteUri = (uri) => /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(uri);
|
|
53
|
+
//#endregion
|
|
54
54
|
//#region src/utils/what-is.ts
|
|
55
55
|
const whatIs = (what) => {
|
|
56
56
|
if (typeof what === "object") {
|
|
@@ -59,8 +59,7 @@
|
|
|
59
59
|
return "object";
|
|
60
60
|
}
|
|
61
61
|
if (typeof what === "number") {
|
|
62
|
-
if (Number.isFinite(what))
|
|
63
|
-
else return "number";
|
|
62
|
+
if (Number.isFinite(what)) return what % 1 === 0 ? "integer" : "number";
|
|
64
63
|
if (Number.isNaN(what)) return "not-a-number";
|
|
65
64
|
return "unknown-number";
|
|
66
65
|
}
|
|
@@ -72,18 +71,12 @@
|
|
|
72
71
|
function isInteger(value) {
|
|
73
72
|
return typeof value === "number" && Number.isFinite(value) && value % 1 === 0;
|
|
74
73
|
}
|
|
75
|
-
|
|
76
|
-
//#region src/json-schema.ts
|
|
77
|
-
/**
|
|
78
|
-
* Keywords whose values are not JSON Schema sub-schemas and must not be
|
|
79
|
-
* traversed during schema walking (id collection, reference collection, etc.).
|
|
80
|
-
*/
|
|
81
|
-
const NON_SCHEMA_KEYWORDS = [
|
|
74
|
+
const NON_SCHEMA_KEYWORDS_SET = /* @__PURE__ */ new Set([
|
|
82
75
|
"enum",
|
|
83
76
|
"const",
|
|
84
77
|
"default",
|
|
85
78
|
"examples"
|
|
86
|
-
];
|
|
79
|
+
]);
|
|
87
80
|
/** Returns true if the key is an internal z-schema property (prefixed with `__$`). */
|
|
88
81
|
const isInternalKey = (key) => key.startsWith("__$");
|
|
89
82
|
const getId = (schema) => {
|
|
@@ -104,7 +97,7 @@
|
|
|
104
97
|
} catch {}
|
|
105
98
|
}
|
|
106
99
|
if (!targetBaseUri || nextBaseUri === targetBaseUri) {
|
|
107
|
-
if (schemaId && (schemaId === id || schemaId
|
|
100
|
+
if (schemaId && (schemaId === id || schemaId.startsWith("#") && schemaId.slice(1) === id)) return schema;
|
|
108
101
|
if (schema.$anchor === id || schema.$dynamicAnchor === id) return schema;
|
|
109
102
|
}
|
|
110
103
|
let result;
|
|
@@ -116,7 +109,7 @@
|
|
|
116
109
|
const keys = Object.keys(schema);
|
|
117
110
|
for (let i = keys.length - 1; i >= 0; i--) {
|
|
118
111
|
const k = keys[i];
|
|
119
|
-
if (isInternalKey(k) ||
|
|
112
|
+
if (isInternalKey(k) || NON_SCHEMA_KEYWORDS_SET.has(k)) continue;
|
|
120
113
|
result = findId(schema[k], id, targetBaseUri, nextBaseUri, maxDepth, _depth + 1);
|
|
121
114
|
if (result) return result;
|
|
122
115
|
}
|
|
@@ -177,11 +170,10 @@
|
|
|
177
170
|
MAX_RECURSION_DEPTH_EXCEEDED: "Maximum recursion depth ({0}) exceeded. If your schema or data is deeply nested and valid, increase the maxRecursionDepth option."
|
|
178
171
|
};
|
|
179
172
|
var ValidateError = class extends Error {
|
|
180
|
-
name;
|
|
173
|
+
name = "ValidateError";
|
|
181
174
|
details;
|
|
182
175
|
constructor(message, details) {
|
|
183
176
|
super(message);
|
|
184
|
-
this.name = "z-schema validation error";
|
|
185
177
|
this.details = details;
|
|
186
178
|
}
|
|
187
179
|
};
|
|
@@ -202,49 +194,48 @@
|
|
|
202
194
|
//#region src/utils/clone.ts
|
|
203
195
|
const shallowClone = (src) => {
|
|
204
196
|
if (src == null || typeof src !== "object") return src;
|
|
205
|
-
let res;
|
|
206
197
|
if (Array.isArray(src)) {
|
|
207
|
-
res = [];
|
|
198
|
+
const res = [];
|
|
208
199
|
for (let i = 0; i < src.length; i++) res[i] = src[i];
|
|
209
|
-
|
|
210
|
-
res = {};
|
|
211
|
-
const keys = Object.keys(src).sort();
|
|
212
|
-
for (const key of keys) copyProp(src, res, key);
|
|
200
|
+
return res;
|
|
213
201
|
}
|
|
202
|
+
const res = {};
|
|
203
|
+
const keys = Object.keys(src).sort();
|
|
204
|
+
for (let i = 0; i < keys.length; i++) copyProp(src, res, keys[i]);
|
|
214
205
|
return res;
|
|
215
206
|
};
|
|
216
207
|
const deepClone = (src, maxDepth = 100) => {
|
|
217
208
|
let vidx = 0;
|
|
218
209
|
const visited = /* @__PURE__ */ new Map();
|
|
219
210
|
const cloned = [];
|
|
220
|
-
const cloneDeepInner = (
|
|
221
|
-
if (typeof
|
|
211
|
+
const cloneDeepInner = (node, _depth) => {
|
|
212
|
+
if (typeof node !== "object" || node === null) return node;
|
|
222
213
|
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.`);
|
|
223
|
-
|
|
224
|
-
const cidx = visited.get(src);
|
|
214
|
+
const cidx = visited.get(node);
|
|
225
215
|
if (cidx !== void 0) return cloned[cidx];
|
|
226
|
-
visited.set(
|
|
227
|
-
if (Array.isArray(
|
|
228
|
-
res = [];
|
|
229
|
-
cloned.push(res);
|
|
230
|
-
for (let i = 0; i < src.length; i++) res[i] = cloneDeepInner(src[i], _depth + 1);
|
|
231
|
-
} else {
|
|
232
|
-
res = {};
|
|
216
|
+
visited.set(node, vidx++);
|
|
217
|
+
if (Array.isArray(node)) {
|
|
218
|
+
const res = [];
|
|
233
219
|
cloned.push(res);
|
|
234
|
-
|
|
235
|
-
|
|
220
|
+
for (let i = 0; i < node.length; i++) res[i] = cloneDeepInner(node[i], _depth + 1);
|
|
221
|
+
return res;
|
|
236
222
|
}
|
|
223
|
+
const res = {};
|
|
224
|
+
cloned.push(res);
|
|
225
|
+
const keys = Object.keys(node).sort();
|
|
226
|
+
for (let i = 0; i < keys.length; i++) copyProp(node, res, keys[i], (v) => cloneDeepInner(v, _depth + 1));
|
|
237
227
|
return res;
|
|
238
228
|
};
|
|
239
229
|
return cloneDeepInner(src, 0);
|
|
240
230
|
};
|
|
241
231
|
//#endregion
|
|
242
232
|
//#region src/utils/json.ts
|
|
233
|
+
const sortedKeys = (obj) => Object.keys(obj).sort();
|
|
243
234
|
const areEqual = (json1, json2, options, _depth = 0) => {
|
|
244
235
|
const caseInsensitiveComparison = options?.caseInsensitiveComparison || false;
|
|
245
236
|
const maxDepth = options?.maxDepth ?? 100;
|
|
246
237
|
if (json1 === json2) return true;
|
|
247
|
-
if (caseInsensitiveComparison
|
|
238
|
+
if (caseInsensitiveComparison && typeof json1 === "string" && typeof json2 === "string" && json1.toUpperCase() === json2.toUpperCase()) return true;
|
|
248
239
|
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.`);
|
|
249
240
|
let i, len;
|
|
250
241
|
if (Array.isArray(json1) && Array.isArray(json2)) {
|
|
@@ -255,20 +246,24 @@
|
|
|
255
246
|
}
|
|
256
247
|
if (isObject(json1) && isObject(json2)) {
|
|
257
248
|
const keys1 = sortedKeys(json1);
|
|
258
|
-
|
|
249
|
+
const keys2 = sortedKeys(json2);
|
|
250
|
+
if (!areEqual(keys1, keys2, options, _depth + 1)) return false;
|
|
259
251
|
len = keys1.length;
|
|
260
252
|
for (i = 0; i < len; i++) if (!areEqual(json1[keys1[i]], json2[keys1[i]], options, _depth + 1)) return false;
|
|
261
253
|
return true;
|
|
262
254
|
}
|
|
263
255
|
return false;
|
|
264
256
|
};
|
|
265
|
-
const decodeJSONPointer = (str) =>
|
|
266
|
-
return decodeURIComponent(str).replace(/~[0-1]/g, (x) => x === "~1" ? "/" : "~");
|
|
267
|
-
};
|
|
268
|
-
const sortedKeys = (obj) => Object.keys(obj).sort();
|
|
257
|
+
const decodeJSONPointer = (str) => decodeURIComponent(str).replaceAll(/~[0-1]/g, (x) => x === "~1" ? "/" : "~");
|
|
269
258
|
const get = (obj, path) => {
|
|
270
259
|
if (typeof path === "string") path = path.split(".");
|
|
271
|
-
|
|
260
|
+
let acc = obj;
|
|
261
|
+
for (let i = 0; i < path.length; i++) {
|
|
262
|
+
const key = path[i];
|
|
263
|
+
if (acc && acc[key] !== void 0) acc = acc[key];
|
|
264
|
+
else return;
|
|
265
|
+
}
|
|
266
|
+
return acc;
|
|
272
267
|
};
|
|
273
268
|
//#endregion
|
|
274
269
|
//#region src/utils/symbols.ts
|
|
@@ -298,8 +293,8 @@
|
|
|
298
293
|
if (parentOrOptions instanceof Report) {
|
|
299
294
|
this.reportOptions = reportOptionsOrValidate || {};
|
|
300
295
|
this.validateOptions = validateOptions || parentOrOptions.validateOptions;
|
|
301
|
-
this.__$recursiveAnchorStack =
|
|
302
|
-
this.__$dynamicScopeStack =
|
|
296
|
+
this.__$recursiveAnchorStack = parentOrOptions.__$recursiveAnchorStack.slice();
|
|
297
|
+
this.__$dynamicScopeStack = parentOrOptions.__$dynamicScopeStack.slice();
|
|
303
298
|
this.__validationResultCache = parentOrOptions.__validationResultCache;
|
|
304
299
|
} else {
|
|
305
300
|
this.reportOptions = {};
|
|
@@ -382,30 +377,24 @@
|
|
|
382
377
|
setTimeout(checkTimeout, ASYNC_TIMEOUT_POLL_MS);
|
|
383
378
|
}
|
|
384
379
|
getPath(returnPathAsString) {
|
|
385
|
-
|
|
386
|
-
if (
|
|
387
|
-
path = path.concat(this.path);
|
|
388
|
-
if (returnPathAsString !== true) return "#/" + path.map(function(segment) {
|
|
380
|
+
const path = this.parentReport ? this.parentReport.path.concat(this.path) : this.path.slice();
|
|
381
|
+
if (returnPathAsString !== true) return `#/${path.map((segment) => {
|
|
389
382
|
segment = segment.toString();
|
|
390
|
-
if (isAbsoluteUri(segment)) return
|
|
391
|
-
return segment.
|
|
392
|
-
}).join("/")
|
|
383
|
+
if (isAbsoluteUri(segment)) return `uri(${segment})`;
|
|
384
|
+
return segment.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
385
|
+
}).join("/")}`;
|
|
393
386
|
return path;
|
|
394
387
|
}
|
|
395
388
|
getSchemaPath() {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
schemaPath = schemaPath.concat(this.schemaPath);
|
|
399
|
-
return schemaPath;
|
|
389
|
+
if (this.parentReport) return this.parentReport.schemaPath.concat(this.schemaPath);
|
|
390
|
+
return this.schemaPath.slice();
|
|
400
391
|
}
|
|
401
392
|
getSchemaId() {
|
|
402
393
|
if (!this.rootSchema) return;
|
|
403
|
-
|
|
404
|
-
if (this.parentReport) path = path.concat(this.parentReport.path);
|
|
405
|
-
path = path.concat(this.path);
|
|
394
|
+
const path = this.parentReport ? this.parentReport.path.concat(this.path) : this.path.slice();
|
|
406
395
|
while (path.length > 0) {
|
|
407
396
|
const obj = get(this.rootSchema, path);
|
|
408
|
-
if (obj && obj.id) return obj.id;
|
|
397
|
+
if (isObject(obj) && typeof obj.id === "string") return obj.id;
|
|
409
398
|
path.pop();
|
|
410
399
|
}
|
|
411
400
|
return this.rootSchema.id;
|
|
@@ -428,11 +417,11 @@
|
|
|
428
417
|
}
|
|
429
418
|
addCustomError(errorCode, errorMessage, params, subReports, schema, keyword) {
|
|
430
419
|
if (typeof this.reportOptions.maxErrors === "number" && this.errors.length >= this.reportOptions.maxErrors) return;
|
|
431
|
-
if (!errorMessage) throw new Error(
|
|
432
|
-
params
|
|
420
|
+
if (!errorMessage) throw new Error(`No errorMessage known for code ${errorCode}`);
|
|
421
|
+
params ||= [];
|
|
433
422
|
for (let idx = 0; idx < params.length; idx++) {
|
|
434
423
|
const param = params[idx] === null || isObject(params[idx]) ? JSON.stringify(params[idx]) : params[idx];
|
|
435
|
-
errorMessage = errorMessage.replace(
|
|
424
|
+
errorMessage = errorMessage.replace(`{${idx}}`, param.toString());
|
|
436
425
|
}
|
|
437
426
|
const err = {
|
|
438
427
|
code: errorCode,
|
|
@@ -441,10 +430,10 @@
|
|
|
441
430
|
path: this.getPath(this.options.reportPathAsArray),
|
|
442
431
|
schemaPath: this.getSchemaPath(),
|
|
443
432
|
schemaId: this.getSchemaId(),
|
|
444
|
-
keyword
|
|
433
|
+
keyword,
|
|
434
|
+
[schemaSymbol]: schema,
|
|
435
|
+
[jsonSymbol]: this.getJson()
|
|
445
436
|
};
|
|
446
|
-
err[schemaSymbol] = schema;
|
|
447
|
-
err[jsonSymbol] = this.getJson();
|
|
448
437
|
if (schema && typeof schema === "string") err.description = schema;
|
|
449
438
|
else if (schema && typeof schema === "object") {
|
|
450
439
|
if (schema.title) err.title = schema.title;
|
|
@@ -453,7 +442,10 @@
|
|
|
453
442
|
if (subReports != null) {
|
|
454
443
|
if (!Array.isArray(subReports)) subReports = [subReports];
|
|
455
444
|
err.inner = [];
|
|
456
|
-
for (
|
|
445
|
+
for (let si = 0; si < subReports.length; si++) {
|
|
446
|
+
const errs = subReports[si].errors;
|
|
447
|
+
for (let ei = 0; ei < errs.length; ei++) err.inner.push(errs[ei]);
|
|
448
|
+
}
|
|
457
449
|
if (err.inner.length === 0) err.inner = void 0;
|
|
458
450
|
}
|
|
459
451
|
if (Array.isArray(this.validateOptions.excludeErrors) && this.validateOptions.excludeErrors.includes(errorCode)) return;
|
|
@@ -503,7 +495,7 @@
|
|
|
503
495
|
let normalized;
|
|
504
496
|
if (typeof options === "object") {
|
|
505
497
|
let keys = Object.keys(options);
|
|
506
|
-
for (const key of keys) if (defaultOptions[key] === void 0) throw new Error(
|
|
498
|
+
for (const key of keys) if (defaultOptions[key] === void 0) throw new Error(`Unexpected option passed to constructor: ${key}`);
|
|
507
499
|
keys = Object.keys(defaultOptions);
|
|
508
500
|
for (const key of keys) if (options[key] === void 0) options[key] = shallowClone(defaultOptions[key]);
|
|
509
501
|
normalized = options;
|
|
@@ -531,7 +523,7 @@
|
|
|
531
523
|
}
|
|
532
524
|
const getEffectiveId = (schema) => {
|
|
533
525
|
let id = getId(schema);
|
|
534
|
-
if ((!id || !isAbsoluteUri(id)) && typeof schema.id === "string" && isAbsoluteUri(schema.id)) id = schema
|
|
526
|
+
if ((!id || !isAbsoluteUri(id)) && typeof schema.id === "string" && isAbsoluteUri(schema.id)) ({id} = schema);
|
|
535
527
|
return id;
|
|
536
528
|
};
|
|
537
529
|
/**
|
|
@@ -540,9 +532,7 @@
|
|
|
540
532
|
* the instance `validator.setRemoteReference()` (instance cache).
|
|
541
533
|
*/
|
|
542
534
|
function prepareRemoteSchema(schema, uri, validationOptions, maxCloneDepth) {
|
|
543
|
-
|
|
544
|
-
if (typeof schema === "string") _schema = JSON.parse(schema);
|
|
545
|
-
else _schema = deepClone(schema, maxCloneDepth);
|
|
535
|
+
const _schema = typeof schema === "string" ? JSON.parse(schema) : deepClone(schema, maxCloneDepth);
|
|
546
536
|
if (!_schema.id) _schema.id = uri;
|
|
547
537
|
if (validationOptions) _schema.__$validationOptions = normalizeOptions(validationOptions);
|
|
548
538
|
return _schema;
|
|
@@ -550,6 +540,7 @@
|
|
|
550
540
|
var SchemaCache = class SchemaCache {
|
|
551
541
|
static global_cache = Object.create(null);
|
|
552
542
|
cache = Object.create(null);
|
|
543
|
+
validator;
|
|
553
544
|
constructor(validator) {
|
|
554
545
|
this.validator = validator;
|
|
555
546
|
}
|
|
@@ -626,7 +617,7 @@
|
|
|
626
617
|
usesAncestorReport = true;
|
|
627
618
|
} else {
|
|
628
619
|
remoteReport = new Report(report);
|
|
629
|
-
const noCache = result.id && isAbsoluteUri(result.id)
|
|
620
|
+
const noCache = !(result.id && isAbsoluteUri(result.id));
|
|
630
621
|
if (this.validator.sc.compileSchema(remoteReport, result, { noCache })) {
|
|
631
622
|
const savedOptions = this.validator.options;
|
|
632
623
|
try {
|
|
@@ -1966,8 +1957,8 @@
|
|
|
1966
1957
|
module.exports.default = exports.default;
|
|
1967
1958
|
}));
|
|
1968
1959
|
//#endregion
|
|
1969
|
-
//#region
|
|
1970
|
-
var
|
|
1960
|
+
//#region node_modules/validator/lib/isURL.js
|
|
1961
|
+
var require_isURL = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1971
1962
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1972
1963
|
exports.default = isURL;
|
|
1973
1964
|
var _assertString = _interopRequireDefault(require_assertString());
|
|
@@ -2132,9 +2123,12 @@
|
|
|
2132
2123
|
}
|
|
2133
2124
|
module.exports = exports.default;
|
|
2134
2125
|
module.exports.default = exports.default;
|
|
2135
|
-
}))
|
|
2136
|
-
|
|
2126
|
+
}));
|
|
2127
|
+
//#endregion
|
|
2128
|
+
//#region src/utils/date.ts
|
|
2137
2129
|
var import_isIP = /* @__PURE__ */ __toESM(require_isIP(), 1);
|
|
2130
|
+
var import_isEmail = /* @__PURE__ */ __toESM(require_isEmail(), 1);
|
|
2131
|
+
var import_isURL = /* @__PURE__ */ __toESM(require_isURL(), 1);
|
|
2138
2132
|
const isLeapYear = (year) => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
2139
2133
|
const getDaysInMonth = (year, month) => {
|
|
2140
2134
|
switch (month) {
|
|
@@ -2300,8 +2294,8 @@
|
|
|
2300
2294
|
let k = 0;
|
|
2301
2295
|
delta = firstTime ? floor(delta / damp) : delta >> 1;
|
|
2302
2296
|
delta += floor(delta / numPoints);
|
|
2303
|
-
for (; delta >
|
|
2304
|
-
return floor(k +
|
|
2297
|
+
for (; delta > 455; k += base) delta = floor(delta / baseMinusTMin);
|
|
2298
|
+
return floor(k + 36 * delta / (delta + skew));
|
|
2305
2299
|
};
|
|
2306
2300
|
/**
|
|
2307
2301
|
* Converts a Punycode string of ASCII-only symbols to a string of Unicode
|
|
@@ -2426,7 +2420,19 @@
|
|
|
2426
2420
|
});
|
|
2427
2421
|
};
|
|
2428
2422
|
module.exports = {
|
|
2423
|
+
/**
|
|
2424
|
+
* A string representing the current Punycode.js version number.
|
|
2425
|
+
* @memberOf punycode
|
|
2426
|
+
* @type String
|
|
2427
|
+
*/
|
|
2429
2428
|
"version": "2.3.1",
|
|
2429
|
+
/**
|
|
2430
|
+
* An object of methods to convert from JavaScript's internal character
|
|
2431
|
+
* representation (UCS-2) to Unicode code points, and back.
|
|
2432
|
+
* @see <https://mathiasbynens.be/notes/javascript-encoding>
|
|
2433
|
+
* @memberOf punycode
|
|
2434
|
+
* @type Object
|
|
2435
|
+
*/
|
|
2430
2436
|
"ucs2": {
|
|
2431
2437
|
"decode": ucs2decode,
|
|
2432
2438
|
"encode": ucs2encode
|
|
@@ -2437,13 +2443,104 @@
|
|
|
2437
2443
|
"toUnicode": toUnicode
|
|
2438
2444
|
};
|
|
2439
2445
|
})))(), 1);
|
|
2440
|
-
const IDN_SEPARATOR_REGEX = /[\u3002\
|
|
2441
|
-
const IDN_SEPARATOR_TEST_REGEX = /[\u3002\
|
|
2446
|
+
const IDN_SEPARATOR_REGEX = /[\u3002\uFF0E\uFF61]/g;
|
|
2447
|
+
const IDN_SEPARATOR_TEST_REGEX = /[\u3002\uFF0E\uFF61]/;
|
|
2448
|
+
const XN_LABEL_REGEX = /^xn--/i;
|
|
2449
|
+
const DISALLOWED_CATEGORY_REGEX = /[\p{P}\p{S}\p{Z}\p{C}]/u;
|
|
2450
|
+
const DISALLOWED_CATEGORY_WHITELIST = /* @__PURE__ */ new Set([
|
|
2451
|
+
"-",
|
|
2452
|
+
"·",
|
|
2453
|
+
"͵",
|
|
2454
|
+
"׳",
|
|
2455
|
+
"״",
|
|
2456
|
+
"・",
|
|
2457
|
+
"۽",
|
|
2458
|
+
"۾",
|
|
2459
|
+
"་",
|
|
2460
|
+
"",
|
|
2461
|
+
""
|
|
2462
|
+
]);
|
|
2463
|
+
const isDisallowedCodePoint = (char) => DISALLOWED_CATEGORY_REGEX.test(char) && !DISALLOWED_CATEGORY_WHITELIST.has(char);
|
|
2464
|
+
const TRANSPARENT_MARK_REGEX = /\p{Mn}/u;
|
|
2465
|
+
const ARABIC_SCRIPT_REGEX = /\p{Script=Arabic}/u;
|
|
2466
|
+
const ARABIC_INDIC_DIGITS_REGEX = /[\u0660-\u0669\u06F0-\u06F9]/;
|
|
2467
|
+
const isArabicJoiningLetter = (char) => char !== void 0 && ARABIC_SCRIPT_REGEX.test(char) && !ARABIC_INDIC_DIGITS_REGEX.test(char);
|
|
2468
|
+
const hasZwnjJoiningContext = (label, idx) => {
|
|
2469
|
+
let before = idx - 1;
|
|
2470
|
+
while (before >= 0 && TRANSPARENT_MARK_REGEX.test(label[before])) before--;
|
|
2471
|
+
let after = idx + 1;
|
|
2472
|
+
while (after < label.length && TRANSPARENT_MARK_REGEX.test(label[after])) after++;
|
|
2473
|
+
return isArabicJoiningLetter(label[before]) && isArabicJoiningLetter(label[after]);
|
|
2474
|
+
};
|
|
2475
|
+
const BIDI_NSM_REGEX = /[\p{Mn}\p{Me}]/u;
|
|
2476
|
+
const BIDI_ARABIC_INDIC_DIGIT_REGEX = /[\u0660-\u0669]/;
|
|
2477
|
+
const BIDI_EXTENDED_ARABIC_INDIC_DIGIT_REGEX = /[\u06F0-\u06F9]/;
|
|
2478
|
+
const BIDI_HEBREW_SCRIPT_REGEX = /\p{Script=Hebrew}/u;
|
|
2479
|
+
const BIDI_AL_SCRIPT_REGEX = /[\p{Script=Arabic}\p{Script=Syriac}\p{Script=Thaana}]/u;
|
|
2480
|
+
const BIDI_ASCII_DIGIT_REGEX = /[0-9]/;
|
|
2481
|
+
const BIDI_LETTER_REGEX = /\p{L}/u;
|
|
2482
|
+
const classifyBidi = (char) => {
|
|
2483
|
+
if (BIDI_NSM_REGEX.test(char)) return "NSM";
|
|
2484
|
+
if (BIDI_ARABIC_INDIC_DIGIT_REGEX.test(char)) return "AN";
|
|
2485
|
+
if (BIDI_EXTENDED_ARABIC_INDIC_DIGIT_REGEX.test(char)) return "EN";
|
|
2486
|
+
if (BIDI_HEBREW_SCRIPT_REGEX.test(char)) return "R";
|
|
2487
|
+
if (BIDI_AL_SCRIPT_REGEX.test(char)) return "AL";
|
|
2488
|
+
if (BIDI_ASCII_DIGIT_REGEX.test(char)) return "EN";
|
|
2489
|
+
if (BIDI_LETTER_REGEX.test(char)) return "L";
|
|
2490
|
+
return "ON";
|
|
2491
|
+
};
|
|
2492
|
+
const isLabelBidiTriggering = (label) => {
|
|
2493
|
+
for (const char of label) {
|
|
2494
|
+
const bidiClass = classifyBidi(char);
|
|
2495
|
+
if (bidiClass === "R" || bidiClass === "AL" || bidiClass === "AN") return true;
|
|
2496
|
+
}
|
|
2497
|
+
return false;
|
|
2498
|
+
};
|
|
2499
|
+
const isLabelBidiRuleValid = (label) => {
|
|
2500
|
+
const classes = [];
|
|
2501
|
+
for (const char of label) classes.push(classifyBidi(char));
|
|
2502
|
+
if (classes.length === 0) return false;
|
|
2503
|
+
const first = classes[0];
|
|
2504
|
+
if (first !== "L" && first !== "R" && first !== "AL") return false;
|
|
2505
|
+
let lastIdx = classes.length - 1;
|
|
2506
|
+
while (lastIdx > 0 && classes[lastIdx] === "NSM") lastIdx--;
|
|
2507
|
+
const last = classes[lastIdx];
|
|
2508
|
+
if (first === "R" || first === "AL") {
|
|
2509
|
+
let hasEN = false;
|
|
2510
|
+
let hasAN = false;
|
|
2511
|
+
for (let i = 0; i < classes.length; i++) {
|
|
2512
|
+
const c = classes[i];
|
|
2513
|
+
if (c !== "R" && c !== "AL" && c !== "AN" && c !== "EN" && c !== "NSM" && c !== "ON") return false;
|
|
2514
|
+
if (c === "EN") hasEN = true;
|
|
2515
|
+
else if (c === "AN") hasAN = true;
|
|
2516
|
+
}
|
|
2517
|
+
if (hasEN && hasAN) return false;
|
|
2518
|
+
return last === "R" || last === "AL" || last === "EN" || last === "AN";
|
|
2519
|
+
}
|
|
2520
|
+
for (let i = 0; i < classes.length; i++) {
|
|
2521
|
+
const c = classes[i];
|
|
2522
|
+
if (c !== "L" && c !== "EN" && c !== "NSM" && c !== "ON") return false;
|
|
2523
|
+
}
|
|
2524
|
+
return last === "L" || last === "EN";
|
|
2525
|
+
};
|
|
2526
|
+
const isDomainBidiValid = (unicodeLabels) => {
|
|
2527
|
+
let isBidiDomain = false;
|
|
2528
|
+
for (let i = 0; i < unicodeLabels.length; i++) if (isLabelBidiTriggering(unicodeLabels[i])) {
|
|
2529
|
+
isBidiDomain = true;
|
|
2530
|
+
break;
|
|
2531
|
+
}
|
|
2532
|
+
if (!isBidiDomain) return true;
|
|
2533
|
+
for (let i = 0; i < unicodeLabels.length; i++) if (!isLabelBidiRuleValid(unicodeLabels[i])) return false;
|
|
2534
|
+
return true;
|
|
2535
|
+
};
|
|
2442
2536
|
const splitHostnameLabels = (hostname) => {
|
|
2443
2537
|
if (hostname.length === 0 || hostname.length > 255) return null;
|
|
2444
2538
|
if (hostname.startsWith(".") || hostname.endsWith(".")) return null;
|
|
2445
2539
|
const labels = hostname.split(".");
|
|
2446
|
-
|
|
2540
|
+
for (let i = 0; i < labels.length; i++) {
|
|
2541
|
+
const len = labels[i].length;
|
|
2542
|
+
if (len === 0 || len > 63) return null;
|
|
2543
|
+
}
|
|
2447
2544
|
return labels;
|
|
2448
2545
|
};
|
|
2449
2546
|
const isAsciiHostnameLabel = (label) => /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label);
|
|
@@ -2451,47 +2548,42 @@
|
|
|
2451
2548
|
const isHebrew = (char) => /\p{Script=Hebrew}/u.test(char);
|
|
2452
2549
|
const hasCjkKanaOrHan = (input) => /[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}]/u.test(input);
|
|
2453
2550
|
const toUnicodeLabel = (label) => {
|
|
2454
|
-
if (
|
|
2551
|
+
if (!XN_LABEL_REGEX.test(label)) return label;
|
|
2455
2552
|
try {
|
|
2456
2553
|
return import_punycode.default.toUnicode(label.toLowerCase());
|
|
2457
|
-
} catch
|
|
2554
|
+
} catch {
|
|
2458
2555
|
return null;
|
|
2459
2556
|
}
|
|
2460
2557
|
};
|
|
2461
2558
|
const isValidIdnUnicodeLabel = (label) => {
|
|
2462
2559
|
if (label.startsWith("-") || label.endsWith("-")) return false;
|
|
2463
|
-
if (label.length >= 4 && label[2] === "-" && label[3] === "-" &&
|
|
2560
|
+
if (label.length >= 4 && label[2] === "-" && label[3] === "-" && !XN_LABEL_REGEX.test(label)) return false;
|
|
2464
2561
|
if (/^\p{M}/u.test(label)) return false;
|
|
2465
|
-
if (/[\
|
|
2562
|
+
if (/[\u302E\u302F\u0640\u07FA]/u.test(label)) return false;
|
|
2466
2563
|
for (let idx = 0; idx < label.length; idx++) {
|
|
2467
2564
|
const char = label[idx];
|
|
2468
|
-
if (char === "·")
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
if (char === "
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
}
|
|
2477
|
-
if (char === "") {
|
|
2478
|
-
if (idx === 0 || label[idx - 1] !== "्") return false;
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
if (label.includes("・") && !hasCjkKanaOrHan(label.replace(/\u30fb/g, ""))) return false;
|
|
2565
|
+
if (char === "·" && (idx === 0 || idx === label.length - 1 || label[idx - 1] !== "l" || label[idx + 1] !== "l")) return false;
|
|
2566
|
+
if (char === "͵" && (idx === label.length - 1 || !isGreek(label[idx + 1]))) return false;
|
|
2567
|
+
if ((char === "׳" || char === "״") && (idx === 0 || !isHebrew(label[idx - 1]))) return false;
|
|
2568
|
+
if (char === "" && (idx === 0 || label[idx - 1] !== "्")) return false;
|
|
2569
|
+
if (char === "" && (idx === 0 || label[idx - 1] !== "्" && !hasZwnjJoiningContext(label, idx))) return false;
|
|
2570
|
+
}
|
|
2571
|
+
for (const char of label) if (isDisallowedCodePoint(char)) return false;
|
|
2572
|
+
if (label.includes("・") && !hasCjkKanaOrHan(label.replaceAll("・", ""))) return false;
|
|
2482
2573
|
const hasArabicIndic = /[\u0660-\u0669]/.test(label);
|
|
2483
|
-
const hasExtendedArabicIndic = /[\
|
|
2574
|
+
const hasExtendedArabicIndic = /[\u06F0-\u06F9]/.test(label);
|
|
2484
2575
|
if (hasArabicIndic && hasExtendedArabicIndic) return false;
|
|
2485
2576
|
return true;
|
|
2486
2577
|
};
|
|
2487
2578
|
const isValidHostname = (hostname) => {
|
|
2488
|
-
if (IDN_SEPARATOR_TEST_REGEX.test(hostname) || /[^\
|
|
2579
|
+
if (IDN_SEPARATOR_TEST_REGEX.test(hostname) || /[^\u0000-\u007F]/.test(hostname)) return false;
|
|
2489
2580
|
if (import_isIP.default.default(hostname, 4)) return false;
|
|
2490
2581
|
const labels = splitHostnameLabels(hostname);
|
|
2491
2582
|
if (labels === null) return false;
|
|
2492
|
-
for (
|
|
2583
|
+
for (let i = 0; i < labels.length; i++) {
|
|
2584
|
+
const label = labels[i];
|
|
2493
2585
|
if (!isAsciiHostnameLabel(label)) return false;
|
|
2494
|
-
if (
|
|
2586
|
+
if (XN_LABEL_REGEX.test(label)) {
|
|
2495
2587
|
const unicodeLabel = toUnicodeLabel(label);
|
|
2496
2588
|
if (unicodeLabel === null || !isValidIdnUnicodeLabel(unicodeLabel)) return false;
|
|
2497
2589
|
}
|
|
@@ -2499,13 +2591,28 @@
|
|
|
2499
2591
|
return true;
|
|
2500
2592
|
};
|
|
2501
2593
|
const isValidIdnHostname = (hostname) => {
|
|
2502
|
-
const
|
|
2594
|
+
const normalizedHostname = hostname.replace(IDN_SEPARATOR_REGEX, ".");
|
|
2595
|
+
const labels = splitHostnameLabels(normalizedHostname);
|
|
2503
2596
|
if (labels === null) return false;
|
|
2504
|
-
|
|
2597
|
+
const unicodeLabels = [];
|
|
2598
|
+
let totalLength = labels.length - 1;
|
|
2599
|
+
for (let i = 0; i < labels.length; i++) {
|
|
2600
|
+
const label = labels[i];
|
|
2505
2601
|
const unicodeLabel = toUnicodeLabel(label);
|
|
2506
2602
|
if (unicodeLabel === null || !isValidIdnUnicodeLabel(unicodeLabel)) return false;
|
|
2603
|
+
let aLabel;
|
|
2604
|
+
try {
|
|
2605
|
+
aLabel = import_punycode.default.toASCII(unicodeLabel);
|
|
2606
|
+
} catch {
|
|
2607
|
+
return false;
|
|
2608
|
+
}
|
|
2609
|
+
if (XN_LABEL_REGEX.test(label) && aLabel.toLowerCase() !== label.toLowerCase()) return false;
|
|
2610
|
+
if (aLabel.length > 63) return false;
|
|
2611
|
+
totalLength += aLabel.length;
|
|
2612
|
+
unicodeLabels.push(unicodeLabel);
|
|
2507
2613
|
}
|
|
2508
|
-
return
|
|
2614
|
+
if (totalLength > 253) return false;
|
|
2615
|
+
return isDomainBidiValid(unicodeLabels);
|
|
2509
2616
|
};
|
|
2510
2617
|
//#endregion
|
|
2511
2618
|
//#region src/utils/time.ts
|
|
@@ -2518,22 +2625,22 @@
|
|
|
2518
2625
|
minute: normalizedUtcTotalMinutes % 60
|
|
2519
2626
|
};
|
|
2520
2627
|
};
|
|
2521
|
-
const RFC3339_TIME_REGEX = /^([0-9]{2}):([0-9]{2}):([0-9]{2})(
|
|
2628
|
+
const RFC3339_TIME_REGEX = /^(?<hour>[0-9]{2}):(?<minute>[0-9]{2}):(?<second>[0-9]{2})(?<fraction>\.[0-9]+)?(?<offset>z|(?<offsetValue>[+-][0-9]{2}:[0-9]{2}))$/i;
|
|
2522
2629
|
const parseRfc3339Time = (time) => {
|
|
2523
2630
|
const matches = RFC3339_TIME_REGEX.exec(time);
|
|
2524
2631
|
if (matches === null) return null;
|
|
2525
|
-
const hour = parseInt(matches[1], 10);
|
|
2526
|
-
const minute = parseInt(matches[2], 10);
|
|
2527
|
-
const second = parseInt(matches[3], 10);
|
|
2632
|
+
const hour = Number.parseInt(matches[1], 10);
|
|
2633
|
+
const minute = Number.parseInt(matches[2], 10);
|
|
2634
|
+
const second = Number.parseInt(matches[3], 10);
|
|
2528
2635
|
if (hour > 23 || minute > 59 || second > 60) return null;
|
|
2529
2636
|
let utcHour = hour;
|
|
2530
2637
|
let utcMinute = minute;
|
|
2531
2638
|
if (matches[5].toLowerCase() !== "z") {
|
|
2532
|
-
const offsetMatches = /^([+-])([0-9]{2}):([0-9]{2})$/.exec(matches[5]);
|
|
2639
|
+
const offsetMatches = /^(?<sign>[+-])(?<hour>[0-9]{2}):(?<minute>[0-9]{2})$/.exec(matches[5]);
|
|
2533
2640
|
if (offsetMatches === null) return null;
|
|
2534
2641
|
const offsetSign = offsetMatches[1];
|
|
2535
|
-
const offsetHour = parseInt(offsetMatches[2], 10);
|
|
2536
|
-
const offsetMinute = parseInt(offsetMatches[3], 10);
|
|
2642
|
+
const offsetHour = Number.parseInt(offsetMatches[2], 10);
|
|
2643
|
+
const offsetMinute = Number.parseInt(offsetMatches[3], 10);
|
|
2537
2644
|
if (offsetHour > 23 || offsetMinute > 59) return null;
|
|
2538
2645
|
const utc = toUtcTime(hour, minute, offsetSign, offsetHour, offsetMinute);
|
|
2539
2646
|
utcHour = utc.hour;
|
|
@@ -2552,19 +2659,20 @@
|
|
|
2552
2659
|
//#region src/format-validators.ts
|
|
2553
2660
|
const dateValidator = (date) => {
|
|
2554
2661
|
if (typeof date !== "string") return true;
|
|
2555
|
-
const matches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(date);
|
|
2662
|
+
const matches = /^(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})$/.exec(date);
|
|
2556
2663
|
if (matches === null) return false;
|
|
2557
|
-
return isValidRfc3339Date(parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3], 10));
|
|
2664
|
+
return isValidRfc3339Date(Number.parseInt(matches[1], 10), Number.parseInt(matches[2], 10), Number.parseInt(matches[3], 10));
|
|
2558
2665
|
};
|
|
2559
2666
|
const dateTimeValidator = (dateTime) => {
|
|
2560
2667
|
if (typeof dateTime !== "string") return true;
|
|
2561
|
-
|
|
2562
|
-
if (
|
|
2563
|
-
|
|
2564
|
-
const
|
|
2565
|
-
const
|
|
2668
|
+
let tIdx = dateTime.indexOf("T");
|
|
2669
|
+
if (tIdx === -1) tIdx = dateTime.indexOf("t");
|
|
2670
|
+
if (tIdx === -1) return false;
|
|
2671
|
+
const datePart = dateTime.slice(0, tIdx);
|
|
2672
|
+
const timePart = dateTime.slice(tIdx + 1);
|
|
2673
|
+
const dateMatches = /^(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})$/.exec(datePart);
|
|
2566
2674
|
if (dateMatches === null) return false;
|
|
2567
|
-
if (!isValidRfc3339Date(parseInt(dateMatches[1], 10), parseInt(dateMatches[2], 10), parseInt(dateMatches[3], 10))) return false;
|
|
2675
|
+
if (!isValidRfc3339Date(Number.parseInt(dateMatches[1], 10), Number.parseInt(dateMatches[2], 10), Number.parseInt(dateMatches[3], 10))) return false;
|
|
2568
2676
|
return parseRfc3339Time(timePart) !== null;
|
|
2569
2677
|
};
|
|
2570
2678
|
const emailValidator = (email) => {
|
|
@@ -2573,7 +2681,7 @@
|
|
|
2573
2681
|
require_tld: true,
|
|
2574
2682
|
allow_ip_domain: true
|
|
2575
2683
|
})) return true;
|
|
2576
|
-
const ipv6Literal = /^(
|
|
2684
|
+
const ipv6Literal = /^(?<localPart>.+)@\[IPv6:(?<address>[^\]]+)\]$/i.exec(email);
|
|
2577
2685
|
if (!ipv6Literal) return false;
|
|
2578
2686
|
const localPart = ipv6Literal[1];
|
|
2579
2687
|
const addressPart = ipv6Literal[2];
|
|
@@ -2593,26 +2701,26 @@
|
|
|
2593
2701
|
if (ipv6.includes("%")) return false;
|
|
2594
2702
|
return import_isIP.default.default(ipv6, 6);
|
|
2595
2703
|
};
|
|
2704
|
+
const INVALID_REGEX_ESCAPES = /* @__PURE__ */ new Set(["a"]);
|
|
2596
2705
|
const regexValidator = (input) => {
|
|
2597
2706
|
if (typeof input !== "string") return true;
|
|
2598
|
-
const invalidEscapes = new Set(["a"]);
|
|
2599
2707
|
for (let idx = 0; idx < input.length; idx++) {
|
|
2600
2708
|
if (input[idx] !== "\\") continue;
|
|
2601
2709
|
idx++;
|
|
2602
2710
|
if (idx >= input.length) return false;
|
|
2603
2711
|
const escaped = input[idx];
|
|
2604
|
-
if (
|
|
2712
|
+
if (INVALID_REGEX_ESCAPES.has(escaped)) return false;
|
|
2605
2713
|
}
|
|
2606
2714
|
try {
|
|
2607
|
-
RegExp(input);
|
|
2715
|
+
new RegExp(input);
|
|
2608
2716
|
return true;
|
|
2609
|
-
} catch
|
|
2717
|
+
} catch {
|
|
2610
2718
|
return false;
|
|
2611
2719
|
}
|
|
2612
2720
|
};
|
|
2613
2721
|
const durationValidator = (input) => {
|
|
2614
2722
|
if (typeof input !== "string") return true;
|
|
2615
|
-
if (!/^P[\
|
|
2723
|
+
if (!/^P[\u0000-\u007F]*$/.test(input)) return false;
|
|
2616
2724
|
if (!input.startsWith("P")) return false;
|
|
2617
2725
|
const body = input.slice(1);
|
|
2618
2726
|
if (body.length === 0) return false;
|
|
@@ -2622,7 +2730,7 @@
|
|
|
2622
2730
|
const datePart = parts[0];
|
|
2623
2731
|
const timePart = parts.length === 2 ? parts[1] : void 0;
|
|
2624
2732
|
if (datePart.length > 0 && !/^(?:\d+Y(?:\d+M(?:\d+D)?)?|\d+M(?:\d+D)?|\d+D)$/.test(datePart)) return false;
|
|
2625
|
-
const hasDateComponent =
|
|
2733
|
+
const hasDateComponent = datePart.length > 0;
|
|
2626
2734
|
let hasTimeComponent = false;
|
|
2627
2735
|
if (timePart !== void 0) {
|
|
2628
2736
|
if (timePart.length === 0) return false;
|
|
@@ -2637,32 +2745,31 @@
|
|
|
2637
2745
|
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);
|
|
2638
2746
|
};
|
|
2639
2747
|
const strictUriValidator = (uri) => typeof uri !== "string" || import_isURL.default.default(uri);
|
|
2748
|
+
const isHexChar = (c) => c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
|
|
2640
2749
|
const hasValidPercentEncoding = (str) => {
|
|
2641
|
-
for (let i = 0; i < str.length; i++) if (str[i] === "%")
|
|
2642
|
-
if (i + 2 >= str.length || !/[0-9a-fA-F]/.test(str[i + 1]) || !/[0-9a-fA-F]/.test(str[i + 2])) return false;
|
|
2643
|
-
}
|
|
2750
|
+
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;
|
|
2644
2751
|
return true;
|
|
2645
2752
|
};
|
|
2646
|
-
const uriValidator =
|
|
2753
|
+
const uriValidator = (uri) => {
|
|
2647
2754
|
if (typeof uri !== "string") return true;
|
|
2648
|
-
if (/[^\
|
|
2755
|
+
if (/[^\u0000-\u007F]/.test(uri)) return false;
|
|
2649
2756
|
if (!hasValidPercentEncoding(uri)) return false;
|
|
2650
|
-
const match =
|
|
2757
|
+
const match = /^(?<scheme>[a-zA-Z][a-zA-Z0-9+.-]*):\/\/(?<authority>[^/?#]*)/.exec(uri);
|
|
2651
2758
|
if (match) {
|
|
2652
2759
|
const authority = match[2];
|
|
2653
2760
|
const atIndex = authority.indexOf("@");
|
|
2654
2761
|
if (atIndex > 0) {
|
|
2655
|
-
const userinfo = authority.
|
|
2762
|
+
const userinfo = authority.slice(0, atIndex);
|
|
2656
2763
|
if (userinfo.includes("[") || userinfo.includes("]")) return false;
|
|
2657
2764
|
}
|
|
2658
|
-
let hostPort = atIndex
|
|
2765
|
+
let hostPort = atIndex === -1 ? authority : authority.slice(atIndex + 1);
|
|
2659
2766
|
if (hostPort.startsWith("[")) {
|
|
2660
2767
|
const bracketEnd = hostPort.indexOf("]");
|
|
2661
|
-
if (bracketEnd
|
|
2768
|
+
if (bracketEnd !== -1) hostPort = hostPort.slice(bracketEnd + 1);
|
|
2662
2769
|
}
|
|
2663
2770
|
const colonIndex = hostPort.lastIndexOf(":");
|
|
2664
|
-
if (colonIndex
|
|
2665
|
-
const port = hostPort.
|
|
2771
|
+
if (colonIndex !== -1) {
|
|
2772
|
+
const port = hostPort.slice(colonIndex + 1);
|
|
2666
2773
|
if (port.length > 0 && !/^\d+$/.test(port)) return false;
|
|
2667
2774
|
}
|
|
2668
2775
|
}
|
|
@@ -2670,12 +2777,12 @@
|
|
|
2670
2777
|
};
|
|
2671
2778
|
const uriReferenceValidator = (uri) => {
|
|
2672
2779
|
if (typeof uri !== "string") return true;
|
|
2673
|
-
if (/[^\
|
|
2674
|
-
return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/.test(uri);
|
|
2780
|
+
if (/[^\u0000-\u007F]/.test(uri)) return false;
|
|
2781
|
+
return /^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/.test(uri);
|
|
2675
2782
|
};
|
|
2676
2783
|
const uriTemplateValidator = (uri) => {
|
|
2677
2784
|
if (typeof uri !== "string") return true;
|
|
2678
|
-
if (!/^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^`| ]*$/.test(uri)) return false;
|
|
2785
|
+
if (!/^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^`| ]*$/.test(uri)) return false;
|
|
2679
2786
|
let inExpression = false;
|
|
2680
2787
|
for (let idx = 0; idx < uri.length; idx++) {
|
|
2681
2788
|
const ch = uri[idx];
|
|
@@ -2701,29 +2808,39 @@
|
|
|
2701
2808
|
if (typeof pointer !== "string") return true;
|
|
2702
2809
|
if (pointer === "") return true;
|
|
2703
2810
|
if (!/^(?:\/[^/]*)+$/.test(pointer)) return false;
|
|
2704
|
-
const tokens = pointer.split("/")
|
|
2705
|
-
for (
|
|
2811
|
+
const tokens = pointer.split("/");
|
|
2812
|
+
for (let i = 1; i < tokens.length; i++) if (!hasValidTildeEscapes(tokens[i])) return false;
|
|
2706
2813
|
return true;
|
|
2707
2814
|
};
|
|
2708
2815
|
const relativeJsonPointerValidator = (pointer) => {
|
|
2709
2816
|
if (typeof pointer !== "string") return true;
|
|
2710
|
-
const match =
|
|
2817
|
+
const match = /^(?<int>0|[1-9]\d*)(?<suffix>.*)$/.exec(pointer);
|
|
2711
2818
|
if (!match) return false;
|
|
2712
2819
|
const suffix = match[2];
|
|
2713
2820
|
if (suffix === "" || suffix === "#") return true;
|
|
2714
2821
|
if (!suffix.startsWith("/")) return false;
|
|
2715
2822
|
if (!/^(?:\/[^/]*)+$/.test(suffix)) return false;
|
|
2716
|
-
const tokens = suffix.split("/")
|
|
2717
|
-
for (
|
|
2823
|
+
const tokens = suffix.split("/");
|
|
2824
|
+
for (let i = 1; i < tokens.length; i++) if (!hasValidTildeEscapes(tokens[i])) return false;
|
|
2718
2825
|
return true;
|
|
2719
2826
|
};
|
|
2720
2827
|
const timeValidator = (time) => {
|
|
2721
2828
|
if (typeof time !== "string") return true;
|
|
2722
2829
|
return parseRfc3339Time(time) !== null;
|
|
2723
2830
|
};
|
|
2831
|
+
const LONE_SURROGATE_REGEX = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
2832
|
+
const QUOTED_LOCAL_PART_REGEX = /^"(?:[^"\\]|\\.)*"$/u;
|
|
2833
|
+
const UNQUOTED_LOCAL_PART_REGEX = /^[^\s@]+$/u;
|
|
2834
|
+
const isValidIdnEmailLocalPart = (localPart) => {
|
|
2835
|
+
if (localPart.length === 0 || LONE_SURROGATE_REGEX.test(localPart)) return false;
|
|
2836
|
+
if (localPart.length >= 2 && localPart.startsWith("\"") && localPart.endsWith("\"")) return QUOTED_LOCAL_PART_REGEX.test(localPart);
|
|
2837
|
+
return UNQUOTED_LOCAL_PART_REGEX.test(localPart);
|
|
2838
|
+
};
|
|
2724
2839
|
const idnEmailValidator = (email) => {
|
|
2725
2840
|
if (typeof email !== "string") return true;
|
|
2726
|
-
|
|
2841
|
+
const atIdx = email.lastIndexOf("@");
|
|
2842
|
+
if (atIdx <= 0 || atIdx === email.length - 1) return false;
|
|
2843
|
+
return isValidIdnEmailLocalPart(email.slice(0, atIdx)) && isValidIdnHostname(email.slice(atIdx + 1));
|
|
2727
2844
|
};
|
|
2728
2845
|
const idnHostnameValidator = (hostname) => {
|
|
2729
2846
|
if (typeof hostname !== "string") return true;
|
|
@@ -2735,13 +2852,13 @@
|
|
|
2735
2852
|
try {
|
|
2736
2853
|
new URL(iri);
|
|
2737
2854
|
return true;
|
|
2738
|
-
} catch
|
|
2855
|
+
} catch {
|
|
2739
2856
|
return false;
|
|
2740
2857
|
}
|
|
2741
2858
|
};
|
|
2742
2859
|
const iriReferenceValidator = (iriReference) => {
|
|
2743
2860
|
if (typeof iriReference !== "string") return true;
|
|
2744
|
-
return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/u.test(iriReference);
|
|
2861
|
+
return /^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/u.test(iriReference);
|
|
2745
2862
|
};
|
|
2746
2863
|
const inbuiltValidators = {
|
|
2747
2864
|
date: dateValidator,
|
|
@@ -2767,13 +2884,12 @@
|
|
|
2767
2884
|
uuid: uuidValidator
|
|
2768
2885
|
};
|
|
2769
2886
|
const customValidators = {};
|
|
2770
|
-
function
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
};
|
|
2887
|
+
function resolveFormatValidator(name, options) {
|
|
2888
|
+
const custom = options?.customFormats;
|
|
2889
|
+
if (custom && Object.hasOwn(custom, name)) return custom[name];
|
|
2890
|
+
if (Object.hasOwn(customValidators, name)) return customValidators[name];
|
|
2891
|
+
if (options?.strictUris && name === "uri") return strictUriValidator;
|
|
2892
|
+
return inbuiltValidators[name];
|
|
2777
2893
|
}
|
|
2778
2894
|
function registerFormat(name, validatorFunction) {
|
|
2779
2895
|
customValidators[name] = validatorFunction;
|
|
@@ -3689,12 +3805,12 @@
|
|
|
3689
3805
|
ok: true,
|
|
3690
3806
|
value: new RegExp(pattern, "u")
|
|
3691
3807
|
};
|
|
3692
|
-
} catch (
|
|
3808
|
+
} catch (error) {
|
|
3693
3809
|
return {
|
|
3694
3810
|
ok: false,
|
|
3695
3811
|
error: {
|
|
3696
3812
|
pattern,
|
|
3697
|
-
message:
|
|
3813
|
+
message: error instanceof Error ? error.message : "Invalid regular expression"
|
|
3698
3814
|
}
|
|
3699
3815
|
};
|
|
3700
3816
|
}
|
|
@@ -3703,12 +3819,12 @@
|
|
|
3703
3819
|
ok: true,
|
|
3704
3820
|
value: new RegExp(pattern)
|
|
3705
3821
|
};
|
|
3706
|
-
} catch (
|
|
3822
|
+
} catch (error) {
|
|
3707
3823
|
return {
|
|
3708
3824
|
ok: false,
|
|
3709
3825
|
error: {
|
|
3710
3826
|
pattern,
|
|
3711
|
-
message:
|
|
3827
|
+
message: error instanceof Error ? error.message : "Invalid regular expression"
|
|
3712
3828
|
}
|
|
3713
3829
|
};
|
|
3714
3830
|
}
|
|
@@ -3737,7 +3853,7 @@
|
|
|
3737
3853
|
const seen = /* @__PURE__ */ new Set();
|
|
3738
3854
|
for (let i = 0; i < l; i++) {
|
|
3739
3855
|
const v = arr[i];
|
|
3740
|
-
const key = typeof v
|
|
3856
|
+
const key = `${typeof v}:${String(v)}`;
|
|
3741
3857
|
if (seen.has(key)) {
|
|
3742
3858
|
if (indexes) for (let j = 0; j < i; j++) {
|
|
3743
3859
|
const prev = arr[j];
|
|
@@ -3752,7 +3868,8 @@
|
|
|
3752
3868
|
}
|
|
3753
3869
|
return true;
|
|
3754
3870
|
}
|
|
3755
|
-
|
|
3871
|
+
const eqOpts = { maxDepth };
|
|
3872
|
+
for (let i = 0; i < l; i++) for (let j = i + 1; j < l; j++) if (areEqual(arr[i], arr[j], eqOpts)) {
|
|
3756
3873
|
if (indexes) indexes.push(i, j);
|
|
3757
3874
|
return false;
|
|
3758
3875
|
}
|
|
@@ -3767,11 +3884,7 @@
|
|
|
3767
3884
|
};
|
|
3768
3885
|
//#endregion
|
|
3769
3886
|
//#region src/validation/shared.ts
|
|
3770
|
-
const shouldSkipValidate =
|
|
3771
|
-
return options && Array.isArray(options.includeErrors) && options.includeErrors.length > 0 && !errors.some(function(err) {
|
|
3772
|
-
return options.includeErrors.includes(err);
|
|
3773
|
-
});
|
|
3774
|
-
};
|
|
3887
|
+
const shouldSkipValidate = (options, errors) => options && Array.isArray(options.includeErrors) && options.includeErrors.length > 0 && !errors.some((err) => options.includeErrors.includes(err));
|
|
3775
3888
|
const supportsDependentKeywords = (schema, version) => {
|
|
3776
3889
|
if (typeof schema.$schema === "string") return !/draft-04|draft-06|draft-07/.test(schema.$schema);
|
|
3777
3890
|
return !(version === "draft-04" || version === "draft-06" || version === "draft-07");
|
|
@@ -3780,7 +3893,7 @@
|
|
|
3780
3893
|
const VOCAB_VALIDATION_2020_12 = "https://json-schema.org/draft/2020-12/vocab/validation";
|
|
3781
3894
|
const VOCAB_FORMAT_2019_09 = "https://json-schema.org/draft/2019-09/vocab/format";
|
|
3782
3895
|
const VOCAB_FORMAT_ASSERTION_2020_12 = "https://json-schema.org/draft/2020-12/vocab/format-assertion";
|
|
3783
|
-
const VALIDATION_VOCAB_KEYWORDS = new Set([
|
|
3896
|
+
const VALIDATION_VOCAB_KEYWORDS = /* @__PURE__ */ new Set([
|
|
3784
3897
|
"type",
|
|
3785
3898
|
"multipleOf",
|
|
3786
3899
|
"maximum",
|
|
@@ -3811,7 +3924,9 @@
|
|
|
3811
3924
|
const metaSchema = currentSchemaMeta || rootSchemaMeta;
|
|
3812
3925
|
if (!metaSchema || typeof metaSchema !== "object" || !isObject(metaSchema.$vocabulary)) return true;
|
|
3813
3926
|
const vocabulary = metaSchema.$vocabulary;
|
|
3814
|
-
|
|
3927
|
+
const has2019 = Object.hasOwn(vocabulary, VOCAB_VALIDATION_2019_09);
|
|
3928
|
+
const has2020 = Object.hasOwn(vocabulary, VOCAB_VALIDATION_2020_12);
|
|
3929
|
+
if (has2019 || has2020) return vocabulary[VOCAB_VALIDATION_2019_09] || vocabulary[VOCAB_VALIDATION_2020_12];
|
|
3815
3930
|
return false;
|
|
3816
3931
|
};
|
|
3817
3932
|
/**
|
|
@@ -3827,8 +3942,8 @@
|
|
|
3827
3942
|
const metaSchema = currentSchemaMeta || rootSchemaMeta;
|
|
3828
3943
|
if (!metaSchema || typeof metaSchema !== "object" || !isObject(metaSchema.$vocabulary)) return false;
|
|
3829
3944
|
const vocabulary = metaSchema.$vocabulary;
|
|
3830
|
-
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_ASSERTION_2020_12)) return vocabulary[VOCAB_FORMAT_ASSERTION_2020_12]
|
|
3831
|
-
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_2019_09)) return vocabulary[VOCAB_FORMAT_2019_09]
|
|
3945
|
+
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_ASSERTION_2020_12)) return vocabulary[VOCAB_FORMAT_ASSERTION_2020_12];
|
|
3946
|
+
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_2019_09)) return vocabulary[VOCAB_FORMAT_2019_09];
|
|
3832
3947
|
return false;
|
|
3833
3948
|
};
|
|
3834
3949
|
function cacheValidationResult(report, schema, json, passed) {
|
|
@@ -3852,9 +3967,14 @@
|
|
|
3852
3967
|
*/
|
|
3853
3968
|
function deferOrRunSync(report, subReports, decisionFn) {
|
|
3854
3969
|
const asyncTasksBefore = report.asyncTasks.length;
|
|
3855
|
-
for (
|
|
3970
|
+
for (let i = 0; i < subReports.length; i++) {
|
|
3971
|
+
const tasks = subReports[i].asyncTasks;
|
|
3972
|
+
for (let j = 0; j < tasks.length; j++) report.asyncTasks.push(tasks[j]);
|
|
3973
|
+
}
|
|
3856
3974
|
if (report.asyncTasks.length > asyncTasksBefore) report.addAsyncTaskWithPath((callback) => {
|
|
3857
|
-
setTimeout(() =>
|
|
3975
|
+
setTimeout(() => {
|
|
3976
|
+
callback(null);
|
|
3977
|
+
}, 0);
|
|
3858
3978
|
}, [], () => {
|
|
3859
3979
|
decisionFn();
|
|
3860
3980
|
});
|
|
@@ -3862,35 +3982,33 @@
|
|
|
3862
3982
|
}
|
|
3863
3983
|
//#endregion
|
|
3864
3984
|
//#region src/validation/array.ts
|
|
3865
|
-
function additionalItemsValidator(report, schema, json) {
|
|
3866
|
-
if (shouldSkipValidate(
|
|
3985
|
+
function additionalItemsValidator(ctx, report, schema, json) {
|
|
3986
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_ADDITIONAL_ITEMS"])) return;
|
|
3867
3987
|
if (!Array.isArray(json)) return;
|
|
3868
|
-
if (schema.additionalItems === false && Array.isArray(schema.items))
|
|
3869
|
-
if (json.length > schema.items.length) report.addError("ARRAY_ADDITIONAL_ITEMS", void 0, void 0, schema, "additionalItems");
|
|
3870
|
-
}
|
|
3988
|
+
if (schema.additionalItems === false && Array.isArray(schema.items) && json.length > schema.items.length) report.addError("ARRAY_ADDITIONAL_ITEMS", void 0, void 0, schema, "additionalItems");
|
|
3871
3989
|
}
|
|
3872
3990
|
function itemsValidator() {}
|
|
3873
3991
|
function prefixItemsValidator() {}
|
|
3874
|
-
function maxItemsValidator(report, schema, json) {
|
|
3875
|
-
if (shouldSkipValidate(
|
|
3992
|
+
function maxItemsValidator(ctx, report, schema, json) {
|
|
3993
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_LENGTH_LONG"])) return;
|
|
3876
3994
|
if (!Array.isArray(json)) return;
|
|
3877
3995
|
if (json.length > schema.maxItems) report.addError("ARRAY_LENGTH_LONG", [json.length, schema.maxItems], void 0, schema, "maxItems");
|
|
3878
3996
|
}
|
|
3879
|
-
function minItemsValidator(report, schema, json) {
|
|
3880
|
-
if (shouldSkipValidate(
|
|
3997
|
+
function minItemsValidator(ctx, report, schema, json) {
|
|
3998
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_LENGTH_SHORT"])) return;
|
|
3881
3999
|
if (!Array.isArray(json)) return;
|
|
3882
4000
|
if (json.length < schema.minItems) report.addError("ARRAY_LENGTH_SHORT", [json.length, schema.minItems], void 0, schema, "minItems");
|
|
3883
4001
|
}
|
|
3884
|
-
function uniqueItemsValidator(report, schema, json) {
|
|
3885
|
-
if (shouldSkipValidate(
|
|
4002
|
+
function uniqueItemsValidator(ctx, report, schema, json) {
|
|
4003
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ARRAY_UNIQUE"])) return;
|
|
3886
4004
|
if (!Array.isArray(json)) return;
|
|
3887
4005
|
if (schema.uniqueItems === true) {
|
|
3888
4006
|
const matches = [];
|
|
3889
|
-
if (isUniqueArray(json, matches,
|
|
4007
|
+
if (!isUniqueArray(json, matches, ctx.options.maxRecursionDepth)) report.addError("ARRAY_UNIQUE", matches, void 0, schema, "uniqueItems");
|
|
3890
4008
|
}
|
|
3891
4009
|
}
|
|
3892
|
-
function containsValidator(report, schema, json) {
|
|
3893
|
-
if (shouldSkipValidate(
|
|
4010
|
+
function containsValidator(ctx, report, schema, json) {
|
|
4011
|
+
if (shouldSkipValidate(ctx.validateOptions, ["CONTAINS"])) return;
|
|
3894
4012
|
if (!Array.isArray(json)) return;
|
|
3895
4013
|
const containsSchema = schema.contains;
|
|
3896
4014
|
if (containsSchema === void 0) return;
|
|
@@ -3899,16 +4017,16 @@
|
|
|
3899
4017
|
for (let idx = 0; idx < json.length; idx++) {
|
|
3900
4018
|
const subReport = new Report_(report);
|
|
3901
4019
|
subReports.push(subReport);
|
|
3902
|
-
|
|
4020
|
+
ctx._jsonValidate(subReport, containsSchema, json[idx]);
|
|
3903
4021
|
cacheValidationResult(report, containsSchema, json[idx], subReport.errors.length === 0);
|
|
3904
4022
|
}
|
|
3905
4023
|
const addContainsErrorIfNeeded = () => {
|
|
3906
4024
|
let matchingItems = 0;
|
|
3907
|
-
for (
|
|
3908
|
-
const supportsContainsBounds =
|
|
4025
|
+
for (let i = 0; i < subReports.length; i++) if (subReports[i].errors.length === 0) matchingItems += 1;
|
|
4026
|
+
const supportsContainsBounds = ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12";
|
|
3909
4027
|
const minContains = supportsContainsBounds && typeof schema.minContains === "number" ? schema.minContains ?? 1 : 1;
|
|
3910
4028
|
const maxContains = supportsContainsBounds && typeof schema.maxContains === "number" ? schema.maxContains : void 0;
|
|
3911
|
-
if (!(matchingItems >= minContains) || !(maxContains === void 0 || matchingItems <= maxContains)) report.addError("CONTAINS", void 0, subReports, schema
|
|
4029
|
+
if (!(matchingItems >= minContains) || !(maxContains === void 0 || matchingItems <= maxContains)) report.addError("CONTAINS", void 0, subReports, schema);
|
|
3912
4030
|
};
|
|
3913
4031
|
deferOrRunSync(report, subReports, addContainsErrorIfNeeded);
|
|
3914
4032
|
}
|
|
@@ -3916,18 +4034,18 @@
|
|
|
3916
4034
|
function minContainsValidator() {}
|
|
3917
4035
|
//#endregion
|
|
3918
4036
|
//#region src/validation/combinators.ts
|
|
3919
|
-
function allOfValidator(report, schema, json) {
|
|
4037
|
+
function allOfValidator(ctx, report, schema, json) {
|
|
3920
4038
|
for (let i = 0; i < schema.allOf.length; i++) {
|
|
3921
|
-
const validateResult =
|
|
3922
|
-
if (
|
|
4039
|
+
const validateResult = ctx._jsonValidate(report, schema.allOf[i], json);
|
|
4040
|
+
if (ctx.options.breakOnFirstError && !validateResult) break;
|
|
3923
4041
|
}
|
|
3924
4042
|
}
|
|
3925
|
-
function anyOfValidator(report, schema, json) {
|
|
4043
|
+
function anyOfValidator(ctx, report, schema, json) {
|
|
3926
4044
|
const subReports = [];
|
|
3927
4045
|
for (let i = 0; i < schema.anyOf.length; i++) {
|
|
3928
4046
|
const subReport = new Report(report);
|
|
3929
4047
|
subReports.push(subReport);
|
|
3930
|
-
|
|
4048
|
+
ctx._jsonValidate(subReport, schema.anyOf[i], json);
|
|
3931
4049
|
cacheValidationResult(report, schema.anyOf[i], json, subReport.errors.length === 0);
|
|
3932
4050
|
}
|
|
3933
4051
|
deferOrRunSync(report, subReports, () => {
|
|
@@ -3936,15 +4054,15 @@
|
|
|
3936
4054
|
passed = true;
|
|
3937
4055
|
break;
|
|
3938
4056
|
}
|
|
3939
|
-
if (passed
|
|
4057
|
+
if (!passed) report.addError("ANY_OF_MISSING", void 0, subReports, schema, "anyOf");
|
|
3940
4058
|
});
|
|
3941
4059
|
}
|
|
3942
|
-
function oneOfValidator(report, schema, json) {
|
|
4060
|
+
function oneOfValidator(ctx, report, schema, json) {
|
|
3943
4061
|
const subReports = [];
|
|
3944
4062
|
for (let i = 0; i < schema.oneOf.length; i++) {
|
|
3945
4063
|
const subReport = new Report(report);
|
|
3946
4064
|
subReports.push(subReport);
|
|
3947
|
-
|
|
4065
|
+
ctx._jsonValidate(subReport, schema.oneOf[i], json);
|
|
3948
4066
|
cacheValidationResult(report, schema.oneOf[i], json, subReport.errors.length === 0);
|
|
3949
4067
|
}
|
|
3950
4068
|
deferOrRunSync(report, subReports, () => {
|
|
@@ -3954,77 +4072,77 @@
|
|
|
3954
4072
|
else if (passes > 1) report.addError("ONE_OF_MULTIPLE", void 0, void 0, schema, "oneOf");
|
|
3955
4073
|
});
|
|
3956
4074
|
}
|
|
3957
|
-
function notValidator(report, schema, json) {
|
|
4075
|
+
function notValidator(ctx, report, schema, json) {
|
|
3958
4076
|
const subReport = new Report(report);
|
|
3959
|
-
if (
|
|
4077
|
+
if (ctx._jsonValidate(subReport, schema.not, json)) report.addError("NOT_PASSED", void 0, void 0, schema, "not");
|
|
3960
4078
|
}
|
|
3961
|
-
function ifValidator(report, schema, json) {
|
|
3962
|
-
if (
|
|
4079
|
+
function ifValidator(ctx, report, schema, json) {
|
|
4080
|
+
if (ctx.options.version === "draft-04" || ctx.options.version === "draft-06") return;
|
|
3963
4081
|
const conditionSchema = schema.if;
|
|
3964
4082
|
const thenSchema = schema.then;
|
|
3965
4083
|
const elseSchema = schema.else;
|
|
3966
4084
|
if (conditionSchema === void 0 || thenSchema === void 0 && elseSchema === void 0) return;
|
|
3967
4085
|
const conditionReport = new Report(report);
|
|
3968
|
-
|
|
4086
|
+
ctx._jsonValidate(conditionReport, conditionSchema, json);
|
|
3969
4087
|
cacheValidationResult(report, conditionSchema, json, conditionReport.errors.length === 0);
|
|
3970
4088
|
const branchSchema = conditionReport.errors.length === 0 ? thenSchema : elseSchema;
|
|
3971
4089
|
if (branchSchema === void 0) return;
|
|
3972
|
-
|
|
4090
|
+
ctx._jsonValidate(report, branchSchema, json);
|
|
3973
4091
|
}
|
|
3974
4092
|
function thenValidator() {}
|
|
3975
4093
|
function elseValidator() {}
|
|
3976
4094
|
//#endregion
|
|
3977
4095
|
//#region src/validation/numeric.ts
|
|
3978
|
-
function multipleOfValidator(report, schema, json) {
|
|
3979
|
-
if (shouldSkipValidate(
|
|
4096
|
+
function multipleOfValidator(ctx, report, schema, json) {
|
|
4097
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MULTIPLE_OF"])) return;
|
|
3980
4098
|
if (typeof json !== "number") return;
|
|
3981
4099
|
const result = json / schema.multipleOf;
|
|
3982
4100
|
if (!Number.isFinite(result) || Math.abs(result - Math.round(result)) >= 1e-10) report.addError("MULTIPLE_OF", [json, schema.multipleOf], void 0, schema, "multipleOf");
|
|
3983
4101
|
}
|
|
3984
|
-
function maximumValidator(report, schema, json) {
|
|
3985
|
-
if (shouldSkipValidate(
|
|
4102
|
+
function maximumValidator(ctx, report, schema, json) {
|
|
4103
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MAXIMUM", "MAXIMUM_EXCLUSIVE"])) return;
|
|
3986
4104
|
if (typeof json !== "number") return;
|
|
3987
4105
|
if (schema.exclusiveMaximum !== true) {
|
|
3988
4106
|
if (json > schema.maximum) report.addError("MAXIMUM", [json, schema.maximum], void 0, schema, "maximum");
|
|
3989
4107
|
} else if (json >= schema.maximum) report.addError("MAXIMUM_EXCLUSIVE", [json, schema.maximum], void 0, schema, "maximum");
|
|
3990
4108
|
}
|
|
3991
|
-
function exclusiveMaximumValidator(report, schema, json) {
|
|
4109
|
+
function exclusiveMaximumValidator(ctx, report, schema, json) {
|
|
3992
4110
|
if (typeof schema.exclusiveMaximum === "number") {
|
|
3993
|
-
if (shouldSkipValidate(
|
|
4111
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MAXIMUM_EXCLUSIVE"])) return;
|
|
3994
4112
|
if (typeof json !== "number") return;
|
|
3995
4113
|
if (json >= schema.exclusiveMaximum) report.addError("MAXIMUM_EXCLUSIVE", [json, schema.exclusiveMaximum], void 0, schema, "exclusiveMaximum");
|
|
3996
4114
|
}
|
|
3997
4115
|
}
|
|
3998
|
-
function minimumValidator(report, schema, json) {
|
|
3999
|
-
if (shouldSkipValidate(
|
|
4116
|
+
function minimumValidator(ctx, report, schema, json) {
|
|
4117
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MINIMUM", "MINIMUM_EXCLUSIVE"])) return;
|
|
4000
4118
|
if (typeof json !== "number") return;
|
|
4001
4119
|
if (schema.exclusiveMinimum !== true) {
|
|
4002
4120
|
if (json < schema.minimum) report.addError("MINIMUM", [json, schema.minimum], void 0, schema, "minimum");
|
|
4003
4121
|
} else if (json <= schema.minimum) report.addError("MINIMUM_EXCLUSIVE", [json, schema.minimum], void 0, schema, "minimum");
|
|
4004
4122
|
}
|
|
4005
|
-
function exclusiveMinimumValidator(report, schema, json) {
|
|
4123
|
+
function exclusiveMinimumValidator(ctx, report, schema, json) {
|
|
4006
4124
|
if (typeof schema.exclusiveMinimum === "number") {
|
|
4007
|
-
if (shouldSkipValidate(
|
|
4125
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MINIMUM_EXCLUSIVE"])) return;
|
|
4008
4126
|
if (typeof json !== "number") return;
|
|
4009
4127
|
if (json <= schema.exclusiveMinimum) report.addError("MINIMUM_EXCLUSIVE", [json, schema.exclusiveMinimum], void 0, schema, "exclusiveMinimum");
|
|
4010
4128
|
}
|
|
4011
4129
|
}
|
|
4012
4130
|
//#endregion
|
|
4013
4131
|
//#region src/validation/object.ts
|
|
4014
|
-
function maxPropertiesValidator(report, schema, json) {
|
|
4015
|
-
if (shouldSkipValidate(
|
|
4132
|
+
function maxPropertiesValidator(ctx, report, schema, json) {
|
|
4133
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_PROPERTIES_MAXIMUM"])) return;
|
|
4016
4134
|
if (!isObject(json)) return;
|
|
4017
4135
|
const keysCount = Object.keys(json).length;
|
|
4018
4136
|
if (keysCount > schema.maxProperties) report.addError("OBJECT_PROPERTIES_MAXIMUM", [keysCount, schema.maxProperties], void 0, schema, "maxProperties");
|
|
4019
4137
|
}
|
|
4020
|
-
function minPropertiesValidator(report, schema, json) {
|
|
4021
|
-
if (shouldSkipValidate(
|
|
4138
|
+
function minPropertiesValidator(ctx, report, schema, json) {
|
|
4139
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_PROPERTIES_MINIMUM"])) return;
|
|
4022
4140
|
if (!isObject(json)) return;
|
|
4023
4141
|
const keysCount = Object.keys(json).length;
|
|
4024
4142
|
if (keysCount < schema.minProperties) report.addError("OBJECT_PROPERTIES_MINIMUM", [keysCount, schema.minProperties], void 0, schema, "minProperties");
|
|
4025
4143
|
}
|
|
4026
|
-
function requiredValidator(report, schema, json) {
|
|
4027
|
-
if (shouldSkipValidate(
|
|
4144
|
+
function requiredValidator(ctx, report, schema, json) {
|
|
4145
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_MISSING_REQUIRED_PROPERTY"])) return;
|
|
4028
4146
|
if (!isObject(json)) return;
|
|
4029
4147
|
const idx = schema.required.length;
|
|
4030
4148
|
for (let i = 0; i < idx; i++) {
|
|
@@ -4032,30 +4150,31 @@
|
|
|
4032
4150
|
if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_MISSING_REQUIRED_PROPERTY", [requiredPropertyName], void 0, schema, "required");
|
|
4033
4151
|
}
|
|
4034
4152
|
}
|
|
4035
|
-
function additionalPropertiesValidator(report, schema, json) {
|
|
4036
|
-
if (schema.properties === void 0 && schema.patternProperties === void 0)
|
|
4153
|
+
function additionalPropertiesValidator(ctx, report, schema, json) {
|
|
4154
|
+
if (schema.properties === void 0 && schema.patternProperties === void 0) propertiesValidator(ctx, report, schema, json);
|
|
4037
4155
|
}
|
|
4038
|
-
function patternPropertiesValidator(report, schema, json) {
|
|
4039
|
-
if (schema.properties === void 0)
|
|
4156
|
+
function patternPropertiesValidator(ctx, report, schema, json) {
|
|
4157
|
+
if (schema.properties === void 0) propertiesValidator(ctx, report, schema, json);
|
|
4040
4158
|
}
|
|
4041
|
-
function propertiesValidator(report, schema, json) {
|
|
4042
|
-
if (shouldSkipValidate(
|
|
4159
|
+
function propertiesValidator(ctx, report, schema, json) {
|
|
4160
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_ADDITIONAL_PROPERTIES"])) return;
|
|
4043
4161
|
if (!isObject(json)) return;
|
|
4044
|
-
const properties = schema.properties
|
|
4045
|
-
const patternProperties = schema.patternProperties
|
|
4162
|
+
const properties = schema.properties === void 0 ? {} : schema.properties;
|
|
4163
|
+
const patternProperties = schema.patternProperties === void 0 ? {} : schema.patternProperties;
|
|
4046
4164
|
if (schema.additionalProperties === false) {
|
|
4047
4165
|
let s = Object.keys(json);
|
|
4048
4166
|
const p = Object.keys(properties);
|
|
4049
4167
|
const pp = Object.keys(patternProperties);
|
|
4050
4168
|
s = difference(s, p);
|
|
4051
|
-
for (
|
|
4169
|
+
for (let i = 0; i < pp.length; i++) {
|
|
4170
|
+
const ppKey = pp[i];
|
|
4052
4171
|
const result = compileSchemaRegex(ppKey);
|
|
4053
4172
|
if (!result.ok) continue;
|
|
4054
4173
|
const regExp = result.value;
|
|
4055
|
-
for (let idx2 = s.length - 1; idx2 >= 0; idx2--) if (regExp.test(s[idx2])
|
|
4174
|
+
for (let idx2 = s.length - 1; idx2 >= 0; idx2--) if (regExp.test(s[idx2])) s.splice(idx2, 1);
|
|
4056
4175
|
}
|
|
4057
4176
|
if (s.length > 0) {
|
|
4058
|
-
if (Array.isArray(
|
|
4177
|
+
if (Array.isArray(ctx.options.assumeAdditional)) for (const allowed of ctx.options.assumeAdditional) {
|
|
4059
4178
|
const io = s.indexOf(allowed);
|
|
4060
4179
|
if (io !== -1) s.splice(io, 1);
|
|
4061
4180
|
}
|
|
@@ -4063,29 +4182,29 @@
|
|
|
4063
4182
|
}
|
|
4064
4183
|
}
|
|
4065
4184
|
}
|
|
4066
|
-
function dependenciesValidator(report, schema, json) {
|
|
4067
|
-
if (shouldSkipValidate(
|
|
4185
|
+
function dependenciesValidator(ctx, report, schema, json) {
|
|
4186
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_DEPENDENCY_KEY"])) return;
|
|
4068
4187
|
if (!isObject(json)) return;
|
|
4069
4188
|
const keys = Object.keys(schema.dependencies);
|
|
4070
4189
|
for (const dependencyName of keys) if (Object.hasOwn(json, dependencyName)) {
|
|
4071
4190
|
const dependencyDefinition = schema.dependencies[dependencyName];
|
|
4072
4191
|
if (Array.isArray(dependencyDefinition)) {
|
|
4073
4192
|
for (const requiredPropertyName of dependencyDefinition) if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], void 0, schema, "dependencies");
|
|
4074
|
-
} else
|
|
4193
|
+
} else ctx._jsonValidate(report, dependencyDefinition, json);
|
|
4075
4194
|
}
|
|
4076
4195
|
}
|
|
4077
|
-
function dependentSchemasValidator(report, schema, json) {
|
|
4078
|
-
if (!supportsDependentKeywords(schema,
|
|
4196
|
+
function dependentSchemasValidator(ctx, report, schema, json) {
|
|
4197
|
+
if (!supportsDependentKeywords(schema, ctx.options.version)) return;
|
|
4079
4198
|
if (!isObject(json) || !isObject(schema.dependentSchemas)) return;
|
|
4080
4199
|
const keys = Object.keys(schema.dependentSchemas);
|
|
4081
4200
|
for (const dependencyName of keys) if (Object.hasOwn(json, dependencyName)) {
|
|
4082
4201
|
const dependencySchema = schema.dependentSchemas[dependencyName];
|
|
4083
|
-
|
|
4202
|
+
ctx._jsonValidate(report, dependencySchema, json);
|
|
4084
4203
|
}
|
|
4085
4204
|
}
|
|
4086
|
-
function dependentRequiredValidator(report, schema, json) {
|
|
4087
|
-
if (!supportsDependentKeywords(schema,
|
|
4088
|
-
if (shouldSkipValidate(
|
|
4205
|
+
function dependentRequiredValidator(ctx, report, schema, json) {
|
|
4206
|
+
if (!supportsDependentKeywords(schema, ctx.options.version)) return;
|
|
4207
|
+
if (shouldSkipValidate(ctx.validateOptions, ["OBJECT_DEPENDENCY_KEY"])) return;
|
|
4089
4208
|
if (!isObject(json) || !isObject(schema.dependentRequired)) return;
|
|
4090
4209
|
const keys = Object.keys(schema.dependentRequired);
|
|
4091
4210
|
for (const dependencyName of keys) {
|
|
@@ -4095,8 +4214,8 @@
|
|
|
4095
4214
|
for (const requiredPropertyName of requiredProperties) if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], void 0, schema, "dependentRequired");
|
|
4096
4215
|
}
|
|
4097
4216
|
}
|
|
4098
|
-
function propertyNamesValidator(report, schema, json) {
|
|
4099
|
-
if (shouldSkipValidate(
|
|
4217
|
+
function propertyNamesValidator(ctx, report, schema, json) {
|
|
4218
|
+
if (shouldSkipValidate(ctx.validateOptions, ["PROPERTY_NAMES"])) return;
|
|
4100
4219
|
if (!isObject(json)) return;
|
|
4101
4220
|
const propertyNamesSchema = schema.propertyNames;
|
|
4102
4221
|
if (propertyNamesSchema === void 0) return;
|
|
@@ -4106,10 +4225,10 @@
|
|
|
4106
4225
|
for (const key of keys) {
|
|
4107
4226
|
const subReport = new Report_(report);
|
|
4108
4227
|
subReports.push(subReport);
|
|
4109
|
-
|
|
4228
|
+
ctx._jsonValidate(subReport, propertyNamesSchema, key);
|
|
4110
4229
|
}
|
|
4111
4230
|
const addPropertyNameErrors = () => {
|
|
4112
|
-
for (let idx = 0; idx < keys.length; idx++) if (subReports[idx].errors.length > 0) report.addError("PROPERTY_NAMES", [keys[idx]], subReports[idx], schema
|
|
4231
|
+
for (let idx = 0; idx < keys.length; idx++) if (subReports[idx].errors.length > 0) report.addError("PROPERTY_NAMES", [keys[idx]], subReports[idx], schema);
|
|
4113
4232
|
};
|
|
4114
4233
|
deferOrRunSync(report, subReports, addPropertyNameErrors);
|
|
4115
4234
|
}
|
|
@@ -4119,7 +4238,7 @@
|
|
|
4119
4238
|
const hashIdx = dynamicRef.indexOf("#");
|
|
4120
4239
|
if (hashIdx === -1) return;
|
|
4121
4240
|
const fragment = dynamicRef.slice(hashIdx + 1);
|
|
4122
|
-
if (!fragment || fragment
|
|
4241
|
+
if (!fragment || fragment.startsWith("/")) return;
|
|
4123
4242
|
return fragment;
|
|
4124
4243
|
};
|
|
4125
4244
|
const findDynamicAnchorInScope = (scopeSchema, anchorName) => {
|
|
@@ -4146,7 +4265,7 @@
|
|
|
4146
4265
|
*/
|
|
4147
4266
|
const resolveDynamicRef = (schema, dynamicScopeStack) => {
|
|
4148
4267
|
const resolved = schema.__$dynamicRefResolved;
|
|
4149
|
-
if (
|
|
4268
|
+
if (resolved === void 0 || !schema.$dynamicRef) return resolved;
|
|
4150
4269
|
let target = resolved;
|
|
4151
4270
|
const anchorName = getDynamicRefAnchorName(schema.$dynamicRef);
|
|
4152
4271
|
if (anchorName && typeof target === "object" && target.$dynamicAnchor === anchorName) for (let scopeIdx = 0; scopeIdx < dynamicScopeStack.length; scopeIdx++) {
|
|
@@ -4173,8 +4292,9 @@
|
|
|
4173
4292
|
} catch {
|
|
4174
4293
|
return;
|
|
4175
4294
|
}
|
|
4176
|
-
|
|
4177
|
-
|
|
4295
|
+
const bufferCtor = globalThis.Buffer;
|
|
4296
|
+
if (bufferCtor !== void 0) try {
|
|
4297
|
+
return bufferCtor.from(value, "base64").toString("utf-8");
|
|
4178
4298
|
} catch {
|
|
4179
4299
|
return;
|
|
4180
4300
|
}
|
|
@@ -4183,27 +4303,37 @@
|
|
|
4183
4303
|
//#region src/utils/unicode.ts
|
|
4184
4304
|
/**
|
|
4185
4305
|
* Returns the number of Unicode code points in the string.
|
|
4186
|
-
* Uses
|
|
4306
|
+
* Uses a surrogate-aware charCodeAt scan (equivalent to the string iterator)
|
|
4307
|
+
* that counts a surrogate pair as one code point and lone surrogates as one each.
|
|
4187
4308
|
*/
|
|
4188
4309
|
function unicodeLength(str) {
|
|
4189
|
-
let count =
|
|
4190
|
-
for (
|
|
4310
|
+
let count = str.length;
|
|
4311
|
+
for (let i = 0; i < str.length - 1; i++) {
|
|
4312
|
+
const hi = str.charCodeAt(i);
|
|
4313
|
+
if (hi >= 55296 && hi <= 56319) {
|
|
4314
|
+
const lo = str.charCodeAt(i + 1);
|
|
4315
|
+
if (lo >= 56320 && lo <= 57343) {
|
|
4316
|
+
count--;
|
|
4317
|
+
i++;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4191
4321
|
return count;
|
|
4192
4322
|
}
|
|
4193
4323
|
//#endregion
|
|
4194
4324
|
//#region src/validation/string.ts
|
|
4195
|
-
function minLengthValidator(report, schema, json) {
|
|
4196
|
-
if (shouldSkipValidate(
|
|
4325
|
+
function minLengthValidator(ctx, report, schema, json) {
|
|
4326
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MIN_LENGTH"])) return;
|
|
4197
4327
|
if (typeof json !== "string") return;
|
|
4198
4328
|
if (unicodeLength(json) < schema.minLength) report.addError("MIN_LENGTH", [json.length, schema.minLength], void 0, schema, "minLength");
|
|
4199
4329
|
}
|
|
4200
|
-
function maxLengthValidator(report, schema, json) {
|
|
4201
|
-
if (shouldSkipValidate(
|
|
4330
|
+
function maxLengthValidator(ctx, report, schema, json) {
|
|
4331
|
+
if (shouldSkipValidate(ctx.validateOptions, ["MAX_LENGTH"])) return;
|
|
4202
4332
|
if (typeof json !== "string") return;
|
|
4203
4333
|
if (unicodeLength(json) > schema.maxLength) report.addError("MAX_LENGTH", [json.length, schema.maxLength], void 0, schema, "maxLength");
|
|
4204
4334
|
}
|
|
4205
|
-
function patternValidator(report, schema, json) {
|
|
4206
|
-
if (shouldSkipValidate(
|
|
4335
|
+
function patternValidator(ctx, report, schema, json) {
|
|
4336
|
+
if (shouldSkipValidate(ctx.validateOptions, ["PATTERN"])) return;
|
|
4207
4337
|
if (typeof json !== "string") return;
|
|
4208
4338
|
const result = compileSchemaRegex(schema.pattern);
|
|
4209
4339
|
if (!result.ok) {
|
|
@@ -4216,46 +4346,46 @@
|
|
|
4216
4346
|
}
|
|
4217
4347
|
if (!result.value.test(json)) report.addError("PATTERN", [schema.pattern, json], void 0, schema, "pattern");
|
|
4218
4348
|
}
|
|
4219
|
-
function formatValidator(report, schema, json) {
|
|
4220
|
-
if (
|
|
4221
|
-
if (
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
const isModernDraft = this.options.version === "draft2019-09" || this.options.version === "draft2020-12";
|
|
4225
|
-
const formatValidatorFn = getFormatValidators(this.options)[schema.format];
|
|
4349
|
+
function formatValidator(ctx, report, schema, json) {
|
|
4350
|
+
if (ctx.options.formatAssertions === false) return;
|
|
4351
|
+
if (ctx.options.formatAssertions === true && !isFormatAssertionVocabEnabled(schema, report, ctx.options.version)) return;
|
|
4352
|
+
const isModernDraft = ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12";
|
|
4353
|
+
const formatValidatorFn = resolveFormatValidator(schema.format, ctx.options);
|
|
4226
4354
|
if (typeof formatValidatorFn === "function") {
|
|
4227
|
-
if (shouldSkipValidate(
|
|
4355
|
+
if (shouldSkipValidate(ctx.validateOptions, ["INVALID_FORMAT"])) return;
|
|
4228
4356
|
if (report.hasError("INVALID_TYPE", [schema.type, whatIs(json)])) return;
|
|
4229
|
-
if (formatValidatorFn.length === 2) report.addAsyncTaskWithPath(formatValidatorFn, [json],
|
|
4357
|
+
if (formatValidatorFn.length === 2) report.addAsyncTaskWithPath(formatValidatorFn, [json], (result) => {
|
|
4230
4358
|
if (result !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
4231
4359
|
});
|
|
4232
4360
|
else {
|
|
4233
|
-
const result = formatValidatorFn.call(
|
|
4361
|
+
const result = formatValidatorFn.call(ctx, json);
|
|
4234
4362
|
if (result instanceof Promise) {
|
|
4235
4363
|
const promiseResult = result;
|
|
4236
4364
|
report.addAsyncTaskWithPath(async (callback) => {
|
|
4365
|
+
let resolved = false;
|
|
4237
4366
|
try {
|
|
4238
|
-
|
|
4239
|
-
} catch
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
}, [], function(resolvedResult) {
|
|
4367
|
+
resolved = await promiseResult;
|
|
4368
|
+
} catch {}
|
|
4369
|
+
callback(resolved);
|
|
4370
|
+
}, [], (resolvedResult) => {
|
|
4243
4371
|
if (resolvedResult !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
4244
4372
|
});
|
|
4245
|
-
} else if (result
|
|
4373
|
+
} else if (!result) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
4246
4374
|
}
|
|
4247
|
-
} else if (
|
|
4375
|
+
} else if (ctx.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
4248
4376
|
}
|
|
4249
|
-
function contentEncodingValidator(report, schema, json) {
|
|
4250
|
-
if (
|
|
4377
|
+
function contentEncodingValidator(ctx, report, schema, json) {
|
|
4378
|
+
if (ctx.options.version !== "draft-07") return;
|
|
4251
4379
|
if (typeof json !== "string") return;
|
|
4252
|
-
|
|
4380
|
+
const { contentEncoding } = schema;
|
|
4381
|
+
if (contentEncoding !== "base64") return;
|
|
4253
4382
|
if (!isValidBase64(json)) report.addError("INVALID_FORMAT", ["contentEncoding:base64", JSON.stringify(json)], void 0, schema, "contentEncoding");
|
|
4254
4383
|
}
|
|
4255
|
-
function contentMediaTypeValidator(report, schema, json) {
|
|
4256
|
-
if (
|
|
4384
|
+
function contentMediaTypeValidator(ctx, report, schema, json) {
|
|
4385
|
+
if (ctx.options.version !== "draft-07") return;
|
|
4257
4386
|
if (typeof json !== "string") return;
|
|
4258
|
-
|
|
4387
|
+
const { contentMediaType } = schema;
|
|
4388
|
+
if (contentMediaType !== "application/json") return;
|
|
4259
4389
|
let payload = json;
|
|
4260
4390
|
if (schema.contentEncoding === "base64") {
|
|
4261
4391
|
const decoded = decodeBase64(json);
|
|
@@ -4273,38 +4403,40 @@
|
|
|
4273
4403
|
}
|
|
4274
4404
|
//#endregion
|
|
4275
4405
|
//#region src/validation/type.ts
|
|
4276
|
-
function typeValidator(report, schema, json) {
|
|
4277
|
-
if (shouldSkipValidate(
|
|
4406
|
+
function typeValidator(ctx, report, schema, json) {
|
|
4407
|
+
if (shouldSkipValidate(ctx.validateOptions, ["INVALID_TYPE"])) return;
|
|
4278
4408
|
const jsonType = whatIs(json);
|
|
4279
4409
|
if (typeof schema.type === "string") {
|
|
4280
4410
|
if (jsonType !== schema.type && (jsonType !== "integer" || schema.type !== "number")) report.addError("INVALID_TYPE", [schema.type, jsonType], void 0, schema, "type");
|
|
4281
4411
|
} 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");
|
|
4282
4412
|
}
|
|
4283
|
-
function enumValidator(report, schema, json) {
|
|
4284
|
-
if (shouldSkipValidate(
|
|
4285
|
-
|
|
4286
|
-
|
|
4413
|
+
function enumValidator(ctx, report, schema, json) {
|
|
4414
|
+
if (shouldSkipValidate(ctx.validateOptions, ["ENUM_CASE_MISMATCH", "ENUM_MISMATCH"])) return;
|
|
4415
|
+
const eqOpts = { maxDepth: ctx.options.maxRecursionDepth };
|
|
4416
|
+
const eqOptsCI = {
|
|
4417
|
+
caseInsensitiveComparison: true,
|
|
4418
|
+
maxDepth: ctx.options.maxRecursionDepth
|
|
4419
|
+
};
|
|
4420
|
+
let caseInsensitiveMatch = false, match = false;
|
|
4421
|
+
for (const enumVal of schema.enum) if (areEqual(json, enumVal, eqOpts)) {
|
|
4287
4422
|
match = true;
|
|
4288
4423
|
break;
|
|
4289
|
-
} else if (areEqual(json, enumVal,
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
})) caseInsensitiveMatch = true;
|
|
4293
|
-
if (match === false) {
|
|
4294
|
-
const error = caseInsensitiveMatch && this.options.enumCaseInsensitiveComparison ? "ENUM_CASE_MISMATCH" : "ENUM_MISMATCH";
|
|
4424
|
+
} else if (areEqual(json, enumVal, eqOptsCI)) caseInsensitiveMatch = true;
|
|
4425
|
+
if (!match) {
|
|
4426
|
+
const error = caseInsensitiveMatch && ctx.options.enumCaseInsensitiveComparison ? "ENUM_CASE_MISMATCH" : "ENUM_MISMATCH";
|
|
4295
4427
|
report.addError(error, [JSON.stringify(json)], void 0, schema, "enum");
|
|
4296
4428
|
}
|
|
4297
4429
|
}
|
|
4298
|
-
function constValidator(report, schema, json) {
|
|
4430
|
+
function constValidator(ctx, report, schema, json) {
|
|
4299
4431
|
const constValue = schema.const;
|
|
4300
|
-
if (areEqual(json, constValue, { maxDepth:
|
|
4432
|
+
if (!areEqual(json, constValue, { maxDepth: ctx.options.maxRecursionDepth })) report.addError("CONST", [JSON.stringify(constValue)], void 0, schema);
|
|
4301
4433
|
}
|
|
4302
4434
|
//#endregion
|
|
4303
4435
|
//#region src/json-validation.ts
|
|
4304
|
-
function collectEvaluated(args) {
|
|
4436
|
+
function collectEvaluated(ctx, args) {
|
|
4305
4437
|
const { report, currentSchema, json, mode, depth } = args;
|
|
4306
4438
|
if (!currentSchema || typeof currentSchema === "boolean") return /* @__PURE__ */ new Set();
|
|
4307
|
-
if (depth > (
|
|
4439
|
+
if (depth > (ctx.options.maxRecursionDepth ?? 100)) {
|
|
4308
4440
|
report.addError("COLLECT_EVALUATED_DEPTH_EXCEEDED", [depth]);
|
|
4309
4441
|
return /* @__PURE__ */ new Set();
|
|
4310
4442
|
}
|
|
@@ -4315,7 +4447,7 @@
|
|
|
4315
4447
|
return false;
|
|
4316
4448
|
};
|
|
4317
4449
|
const recurse = (subSchema) => {
|
|
4318
|
-
if (mode === "items") return collectEvaluated
|
|
4450
|
+
if (mode === "items") return collectEvaluated(ctx, {
|
|
4319
4451
|
report,
|
|
4320
4452
|
currentSchema: subSchema,
|
|
4321
4453
|
json,
|
|
@@ -4323,7 +4455,7 @@
|
|
|
4323
4455
|
jsonArr: args.jsonArr,
|
|
4324
4456
|
depth: depth + 1
|
|
4325
4457
|
});
|
|
4326
|
-
return collectEvaluated
|
|
4458
|
+
return collectEvaluated(ctx, {
|
|
4327
4459
|
report,
|
|
4328
4460
|
currentSchema: subSchema,
|
|
4329
4461
|
json,
|
|
@@ -4333,7 +4465,7 @@
|
|
|
4333
4465
|
});
|
|
4334
4466
|
};
|
|
4335
4467
|
if (mode === "items") {
|
|
4336
|
-
const jsonArr = args
|
|
4468
|
+
const { jsonArr } = args;
|
|
4337
4469
|
if (Array.isArray(currentSchema.prefixItems)) {
|
|
4338
4470
|
const len = Math.min(currentSchema.prefixItems.length, jsonArr.length);
|
|
4339
4471
|
for (let i = 0; i < len; i++) evaluated.add(i);
|
|
@@ -4349,104 +4481,102 @@
|
|
|
4349
4481
|
let passed = getCachedValidationResult(report, currentSchema.contains, jsonArr[i]);
|
|
4350
4482
|
if (passed === void 0) {
|
|
4351
4483
|
const subReport = new Report(report);
|
|
4352
|
-
validate
|
|
4484
|
+
validate(ctx, subReport, currentSchema.contains, jsonArr[i]);
|
|
4353
4485
|
passed = subReport.errors.length === 0;
|
|
4354
4486
|
}
|
|
4355
4487
|
if (passed) evaluated.add(i);
|
|
4356
4488
|
}
|
|
4357
4489
|
if (currentSchema.unevaluatedItems === true) return "all";
|
|
4358
4490
|
} else {
|
|
4359
|
-
const jsonData = args
|
|
4491
|
+
const { jsonData } = args;
|
|
4360
4492
|
if (isObject(currentSchema.properties)) {
|
|
4361
|
-
|
|
4493
|
+
const propKeysCE = Object.keys(currentSchema.properties);
|
|
4494
|
+
for (let i = 0; i < propKeysCE.length; i++) {
|
|
4495
|
+
const key = propKeysCE[i];
|
|
4496
|
+
if (Object.hasOwn(jsonData, key)) evaluated.add(key);
|
|
4497
|
+
}
|
|
4362
4498
|
}
|
|
4363
4499
|
if (isObject(currentSchema.patternProperties)) for (const pattern of Object.keys(currentSchema.patternProperties)) {
|
|
4364
4500
|
const result = compileSchemaRegex(pattern);
|
|
4365
4501
|
if (result.ok) {
|
|
4366
|
-
|
|
4502
|
+
const jdKeys = Object.keys(jsonData);
|
|
4503
|
+
for (let i = 0; i < jdKeys.length; i++) if (result.value.test(jdKeys[i])) evaluated.add(jdKeys[i]);
|
|
4367
4504
|
}
|
|
4368
4505
|
}
|
|
4369
4506
|
if (currentSchema.additionalProperties !== void 0) {
|
|
4370
|
-
const
|
|
4507
|
+
const propKeySet = new Set(isObject(currentSchema.properties) ? Object.keys(currentSchema.properties) : []);
|
|
4371
4508
|
const patternRegexes = [];
|
|
4372
4509
|
if (isObject(currentSchema.patternProperties)) for (const pattern of Object.keys(currentSchema.patternProperties)) {
|
|
4373
4510
|
const result = compileSchemaRegex(pattern);
|
|
4374
4511
|
if (result.ok) patternRegexes.push(result.value);
|
|
4375
4512
|
}
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4513
|
+
const apKeys = Object.keys(jsonData);
|
|
4514
|
+
for (let i = 0; i < apKeys.length; i++) {
|
|
4515
|
+
const key = apKeys[i];
|
|
4516
|
+
if (propKeySet.has(key)) continue;
|
|
4517
|
+
let matchedPattern = false;
|
|
4518
|
+
for (let pi = 0; pi < patternRegexes.length; pi++) if (patternRegexes[pi].test(key)) {
|
|
4519
|
+
matchedPattern = true;
|
|
4520
|
+
break;
|
|
4521
|
+
}
|
|
4522
|
+
if (matchedPattern) continue;
|
|
4379
4523
|
evaluated.add(key);
|
|
4380
4524
|
}
|
|
4381
4525
|
}
|
|
4382
4526
|
if (isObject(currentSchema.dependentSchemas)) {
|
|
4383
|
-
for (const [depKey, depSchema] of Object.entries(currentSchema.dependentSchemas)) if (Object.hasOwn(jsonData, depKey))
|
|
4384
|
-
if (merge(recurse(depSchema))) return "all";
|
|
4385
|
-
}
|
|
4527
|
+
for (const [depKey, depSchema] of Object.entries(currentSchema.dependentSchemas)) if (Object.hasOwn(jsonData, depKey) && merge(recurse(depSchema))) return "all";
|
|
4386
4528
|
}
|
|
4387
4529
|
if (currentSchema.unevaluatedProperties === true) return "all";
|
|
4388
4530
|
}
|
|
4389
4531
|
if (Array.isArray(currentSchema.allOf)) {
|
|
4390
|
-
for (
|
|
4532
|
+
for (let i = 0; i < currentSchema.allOf.length; i++) if (merge(recurse(currentSchema.allOf[i]))) return "all";
|
|
4391
4533
|
}
|
|
4392
|
-
if (Array.isArray(currentSchema.anyOf)) for (
|
|
4534
|
+
if (Array.isArray(currentSchema.anyOf)) for (let i = 0; i < currentSchema.anyOf.length; i++) {
|
|
4535
|
+
const subSchema = currentSchema.anyOf[i];
|
|
4393
4536
|
let passed = getCachedValidationResult(report, subSchema, json);
|
|
4394
4537
|
if (passed === void 0) {
|
|
4395
4538
|
const subReport = new Report(report);
|
|
4396
|
-
validate
|
|
4539
|
+
validate(ctx, subReport, subSchema, json);
|
|
4397
4540
|
passed = subReport.errors.length === 0;
|
|
4398
4541
|
}
|
|
4399
|
-
if (passed)
|
|
4400
|
-
if (merge(recurse(subSchema))) return "all";
|
|
4401
|
-
}
|
|
4542
|
+
if (passed && merge(recurse(subSchema))) return "all";
|
|
4402
4543
|
}
|
|
4403
|
-
if (Array.isArray(currentSchema.oneOf)) for (
|
|
4544
|
+
if (Array.isArray(currentSchema.oneOf)) for (let i = 0; i < currentSchema.oneOf.length; i++) {
|
|
4545
|
+
const subSchema = currentSchema.oneOf[i];
|
|
4404
4546
|
let passed = getCachedValidationResult(report, subSchema, json);
|
|
4405
4547
|
if (passed === void 0) {
|
|
4406
4548
|
const subReport = new Report(report);
|
|
4407
|
-
validate
|
|
4549
|
+
validate(ctx, subReport, subSchema, json);
|
|
4408
4550
|
passed = subReport.errors.length === 0;
|
|
4409
4551
|
}
|
|
4410
|
-
if (passed)
|
|
4411
|
-
if (merge(recurse(subSchema))) return "all";
|
|
4412
|
-
}
|
|
4552
|
+
if (passed && merge(recurse(subSchema))) return "all";
|
|
4413
4553
|
}
|
|
4414
4554
|
if (currentSchema.if !== void 0) {
|
|
4415
4555
|
let condPassed = getCachedValidationResult(report, currentSchema.if, json);
|
|
4416
4556
|
if (condPassed === void 0) {
|
|
4417
4557
|
const condReport = new Report(report);
|
|
4418
|
-
validate
|
|
4558
|
+
validate(ctx, condReport, currentSchema.if, json);
|
|
4419
4559
|
condPassed = condReport.errors.length === 0;
|
|
4420
4560
|
}
|
|
4421
4561
|
if (condPassed) {
|
|
4422
4562
|
if (merge(recurse(currentSchema.if))) return "all";
|
|
4423
|
-
if (currentSchema.then !== void 0)
|
|
4424
|
-
|
|
4425
|
-
}
|
|
4426
|
-
} else if (currentSchema.else !== void 0) {
|
|
4427
|
-
if (merge(recurse(currentSchema.else))) return "all";
|
|
4428
|
-
}
|
|
4429
|
-
}
|
|
4430
|
-
if (currentSchema.__$refResolved && currentSchema.__$refResolved !== currentSchema) {
|
|
4431
|
-
if (merge(recurse(currentSchema.__$refResolved))) return "all";
|
|
4563
|
+
if (currentSchema.then !== void 0 && merge(recurse(currentSchema.then))) return "all";
|
|
4564
|
+
} else if (currentSchema.else !== void 0 && merge(recurse(currentSchema.else))) return "all";
|
|
4432
4565
|
}
|
|
4566
|
+
if (currentSchema.__$refResolved && currentSchema.__$refResolved !== currentSchema && merge(recurse(currentSchema.__$refResolved))) return "all";
|
|
4433
4567
|
const recursiveTarget = resolveRecursiveRef(currentSchema, report.__$recursiveAnchorStack);
|
|
4434
|
-
if (recursiveTarget && recursiveTarget !== currentSchema)
|
|
4435
|
-
if (merge(recurse(recursiveTarget))) return "all";
|
|
4436
|
-
}
|
|
4568
|
+
if (recursiveTarget && recursiveTarget !== currentSchema && merge(recurse(recursiveTarget))) return "all";
|
|
4437
4569
|
const dynamicTarget = resolveDynamicRef(currentSchema, report.__$dynamicScopeStack);
|
|
4438
|
-
if (dynamicTarget && dynamicTarget !== currentSchema)
|
|
4439
|
-
if (merge(recurse(dynamicTarget))) return "all";
|
|
4440
|
-
}
|
|
4570
|
+
if (dynamicTarget && dynamicTarget !== currentSchema && merge(recurse(dynamicTarget))) return "all";
|
|
4441
4571
|
return evaluated;
|
|
4442
4572
|
}
|
|
4443
|
-
function unevaluatedItemsValidator(report, schema, json) {
|
|
4573
|
+
function unevaluatedItemsValidator(ctx, report, schema, json) {
|
|
4444
4574
|
if (!Array.isArray(json)) return;
|
|
4445
4575
|
if (schema.unevaluatedItems === true) return;
|
|
4446
4576
|
const unevalSchema = schema.unevaluatedItems;
|
|
4447
4577
|
if (unevalSchema === void 0) return;
|
|
4448
4578
|
if (json.length === 0) return;
|
|
4449
|
-
const evaluatedItems = collectEvaluated
|
|
4579
|
+
const evaluatedItems = collectEvaluated(ctx, {
|
|
4450
4580
|
report,
|
|
4451
4581
|
currentSchema: schema,
|
|
4452
4582
|
json,
|
|
@@ -4459,23 +4589,24 @@
|
|
|
4459
4589
|
for (let i = 0; i < json.length; i++) if (!evaluatedItems.has(i)) unevaluatedIndices.push(i);
|
|
4460
4590
|
if (unevaluatedIndices.length === 0) return;
|
|
4461
4591
|
if (unevalSchema === false) report.addError("ARRAY_UNEVALUATED_ITEMS", void 0, void 0, schema, "unevaluatedItems");
|
|
4462
|
-
else for (
|
|
4592
|
+
else for (let i = 0; i < unevaluatedIndices.length; i++) {
|
|
4593
|
+
const idx = unevaluatedIndices[i];
|
|
4463
4594
|
const subReport = new Report(report);
|
|
4464
|
-
validate
|
|
4595
|
+
validate(ctx, subReport, unevalSchema, json[idx]);
|
|
4465
4596
|
if (subReport.errors.length > 0) {
|
|
4466
4597
|
report.addError("ARRAY_UNEVALUATED_ITEMS", void 0, void 0, schema, "unevaluatedItems");
|
|
4467
4598
|
break;
|
|
4468
4599
|
}
|
|
4469
4600
|
}
|
|
4470
4601
|
}
|
|
4471
|
-
function unevaluatedPropertiesValidator(report, schema, json) {
|
|
4602
|
+
function unevaluatedPropertiesValidator(ctx, report, schema, json) {
|
|
4472
4603
|
if (!isObject(json)) return;
|
|
4473
4604
|
if (schema.unevaluatedProperties === true) return;
|
|
4474
4605
|
const unevalSchema = schema.unevaluatedProperties;
|
|
4475
4606
|
if (unevalSchema === void 0) return;
|
|
4476
4607
|
const allKeys = Object.keys(json);
|
|
4477
4608
|
if (allKeys.length === 0) return;
|
|
4478
|
-
const evaluatedProperties = collectEvaluated
|
|
4609
|
+
const evaluatedProperties = collectEvaluated(ctx, {
|
|
4479
4610
|
report,
|
|
4480
4611
|
currentSchema: schema,
|
|
4481
4612
|
json,
|
|
@@ -4484,32 +4615,35 @@
|
|
|
4484
4615
|
depth: 0
|
|
4485
4616
|
});
|
|
4486
4617
|
if (evaluatedProperties === "all") return;
|
|
4487
|
-
const unevaluatedKeys =
|
|
4618
|
+
const unevaluatedKeys = [];
|
|
4619
|
+
for (let i = 0; i < allKeys.length; i++) if (!evaluatedProperties.has(allKeys[i])) unevaluatedKeys.push(allKeys[i]);
|
|
4488
4620
|
if (unevaluatedKeys.length === 0) return;
|
|
4489
4621
|
if (unevalSchema === false) report.addError("OBJECT_UNEVALUATED_PROPERTIES", [unevaluatedKeys.join(", ")], void 0, schema, "unevaluatedProperties");
|
|
4490
|
-
else for (
|
|
4622
|
+
else for (let i = 0; i < unevaluatedKeys.length; i++) {
|
|
4623
|
+
const key = unevaluatedKeys[i];
|
|
4491
4624
|
const subReport = new Report(report);
|
|
4492
|
-
validate
|
|
4625
|
+
validate(ctx, subReport, unevalSchema, json[key]);
|
|
4493
4626
|
if (subReport.errors.length > 0) report.addError("OBJECT_UNEVALUATED_PROPERTIES", [key], void 0, schema, "unevaluatedProperties");
|
|
4494
4627
|
}
|
|
4495
4628
|
}
|
|
4496
4629
|
function definitionsValidator() {}
|
|
4630
|
+
const noopValidator = () => {};
|
|
4497
4631
|
const JsonValidators = {
|
|
4498
|
-
id:
|
|
4499
|
-
$id:
|
|
4500
|
-
$ref:
|
|
4501
|
-
$schema:
|
|
4502
|
-
$dynamicAnchor:
|
|
4503
|
-
$dynamicRef:
|
|
4504
|
-
$anchor:
|
|
4505
|
-
$defs:
|
|
4506
|
-
$vocabulary:
|
|
4507
|
-
$recursiveAnchor:
|
|
4508
|
-
$recursiveRef:
|
|
4509
|
-
examples:
|
|
4510
|
-
title:
|
|
4511
|
-
description:
|
|
4512
|
-
default:
|
|
4632
|
+
id: noopValidator,
|
|
4633
|
+
$id: noopValidator,
|
|
4634
|
+
$ref: noopValidator,
|
|
4635
|
+
$schema: noopValidator,
|
|
4636
|
+
$dynamicAnchor: noopValidator,
|
|
4637
|
+
$dynamicRef: noopValidator,
|
|
4638
|
+
$anchor: noopValidator,
|
|
4639
|
+
$defs: noopValidator,
|
|
4640
|
+
$vocabulary: noopValidator,
|
|
4641
|
+
$recursiveAnchor: noopValidator,
|
|
4642
|
+
$recursiveRef: noopValidator,
|
|
4643
|
+
examples: noopValidator,
|
|
4644
|
+
title: noopValidator,
|
|
4645
|
+
description: noopValidator,
|
|
4646
|
+
default: noopValidator,
|
|
4513
4647
|
type: typeValidator,
|
|
4514
4648
|
enum: enumValidator,
|
|
4515
4649
|
const: constValidator,
|
|
@@ -4554,18 +4688,18 @@
|
|
|
4554
4688
|
else: elseValidator,
|
|
4555
4689
|
definitions: definitionsValidator
|
|
4556
4690
|
};
|
|
4557
|
-
|
|
4691
|
+
function recurseArray(ctx, report, schema, json) {
|
|
4558
4692
|
const schemaUri = typeof schema.$schema === "string" ? schema.$schema : void 0;
|
|
4559
|
-
const prefixItems = (schemaUri === "https://json-schema.org/draft/2020-12/schema" || !schemaUri &&
|
|
4693
|
+
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;
|
|
4560
4694
|
if (prefixItems) {
|
|
4561
4695
|
for (let idx = 0; idx < json.length; idx++) if (idx < prefixItems.length) {
|
|
4562
4696
|
report.path.push(idx);
|
|
4563
|
-
validate
|
|
4697
|
+
validate(ctx, report, prefixItems[idx], json[idx]);
|
|
4564
4698
|
report.path.pop();
|
|
4565
4699
|
} else if (schema.items !== void 0 && !Array.isArray(schema.items)) {
|
|
4566
4700
|
report.path.push(idx);
|
|
4567
4701
|
report.schemaPath.push("items");
|
|
4568
|
-
validate
|
|
4702
|
+
validate(ctx, report, schema.items, json[idx]);
|
|
4569
4703
|
report.schemaPath.pop();
|
|
4570
4704
|
report.path.pop();
|
|
4571
4705
|
}
|
|
@@ -4574,50 +4708,56 @@
|
|
|
4574
4708
|
if (Array.isArray(schema.items)) {
|
|
4575
4709
|
for (let idx = 0; idx < json.length; idx++) if (idx < schema.items.length) {
|
|
4576
4710
|
report.path.push(idx);
|
|
4577
|
-
validate
|
|
4711
|
+
validate(ctx, report, schema.items[idx], json[idx]);
|
|
4578
4712
|
report.path.pop();
|
|
4579
4713
|
} else if (typeof schema.additionalItems === "object") {
|
|
4580
4714
|
report.path.push(idx);
|
|
4581
|
-
validate
|
|
4715
|
+
validate(ctx, report, schema.additionalItems, json[idx]);
|
|
4582
4716
|
report.path.pop();
|
|
4583
4717
|
}
|
|
4584
4718
|
} else if (typeof schema.items === "object" || typeof schema.items === "boolean") for (let idx = 0; idx < json.length; idx++) {
|
|
4585
4719
|
report.path.push(idx);
|
|
4586
4720
|
report.schemaPath.push("items");
|
|
4587
|
-
validate
|
|
4721
|
+
validate(ctx, report, schema.items, json[idx]);
|
|
4588
4722
|
report.schemaPath.pop();
|
|
4589
4723
|
report.path.pop();
|
|
4590
4724
|
}
|
|
4591
|
-
}
|
|
4592
|
-
|
|
4593
|
-
let additionalProperties = schema
|
|
4725
|
+
}
|
|
4726
|
+
function recurseObject(ctx, report, schema, json) {
|
|
4727
|
+
let { additionalProperties } = schema;
|
|
4594
4728
|
if (additionalProperties === true || additionalProperties === void 0) additionalProperties = {};
|
|
4595
4729
|
const p = schema.properties ? Object.keys(schema.properties) : [];
|
|
4596
4730
|
const pp = schema.patternProperties ? Object.keys(schema.patternProperties) : [];
|
|
4597
4731
|
const keys = Object.keys(json);
|
|
4732
|
+
const ppCompiled = [];
|
|
4733
|
+
for (let i = 0; i < pp.length; i++) {
|
|
4734
|
+
const r = compileSchemaRegex(pp[i]);
|
|
4735
|
+
if (r.ok) ppCompiled.push({
|
|
4736
|
+
key: pp[i],
|
|
4737
|
+
re: r.value
|
|
4738
|
+
});
|
|
4739
|
+
}
|
|
4598
4740
|
for (const m of keys) {
|
|
4599
4741
|
const propertyValue = json[m];
|
|
4742
|
+
const isProp = p.includes(m);
|
|
4600
4743
|
const s = [];
|
|
4601
|
-
if (
|
|
4602
|
-
for (
|
|
4603
|
-
const result = compileSchemaRegex(regexString);
|
|
4604
|
-
if (result.ok && result.value.test(m) === true) s.push(schema.patternProperties[regexString]);
|
|
4605
|
-
}
|
|
4744
|
+
if (isProp) s.push(schema.properties[m]);
|
|
4745
|
+
for (let i = 0; i < ppCompiled.length; i++) if (ppCompiled[i].re.test(m)) s.push(schema.patternProperties[ppCompiled[i].key]);
|
|
4606
4746
|
if (s.length === 0 && additionalProperties !== false) s.push(additionalProperties);
|
|
4607
4747
|
for (const schema_s of s) {
|
|
4608
4748
|
report.path.push(m);
|
|
4609
|
-
if (
|
|
4749
|
+
if (isProp) {
|
|
4610
4750
|
report.schemaPath.push("properties");
|
|
4611
4751
|
report.schemaPath.push(m);
|
|
4612
4752
|
} else report.schemaPath.push("additionalProperties");
|
|
4613
|
-
validate
|
|
4753
|
+
validate(ctx, report, schema_s, propertyValue);
|
|
4614
4754
|
report.path.pop();
|
|
4615
4755
|
report.schemaPath.pop();
|
|
4616
|
-
if (
|
|
4756
|
+
if (isProp) report.schemaPath.pop();
|
|
4617
4757
|
}
|
|
4618
4758
|
}
|
|
4619
|
-
}
|
|
4620
|
-
function validate(report, schema, json) {
|
|
4759
|
+
}
|
|
4760
|
+
function validate(ctx, report, schema, json) {
|
|
4621
4761
|
report.commonErrorMessage = "JSON_OBJECT_VALIDATION_FAILED";
|
|
4622
4762
|
if (schema === true) return true;
|
|
4623
4763
|
if (schema === false) {
|
|
@@ -4641,7 +4781,7 @@
|
|
|
4641
4781
|
let pushedDynamicScope = false;
|
|
4642
4782
|
const schemaId = getId(schema);
|
|
4643
4783
|
const dynamicScopeEntry = schema.__$resourceRoot || (isRoot || typeof schemaId === "string" ? schema : void 0);
|
|
4644
|
-
if (dynamicScopeEntry && dynamicScopeStack
|
|
4784
|
+
if (dynamicScopeEntry && dynamicScopeStack.at(-1) !== dynamicScopeEntry) {
|
|
4645
4785
|
dynamicScopeStack.push(dynamicScopeEntry);
|
|
4646
4786
|
pushedDynamicScope = true;
|
|
4647
4787
|
}
|
|
@@ -4649,10 +4789,11 @@
|
|
|
4649
4789
|
recursiveAnchorStack.push(schema);
|
|
4650
4790
|
pushedRecursiveAnchor = true;
|
|
4651
4791
|
}
|
|
4652
|
-
if (schema.$ref !== void 0) if (
|
|
4653
|
-
if (
|
|
4654
|
-
else
|
|
4655
|
-
|
|
4792
|
+
if (schema.$ref !== void 0) if (ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12") {
|
|
4793
|
+
if (schema.__$refResolved) validate(ctx, report, schema.__$refResolved, json);
|
|
4794
|
+
else report.addError("REF_UNRESOLVED", [schema.$ref], void 0, schema);
|
|
4795
|
+
const refIdx = keys.indexOf("$ref");
|
|
4796
|
+
if (refIdx !== -1) keys.splice(refIdx, 1);
|
|
4656
4797
|
} else {
|
|
4657
4798
|
let maxRefs = 99;
|
|
4658
4799
|
while (schema.$ref && maxRefs > 0) {
|
|
@@ -4670,58 +4811,66 @@
|
|
|
4670
4811
|
report.schemaPath = [];
|
|
4671
4812
|
}
|
|
4672
4813
|
if (schema.$recursiveRef !== void 0) {
|
|
4673
|
-
if (
|
|
4814
|
+
if (ctx.options.version === "draft2019-09" || ctx.options.version === "draft2020-12") {
|
|
4674
4815
|
const recursiveRefTarget = resolveRecursiveRef(schema, recursiveAnchorStack);
|
|
4675
|
-
if (
|
|
4676
|
-
else
|
|
4677
|
-
|
|
4816
|
+
if (recursiveRefTarget) validate(ctx, report, recursiveRefTarget, json);
|
|
4817
|
+
else report.addError("REF_UNRESOLVED", [schema.$recursiveRef], void 0, schema);
|
|
4818
|
+
const recursiveRefIdx = keys.indexOf("$recursiveRef");
|
|
4819
|
+
if (recursiveRefIdx !== -1) keys.splice(recursiveRefIdx, 1);
|
|
4678
4820
|
}
|
|
4679
4821
|
}
|
|
4680
4822
|
if (schema.$dynamicRef !== void 0) {
|
|
4681
|
-
if (
|
|
4823
|
+
if (ctx.options.version === "draft2020-12") {
|
|
4682
4824
|
const dynamicRefTarget = resolveDynamicRef(schema, dynamicScopeStack);
|
|
4683
|
-
if (
|
|
4684
|
-
else validate
|
|
4685
|
-
|
|
4825
|
+
if (dynamicRefTarget === void 0) report.addError("REF_UNRESOLVED", [schema.$dynamicRef], void 0, schema);
|
|
4826
|
+
else validate(ctx, report, dynamicRefTarget, json);
|
|
4827
|
+
const dynamicRefIdx = keys.indexOf("$dynamicRef");
|
|
4828
|
+
if (dynamicRefIdx !== -1) keys.splice(dynamicRefIdx, 1);
|
|
4686
4829
|
}
|
|
4687
4830
|
}
|
|
4688
|
-
const validationVocabularyEnabled = isValidationVocabularyEnabled(schema, report,
|
|
4689
|
-
if (!validationVocabularyEnabled)
|
|
4831
|
+
const validationVocabularyEnabled = isValidationVocabularyEnabled(schema, report, ctx.options.version);
|
|
4832
|
+
if (!validationVocabularyEnabled) {
|
|
4833
|
+
let wi = 0;
|
|
4834
|
+
for (let ri = 0; ri < keys.length; ri++) if (!VALIDATION_VOCAB_KEYWORDS.has(keys[ri])) keys[wi++] = keys[ri];
|
|
4835
|
+
keys.length = wi;
|
|
4836
|
+
}
|
|
4690
4837
|
if (validationVocabularyEnabled && schema.type) {
|
|
4691
4838
|
keys.splice(keys.indexOf("type"), 1);
|
|
4692
4839
|
report.schemaPath.push("type");
|
|
4693
|
-
JsonValidators.type
|
|
4840
|
+
JsonValidators.type(ctx, report, schema, json);
|
|
4694
4841
|
report.schemaPath.pop();
|
|
4695
|
-
if (report.errors.length &&
|
|
4842
|
+
if (report.errors.length && ctx.options.breakOnFirstError) {
|
|
4696
4843
|
if (pushedRecursiveAnchor) recursiveAnchorStack.pop();
|
|
4697
4844
|
if (pushedDynamicScope) dynamicScopeStack.pop();
|
|
4698
4845
|
return false;
|
|
4699
4846
|
}
|
|
4700
4847
|
}
|
|
4701
4848
|
const deferredUnevaluatedKeys = [];
|
|
4702
|
-
for (
|
|
4849
|
+
for (let i = 0; i < keys.length; i++) {
|
|
4850
|
+
const key = keys[i];
|
|
4703
4851
|
if (key === "unevaluatedItems" || key === "unevaluatedProperties") {
|
|
4704
4852
|
deferredUnevaluatedKeys.push(key);
|
|
4705
4853
|
continue;
|
|
4706
4854
|
}
|
|
4707
4855
|
const validator = JsonValidators[key];
|
|
4708
4856
|
if (validator) {
|
|
4709
|
-
validator
|
|
4710
|
-
if (report.errors.length &&
|
|
4857
|
+
validator(ctx, report, schema, json);
|
|
4858
|
+
if (report.errors.length && ctx.options.breakOnFirstError) break;
|
|
4711
4859
|
}
|
|
4712
4860
|
}
|
|
4713
|
-
if (deferredUnevaluatedKeys.length > 0 && !(report.errors.length > 0 &&
|
|
4861
|
+
if (deferredUnevaluatedKeys.length > 0 && !(report.errors.length > 0 && ctx.options.breakOnFirstError)) for (let i = 0; i < deferredUnevaluatedKeys.length; i++) {
|
|
4862
|
+
const key = deferredUnevaluatedKeys[i];
|
|
4714
4863
|
const validator = JsonValidators[key];
|
|
4715
4864
|
if (validator) {
|
|
4716
|
-
validator
|
|
4717
|
-
if (report.errors.length &&
|
|
4865
|
+
validator(ctx, report, schema, json);
|
|
4866
|
+
if (report.errors.length && ctx.options.breakOnFirstError) break;
|
|
4718
4867
|
}
|
|
4719
4868
|
}
|
|
4720
|
-
if (report.errors.length === 0 ||
|
|
4721
|
-
if (Array.isArray(json)) recurseArray
|
|
4722
|
-
else if (isObject(json)) recurseObject
|
|
4869
|
+
if (report.errors.length === 0 || ctx.options.breakOnFirstError === false) {
|
|
4870
|
+
if (Array.isArray(json)) recurseArray(ctx, report, schema, json);
|
|
4871
|
+
else if (isObject(json)) recurseObject(ctx, report, schema, json);
|
|
4723
4872
|
}
|
|
4724
|
-
if (typeof
|
|
4873
|
+
if (typeof ctx.options.customValidator === "function") ctx.options.customValidator.call(ctx, report, schema, json);
|
|
4725
4874
|
if (pushedRecursiveAnchor) recursiveAnchorStack.pop();
|
|
4726
4875
|
if (pushedDynamicScope) dynamicScopeStack.pop();
|
|
4727
4876
|
if (isRoot) report.rootSchema = void 0;
|
|
@@ -4738,14 +4887,14 @@
|
|
|
4738
4887
|
}
|
|
4739
4888
|
//#endregion
|
|
4740
4889
|
//#region src/schema-compiler.ts
|
|
4741
|
-
const UNSAFE_TARGETS = [
|
|
4890
|
+
const UNSAFE_TARGETS = /* @__PURE__ */ new Set([
|
|
4742
4891
|
Object.prototype,
|
|
4743
4892
|
Function.prototype,
|
|
4744
4893
|
Array.prototype
|
|
4745
|
-
];
|
|
4894
|
+
]);
|
|
4746
4895
|
/** Returns true if `obj` is a built-in prototype that must not be mutated. */
|
|
4747
4896
|
function isUnsafeTarget(obj) {
|
|
4748
|
-
return UNSAFE_TARGETS.
|
|
4897
|
+
return UNSAFE_TARGETS.has(obj);
|
|
4749
4898
|
}
|
|
4750
4899
|
/** Safely assign a property on `obj`, refusing prototype-polluting keys. */
|
|
4751
4900
|
function safeSetProperty(obj, key, value) {
|
|
@@ -4758,35 +4907,81 @@
|
|
|
4758
4907
|
if (isUnsafeTarget(obj)) return;
|
|
4759
4908
|
if (key !== "__proto__" && key !== "constructor" && key !== "prototype") delete obj[key];
|
|
4760
4909
|
}
|
|
4910
|
+
const resolveReference = (base, ref) => {
|
|
4911
|
+
if (isAbsoluteUri(ref)) return ref;
|
|
4912
|
+
const baseStr = base ?? "";
|
|
4913
|
+
if (ref.startsWith("#")) {
|
|
4914
|
+
const hashIndex = baseStr.indexOf("#");
|
|
4915
|
+
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + ref;
|
|
4916
|
+
}
|
|
4917
|
+
if (!baseStr) return ref;
|
|
4918
|
+
const hashIndex = baseStr.indexOf("#");
|
|
4919
|
+
const baseNoFrag = hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex);
|
|
4920
|
+
if (isAbsoluteUri(baseNoFrag)) try {
|
|
4921
|
+
return new URL(ref, baseNoFrag).toString();
|
|
4922
|
+
} catch {}
|
|
4923
|
+
let baseDir = baseNoFrag;
|
|
4924
|
+
if (!baseDir.endsWith("/")) {
|
|
4925
|
+
const lastSlash = baseDir.lastIndexOf("/");
|
|
4926
|
+
baseDir = lastSlash === -1 ? "" : baseDir.slice(0, lastSlash + 1);
|
|
4927
|
+
}
|
|
4928
|
+
return baseDir + ref;
|
|
4929
|
+
};
|
|
4930
|
+
const isSimpleIdentifier = (id) => !id.startsWith("#") && !id.includes("/") && !id.includes(".") && !id.includes("#");
|
|
4931
|
+
const resolveIdScope = (base, id) => {
|
|
4932
|
+
if (isAbsoluteUri(id)) return id;
|
|
4933
|
+
const baseStr = base ?? "";
|
|
4934
|
+
if (isSimpleIdentifier(id)) {
|
|
4935
|
+
const hashIndex = baseStr.indexOf("#");
|
|
4936
|
+
return `${hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)}#${id}`;
|
|
4937
|
+
}
|
|
4938
|
+
return resolveReference(base, id);
|
|
4939
|
+
};
|
|
4940
|
+
const resolveSchemaScopeId = (base, schema, id) => {
|
|
4941
|
+
if (typeof schema.$id === "string") return resolveReference(base, id);
|
|
4942
|
+
return resolveIdScope(base, id);
|
|
4943
|
+
};
|
|
4761
4944
|
const collectIds = (obj, maxDepth = 100) => {
|
|
4762
4945
|
const ids = [];
|
|
4763
4946
|
function walk(node, scope, _depth = 0) {
|
|
4764
4947
|
if (typeof node !== "object" || node == null) return;
|
|
4948
|
+
const schemaNode = node;
|
|
4765
4949
|
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.`);
|
|
4766
4950
|
let addedScope = false;
|
|
4767
|
-
const nodeId = getId(
|
|
4951
|
+
const nodeId = getId(schemaNode);
|
|
4768
4952
|
if (typeof nodeId === "string") {
|
|
4769
4953
|
let type = isAbsoluteUri(nodeId) ? "absolute" : "relative";
|
|
4770
4954
|
if (scope.length === 0) type = "root";
|
|
4771
4955
|
const id = {
|
|
4772
4956
|
id: nodeId,
|
|
4773
4957
|
type,
|
|
4774
|
-
obj:
|
|
4958
|
+
obj: schemaNode
|
|
4775
4959
|
};
|
|
4776
4960
|
if (type === "absolute" || type === "root" && isAbsoluteUri(nodeId)) id.absoluteUri = nodeId;
|
|
4777
|
-
else if (type === "root" && typeof
|
|
4961
|
+
else if (type === "root" && typeof schemaNode.id === "string" && isAbsoluteUri(schemaNode.id) && schemaNode.id !== nodeId) id.absoluteUri = resolveSchemaScopeId(schemaNode.id, schemaNode, nodeId);
|
|
4778
4962
|
else if (type === "relative") {
|
|
4779
|
-
|
|
4780
|
-
|
|
4963
|
+
let absoluteParent;
|
|
4964
|
+
for (let i = scope.length - 1; i >= 0; i--) {
|
|
4965
|
+
const sc = scope[i];
|
|
4966
|
+
if (sc.type === "absolute" || sc.type === "root" && sc.absoluteUri) {
|
|
4967
|
+
absoluteParent = sc;
|
|
4968
|
+
break;
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
id.absoluteParent = absoluteParent;
|
|
4972
|
+
if (id.absoluteParent) {
|
|
4973
|
+
const parentUri = id.absoluteParent.absoluteUri || id.absoluteParent.id;
|
|
4974
|
+
id.absoluteUri = resolveSchemaScopeId(parentUri, schemaNode, id.id);
|
|
4975
|
+
}
|
|
4781
4976
|
}
|
|
4782
4977
|
ids.push(id);
|
|
4783
4978
|
scope.push(id);
|
|
4784
4979
|
addedScope = true;
|
|
4785
4980
|
}
|
|
4786
4981
|
if (Array.isArray(node)) for (const item of node) walk(item, scope, _depth + 1);
|
|
4787
|
-
else for (const key of Object.keys(
|
|
4788
|
-
if (isInternalKey(key) ||
|
|
4789
|
-
walk(
|
|
4982
|
+
else for (const key of Object.keys(schemaNode)) {
|
|
4983
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
4984
|
+
walk(schemaNode[key], scope, _depth + 1);
|
|
4790
4985
|
}
|
|
4791
4986
|
if (addedScope) scope.pop();
|
|
4792
4987
|
}
|
|
@@ -4794,42 +4989,42 @@
|
|
|
4794
4989
|
return ids;
|
|
4795
4990
|
};
|
|
4796
4991
|
const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _depth = 0) => {
|
|
4797
|
-
results
|
|
4798
|
-
scope
|
|
4799
|
-
path
|
|
4800
|
-
options
|
|
4992
|
+
results ||= [];
|
|
4993
|
+
scope ||= [];
|
|
4994
|
+
path ||= [];
|
|
4995
|
+
options ||= {};
|
|
4801
4996
|
if (typeof obj !== "object" || obj === null) return results;
|
|
4802
4997
|
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.`);
|
|
4803
|
-
const hasRef = typeof obj.$ref === "string" &&
|
|
4998
|
+
const hasRef = typeof obj.$ref === "string" && obj.__$refResolved === void 0;
|
|
4804
4999
|
let addedScope = false;
|
|
4805
5000
|
const isRootScope = scope.length === 0;
|
|
4806
5001
|
let scopeId = getId(obj);
|
|
4807
5002
|
if (typeof obj.id === "string" && isAbsoluteUri(obj.id) && (!scopeId || !isAbsoluteUri(scopeId))) scopeId = obj.id;
|
|
4808
5003
|
if (typeof scopeId === "string" && (isRootScope || !hasRef || options.useRefObjectScope === true)) {
|
|
4809
|
-
const base = scope.length > 0 ? scope
|
|
5004
|
+
const base = scope.length > 0 ? scope.at(-1) : void 0;
|
|
4810
5005
|
scope.push(resolveSchemaScopeId(base, obj, scopeId));
|
|
4811
5006
|
addedScope = true;
|
|
4812
5007
|
}
|
|
4813
5008
|
if (hasRef) results.push({
|
|
4814
|
-
ref: resolveReference(scope
|
|
5009
|
+
ref: resolveReference(scope.at(-1), obj.$ref),
|
|
4815
5010
|
key: "$ref",
|
|
4816
5011
|
obj,
|
|
4817
5012
|
path: path.slice(0)
|
|
4818
5013
|
});
|
|
4819
|
-
if (typeof obj.$recursiveRef === "string" &&
|
|
4820
|
-
ref: resolveReference(scope
|
|
5014
|
+
if (typeof obj.$recursiveRef === "string" && obj.__$recursiveRefResolved === void 0) results.push({
|
|
5015
|
+
ref: resolveReference(scope.at(-1), obj.$recursiveRef),
|
|
4821
5016
|
key: "$recursiveRef",
|
|
4822
5017
|
obj,
|
|
4823
5018
|
path: path.slice(0)
|
|
4824
5019
|
});
|
|
4825
|
-
if (typeof obj.$dynamicRef === "string" &&
|
|
4826
|
-
ref: resolveReference(scope
|
|
5020
|
+
if (typeof obj.$dynamicRef === "string" && obj.__$dynamicRefResolved === void 0) results.push({
|
|
5021
|
+
ref: resolveReference(scope.at(-1), obj.$dynamicRef),
|
|
4827
5022
|
key: "$dynamicRef",
|
|
4828
5023
|
obj,
|
|
4829
5024
|
path: path.slice(0)
|
|
4830
5025
|
});
|
|
4831
|
-
if (typeof obj.$schema === "string" &&
|
|
4832
|
-
ref: resolveReference(scope
|
|
5026
|
+
if (typeof obj.$schema === "string" && obj.__$schemaResolved === void 0) results.push({
|
|
5027
|
+
ref: resolveReference(scope.at(-1), obj.$schema),
|
|
4833
5028
|
key: "$schema",
|
|
4834
5029
|
obj,
|
|
4835
5030
|
path: path.slice(0)
|
|
@@ -4842,7 +5037,7 @@
|
|
|
4842
5037
|
else {
|
|
4843
5038
|
const keys = Object.keys(obj);
|
|
4844
5039
|
for (const key of keys) {
|
|
4845
|
-
if (isInternalKey(key) ||
|
|
5040
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
4846
5041
|
path.push(key);
|
|
4847
5042
|
collectReferences(obj[key], results, scope, path, options, maxDepth, _depth + 1);
|
|
4848
5043
|
path.pop();
|
|
@@ -4851,41 +5046,8 @@
|
|
|
4851
5046
|
if (addedScope) scope.pop();
|
|
4852
5047
|
return results;
|
|
4853
5048
|
};
|
|
4854
|
-
const resolveReference = (base, ref) => {
|
|
4855
|
-
if (isAbsoluteUri(ref)) return ref;
|
|
4856
|
-
const baseStr = base ?? "";
|
|
4857
|
-
if (ref[0] === "#") {
|
|
4858
|
-
const hashIndex = baseStr.indexOf("#");
|
|
4859
|
-
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + ref;
|
|
4860
|
-
}
|
|
4861
|
-
if (!baseStr) return ref;
|
|
4862
|
-
const hashIndex = baseStr.indexOf("#");
|
|
4863
|
-
const baseNoFrag = hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex);
|
|
4864
|
-
if (isAbsoluteUri(baseNoFrag)) try {
|
|
4865
|
-
return new URL(ref, baseNoFrag).toString();
|
|
4866
|
-
} catch {}
|
|
4867
|
-
let baseDir = baseNoFrag;
|
|
4868
|
-
if (!baseDir.endsWith("/")) {
|
|
4869
|
-
const lastSlash = baseDir.lastIndexOf("/");
|
|
4870
|
-
baseDir = lastSlash === -1 ? "" : baseDir.slice(0, lastSlash + 1);
|
|
4871
|
-
}
|
|
4872
|
-
return baseDir + ref;
|
|
4873
|
-
};
|
|
4874
|
-
const isSimpleIdentifier = (id) => id[0] !== "#" && !id.includes("/") && !id.includes(".") && !id.includes("#");
|
|
4875
|
-
const resolveIdScope = (base, id) => {
|
|
4876
|
-
if (isAbsoluteUri(id)) return id;
|
|
4877
|
-
const baseStr = base ?? "";
|
|
4878
|
-
if (isSimpleIdentifier(id)) {
|
|
4879
|
-
const hashIndex = baseStr.indexOf("#");
|
|
4880
|
-
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + "#" + id;
|
|
4881
|
-
}
|
|
4882
|
-
return resolveReference(base, id);
|
|
4883
|
-
};
|
|
4884
|
-
const resolveSchemaScopeId = (base, schema, id) => {
|
|
4885
|
-
if (typeof schema.$id === "string") return resolveReference(base, id);
|
|
4886
|
-
return resolveIdScope(base, id);
|
|
4887
|
-
};
|
|
4888
5049
|
var SchemaCompiler = class {
|
|
5050
|
+
validator;
|
|
4889
5051
|
constructor(validator) {
|
|
4890
5052
|
this.validator = validator;
|
|
4891
5053
|
}
|
|
@@ -4894,7 +5056,8 @@
|
|
|
4894
5056
|
for (const item of ids) if (item.absoluteUri) {
|
|
4895
5057
|
this.validator.scache.cacheSchemaByUri(item.absoluteUri, item.obj);
|
|
4896
5058
|
if (item.type === "relative" && item.absoluteParent && isSimpleIdentifier(item.id)) {
|
|
4897
|
-
const
|
|
5059
|
+
const parentUri = item.absoluteParent.absoluteUri || item.absoluteParent.id;
|
|
5060
|
+
const altAbsoluteUri = resolveReference(parentUri, item.id);
|
|
4898
5061
|
this.validator.scache.cacheSchemaByUri(altAbsoluteUri, item.obj);
|
|
4899
5062
|
}
|
|
4900
5063
|
} else if (item.type === "root") this.validator.scache.cacheSchemaByUri(item.id, item.obj);
|
|
@@ -4903,19 +5066,19 @@
|
|
|
4903
5066
|
report.commonErrorMessage = "SCHEMA_COMPILATION_FAILED";
|
|
4904
5067
|
if (typeof schema === "string") {
|
|
4905
5068
|
const loadedSchema = this.validator.scache.getSchemaByUri(report, schema);
|
|
4906
|
-
if (
|
|
5069
|
+
if (loadedSchema === void 0) {
|
|
4907
5070
|
report.addError("SCHEMA_NOT_REACHABLE", [schema]);
|
|
4908
5071
|
return false;
|
|
4909
5072
|
}
|
|
4910
5073
|
schema = loadedSchema;
|
|
4911
5074
|
}
|
|
4912
5075
|
if (Array.isArray(schema)) {
|
|
4913
|
-
if (!options?.noCache) schema.
|
|
5076
|
+
if (!options?.noCache) for (let i = 0; i < schema.length; i++) this.collectAndCacheIds(schema[i]);
|
|
4914
5077
|
return this.compileArrayOfSchemas(report, schema);
|
|
4915
5078
|
} else if (typeof schema === "boolean") return true;
|
|
4916
|
-
|
|
5079
|
+
if (!options?.noCache) this.collectAndCacheIds(schema);
|
|
4917
5080
|
const canMutateSchemaObject = schema !== Object.prototype && schema !== Function.prototype && schema !== Array.prototype;
|
|
4918
|
-
if (canMutateSchemaObject && schema.__$compiled && schema.id && this.validator.scache.checkCacheForUri(schema.id)
|
|
5081
|
+
if (canMutateSchemaObject && schema.__$compiled && schema.id && !this.validator.scache.checkCacheForUri(schema.id)) schema.__$compiled = void 0;
|
|
4919
5082
|
if (schema.__$compiled) return true;
|
|
4920
5083
|
if (canMutateSchemaObject && !schema.$schema && this.validator.options.version !== "none") schema.$schema = this.validator.getDefaultSchemaId();
|
|
4921
5084
|
if (schema.id && typeof schema.id === "string" && !options?.noCache) this.validator.scache.cacheSchemaByUri(schema.id, schema);
|
|
@@ -4930,7 +5093,7 @@
|
|
|
4930
5093
|
const refs = collectReferences(schema, void 0, void 0, void 0, { useRefObjectScope }, this.validator.options.maxRecursionDepth);
|
|
4931
5094
|
for (const refObj of refs) {
|
|
4932
5095
|
let response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
4933
|
-
if (
|
|
5096
|
+
if (response === void 0) {
|
|
4934
5097
|
const schemaReader = getSchemaReader();
|
|
4935
5098
|
if (schemaReader) {
|
|
4936
5099
|
const remotePath = getRemotePath(refObj.ref);
|
|
@@ -4938,23 +5101,24 @@
|
|
|
4938
5101
|
if (s) {
|
|
4939
5102
|
s.id = remotePath;
|
|
4940
5103
|
const subreport = new Report(report);
|
|
4941
|
-
if (
|
|
4942
|
-
else
|
|
5104
|
+
if (this.compileSchema(subreport, s)) response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
5105
|
+
else for (let i = 0; i < subreport.errors.length; i++) report.errors.push(subreport.errors[i]);
|
|
4943
5106
|
}
|
|
4944
5107
|
}
|
|
4945
5108
|
}
|
|
4946
|
-
if (
|
|
5109
|
+
if (response === void 0) {
|
|
4947
5110
|
const hasNotValid = report.hasError("REMOTE_NOT_VALID", [refObj.ref]);
|
|
4948
5111
|
const isAbsolute = isAbsoluteUri(refObj.ref);
|
|
4949
5112
|
let isDownloaded = false;
|
|
4950
5113
|
const ignoreUnresolvableRemotes = this.validator.options.ignoreUnresolvableReferences === true;
|
|
4951
5114
|
if (isAbsolute) isDownloaded = this.validator.scache.checkCacheForUri(refObj.ref);
|
|
4952
5115
|
if (hasNotValid) {} else if (ignoreUnresolvableRemotes && isAbsolute) {} else if (isDownloaded) {} else {
|
|
4953
|
-
|
|
5116
|
+
const pathLen = refObj.path.length;
|
|
5117
|
+
for (let i = 0; i < pathLen; i++) report.path.push(refObj.path[i]);
|
|
4954
5118
|
report.addError("UNRESOLVABLE_REFERENCE", [refObj.ref]);
|
|
4955
|
-
report.path
|
|
5119
|
+
report.path.length -= pathLen;
|
|
4956
5120
|
if (isValidExceptReferences && canMutateSchemaObject && !isUnsafeTarget(schema)) {
|
|
4957
|
-
schema.__$missingReferences
|
|
5121
|
+
schema.__$missingReferences ||= [];
|
|
4958
5122
|
schema.__$missingReferences.push(refObj);
|
|
4959
5123
|
}
|
|
4960
5124
|
}
|
|
@@ -4969,13 +5133,20 @@
|
|
|
4969
5133
|
compileArrayOfSchemas(report, arr) {
|
|
4970
5134
|
let compiled = 0, lastLoopCompiled;
|
|
4971
5135
|
do {
|
|
4972
|
-
|
|
5136
|
+
let wi = 0;
|
|
5137
|
+
for (let ri = 0; ri < report.errors.length; ri++) if (report.errors[ri].code !== "UNRESOLVABLE_REFERENCE") report.errors[wi++] = report.errors[ri];
|
|
5138
|
+
report.errors.length = wi;
|
|
4973
5139
|
lastLoopCompiled = compiled;
|
|
4974
5140
|
compiled = this.compileArrayOfSchemasLoop(report, arr);
|
|
5141
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
5142
|
+
for (let i = 0; i < arr.length; i++) {
|
|
5143
|
+
const schemaId = arr[i].id;
|
|
5144
|
+
if (schemaId && !idMap.has(schemaId)) idMap.set(schemaId, arr[i]);
|
|
5145
|
+
}
|
|
4975
5146
|
for (const sch of arr) if (sch.__$missingReferences) {
|
|
4976
5147
|
for (let idx2 = sch.__$missingReferences.length - 1; idx2 >= 0; idx2--) {
|
|
4977
5148
|
const refObj = sch.__$missingReferences[idx2];
|
|
4978
|
-
const response =
|
|
5149
|
+
const response = idMap.get(refObj.ref);
|
|
4979
5150
|
if (response) {
|
|
4980
5151
|
safeSetProperty(refObj.obj, `__${refObj.key}Resolved`, response);
|
|
4981
5152
|
sch.__$missingReferences.splice(idx2, 1);
|
|
@@ -4991,62 +5162,74 @@
|
|
|
4991
5162
|
for (const schema of arr) {
|
|
4992
5163
|
const report = new Report(mainReport);
|
|
4993
5164
|
if (this.compileSchema(report, schema)) compiledCount++;
|
|
4994
|
-
|
|
5165
|
+
for (let i = 0; i < report.errors.length; i++) mainReport.errors.push(report.errors[i]);
|
|
4995
5166
|
}
|
|
4996
5167
|
return compiledCount;
|
|
4997
5168
|
}
|
|
4998
5169
|
};
|
|
4999
5170
|
//#endregion
|
|
5000
5171
|
//#region src/schema-validator.ts
|
|
5172
|
+
const PRIMITIVE_TYPES = [
|
|
5173
|
+
"array",
|
|
5174
|
+
"boolean",
|
|
5175
|
+
"integer",
|
|
5176
|
+
"number",
|
|
5177
|
+
"null",
|
|
5178
|
+
"object",
|
|
5179
|
+
"string"
|
|
5180
|
+
];
|
|
5181
|
+
const PRIMITIVE_TYPE_STR = PRIMITIVE_TYPES.join(",");
|
|
5182
|
+
const PRIMITIVE_TYPES_SET = new Set(PRIMITIVE_TYPES);
|
|
5001
5183
|
const SchemaValidators = {
|
|
5002
|
-
$ref
|
|
5184
|
+
$ref(report, schema) {
|
|
5003
5185
|
if (typeof schema.$ref !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["$ref", "string"], void 0, schema, "$ref");
|
|
5004
5186
|
},
|
|
5005
|
-
$schema
|
|
5187
|
+
$schema(report, schema) {
|
|
5006
5188
|
if (typeof schema.$schema !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["$schema", "string"], void 0, schema, "$schema");
|
|
5007
5189
|
},
|
|
5008
|
-
multipleOf
|
|
5190
|
+
multipleOf(report, schema) {
|
|
5009
5191
|
if (typeof schema.multipleOf !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["multipleOf", "number"], void 0, schema, "multipleOf");
|
|
5010
5192
|
else if (schema.multipleOf <= 0) report.addError("KEYWORD_MUST_BE", ["multipleOf", "strictly greater than 0"], void 0, schema, "multipleOf");
|
|
5011
5193
|
},
|
|
5012
|
-
maximum
|
|
5194
|
+
maximum(report, schema) {
|
|
5013
5195
|
if (typeof schema.maximum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["maximum", "number"], void 0, schema, "maximum");
|
|
5014
5196
|
},
|
|
5015
|
-
exclusiveMaximum
|
|
5197
|
+
exclusiveMaximum(report, schema) {
|
|
5016
5198
|
if (report.options.version === "draft-04") {
|
|
5017
5199
|
if (typeof schema.exclusiveMaximum !== "boolean") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMaximum", "boolean"], void 0, schema, "exclusiveMaximum");
|
|
5018
5200
|
else if (schema.maximum === void 0) report.addError("KEYWORD_DEPENDENCY", ["exclusiveMaximum", "maximum"], void 0, schema, "exclusiveMaximum");
|
|
5019
5201
|
} else if (typeof schema.exclusiveMaximum !== "boolean" && typeof schema.exclusiveMaximum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMaximum", ["boolean", "number"]], void 0, schema, "exclusiveMaximum");
|
|
5020
5202
|
},
|
|
5021
|
-
minimum
|
|
5203
|
+
minimum(report, schema) {
|
|
5022
5204
|
if (typeof schema.minimum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["minimum", "number"], void 0, schema, "minimum");
|
|
5023
5205
|
},
|
|
5024
|
-
exclusiveMinimum
|
|
5206
|
+
exclusiveMinimum(report, schema) {
|
|
5025
5207
|
if (report.options.version === "draft-04") {
|
|
5026
5208
|
if (typeof schema.exclusiveMinimum !== "boolean") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMinimum", "boolean"], void 0, schema, "exclusiveMinimum");
|
|
5027
5209
|
else if (schema.minimum === void 0) report.addError("KEYWORD_DEPENDENCY", ["exclusiveMinimum", "minimum"], void 0, schema, "exclusiveMinimum");
|
|
5028
5210
|
} else if (typeof schema.exclusiveMinimum !== "boolean" && typeof schema.exclusiveMinimum !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["exclusiveMinimum", ["boolean", "number"]], void 0, schema, "exclusiveMinimum");
|
|
5029
5211
|
},
|
|
5030
|
-
maxLength
|
|
5212
|
+
maxLength(report, schema) {
|
|
5031
5213
|
if (!isInteger(schema.maxLength)) report.addError("KEYWORD_TYPE_EXPECTED", ["maxLength", "integer"], void 0, schema, "maxLength");
|
|
5032
5214
|
else if (schema.maxLength < 0) report.addError("KEYWORD_MUST_BE", ["maxLength", "greater than, or equal to 0"], void 0, schema, "maxLength");
|
|
5033
5215
|
},
|
|
5034
|
-
minLength
|
|
5216
|
+
minLength(report, schema) {
|
|
5035
5217
|
if (!isInteger(schema.minLength)) report.addError("KEYWORD_TYPE_EXPECTED", ["minLength", "integer"], void 0, schema, "minLength");
|
|
5036
5218
|
else if (schema.minLength < 0) report.addError("KEYWORD_MUST_BE", ["minLength", "greater than, or equal to 0"], void 0, schema, "minLength");
|
|
5037
5219
|
},
|
|
5038
|
-
pattern
|
|
5039
|
-
if (typeof schema.pattern !== "string")
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
if (!result.ok) report.addError("KEYWORD_PATTERN", [
|
|
5043
|
-
"pattern",
|
|
5044
|
-
schema.pattern,
|
|
5045
|
-
result.error.message
|
|
5046
|
-
], void 0, schema, "pattern");
|
|
5220
|
+
pattern(report, schema) {
|
|
5221
|
+
if (typeof schema.pattern !== "string") {
|
|
5222
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["pattern", "string"], void 0, schema, "pattern");
|
|
5223
|
+
return;
|
|
5047
5224
|
}
|
|
5225
|
+
const result = compileSchemaRegex(schema.pattern);
|
|
5226
|
+
if (!result.ok) report.addError("KEYWORD_PATTERN", [
|
|
5227
|
+
"pattern",
|
|
5228
|
+
schema.pattern,
|
|
5229
|
+
result.error.message
|
|
5230
|
+
], void 0, schema, "pattern");
|
|
5048
5231
|
},
|
|
5049
|
-
additionalItems
|
|
5232
|
+
additionalItems(report, schema) {
|
|
5050
5233
|
if (typeof schema.additionalItems !== "boolean" && !isObject(schema.additionalItems)) report.addError("KEYWORD_TYPE_EXPECTED", ["additionalItems", ["boolean", "object"]], void 0, schema, "additionalItems");
|
|
5051
5234
|
else if (isObject(schema.additionalItems)) {
|
|
5052
5235
|
report.path.push("additionalItems");
|
|
@@ -5054,7 +5237,7 @@
|
|
|
5054
5237
|
report.path.pop();
|
|
5055
5238
|
}
|
|
5056
5239
|
},
|
|
5057
|
-
items
|
|
5240
|
+
items(report, schema) {
|
|
5058
5241
|
if (Array.isArray(schema.items)) for (let idx = 0; idx < schema.items.length; idx++) {
|
|
5059
5242
|
report.path.push("items");
|
|
5060
5243
|
report.path.push(idx);
|
|
@@ -5074,34 +5257,34 @@
|
|
|
5074
5257
|
if (this.options.forceAdditional === true && schema.additionalItems === void 0 && Array.isArray(schema.items)) report.addError("KEYWORD_UNDEFINED_STRICT", ["additionalItems"], void 0, schema, "additionalItems");
|
|
5075
5258
|
if (this.options.assumeAdditional && schema.additionalItems === void 0 && Array.isArray(schema.items)) schema.additionalItems = false;
|
|
5076
5259
|
},
|
|
5077
|
-
maxItems
|
|
5260
|
+
maxItems(report, schema) {
|
|
5078
5261
|
if (typeof schema.maxItems !== "number") report.addError("KEYWORD_TYPE_EXPECTED", ["maxItems", "integer"], void 0, schema, "maxItems");
|
|
5079
5262
|
else if (schema.maxItems < 0) report.addError("KEYWORD_MUST_BE", ["maxItems", "greater than, or equal to 0"], void 0, schema, "maxItems");
|
|
5080
5263
|
},
|
|
5081
|
-
minItems
|
|
5264
|
+
minItems(report, schema) {
|
|
5082
5265
|
if (!isInteger(schema.minItems)) report.addError("KEYWORD_TYPE_EXPECTED", ["minItems", "integer"], void 0, schema, "minItems");
|
|
5083
5266
|
else if (schema.minItems < 0) report.addError("KEYWORD_MUST_BE", ["minItems", "greater than, or equal to 0"], void 0, schema, "minItems");
|
|
5084
5267
|
},
|
|
5085
|
-
uniqueItems
|
|
5268
|
+
uniqueItems(report, schema) {
|
|
5086
5269
|
if (typeof schema.uniqueItems !== "boolean") report.addError("KEYWORD_TYPE_EXPECTED", ["uniqueItems", "boolean"], void 0, schema, "uniqueItems");
|
|
5087
5270
|
},
|
|
5088
|
-
maxProperties
|
|
5271
|
+
maxProperties(report, schema) {
|
|
5089
5272
|
if (!isInteger(schema.maxProperties)) report.addError("KEYWORD_TYPE_EXPECTED", ["maxProperties", "integer"], void 0, schema, "maxProperties");
|
|
5090
5273
|
else if (schema.maxProperties < 0) report.addError("KEYWORD_MUST_BE", ["maxProperties", "greater than, or equal to 0"], void 0, schema, "maxProperties");
|
|
5091
5274
|
},
|
|
5092
|
-
minProperties
|
|
5275
|
+
minProperties(report, schema) {
|
|
5093
5276
|
if (!isInteger(schema.minProperties)) report.addError("KEYWORD_TYPE_EXPECTED", ["minProperties", "integer"], void 0, schema, "minProperties");
|
|
5094
5277
|
else if (schema.minProperties < 0) report.addError("KEYWORD_MUST_BE", ["minProperties", "greater than, or equal to 0"], void 0, schema, "minProperties");
|
|
5095
5278
|
},
|
|
5096
|
-
required
|
|
5279
|
+
required(report, schema) {
|
|
5097
5280
|
if (!Array.isArray(schema.required)) report.addError("KEYWORD_TYPE_EXPECTED", ["required", "array"], void 0, schema, "required");
|
|
5098
5281
|
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");
|
|
5099
5282
|
else {
|
|
5100
5283
|
for (const item of schema.required) if (typeof item !== "string") report.addError("KEYWORD_VALUE_TYPE", ["required", "string"], void 0, schema, "required");
|
|
5101
|
-
if (isUniqueArray(schema.required)
|
|
5284
|
+
if (!isUniqueArray(schema.required)) report.addError("KEYWORD_MUST_BE", ["required", "an array with unique items"], void 0, schema, "required");
|
|
5102
5285
|
}
|
|
5103
5286
|
},
|
|
5104
|
-
additionalProperties
|
|
5287
|
+
additionalProperties(report, schema) {
|
|
5105
5288
|
if (typeof schema.additionalProperties !== "boolean" && !isObject(schema.additionalProperties)) report.addError("KEYWORD_TYPE_EXPECTED", ["additionalProperties", ["boolean", "object"]], void 0, schema, "additionalProperties");
|
|
5106
5289
|
else if (isObject(schema.additionalProperties)) {
|
|
5107
5290
|
report.path.push("additionalProperties");
|
|
@@ -5109,7 +5292,7 @@
|
|
|
5109
5292
|
report.path.pop();
|
|
5110
5293
|
}
|
|
5111
5294
|
},
|
|
5112
|
-
properties
|
|
5295
|
+
properties(report, schema) {
|
|
5113
5296
|
if (!isObject(schema.properties)) {
|
|
5114
5297
|
report.addError("KEYWORD_TYPE_EXPECTED", ["properties", "object"], void 0, schema, "properties");
|
|
5115
5298
|
return;
|
|
@@ -5127,7 +5310,7 @@
|
|
|
5127
5310
|
if (this.options.assumeAdditional && schema.additionalProperties === void 0) schema.additionalProperties = false;
|
|
5128
5311
|
if (this.options.forceProperties === true && keys.length === 0) report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["properties"], void 0, schema, "properties");
|
|
5129
5312
|
},
|
|
5130
|
-
patternProperties
|
|
5313
|
+
patternProperties(report, schema) {
|
|
5131
5314
|
if (!isObject(schema.patternProperties)) {
|
|
5132
5315
|
report.addError("KEYWORD_TYPE_EXPECTED", ["patternProperties", "object"], void 0, schema, "patternProperties");
|
|
5133
5316
|
return;
|
|
@@ -5149,93 +5332,52 @@
|
|
|
5149
5332
|
}
|
|
5150
5333
|
if (this.options.forceProperties === true && keys.length === 0) report.addError("CUSTOM_MODE_FORCE_PROPERTIES", ["patternProperties"], void 0, schema, "patternProperties");
|
|
5151
5334
|
},
|
|
5152
|
-
dependencies
|
|
5153
|
-
if (!isObject(schema.dependencies))
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5335
|
+
dependencies(report, schema) {
|
|
5336
|
+
if (!isObject(schema.dependencies)) {
|
|
5337
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["dependencies", "object"], void 0, schema, "dependencies");
|
|
5338
|
+
return;
|
|
5339
|
+
}
|
|
5340
|
+
const keys = Object.keys(schema.dependencies);
|
|
5341
|
+
for (const schemaKey of keys) {
|
|
5342
|
+
const schemaDependency = schema.dependencies[schemaKey];
|
|
5343
|
+
if (isObject(schemaDependency) || report.options.version !== "draft-04" && typeof schemaDependency === "boolean") {
|
|
5344
|
+
report.path.push("dependencies");
|
|
5345
|
+
report.path.push(schemaKey);
|
|
5346
|
+
this.validateSchema(report, schemaDependency);
|
|
5347
|
+
report.path.pop();
|
|
5348
|
+
report.path.pop();
|
|
5349
|
+
} else if (Array.isArray(schemaDependency)) {
|
|
5350
|
+
const depArray = schemaDependency;
|
|
5351
|
+
if (report.options.version === "draft-04" && depArray.length === 0) report.addError("KEYWORD_MUST_BE", ["dependencies", "not empty array"], void 0, schema, "dependencies");
|
|
5352
|
+
for (const dep of depArray) if (typeof dep !== "string") report.addError("KEYWORD_VALUE_TYPE", ["dependencies", "string"], void 0, schema, "dependencies");
|
|
5353
|
+
if (!isUniqueArray(depArray)) report.addError("KEYWORD_MUST_BE", ["dependencies", "an array with unique items"], void 0, schema, "dependencies");
|
|
5354
|
+
} else report.addError("KEYWORD_VALUE_TYPE", ["dependencies", report.options.version === "draft-04" ? "object or array" : "boolean, object or array"], void 0, schema, "dependencies");
|
|
5171
5355
|
}
|
|
5172
5356
|
},
|
|
5173
|
-
enum
|
|
5174
|
-
if (Array.isArray(schema.enum)
|
|
5357
|
+
enum(report, schema) {
|
|
5358
|
+
if (!Array.isArray(schema.enum)) report.addError("KEYWORD_TYPE_EXPECTED", ["enum", "array"], void 0, schema, "enum");
|
|
5175
5359
|
else if (schema.enum.length === 0) report.addError("KEYWORD_MUST_BE", ["enum", "an array with at least one element"], void 0, schema, "enum");
|
|
5176
|
-
else if (isUniqueArray(schema.enum)
|
|
5360
|
+
else if (!isUniqueArray(schema.enum)) report.addError("KEYWORD_MUST_BE", ["enum", "an array with unique elements"], void 0, schema, "enum");
|
|
5177
5361
|
},
|
|
5178
|
-
type
|
|
5179
|
-
const primitiveTypes = [
|
|
5180
|
-
"array",
|
|
5181
|
-
"boolean",
|
|
5182
|
-
"integer",
|
|
5183
|
-
"number",
|
|
5184
|
-
"null",
|
|
5185
|
-
"object",
|
|
5186
|
-
"string"
|
|
5187
|
-
];
|
|
5188
|
-
const primitiveTypeStr = primitiveTypes.join(",");
|
|
5362
|
+
type(report, schema) {
|
|
5189
5363
|
const isArray = Array.isArray(schema.type);
|
|
5190
5364
|
if (Array.isArray(schema.type)) {
|
|
5191
|
-
for (const typeItem of schema.type) if (!
|
|
5192
|
-
if (isUniqueArray(schema.type)
|
|
5365
|
+
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");
|
|
5366
|
+
if (!isUniqueArray(schema.type)) report.addError("KEYWORD_MUST_BE", ["type", "an object with unique properties"], void 0, schema, "type");
|
|
5193
5367
|
} else if (typeof schema.type === "string") {
|
|
5194
|
-
if (!
|
|
5368
|
+
if (!PRIMITIVE_TYPES_SET.has(schema.type)) report.addError("KEYWORD_TYPE_EXPECTED", ["type", PRIMITIVE_TYPE_STR], void 0, schema, "type");
|
|
5195
5369
|
} else report.addError("KEYWORD_TYPE_EXPECTED", ["type", ["string", "array"]], void 0, schema, "type");
|
|
5196
|
-
if (this.options.noEmptyStrings === true)
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
if (this.options.
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
}
|
|
5205
|
-
}
|
|
5206
|
-
if (this.options.forceProperties === true) {
|
|
5207
|
-
if (schema.type === "object" || isArray && schema.type.includes("object")) {
|
|
5208
|
-
if (schema.properties === void 0 && schema.patternProperties === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["properties"], void 0, schema, "properties");
|
|
5209
|
-
}
|
|
5210
|
-
}
|
|
5211
|
-
if (this.options.forceItems === true) {
|
|
5212
|
-
if (schema.type === "array" || isArray && schema.type.includes("array")) {
|
|
5213
|
-
if (schema.items === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["items"], void 0, schema, "items");
|
|
5214
|
-
}
|
|
5215
|
-
}
|
|
5216
|
-
if (this.options.forceMinItems === true) {
|
|
5217
|
-
if (schema.type === "array" || isArray && schema.type.includes("array")) {
|
|
5218
|
-
if (schema.minItems === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["minItems"], void 0, schema, "minItems");
|
|
5219
|
-
}
|
|
5220
|
-
}
|
|
5221
|
-
if (this.options.forceMaxItems === true) {
|
|
5222
|
-
if (schema.type === "array" || isArray && schema.type.includes("array")) {
|
|
5223
|
-
if (schema.maxItems === void 0) report.addError("KEYWORD_UNDEFINED_STRICT", ["maxItems"], void 0, schema, "maxItems");
|
|
5224
|
-
}
|
|
5225
|
-
}
|
|
5226
|
-
if (this.options.forceMinLength === true) {
|
|
5227
|
-
if (schema.type === "string" || isArray && schema.type.includes("string")) {
|
|
5228
|
-
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");
|
|
5229
|
-
}
|
|
5230
|
-
}
|
|
5231
|
-
if (this.options.forceMaxLength === true) {
|
|
5232
|
-
if (schema.type === "string" || isArray && schema.type.includes("string")) {
|
|
5233
|
-
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");
|
|
5234
|
-
}
|
|
5235
|
-
}
|
|
5370
|
+
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;
|
|
5371
|
+
if (this.options.noEmptyArrays === true && (schema.type === "array" || isArray && schema.type.includes("array")) && schema.minItems === void 0) schema.minItems = 1;
|
|
5372
|
+
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");
|
|
5373
|
+
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");
|
|
5374
|
+
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");
|
|
5375
|
+
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");
|
|
5376
|
+
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");
|
|
5377
|
+
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");
|
|
5236
5378
|
},
|
|
5237
|
-
allOf
|
|
5238
|
-
if (Array.isArray(schema.allOf)
|
|
5379
|
+
allOf(report, schema) {
|
|
5380
|
+
if (!Array.isArray(schema.allOf)) report.addError("KEYWORD_TYPE_EXPECTED", ["allOf", "array"], void 0, schema, "allOf");
|
|
5239
5381
|
else if (schema.allOf.length === 0) report.addError("KEYWORD_MUST_BE", ["allOf", "an array with at least one element"], void 0, schema, "allOf");
|
|
5240
5382
|
else for (let idx = 0; idx < schema.allOf.length; idx++) {
|
|
5241
5383
|
report.path.push("allOf");
|
|
@@ -5245,8 +5387,8 @@
|
|
|
5245
5387
|
report.path.pop();
|
|
5246
5388
|
}
|
|
5247
5389
|
},
|
|
5248
|
-
anyOf
|
|
5249
|
-
if (Array.isArray(schema.anyOf)
|
|
5390
|
+
anyOf(report, schema) {
|
|
5391
|
+
if (!Array.isArray(schema.anyOf)) report.addError("KEYWORD_TYPE_EXPECTED", ["anyOf", "array"], void 0, schema, "anyOf");
|
|
5250
5392
|
else if (schema.anyOf.length === 0) report.addError("KEYWORD_MUST_BE", ["anyOf", "an array with at least one element"], void 0, schema, "anyOf");
|
|
5251
5393
|
else for (let idx = 0; idx < schema.anyOf.length; idx++) {
|
|
5252
5394
|
report.path.push("anyOf");
|
|
@@ -5256,8 +5398,8 @@
|
|
|
5256
5398
|
report.path.pop();
|
|
5257
5399
|
}
|
|
5258
5400
|
},
|
|
5259
|
-
oneOf
|
|
5260
|
-
if (Array.isArray(schema.oneOf)
|
|
5401
|
+
oneOf(report, schema) {
|
|
5402
|
+
if (!Array.isArray(schema.oneOf)) report.addError("KEYWORD_TYPE_EXPECTED", ["oneOf", "array"], void 0, schema, "oneOf");
|
|
5261
5403
|
else if (schema.oneOf.length === 0) report.addError("KEYWORD_MUST_BE", ["oneOf", "an array with at least one element"], void 0, schema, "oneOf");
|
|
5262
5404
|
else for (let idx = 0; idx < schema.oneOf.length; idx++) {
|
|
5263
5405
|
report.path.push("oneOf");
|
|
@@ -5267,16 +5409,17 @@
|
|
|
5267
5409
|
report.path.pop();
|
|
5268
5410
|
}
|
|
5269
5411
|
},
|
|
5270
|
-
not
|
|
5412
|
+
not(report, schema) {
|
|
5271
5413
|
const notSchema = schema.not;
|
|
5272
|
-
if (!(report.options.version === "draft-04" ? isObject(notSchema) : typeof notSchema === "boolean" || isObject(notSchema)))
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
this.validateSchema(report, notSchema);
|
|
5276
|
-
report.path.pop();
|
|
5414
|
+
if (!(report.options.version === "draft-04" ? isObject(notSchema) : typeof notSchema === "boolean" || isObject(notSchema))) {
|
|
5415
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["not", report.options.version === "draft-04" ? "object" : ["boolean", "object"]], void 0, schema, "not");
|
|
5416
|
+
return;
|
|
5277
5417
|
}
|
|
5418
|
+
report.path.push("not");
|
|
5419
|
+
this.validateSchema(report, notSchema);
|
|
5420
|
+
report.path.pop();
|
|
5278
5421
|
},
|
|
5279
|
-
if
|
|
5422
|
+
if(report, schema) {
|
|
5280
5423
|
if (report.options.version !== "draft-07") return;
|
|
5281
5424
|
const ifSchema = schema.if;
|
|
5282
5425
|
if (!(typeof ifSchema === "boolean" || isObject(ifSchema))) {
|
|
@@ -5287,7 +5430,7 @@
|
|
|
5287
5430
|
this.validateSchema(report, ifSchema);
|
|
5288
5431
|
report.path.pop();
|
|
5289
5432
|
},
|
|
5290
|
-
then
|
|
5433
|
+
then(report, schema) {
|
|
5291
5434
|
if (report.options.version !== "draft-07") return;
|
|
5292
5435
|
const thenSchema = schema.then;
|
|
5293
5436
|
if (!(typeof thenSchema === "boolean" || isObject(thenSchema))) {
|
|
@@ -5298,7 +5441,7 @@
|
|
|
5298
5441
|
this.validateSchema(report, thenSchema);
|
|
5299
5442
|
report.path.pop();
|
|
5300
5443
|
},
|
|
5301
|
-
else
|
|
5444
|
+
else(report, schema) {
|
|
5302
5445
|
if (report.options.version !== "draft-07") return;
|
|
5303
5446
|
const elseSchema = schema.else;
|
|
5304
5447
|
if (!(typeof elseSchema === "boolean" || isObject(elseSchema))) {
|
|
@@ -5309,21 +5452,22 @@
|
|
|
5309
5452
|
this.validateSchema(report, elseSchema);
|
|
5310
5453
|
report.path.pop();
|
|
5311
5454
|
},
|
|
5312
|
-
definitions
|
|
5313
|
-
if (!isObject(schema.definitions))
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5455
|
+
definitions(report, schema) {
|
|
5456
|
+
if (!isObject(schema.definitions)) {
|
|
5457
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["definitions", "object"], void 0, schema, "definitions");
|
|
5458
|
+
return;
|
|
5459
|
+
}
|
|
5460
|
+
const keys = Object.keys(schema.definitions);
|
|
5461
|
+
for (const key of keys) {
|
|
5462
|
+
const val = schema.definitions[key];
|
|
5463
|
+
report.path.push("definitions");
|
|
5464
|
+
report.path.push(key);
|
|
5465
|
+
this.validateSchema(report, val);
|
|
5466
|
+
report.path.pop();
|
|
5467
|
+
report.path.pop();
|
|
5324
5468
|
}
|
|
5325
5469
|
},
|
|
5326
|
-
$defs
|
|
5470
|
+
$defs(report, schema) {
|
|
5327
5471
|
if (report.options.version !== "draft2019-09" && report.options.version !== "draft2020-12") return;
|
|
5328
5472
|
if (!isObject(schema.$defs)) {
|
|
5329
5473
|
report.addError("KEYWORD_TYPE_EXPECTED", ["$defs", "object"], void 0, schema, "$defs");
|
|
@@ -5339,34 +5483,36 @@
|
|
|
5339
5483
|
report.path.pop();
|
|
5340
5484
|
}
|
|
5341
5485
|
},
|
|
5342
|
-
format
|
|
5486
|
+
format(report, schema) {
|
|
5343
5487
|
if (this.options.formatAssertions === false) return;
|
|
5344
|
-
if (typeof schema.format !== "string")
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
if (!isFormatSupported(schema.format, this.options.customFormats) && this.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
5488
|
+
if (typeof schema.format !== "string") {
|
|
5489
|
+
report.addError("KEYWORD_TYPE_EXPECTED", ["format", "string"], void 0, schema, "format");
|
|
5490
|
+
return;
|
|
5348
5491
|
}
|
|
5492
|
+
const isModernDraft = this.options.version === "draft2019-09" || this.options.version === "draft2020-12";
|
|
5493
|
+
if (!isFormatSupported(schema.format, this.options.customFormats) && this.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
5349
5494
|
},
|
|
5350
|
-
contentEncoding
|
|
5495
|
+
contentEncoding(report, schema) {
|
|
5351
5496
|
if (report.options.version !== "draft-07") return;
|
|
5352
5497
|
if (typeof schema.contentEncoding !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["contentEncoding", "string"], void 0, schema, "contentEncoding");
|
|
5353
5498
|
},
|
|
5354
|
-
contentMediaType
|
|
5499
|
+
contentMediaType(report, schema) {
|
|
5355
5500
|
if (report.options.version !== "draft-07") return;
|
|
5356
5501
|
if (typeof schema.contentMediaType !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["contentMediaType", "string"], void 0, schema, "contentMediaType");
|
|
5357
5502
|
},
|
|
5358
|
-
id
|
|
5503
|
+
id(report, schema) {
|
|
5359
5504
|
if (typeof schema.id !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["id", "string"], void 0, schema, "id");
|
|
5360
5505
|
},
|
|
5361
|
-
title
|
|
5506
|
+
title(report, schema) {
|
|
5362
5507
|
if (typeof schema.title !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["title", "string"], void 0, schema, "title");
|
|
5363
5508
|
},
|
|
5364
|
-
description
|
|
5509
|
+
description(report, schema) {
|
|
5365
5510
|
if (typeof schema.description !== "string") report.addError("KEYWORD_TYPE_EXPECTED", ["description", "string"], void 0, schema, "description");
|
|
5366
5511
|
},
|
|
5367
|
-
default
|
|
5512
|
+
default() {}
|
|
5368
5513
|
};
|
|
5369
5514
|
var SchemaValidator = class {
|
|
5515
|
+
validator;
|
|
5370
5516
|
constructor(validator) {
|
|
5371
5517
|
this.validator = validator;
|
|
5372
5518
|
}
|
|
@@ -5386,18 +5532,17 @@
|
|
|
5386
5532
|
if (hasParentSchema) {
|
|
5387
5533
|
if (schema.__$schemaResolved && schema.__$schemaResolved !== schema) {
|
|
5388
5534
|
const subReport = new Report(report);
|
|
5389
|
-
if (validate
|
|
5535
|
+
if (!validate(this.validator, subReport, schema.__$schemaResolved, schema)) report.addError("PARENT_SCHEMA_VALIDATION_FAILED", void 0, subReport, schema, "$schema");
|
|
5390
5536
|
} else if (this.validator.options.ignoreUnresolvableReferences !== true) report.addError("REF_UNRESOLVED", [schema.$schema], void 0, schema, "$schema");
|
|
5391
5537
|
}
|
|
5392
5538
|
if (this.validator.options.noTypeless === true) {
|
|
5393
5539
|
if (schema.type !== void 0) {
|
|
5394
|
-
|
|
5395
|
-
if (Array.isArray(schema.anyOf)) schemas = schemas.concat(schema.anyOf);
|
|
5396
|
-
if (Array.isArray(schema.oneOf)) schemas = schemas.concat(schema.oneOf);
|
|
5397
|
-
if (Array.isArray(schema.allOf)) schemas = schemas.concat(schema.allOf);
|
|
5398
|
-
schemas.forEach(function(sch) {
|
|
5540
|
+
const inheritType = (sch) => {
|
|
5399
5541
|
if (!sch.type) sch.type = schema.type;
|
|
5400
|
-
}
|
|
5542
|
+
};
|
|
5543
|
+
if (Array.isArray(schema.anyOf)) for (let i = 0; i < schema.anyOf.length; i++) inheritType(schema.anyOf[i]);
|
|
5544
|
+
if (Array.isArray(schema.oneOf)) for (let i = 0; i < schema.oneOf.length; i++) inheritType(schema.oneOf[i]);
|
|
5545
|
+
if (Array.isArray(schema.allOf)) for (let i = 0; i < schema.allOf.length; i++) inheritType(schema.allOf[i]);
|
|
5401
5546
|
}
|
|
5402
5547
|
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");
|
|
5403
5548
|
}
|
|
@@ -5405,9 +5550,7 @@
|
|
|
5405
5550
|
for (const key of keys) {
|
|
5406
5551
|
if (key.startsWith("__")) continue;
|
|
5407
5552
|
if (Object.hasOwn(SchemaValidators, key)) SchemaValidators[key].call(this, report, schema);
|
|
5408
|
-
else if (!hasParentSchema)
|
|
5409
|
-
if (this.validator.options.noExtraKeywords === true) report.addError("KEYWORD_UNEXPECTED", [key], void 0, schema, void 0);
|
|
5410
|
-
}
|
|
5553
|
+
else if (!hasParentSchema && this.validator.options.noExtraKeywords === true) report.addError("KEYWORD_UNEXPECTED", [key], void 0, schema);
|
|
5411
5554
|
}
|
|
5412
5555
|
if (this.validator.options.pedanticCheck === true) {
|
|
5413
5556
|
if (schema.enum) {
|
|
@@ -5417,14 +5560,14 @@
|
|
|
5417
5560
|
report.path.push("enum");
|
|
5418
5561
|
for (let idx = 0; idx < schema.enum.length; idx++) {
|
|
5419
5562
|
report.path.push(idx);
|
|
5420
|
-
validate
|
|
5563
|
+
validate(this.validator, report, tmpSchema, schema.enum[idx]);
|
|
5421
5564
|
report.path.pop();
|
|
5422
5565
|
}
|
|
5423
5566
|
report.path.pop();
|
|
5424
5567
|
}
|
|
5425
5568
|
if (schema.default) {
|
|
5426
5569
|
report.path.push("default");
|
|
5427
|
-
validate
|
|
5570
|
+
validate(this.validator, report, schema, schema.default);
|
|
5428
5571
|
report.path.pop();
|
|
5429
5572
|
}
|
|
5430
5573
|
}
|
|
@@ -5461,7 +5604,7 @@
|
|
|
5461
5604
|
* create a circular dependency).
|
|
5462
5605
|
*/
|
|
5463
5606
|
_jsonValidate(report, schema, json) {
|
|
5464
|
-
return validate
|
|
5607
|
+
return validate(this, report, schema, json);
|
|
5465
5608
|
}
|
|
5466
5609
|
getDefaultSchemaId() {
|
|
5467
5610
|
return this.options.version && this.options.version !== "none" ? VERSION_SCHEMA_URL_MAPPING[this.options.version] : VERSION_SCHEMA_URL_MAPPING[defaultOptions.version];
|
|
@@ -5474,9 +5617,9 @@
|
|
|
5474
5617
|
if (!options) options = {};
|
|
5475
5618
|
this.validateOptions = options;
|
|
5476
5619
|
if (typeof schema !== "string" && typeof schema !== "boolean" && !isObject(schema)) {
|
|
5477
|
-
const e = /* @__PURE__ */ new Error(
|
|
5620
|
+
const e = /* @__PURE__ */ new Error(`Invalid .validate call - schema must be a string or object but ${whatIs(schema)} was passed!`);
|
|
5478
5621
|
if (callback) {
|
|
5479
|
-
setTimeout(
|
|
5622
|
+
setTimeout(() => {
|
|
5480
5623
|
callback(e, false);
|
|
5481
5624
|
}, 0);
|
|
5482
5625
|
return;
|
|
@@ -5491,9 +5634,9 @@
|
|
|
5491
5634
|
const schemaName = schema;
|
|
5492
5635
|
_schema = this.scache.getSchema(report, schemaName);
|
|
5493
5636
|
if (!_schema) {
|
|
5494
|
-
const e = /* @__PURE__ */ new Error(
|
|
5637
|
+
const e = /* @__PURE__ */ new Error(`Schema with id '${schemaName}' wasn't found in the validator cache!`);
|
|
5495
5638
|
if (callback) {
|
|
5496
|
-
setTimeout(
|
|
5639
|
+
setTimeout(() => {
|
|
5497
5640
|
callback(e, false);
|
|
5498
5641
|
}, 0);
|
|
5499
5642
|
return;
|
|
@@ -5511,9 +5654,9 @@
|
|
|
5511
5654
|
report.rootSchema = _schema;
|
|
5512
5655
|
_schema = get(_schema, options.schemaPath);
|
|
5513
5656
|
if (!_schema) {
|
|
5514
|
-
const e = /* @__PURE__ */ new Error(
|
|
5657
|
+
const e = /* @__PURE__ */ new Error(`Schema path '${options.schemaPath}' wasn't found in the schema!`);
|
|
5515
5658
|
if (callback) {
|
|
5516
|
-
setTimeout(
|
|
5659
|
+
setTimeout(() => {
|
|
5517
5660
|
callback(e, false);
|
|
5518
5661
|
}, 0);
|
|
5519
5662
|
return;
|
|
@@ -5521,7 +5664,7 @@
|
|
|
5521
5664
|
throw e;
|
|
5522
5665
|
}
|
|
5523
5666
|
}
|
|
5524
|
-
if (!foundError) validate
|
|
5667
|
+
if (!foundError) validate(this, report, _schema, json);
|
|
5525
5668
|
if (callback) {
|
|
5526
5669
|
report.processAsyncTasks(this.options.asyncTimeout, callback);
|
|
5527
5670
|
return;
|
|
@@ -5592,8 +5735,8 @@
|
|
|
5592
5735
|
if (!err) return [];
|
|
5593
5736
|
const details = err.details || [];
|
|
5594
5737
|
const missingRefs = [];
|
|
5595
|
-
function collect(
|
|
5596
|
-
for (const detail of
|
|
5738
|
+
function collect(items) {
|
|
5739
|
+
for (const detail of items) {
|
|
5597
5740
|
if (detail.code === "UNRESOLVABLE_REFERENCE" || detail.code === "SCHEMA_NOT_REACHABLE") missingRefs.push(detail.params[0]);
|
|
5598
5741
|
if (detail.inner) collect(detail.inner);
|
|
5599
5742
|
}
|
|
@@ -5609,9 +5752,13 @@
|
|
|
5609
5752
|
getMissingRemoteReferences(err) {
|
|
5610
5753
|
const missingReferences = this.getMissingReferences(err);
|
|
5611
5754
|
const missingRemoteReferences = [];
|
|
5755
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5612
5756
|
for (const ref of missingReferences) {
|
|
5613
5757
|
const remoteReference = getRemotePath(ref);
|
|
5614
|
-
if (remoteReference && !
|
|
5758
|
+
if (remoteReference && !seen.has(remoteReference)) {
|
|
5759
|
+
seen.add(remoteReference);
|
|
5760
|
+
missingRemoteReferences.push(remoteReference);
|
|
5761
|
+
}
|
|
5615
5762
|
}
|
|
5616
5763
|
return missingRemoteReferences;
|
|
5617
5764
|
}
|
|
@@ -5624,24 +5771,25 @@
|
|
|
5624
5771
|
getResolvedSchema(schemaId) {
|
|
5625
5772
|
const report = new Report(this.options);
|
|
5626
5773
|
const schema = this.scache.getSchemaByUri(report, schemaId);
|
|
5627
|
-
if (!schema) return
|
|
5774
|
+
if (!schema) return;
|
|
5628
5775
|
const clonedSchema = deepClone(schema, this.options.maxRecursionDepth);
|
|
5629
5776
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
5630
|
-
const cleanup =
|
|
5631
|
-
|
|
5632
|
-
const typeOf = whatIs(schema);
|
|
5777
|
+
const cleanup = (node) => {
|
|
5778
|
+
const typeOf = whatIs(node);
|
|
5633
5779
|
if (typeOf !== "object" && typeOf !== "array") return;
|
|
5634
|
-
if (visited.has(
|
|
5635
|
-
visited.add(
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
const
|
|
5639
|
-
|
|
5640
|
-
delete
|
|
5641
|
-
|
|
5780
|
+
if (visited.has(node)) return;
|
|
5781
|
+
visited.add(node);
|
|
5782
|
+
const schemaNode = node;
|
|
5783
|
+
if (schemaNode.$ref && schemaNode.__$refResolved) {
|
|
5784
|
+
const from = schemaNode.__$refResolved;
|
|
5785
|
+
const to = schemaNode;
|
|
5786
|
+
delete schemaNode.$ref;
|
|
5787
|
+
delete schemaNode.__$refResolved;
|
|
5788
|
+
for (const key in from) if (Object.hasOwn(from, key)) copyProp(from, to, key);
|
|
5642
5789
|
}
|
|
5643
|
-
|
|
5644
|
-
|
|
5790
|
+
const record = node;
|
|
5791
|
+
for (const key in record) if (Object.hasOwn(record, key)) if (isInternalKey(key)) delete record[key];
|
|
5792
|
+
else cleanup(record[key]);
|
|
5645
5793
|
};
|
|
5646
5794
|
cleanup(clonedSchema);
|
|
5647
5795
|
return clonedSchema;
|
|
@@ -5650,24 +5798,20 @@
|
|
|
5650
5798
|
//#endregion
|
|
5651
5799
|
//#region src/z-schema.ts
|
|
5652
5800
|
var ZSchema = class ZSchema extends ZSchemaBase {
|
|
5653
|
-
/** @internal Use ZSchema.create() instead. */
|
|
5654
|
-
constructor(options, token) {
|
|
5655
|
-
super(options, token);
|
|
5656
|
-
}
|
|
5657
5801
|
/**
|
|
5658
5802
|
* Register a global format validator available to all instances.
|
|
5659
5803
|
* @param name - The format name (e.g. `'email'`, `'date'`).
|
|
5660
5804
|
* @param validatorFunction - A sync or async function `(value: unknown) => boolean | Promise<boolean>`.
|
|
5661
5805
|
*/
|
|
5662
5806
|
static registerFormat(name, validatorFunction) {
|
|
5663
|
-
|
|
5807
|
+
registerFormat(name, validatorFunction);
|
|
5664
5808
|
}
|
|
5665
5809
|
/**
|
|
5666
5810
|
* Remove a globally registered format validator.
|
|
5667
5811
|
* @param name - The format name to unregister.
|
|
5668
5812
|
*/
|
|
5669
5813
|
static unregisterFormat(name) {
|
|
5670
|
-
|
|
5814
|
+
unregisterFormat(name);
|
|
5671
5815
|
}
|
|
5672
5816
|
/** Returns the names of all globally registered format validators. */
|
|
5673
5817
|
static getRegisteredFormats() {
|
|
@@ -5696,7 +5840,7 @@
|
|
|
5696
5840
|
* @param schemaReader - A function `(uri: string) => JsonSchema | undefined`, or `undefined` to clear.
|
|
5697
5841
|
*/
|
|
5698
5842
|
static setSchemaReader(schemaReader) {
|
|
5699
|
-
|
|
5843
|
+
setSchemaReader(schemaReader);
|
|
5700
5844
|
}
|
|
5701
5845
|
static schemaSymbol = schemaSymbol;
|
|
5702
5846
|
static jsonSymbol = jsonSymbol;
|
|
@@ -5732,10 +5876,10 @@
|
|
|
5732
5876
|
try {
|
|
5733
5877
|
this._validate(json, schema, options ?? {});
|
|
5734
5878
|
return { valid: true };
|
|
5735
|
-
} catch (
|
|
5879
|
+
} catch (error) {
|
|
5736
5880
|
return {
|
|
5737
5881
|
valid: false,
|
|
5738
|
-
err
|
|
5882
|
+
err: error
|
|
5739
5883
|
};
|
|
5740
5884
|
}
|
|
5741
5885
|
}
|
|
@@ -5750,9 +5894,12 @@
|
|
|
5750
5894
|
validateAsync(json, schema, options) {
|
|
5751
5895
|
return new Promise((resolve, reject) => {
|
|
5752
5896
|
try {
|
|
5753
|
-
this._validate(json, schema, options || {}, (err, valid) =>
|
|
5754
|
-
|
|
5755
|
-
|
|
5897
|
+
this._validate(json, schema, options || {}, (err, valid) => {
|
|
5898
|
+
if (err || !valid) reject(err ?? /* @__PURE__ */ new Error("Validation failed"));
|
|
5899
|
+
else resolve(valid);
|
|
5900
|
+
});
|
|
5901
|
+
} catch (error) {
|
|
5902
|
+
reject(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
5756
5903
|
}
|
|
5757
5904
|
});
|
|
5758
5905
|
}
|
|
@@ -5773,10 +5920,10 @@
|
|
|
5773
5920
|
err
|
|
5774
5921
|
});
|
|
5775
5922
|
});
|
|
5776
|
-
} catch (
|
|
5923
|
+
} catch (error) {
|
|
5777
5924
|
resolve({
|
|
5778
5925
|
valid: false,
|
|
5779
|
-
err
|
|
5926
|
+
err: error
|
|
5780
5927
|
});
|
|
5781
5928
|
}
|
|
5782
5929
|
});
|
|
@@ -5799,10 +5946,10 @@
|
|
|
5799
5946
|
try {
|
|
5800
5947
|
this._validateSchema(schemaOrArr);
|
|
5801
5948
|
return { valid: true };
|
|
5802
|
-
} catch (
|
|
5949
|
+
} catch (error) {
|
|
5803
5950
|
return {
|
|
5804
5951
|
valid: false,
|
|
5805
|
-
err
|
|
5952
|
+
err: error
|
|
5806
5953
|
};
|
|
5807
5954
|
}
|
|
5808
5955
|
}
|
|
@@ -5812,10 +5959,6 @@
|
|
|
5812
5959
|
* Created via `ZSchema.create({ safe: true })`.
|
|
5813
5960
|
*/
|
|
5814
5961
|
var ZSchemaSafe = class extends ZSchemaBase {
|
|
5815
|
-
/** @internal Use ZSchema.create() instead. */
|
|
5816
|
-
constructor(options, token) {
|
|
5817
|
-
super(options, token);
|
|
5818
|
-
}
|
|
5819
5962
|
/**
|
|
5820
5963
|
* Validate JSON data against a schema.
|
|
5821
5964
|
* @param json - The data to validate.
|
|
@@ -5827,10 +5970,10 @@
|
|
|
5827
5970
|
try {
|
|
5828
5971
|
this._validate(json, schema, options);
|
|
5829
5972
|
return { valid: true };
|
|
5830
|
-
} catch (
|
|
5973
|
+
} catch (error) {
|
|
5831
5974
|
return {
|
|
5832
5975
|
valid: false,
|
|
5833
|
-
err
|
|
5976
|
+
err: error
|
|
5834
5977
|
};
|
|
5835
5978
|
}
|
|
5836
5979
|
}
|
|
@@ -5843,10 +5986,10 @@
|
|
|
5843
5986
|
try {
|
|
5844
5987
|
this._validateSchema(schemaOrArr);
|
|
5845
5988
|
return { valid: true };
|
|
5846
|
-
} catch (
|
|
5989
|
+
} catch (error) {
|
|
5847
5990
|
return {
|
|
5848
5991
|
valid: false,
|
|
5849
|
-
err
|
|
5992
|
+
err: error
|
|
5850
5993
|
};
|
|
5851
5994
|
}
|
|
5852
5995
|
}
|
|
@@ -5856,10 +5999,6 @@
|
|
|
5856
5999
|
* Created via `ZSchema.create({ async: true })`.
|
|
5857
6000
|
*/
|
|
5858
6001
|
var ZSchemaAsync = class extends ZSchemaBase {
|
|
5859
|
-
/** @internal Use ZSchema.create() instead. */
|
|
5860
|
-
constructor(options, token) {
|
|
5861
|
-
super(options, token);
|
|
5862
|
-
}
|
|
5863
6002
|
/**
|
|
5864
6003
|
* Validate JSON data against a schema asynchronously.
|
|
5865
6004
|
* @param json - The data to validate.
|
|
@@ -5871,9 +6010,12 @@
|
|
|
5871
6010
|
validate(json, schema, options = {}) {
|
|
5872
6011
|
return new Promise((resolve, reject) => {
|
|
5873
6012
|
try {
|
|
5874
|
-
this._validate(json, schema, options, (err, valid) =>
|
|
5875
|
-
|
|
5876
|
-
|
|
6013
|
+
this._validate(json, schema, options, (err, valid) => {
|
|
6014
|
+
if (err || !valid) reject(err ?? /* @__PURE__ */ new Error("Validation failed"));
|
|
6015
|
+
else resolve(valid);
|
|
6016
|
+
});
|
|
6017
|
+
} catch (error) {
|
|
6018
|
+
reject(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
5877
6019
|
}
|
|
5878
6020
|
});
|
|
5879
6021
|
}
|
|
@@ -5892,10 +6034,6 @@
|
|
|
5892
6034
|
* Created via `ZSchema.create({ async: true, safe: true })`.
|
|
5893
6035
|
*/
|
|
5894
6036
|
var ZSchemaAsyncSafe = class extends ZSchemaBase {
|
|
5895
|
-
/** @internal Use ZSchema.create() instead. */
|
|
5896
|
-
constructor(options, token) {
|
|
5897
|
-
super(options, token);
|
|
5898
|
-
}
|
|
5899
6037
|
/**
|
|
5900
6038
|
* Validate JSON data against a schema asynchronously.
|
|
5901
6039
|
* The promise always resolves (never rejects).
|
|
@@ -5913,10 +6051,10 @@
|
|
|
5913
6051
|
err
|
|
5914
6052
|
});
|
|
5915
6053
|
});
|
|
5916
|
-
} catch (
|
|
6054
|
+
} catch (error) {
|
|
5917
6055
|
resolve({
|
|
5918
6056
|
valid: false,
|
|
5919
|
-
err
|
|
6057
|
+
err: error
|
|
5920
6058
|
});
|
|
5921
6059
|
}
|
|
5922
6060
|
});
|
|
@@ -5930,10 +6068,10 @@
|
|
|
5930
6068
|
try {
|
|
5931
6069
|
this._validateSchema(schemaOrArr);
|
|
5932
6070
|
return { valid: true };
|
|
5933
|
-
} catch (
|
|
6071
|
+
} catch (error) {
|
|
5934
6072
|
return {
|
|
5935
6073
|
valid: false,
|
|
5936
|
-
err
|
|
6074
|
+
err: error
|
|
5937
6075
|
};
|
|
5938
6076
|
}
|
|
5939
6077
|
}
|