z-schema 12.2.0 → 12.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/z-schema +1 -1
- package/cjs/{index.js → index.cjs} +696 -687
- package/cjs/{index.d.ts → index.d.cts} +47 -26
- package/dist/{errors.d.mts → errors.d.ts} +2 -2
- package/dist/{errors.mjs → errors.js} +1 -2
- package/dist/{format-validators.mjs → format-validators.js} +43 -36
- package/dist/{index.d.mts → index.d.ts} +9 -9
- package/dist/{index.mjs → index.js} +3 -3
- package/dist/{json-schema-versions.d.mts → json-schema-versions.d.ts} +34 -3
- package/dist/{json-schema.d.mts → json-schema.d.ts} +7 -7
- package/dist/{json-schema.mjs → json-schema.js} +7 -12
- package/dist/{json-validation.mjs → json-validation.js} +143 -127
- package/dist/{report.d.mts → report.d.ts} +7 -8
- package/dist/{report.mjs → report.js} +28 -31
- package/dist/{schema-cache.d.mts → schema-cache.d.ts} +4 -4
- package/dist/{schema-cache.mjs → schema-cache.js} +10 -11
- package/dist/{schema-compiler.d.mts → schema-compiler.d.ts} +4 -4
- package/dist/{schema-compiler.mjs → schema-compiler.js} +95 -77
- package/dist/{schema-validator.d.mts → schema-validator.d.ts} +5 -5
- package/dist/{schema-validator.mjs → schema-validator.js} +138 -166
- package/dist/utils/{array.mjs → array.js} +4 -3
- package/dist/utils/{base64.mjs → base64.js} +3 -2
- package/dist/utils/{clone.mjs → clone.js} +18 -20
- package/dist/utils/{hostname.mjs → hostname.js} +19 -22
- package/dist/utils/{json.mjs → json.js} +11 -7
- package/dist/utils/{schema-regex.mjs → schema-regex.js} +5 -5
- package/dist/utils/{time.mjs → time.js} +5 -5
- package/dist/utils/unicode.js +22 -0
- package/dist/utils/{what-is.mjs → what-is.js} +1 -2
- package/dist/validation/{array.mjs → array.js} +18 -20
- package/dist/validation/{combinators.mjs → combinators.js} +16 -16
- package/dist/validation/{numeric.mjs → numeric.js} +11 -11
- package/dist/validation/{object.mjs → object.js} +35 -34
- package/dist/validation/{ref.mjs → ref.js} +4 -4
- package/dist/validation/{shared.mjs → shared.js} +12 -11
- package/dist/validation/{string.mjs → string.js} +32 -32
- package/dist/validation/type.js +34 -0
- package/dist/{z-schema-base.d.mts → z-schema-base.d.ts} +11 -12
- package/dist/{z-schema-base.mjs → z-schema-base.js} +45 -40
- package/dist/{z-schema-options.d.mts → z-schema-options.d.ts} +3 -3
- package/dist/{z-schema-options.mjs → z-schema-options.js} +4 -4
- package/dist/{z-schema-reader.d.mts → z-schema-reader.d.ts} +1 -1
- package/dist/{z-schema-versions.mjs → z-schema-versions.js} +21 -21
- package/dist/{z-schema.d.mts → z-schema.d.ts} +5 -13
- package/dist/{z-schema.mjs → z-schema.js} +37 -47
- package/package.json +22 -23
- package/src/errors.ts +1 -2
- package/src/format-validators.ts +139 -59
- package/src/json-schema-versions.ts +56 -2
- package/src/json-schema.ts +10 -9
- package/src/json-validation.ts +189 -146
- package/src/report.ts +37 -49
- package/src/schema-cache.ts +13 -13
- package/src/schema-compiler.ts +170 -117
- package/src/schema-validator.ts +239 -238
- package/src/utils/array.ts +9 -6
- package/src/utils/base64.ts +13 -2
- package/src/utils/clone.ts +28 -30
- package/src/utils/date.ts +6 -3
- package/src/utils/hostname.ts +27 -27
- package/src/utils/json.ts +16 -9
- package/src/utils/properties.ts +2 -2
- package/src/utils/schema-regex.ts +4 -4
- package/src/utils/time.ts +5 -5
- package/src/utils/unicode.ts +12 -5
- package/src/utils/what-is.ts +1 -5
- package/src/validation/array.ts +24 -22
- package/src/validation/combinators.ts +14 -14
- package/src/validation/numeric.ts +14 -28
- package/src/validation/object.ts +32 -36
- package/src/validation/ref.ts +5 -6
- package/src/validation/shared.ts +22 -21
- package/src/validation/string.ts +29 -39
- package/src/validation/type.ts +17 -17
- package/src/z-schema-base.ts +49 -38
- package/src/z-schema-options.ts +4 -3
- package/src/z-schema.ts +35 -45
- package/umd/ZSchema.js +711 -695
- package/umd/ZSchema.min.js +2 -2
- package/umd/package.json +3 -0
- package/dist/utils/unicode.mjs +0 -12
- package/dist/validation/type.mjs +0 -32
- /package/dist/{format-validators.d.mts → format-validators.d.ts} +0 -0
- /package/dist/{json-schema-versions.mjs → json-schema-versions.js} +0 -0
- /package/dist/schemas/{draft-04-schema.mjs → draft-04-schema.js} +0 -0
- /package/dist/schemas/{draft-06-schema.mjs → draft-06-schema.js} +0 -0
- /package/dist/schemas/{draft-07-schema.mjs → draft-07-schema.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-applicator.mjs → draft-2019-09-meta-applicator.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-content.mjs → draft-2019-09-meta-content.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-core.mjs → draft-2019-09-meta-core.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-format.mjs → draft-2019-09-meta-format.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-meta-data.mjs → draft-2019-09-meta-meta-data.js} +0 -0
- /package/dist/schemas/{draft-2019-09-meta-validation.mjs → draft-2019-09-meta-validation.js} +0 -0
- /package/dist/schemas/{draft-2019-09-schema.mjs → draft-2019-09-schema.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-applicator.mjs → draft-2020-12-meta-applicator.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-content.mjs → draft-2020-12-meta-content.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-core.mjs → draft-2020-12-meta-core.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-format-annotation.mjs → draft-2020-12-meta-format-annotation.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-format-assertion.mjs → draft-2020-12-meta-format-assertion.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-meta-data.mjs → draft-2020-12-meta-meta-data.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-unevaluated.mjs → draft-2020-12-meta-unevaluated.js} +0 -0
- /package/dist/schemas/{draft-2020-12-meta-validation.mjs → draft-2020-12-meta-validation.js} +0 -0
- /package/dist/schemas/{draft-2020-12-schema.mjs → draft-2020-12-schema.js} +0 -0
- /package/dist/utils/{constants.mjs → constants.js} +0 -0
- /package/dist/utils/{date.mjs → date.js} +0 -0
- /package/dist/utils/{properties.mjs → properties.js} +0 -0
- /package/dist/utils/{symbols.mjs → symbols.js} +0 -0
- /package/dist/utils/{uri.mjs → uri.js} +0 -0
- /package/dist/{z-schema-reader.mjs → z-schema-reader.js} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Report } from "./report.
|
|
2
|
-
import { ZSchemaBase } from "./z-schema-base.
|
|
3
|
-
import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.
|
|
1
|
+
import { Report } from "./report.js";
|
|
2
|
+
import { ZSchemaBase } from "./z-schema-base.js";
|
|
3
|
+
import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.js";
|
|
4
4
|
|
|
5
5
|
//#region src/schema-cache.d.ts
|
|
6
6
|
type SchemaCacheStorage = Record<string, JsonSchemaInternal>;
|
|
7
7
|
declare class SchemaCache {
|
|
8
|
-
private validator;
|
|
9
8
|
static global_cache: SchemaCacheStorage;
|
|
10
9
|
cache: SchemaCacheStorage;
|
|
10
|
+
private readonly validator;
|
|
11
11
|
constructor(validator: ZSchemaBase);
|
|
12
12
|
static cacheSchemaByUri(uri: string, schema: JsonSchemaInternal): void;
|
|
13
13
|
cacheSchemaByUri(uri: string, schema: JsonSchemaInternal): void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { getQueryPath, getRemotePath, isAbsoluteUri } from "./utils/uri.
|
|
2
|
-
import { findId, getId } from "./json-schema.
|
|
3
|
-
import { deepClone } from "./utils/clone.
|
|
4
|
-
import { decodeJSONPointer } from "./utils/json.
|
|
5
|
-
import { Report } from "./report.
|
|
6
|
-
import { normalizeOptions } from "./z-schema-options.
|
|
1
|
+
import { getQueryPath, getRemotePath, isAbsoluteUri } from "./utils/uri.js";
|
|
2
|
+
import { findId, getId } from "./json-schema.js";
|
|
3
|
+
import { deepClone } from "./utils/clone.js";
|
|
4
|
+
import { decodeJSONPointer } from "./utils/json.js";
|
|
5
|
+
import { Report } from "./report.js";
|
|
6
|
+
import { normalizeOptions } from "./z-schema-options.js";
|
|
7
7
|
//#region src/schema-cache.ts
|
|
8
8
|
function getSafeRemotePath(uri) {
|
|
9
9
|
const remotePath = getRemotePath(uri);
|
|
@@ -13,7 +13,7 @@ function getSafeRemotePath(uri) {
|
|
|
13
13
|
}
|
|
14
14
|
const getEffectiveId = (schema) => {
|
|
15
15
|
let id = getId(schema);
|
|
16
|
-
if ((!id || !isAbsoluteUri(id)) && typeof schema.id === "string" && isAbsoluteUri(schema.id)) id = schema
|
|
16
|
+
if ((!id || !isAbsoluteUri(id)) && typeof schema.id === "string" && isAbsoluteUri(schema.id)) ({id} = schema);
|
|
17
17
|
return id;
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
@@ -22,9 +22,7 @@ const getEffectiveId = (schema) => {
|
|
|
22
22
|
* the instance `validator.setRemoteReference()` (instance cache).
|
|
23
23
|
*/
|
|
24
24
|
function prepareRemoteSchema(schema, uri, validationOptions, maxCloneDepth) {
|
|
25
|
-
|
|
26
|
-
if (typeof schema === "string") _schema = JSON.parse(schema);
|
|
27
|
-
else _schema = deepClone(schema, maxCloneDepth);
|
|
25
|
+
const _schema = typeof schema === "string" ? JSON.parse(schema) : deepClone(schema, maxCloneDepth);
|
|
28
26
|
if (!_schema.id) _schema.id = uri;
|
|
29
27
|
if (validationOptions) _schema.__$validationOptions = normalizeOptions(validationOptions);
|
|
30
28
|
return _schema;
|
|
@@ -32,6 +30,7 @@ function prepareRemoteSchema(schema, uri, validationOptions, maxCloneDepth) {
|
|
|
32
30
|
var SchemaCache = class SchemaCache {
|
|
33
31
|
static global_cache = Object.create(null);
|
|
34
32
|
cache = Object.create(null);
|
|
33
|
+
validator;
|
|
35
34
|
constructor(validator) {
|
|
36
35
|
this.validator = validator;
|
|
37
36
|
}
|
|
@@ -108,7 +107,7 @@ var SchemaCache = class SchemaCache {
|
|
|
108
107
|
usesAncestorReport = true;
|
|
109
108
|
} else {
|
|
110
109
|
remoteReport = new Report(report);
|
|
111
|
-
const noCache = result.id && isAbsoluteUri(result.id)
|
|
110
|
+
const noCache = !(result.id && isAbsoluteUri(result.id));
|
|
112
111
|
if (this.validator.sc.compileSchema(remoteReport, result, { noCache })) {
|
|
113
112
|
const savedOptions = this.validator.options;
|
|
114
113
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Report } from "./report.
|
|
2
|
-
import { ZSchemaBase } from "./z-schema-base.
|
|
3
|
-
import { JsonSchemaInternal } from "./json-schema-versions.
|
|
1
|
+
import { Report } from "./report.js";
|
|
2
|
+
import { ZSchemaBase } from "./z-schema-base.js";
|
|
3
|
+
import { JsonSchemaInternal } from "./json-schema-versions.js";
|
|
4
4
|
|
|
5
5
|
//#region src/schema-compiler.d.ts
|
|
6
6
|
interface Reference {
|
|
@@ -10,7 +10,7 @@ interface Reference {
|
|
|
10
10
|
path: Array<string | number>;
|
|
11
11
|
}
|
|
12
12
|
declare class SchemaCompiler {
|
|
13
|
-
private validator;
|
|
13
|
+
private readonly validator;
|
|
14
14
|
constructor(validator: ZSchemaBase);
|
|
15
15
|
collectAndCacheIds(schema: JsonSchemaInternal): void;
|
|
16
16
|
compileSchema(report: Report, schema: JsonSchemaInternal | JsonSchemaInternal[], options?: {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { getRemotePath, isAbsoluteUri } from "./utils/uri.
|
|
2
|
-
import {
|
|
3
|
-
import { Report } from "./report.
|
|
4
|
-
import { getSchemaReader } from "./z-schema-reader.
|
|
1
|
+
import { getRemotePath, isAbsoluteUri } from "./utils/uri.js";
|
|
2
|
+
import { NON_SCHEMA_KEYWORDS_SET, getId, isInternalKey } from "./json-schema.js";
|
|
3
|
+
import { Report } from "./report.js";
|
|
4
|
+
import { getSchemaReader } from "./z-schema-reader.js";
|
|
5
5
|
//#region src/schema-compiler.ts
|
|
6
|
-
const UNSAFE_TARGETS = [
|
|
6
|
+
const UNSAFE_TARGETS = new Set([
|
|
7
7
|
Object.prototype,
|
|
8
8
|
Function.prototype,
|
|
9
9
|
Array.prototype
|
|
10
|
-
];
|
|
10
|
+
]);
|
|
11
11
|
/** Returns true if `obj` is a built-in prototype that must not be mutated. */
|
|
12
12
|
function isUnsafeTarget(obj) {
|
|
13
|
-
return UNSAFE_TARGETS.
|
|
13
|
+
return UNSAFE_TARGETS.has(obj);
|
|
14
14
|
}
|
|
15
15
|
/** Safely assign a property on `obj`, refusing prototype-polluting keys. */
|
|
16
16
|
function safeSetProperty(obj, key, value) {
|
|
@@ -23,35 +23,78 @@ function safeDeleteProperty(obj, key) {
|
|
|
23
23
|
if (isUnsafeTarget(obj)) return;
|
|
24
24
|
if (key !== "__proto__" && key !== "constructor" && key !== "prototype") delete obj[key];
|
|
25
25
|
}
|
|
26
|
+
const resolveReference = (base, ref) => {
|
|
27
|
+
if (isAbsoluteUri(ref)) return ref;
|
|
28
|
+
const baseStr = base ?? "";
|
|
29
|
+
if (ref.startsWith("#")) {
|
|
30
|
+
const hashIndex = baseStr.indexOf("#");
|
|
31
|
+
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + ref;
|
|
32
|
+
}
|
|
33
|
+
if (!baseStr) return ref;
|
|
34
|
+
const hashIndex = baseStr.indexOf("#");
|
|
35
|
+
const baseNoFrag = hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex);
|
|
36
|
+
if (isAbsoluteUri(baseNoFrag)) try {
|
|
37
|
+
return new URL(ref, baseNoFrag).toString();
|
|
38
|
+
} catch {}
|
|
39
|
+
let baseDir = baseNoFrag;
|
|
40
|
+
if (!baseDir.endsWith("/")) {
|
|
41
|
+
const lastSlash = baseDir.lastIndexOf("/");
|
|
42
|
+
baseDir = lastSlash === -1 ? "" : baseDir.slice(0, lastSlash + 1);
|
|
43
|
+
}
|
|
44
|
+
return baseDir + ref;
|
|
45
|
+
};
|
|
46
|
+
const isSimpleIdentifier = (id) => !id.startsWith("#") && !id.includes("/") && !id.includes(".") && !id.includes("#");
|
|
47
|
+
const resolveIdScope = (base, id) => {
|
|
48
|
+
if (isAbsoluteUri(id)) return id;
|
|
49
|
+
const baseStr = base ?? "";
|
|
50
|
+
if (isSimpleIdentifier(id)) {
|
|
51
|
+
const hashIndex = baseStr.indexOf("#");
|
|
52
|
+
return `${hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)}#${id}`;
|
|
53
|
+
}
|
|
54
|
+
return resolveReference(base, id);
|
|
55
|
+
};
|
|
56
|
+
const resolveSchemaScopeId = (base, schema, id) => {
|
|
57
|
+
if (typeof schema.$id === "string") return resolveReference(base, id);
|
|
58
|
+
return resolveIdScope(base, id);
|
|
59
|
+
};
|
|
26
60
|
const collectIds = (obj, maxDepth = 100) => {
|
|
27
61
|
const ids = [];
|
|
28
62
|
function walk(node, scope, _depth = 0) {
|
|
29
63
|
if (typeof node !== "object" || node == null) return;
|
|
64
|
+
const schemaNode = node;
|
|
30
65
|
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.`);
|
|
31
66
|
let addedScope = false;
|
|
32
|
-
const nodeId = getId(
|
|
67
|
+
const nodeId = getId(schemaNode);
|
|
33
68
|
if (typeof nodeId === "string") {
|
|
34
69
|
let type = isAbsoluteUri(nodeId) ? "absolute" : "relative";
|
|
35
70
|
if (scope.length === 0) type = "root";
|
|
36
71
|
const id = {
|
|
37
72
|
id: nodeId,
|
|
38
73
|
type,
|
|
39
|
-
obj:
|
|
74
|
+
obj: schemaNode
|
|
40
75
|
};
|
|
41
76
|
if (type === "absolute" || type === "root" && isAbsoluteUri(nodeId)) id.absoluteUri = nodeId;
|
|
42
|
-
else if (type === "root" && typeof
|
|
77
|
+
else if (type === "root" && typeof schemaNode.id === "string" && isAbsoluteUri(schemaNode.id) && schemaNode.id !== nodeId) id.absoluteUri = resolveSchemaScopeId(schemaNode.id, schemaNode, nodeId);
|
|
43
78
|
else if (type === "relative") {
|
|
44
|
-
|
|
45
|
-
|
|
79
|
+
let absoluteParent;
|
|
80
|
+
for (let i = scope.length - 1; i >= 0; i--) {
|
|
81
|
+
const sc = scope[i];
|
|
82
|
+
if (sc.type === "absolute" || sc.type === "root" && sc.absoluteUri) {
|
|
83
|
+
absoluteParent = sc;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
id.absoluteParent = absoluteParent;
|
|
88
|
+
if (id.absoluteParent) id.absoluteUri = resolveSchemaScopeId(id.absoluteParent.absoluteUri || id.absoluteParent.id, schemaNode, id.id);
|
|
46
89
|
}
|
|
47
90
|
ids.push(id);
|
|
48
91
|
scope.push(id);
|
|
49
92
|
addedScope = true;
|
|
50
93
|
}
|
|
51
94
|
if (Array.isArray(node)) for (const item of node) walk(item, scope, _depth + 1);
|
|
52
|
-
else for (const key of Object.keys(
|
|
53
|
-
if (isInternalKey(key) ||
|
|
54
|
-
walk(
|
|
95
|
+
else for (const key of Object.keys(schemaNode)) {
|
|
96
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
97
|
+
walk(schemaNode[key], scope, _depth + 1);
|
|
55
98
|
}
|
|
56
99
|
if (addedScope) scope.pop();
|
|
57
100
|
}
|
|
@@ -59,42 +102,42 @@ const collectIds = (obj, maxDepth = 100) => {
|
|
|
59
102
|
return ids;
|
|
60
103
|
};
|
|
61
104
|
const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _depth = 0) => {
|
|
62
|
-
results
|
|
63
|
-
scope
|
|
64
|
-
path
|
|
65
|
-
options
|
|
105
|
+
results ||= [];
|
|
106
|
+
scope ||= [];
|
|
107
|
+
path ||= [];
|
|
108
|
+
options ||= {};
|
|
66
109
|
if (typeof obj !== "object" || obj === null) return results;
|
|
67
110
|
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.`);
|
|
68
|
-
const hasRef = typeof obj.$ref === "string" &&
|
|
111
|
+
const hasRef = typeof obj.$ref === "string" && obj.__$refResolved === void 0;
|
|
69
112
|
let addedScope = false;
|
|
70
113
|
const isRootScope = scope.length === 0;
|
|
71
114
|
let scopeId = getId(obj);
|
|
72
115
|
if (typeof obj.id === "string" && isAbsoluteUri(obj.id) && (!scopeId || !isAbsoluteUri(scopeId))) scopeId = obj.id;
|
|
73
116
|
if (typeof scopeId === "string" && (isRootScope || !hasRef || options.useRefObjectScope === true)) {
|
|
74
|
-
const base = scope.length > 0 ? scope
|
|
117
|
+
const base = scope.length > 0 ? scope.at(-1) : void 0;
|
|
75
118
|
scope.push(resolveSchemaScopeId(base, obj, scopeId));
|
|
76
119
|
addedScope = true;
|
|
77
120
|
}
|
|
78
121
|
if (hasRef) results.push({
|
|
79
|
-
ref: resolveReference(scope
|
|
122
|
+
ref: resolveReference(scope.at(-1), obj.$ref),
|
|
80
123
|
key: "$ref",
|
|
81
124
|
obj,
|
|
82
125
|
path: path.slice(0)
|
|
83
126
|
});
|
|
84
|
-
if (typeof obj.$recursiveRef === "string" &&
|
|
85
|
-
ref: resolveReference(scope
|
|
127
|
+
if (typeof obj.$recursiveRef === "string" && obj.__$recursiveRefResolved === void 0) results.push({
|
|
128
|
+
ref: resolveReference(scope.at(-1), obj.$recursiveRef),
|
|
86
129
|
key: "$recursiveRef",
|
|
87
130
|
obj,
|
|
88
131
|
path: path.slice(0)
|
|
89
132
|
});
|
|
90
|
-
if (typeof obj.$dynamicRef === "string" &&
|
|
91
|
-
ref: resolveReference(scope
|
|
133
|
+
if (typeof obj.$dynamicRef === "string" && obj.__$dynamicRefResolved === void 0) results.push({
|
|
134
|
+
ref: resolveReference(scope.at(-1), obj.$dynamicRef),
|
|
92
135
|
key: "$dynamicRef",
|
|
93
136
|
obj,
|
|
94
137
|
path: path.slice(0)
|
|
95
138
|
});
|
|
96
|
-
if (typeof obj.$schema === "string" &&
|
|
97
|
-
ref: resolveReference(scope
|
|
139
|
+
if (typeof obj.$schema === "string" && obj.__$schemaResolved === void 0) results.push({
|
|
140
|
+
ref: resolveReference(scope.at(-1), obj.$schema),
|
|
98
141
|
key: "$schema",
|
|
99
142
|
obj,
|
|
100
143
|
path: path.slice(0)
|
|
@@ -107,7 +150,7 @@ const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _
|
|
|
107
150
|
else {
|
|
108
151
|
const keys = Object.keys(obj);
|
|
109
152
|
for (const key of keys) {
|
|
110
|
-
if (isInternalKey(key) ||
|
|
153
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
111
154
|
path.push(key);
|
|
112
155
|
collectReferences(obj[key], results, scope, path, options, maxDepth, _depth + 1);
|
|
113
156
|
path.pop();
|
|
@@ -116,41 +159,8 @@ const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _
|
|
|
116
159
|
if (addedScope) scope.pop();
|
|
117
160
|
return results;
|
|
118
161
|
};
|
|
119
|
-
const resolveReference = (base, ref) => {
|
|
120
|
-
if (isAbsoluteUri(ref)) return ref;
|
|
121
|
-
const baseStr = base ?? "";
|
|
122
|
-
if (ref[0] === "#") {
|
|
123
|
-
const hashIndex = baseStr.indexOf("#");
|
|
124
|
-
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + ref;
|
|
125
|
-
}
|
|
126
|
-
if (!baseStr) return ref;
|
|
127
|
-
const hashIndex = baseStr.indexOf("#");
|
|
128
|
-
const baseNoFrag = hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex);
|
|
129
|
-
if (isAbsoluteUri(baseNoFrag)) try {
|
|
130
|
-
return new URL(ref, baseNoFrag).toString();
|
|
131
|
-
} catch {}
|
|
132
|
-
let baseDir = baseNoFrag;
|
|
133
|
-
if (!baseDir.endsWith("/")) {
|
|
134
|
-
const lastSlash = baseDir.lastIndexOf("/");
|
|
135
|
-
baseDir = lastSlash === -1 ? "" : baseDir.slice(0, lastSlash + 1);
|
|
136
|
-
}
|
|
137
|
-
return baseDir + ref;
|
|
138
|
-
};
|
|
139
|
-
const isSimpleIdentifier = (id) => id[0] !== "#" && !id.includes("/") && !id.includes(".") && !id.includes("#");
|
|
140
|
-
const resolveIdScope = (base, id) => {
|
|
141
|
-
if (isAbsoluteUri(id)) return id;
|
|
142
|
-
const baseStr = base ?? "";
|
|
143
|
-
if (isSimpleIdentifier(id)) {
|
|
144
|
-
const hashIndex = baseStr.indexOf("#");
|
|
145
|
-
return (hashIndex === -1 ? baseStr : baseStr.slice(0, hashIndex)) + "#" + id;
|
|
146
|
-
}
|
|
147
|
-
return resolveReference(base, id);
|
|
148
|
-
};
|
|
149
|
-
const resolveSchemaScopeId = (base, schema, id) => {
|
|
150
|
-
if (typeof schema.$id === "string") return resolveReference(base, id);
|
|
151
|
-
return resolveIdScope(base, id);
|
|
152
|
-
};
|
|
153
162
|
var SchemaCompiler = class {
|
|
163
|
+
validator;
|
|
154
164
|
constructor(validator) {
|
|
155
165
|
this.validator = validator;
|
|
156
166
|
}
|
|
@@ -168,19 +178,19 @@ var SchemaCompiler = class {
|
|
|
168
178
|
report.commonErrorMessage = "SCHEMA_COMPILATION_FAILED";
|
|
169
179
|
if (typeof schema === "string") {
|
|
170
180
|
const loadedSchema = this.validator.scache.getSchemaByUri(report, schema);
|
|
171
|
-
if (
|
|
181
|
+
if (loadedSchema === void 0) {
|
|
172
182
|
report.addError("SCHEMA_NOT_REACHABLE", [schema]);
|
|
173
183
|
return false;
|
|
174
184
|
}
|
|
175
185
|
schema = loadedSchema;
|
|
176
186
|
}
|
|
177
187
|
if (Array.isArray(schema)) {
|
|
178
|
-
if (!options?.noCache) schema.
|
|
188
|
+
if (!options?.noCache) for (let i = 0; i < schema.length; i++) this.collectAndCacheIds(schema[i]);
|
|
179
189
|
return this.compileArrayOfSchemas(report, schema);
|
|
180
190
|
} else if (typeof schema === "boolean") return true;
|
|
181
|
-
|
|
191
|
+
if (!options?.noCache) this.collectAndCacheIds(schema);
|
|
182
192
|
const canMutateSchemaObject = schema !== Object.prototype && schema !== Function.prototype && schema !== Array.prototype;
|
|
183
|
-
if (canMutateSchemaObject && schema.__$compiled && schema.id && this.validator.scache.checkCacheForUri(schema.id)
|
|
193
|
+
if (canMutateSchemaObject && schema.__$compiled && schema.id && !this.validator.scache.checkCacheForUri(schema.id)) schema.__$compiled = void 0;
|
|
184
194
|
if (schema.__$compiled) return true;
|
|
185
195
|
if (canMutateSchemaObject && !schema.$schema && this.validator.options.version !== "none") schema.$schema = this.validator.getDefaultSchemaId();
|
|
186
196
|
if (schema.id && typeof schema.id === "string" && !options?.noCache) this.validator.scache.cacheSchemaByUri(schema.id, schema);
|
|
@@ -195,7 +205,7 @@ var SchemaCompiler = class {
|
|
|
195
205
|
const refs = collectReferences(schema, void 0, void 0, void 0, { useRefObjectScope }, this.validator.options.maxRecursionDepth);
|
|
196
206
|
for (const refObj of refs) {
|
|
197
207
|
let response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
198
|
-
if (
|
|
208
|
+
if (response === void 0) {
|
|
199
209
|
const schemaReader = getSchemaReader();
|
|
200
210
|
if (schemaReader) {
|
|
201
211
|
const remotePath = getRemotePath(refObj.ref);
|
|
@@ -203,23 +213,24 @@ var SchemaCompiler = class {
|
|
|
203
213
|
if (s) {
|
|
204
214
|
s.id = remotePath;
|
|
205
215
|
const subreport = new Report(report);
|
|
206
|
-
if (
|
|
207
|
-
else
|
|
216
|
+
if (this.compileSchema(subreport, s)) response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
217
|
+
else for (let i = 0; i < subreport.errors.length; i++) report.errors.push(subreport.errors[i]);
|
|
208
218
|
}
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
|
-
if (
|
|
221
|
+
if (response === void 0) {
|
|
212
222
|
const hasNotValid = report.hasError("REMOTE_NOT_VALID", [refObj.ref]);
|
|
213
223
|
const isAbsolute = isAbsoluteUri(refObj.ref);
|
|
214
224
|
let isDownloaded = false;
|
|
215
225
|
const ignoreUnresolvableRemotes = this.validator.options.ignoreUnresolvableReferences === true;
|
|
216
226
|
if (isAbsolute) isDownloaded = this.validator.scache.checkCacheForUri(refObj.ref);
|
|
217
227
|
if (hasNotValid) {} else if (ignoreUnresolvableRemotes && isAbsolute) {} else if (isDownloaded) {} else {
|
|
218
|
-
|
|
228
|
+
const pathLen = refObj.path.length;
|
|
229
|
+
for (let i = 0; i < pathLen; i++) report.path.push(refObj.path[i]);
|
|
219
230
|
report.addError("UNRESOLVABLE_REFERENCE", [refObj.ref]);
|
|
220
|
-
report.path
|
|
231
|
+
report.path.length -= pathLen;
|
|
221
232
|
if (isValidExceptReferences && canMutateSchemaObject && !isUnsafeTarget(schema)) {
|
|
222
|
-
schema.__$missingReferences
|
|
233
|
+
schema.__$missingReferences ||= [];
|
|
223
234
|
schema.__$missingReferences.push(refObj);
|
|
224
235
|
}
|
|
225
236
|
}
|
|
@@ -234,13 +245,20 @@ var SchemaCompiler = class {
|
|
|
234
245
|
compileArrayOfSchemas(report, arr) {
|
|
235
246
|
let compiled = 0, lastLoopCompiled;
|
|
236
247
|
do {
|
|
237
|
-
|
|
248
|
+
let wi = 0;
|
|
249
|
+
for (let ri = 0; ri < report.errors.length; ri++) if (report.errors[ri].code !== "UNRESOLVABLE_REFERENCE") report.errors[wi++] = report.errors[ri];
|
|
250
|
+
report.errors.length = wi;
|
|
238
251
|
lastLoopCompiled = compiled;
|
|
239
252
|
compiled = this.compileArrayOfSchemasLoop(report, arr);
|
|
253
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
254
|
+
for (let i = 0; i < arr.length; i++) {
|
|
255
|
+
const schemaId = arr[i].id;
|
|
256
|
+
if (schemaId && !idMap.has(schemaId)) idMap.set(schemaId, arr[i]);
|
|
257
|
+
}
|
|
240
258
|
for (const sch of arr) if (sch.__$missingReferences) {
|
|
241
259
|
for (let idx2 = sch.__$missingReferences.length - 1; idx2 >= 0; idx2--) {
|
|
242
260
|
const refObj = sch.__$missingReferences[idx2];
|
|
243
|
-
const response =
|
|
261
|
+
const response = idMap.get(refObj.ref);
|
|
244
262
|
if (response) {
|
|
245
263
|
safeSetProperty(refObj.obj, `__${refObj.key}Resolved`, response);
|
|
246
264
|
sch.__$missingReferences.splice(idx2, 1);
|
|
@@ -256,7 +274,7 @@ var SchemaCompiler = class {
|
|
|
256
274
|
for (const schema of arr) {
|
|
257
275
|
const report = new Report(mainReport);
|
|
258
276
|
if (this.compileSchema(report, schema)) compiledCount++;
|
|
259
|
-
|
|
277
|
+
for (let i = 0; i < report.errors.length; i++) mainReport.errors.push(report.errors[i]);
|
|
260
278
|
}
|
|
261
279
|
return compiledCount;
|
|
262
280
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { ZSchemaOptions } from "./z-schema-options.
|
|
2
|
-
import { Report } from "./report.
|
|
3
|
-
import { ZSchemaBase } from "./z-schema-base.
|
|
4
|
-
import { JsonSchemaInternal } from "./json-schema-versions.
|
|
1
|
+
import { ZSchemaOptions } from "./z-schema-options.js";
|
|
2
|
+
import { Report } from "./report.js";
|
|
3
|
+
import { ZSchemaBase } from "./z-schema-base.js";
|
|
4
|
+
import { JsonSchemaInternal } from "./json-schema-versions.js";
|
|
5
5
|
|
|
6
6
|
//#region src/schema-validator.d.ts
|
|
7
7
|
declare class SchemaValidator {
|
|
8
|
-
private validator;
|
|
8
|
+
private readonly validator;
|
|
9
9
|
constructor(validator: ZSchemaBase);
|
|
10
10
|
get options(): ZSchemaOptions;
|
|
11
11
|
validateArrayOfSchemas(report: Report, arr: Array<JsonSchemaInternal | boolean>): boolean;
|