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
|
@@ -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;
|
|
@@ -20,4 +20,4 @@ declare class SchemaCache {
|
|
|
20
20
|
getSchemaByUri(report: Report, uri: string, root?: JsonSchemaInternal): JsonSchemaInternal | undefined;
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
|
-
export { SchemaCache };
|
|
23
|
+
export { SchemaCache, SchemaCacheStorage };
|
|
@@ -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 = /* @__PURE__ */ 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,81 @@ 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) {
|
|
89
|
+
const parentUri = id.absoluteParent.absoluteUri || id.absoluteParent.id;
|
|
90
|
+
id.absoluteUri = resolveSchemaScopeId(parentUri, schemaNode, id.id);
|
|
91
|
+
}
|
|
46
92
|
}
|
|
47
93
|
ids.push(id);
|
|
48
94
|
scope.push(id);
|
|
49
95
|
addedScope = true;
|
|
50
96
|
}
|
|
51
97
|
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(
|
|
98
|
+
else for (const key of Object.keys(schemaNode)) {
|
|
99
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
100
|
+
walk(schemaNode[key], scope, _depth + 1);
|
|
55
101
|
}
|
|
56
102
|
if (addedScope) scope.pop();
|
|
57
103
|
}
|
|
@@ -59,42 +105,42 @@ const collectIds = (obj, maxDepth = 100) => {
|
|
|
59
105
|
return ids;
|
|
60
106
|
};
|
|
61
107
|
const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _depth = 0) => {
|
|
62
|
-
results
|
|
63
|
-
scope
|
|
64
|
-
path
|
|
65
|
-
options
|
|
108
|
+
results ||= [];
|
|
109
|
+
scope ||= [];
|
|
110
|
+
path ||= [];
|
|
111
|
+
options ||= {};
|
|
66
112
|
if (typeof obj !== "object" || obj === null) return results;
|
|
67
113
|
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" &&
|
|
114
|
+
const hasRef = typeof obj.$ref === "string" && obj.__$refResolved === void 0;
|
|
69
115
|
let addedScope = false;
|
|
70
116
|
const isRootScope = scope.length === 0;
|
|
71
117
|
let scopeId = getId(obj);
|
|
72
118
|
if (typeof obj.id === "string" && isAbsoluteUri(obj.id) && (!scopeId || !isAbsoluteUri(scopeId))) scopeId = obj.id;
|
|
73
119
|
if (typeof scopeId === "string" && (isRootScope || !hasRef || options.useRefObjectScope === true)) {
|
|
74
|
-
const base = scope.length > 0 ? scope
|
|
120
|
+
const base = scope.length > 0 ? scope.at(-1) : void 0;
|
|
75
121
|
scope.push(resolveSchemaScopeId(base, obj, scopeId));
|
|
76
122
|
addedScope = true;
|
|
77
123
|
}
|
|
78
124
|
if (hasRef) results.push({
|
|
79
|
-
ref: resolveReference(scope
|
|
125
|
+
ref: resolveReference(scope.at(-1), obj.$ref),
|
|
80
126
|
key: "$ref",
|
|
81
127
|
obj,
|
|
82
128
|
path: path.slice(0)
|
|
83
129
|
});
|
|
84
|
-
if (typeof obj.$recursiveRef === "string" &&
|
|
85
|
-
ref: resolveReference(scope
|
|
130
|
+
if (typeof obj.$recursiveRef === "string" && obj.__$recursiveRefResolved === void 0) results.push({
|
|
131
|
+
ref: resolveReference(scope.at(-1), obj.$recursiveRef),
|
|
86
132
|
key: "$recursiveRef",
|
|
87
133
|
obj,
|
|
88
134
|
path: path.slice(0)
|
|
89
135
|
});
|
|
90
|
-
if (typeof obj.$dynamicRef === "string" &&
|
|
91
|
-
ref: resolveReference(scope
|
|
136
|
+
if (typeof obj.$dynamicRef === "string" && obj.__$dynamicRefResolved === void 0) results.push({
|
|
137
|
+
ref: resolveReference(scope.at(-1), obj.$dynamicRef),
|
|
92
138
|
key: "$dynamicRef",
|
|
93
139
|
obj,
|
|
94
140
|
path: path.slice(0)
|
|
95
141
|
});
|
|
96
|
-
if (typeof obj.$schema === "string" &&
|
|
97
|
-
ref: resolveReference(scope
|
|
142
|
+
if (typeof obj.$schema === "string" && obj.__$schemaResolved === void 0) results.push({
|
|
143
|
+
ref: resolveReference(scope.at(-1), obj.$schema),
|
|
98
144
|
key: "$schema",
|
|
99
145
|
obj,
|
|
100
146
|
path: path.slice(0)
|
|
@@ -107,7 +153,7 @@ const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _
|
|
|
107
153
|
else {
|
|
108
154
|
const keys = Object.keys(obj);
|
|
109
155
|
for (const key of keys) {
|
|
110
|
-
if (isInternalKey(key) ||
|
|
156
|
+
if (isInternalKey(key) || NON_SCHEMA_KEYWORDS_SET.has(key)) continue;
|
|
111
157
|
path.push(key);
|
|
112
158
|
collectReferences(obj[key], results, scope, path, options, maxDepth, _depth + 1);
|
|
113
159
|
path.pop();
|
|
@@ -116,41 +162,8 @@ const collectReferences = (obj, results, scope, path, options, maxDepth = 100, _
|
|
|
116
162
|
if (addedScope) scope.pop();
|
|
117
163
|
return results;
|
|
118
164
|
};
|
|
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
165
|
var SchemaCompiler = class {
|
|
166
|
+
validator;
|
|
154
167
|
constructor(validator) {
|
|
155
168
|
this.validator = validator;
|
|
156
169
|
}
|
|
@@ -159,7 +172,8 @@ var SchemaCompiler = class {
|
|
|
159
172
|
for (const item of ids) if (item.absoluteUri) {
|
|
160
173
|
this.validator.scache.cacheSchemaByUri(item.absoluteUri, item.obj);
|
|
161
174
|
if (item.type === "relative" && item.absoluteParent && isSimpleIdentifier(item.id)) {
|
|
162
|
-
const
|
|
175
|
+
const parentUri = item.absoluteParent.absoluteUri || item.absoluteParent.id;
|
|
176
|
+
const altAbsoluteUri = resolveReference(parentUri, item.id);
|
|
163
177
|
this.validator.scache.cacheSchemaByUri(altAbsoluteUri, item.obj);
|
|
164
178
|
}
|
|
165
179
|
} else if (item.type === "root") this.validator.scache.cacheSchemaByUri(item.id, item.obj);
|
|
@@ -168,19 +182,19 @@ var SchemaCompiler = class {
|
|
|
168
182
|
report.commonErrorMessage = "SCHEMA_COMPILATION_FAILED";
|
|
169
183
|
if (typeof schema === "string") {
|
|
170
184
|
const loadedSchema = this.validator.scache.getSchemaByUri(report, schema);
|
|
171
|
-
if (
|
|
185
|
+
if (loadedSchema === void 0) {
|
|
172
186
|
report.addError("SCHEMA_NOT_REACHABLE", [schema]);
|
|
173
187
|
return false;
|
|
174
188
|
}
|
|
175
189
|
schema = loadedSchema;
|
|
176
190
|
}
|
|
177
191
|
if (Array.isArray(schema)) {
|
|
178
|
-
if (!options?.noCache) schema.
|
|
192
|
+
if (!options?.noCache) for (let i = 0; i < schema.length; i++) this.collectAndCacheIds(schema[i]);
|
|
179
193
|
return this.compileArrayOfSchemas(report, schema);
|
|
180
194
|
} else if (typeof schema === "boolean") return true;
|
|
181
|
-
|
|
195
|
+
if (!options?.noCache) this.collectAndCacheIds(schema);
|
|
182
196
|
const canMutateSchemaObject = schema !== Object.prototype && schema !== Function.prototype && schema !== Array.prototype;
|
|
183
|
-
if (canMutateSchemaObject && schema.__$compiled && schema.id && this.validator.scache.checkCacheForUri(schema.id)
|
|
197
|
+
if (canMutateSchemaObject && schema.__$compiled && schema.id && !this.validator.scache.checkCacheForUri(schema.id)) schema.__$compiled = void 0;
|
|
184
198
|
if (schema.__$compiled) return true;
|
|
185
199
|
if (canMutateSchemaObject && !schema.$schema && this.validator.options.version !== "none") schema.$schema = this.validator.getDefaultSchemaId();
|
|
186
200
|
if (schema.id && typeof schema.id === "string" && !options?.noCache) this.validator.scache.cacheSchemaByUri(schema.id, schema);
|
|
@@ -195,7 +209,7 @@ var SchemaCompiler = class {
|
|
|
195
209
|
const refs = collectReferences(schema, void 0, void 0, void 0, { useRefObjectScope }, this.validator.options.maxRecursionDepth);
|
|
196
210
|
for (const refObj of refs) {
|
|
197
211
|
let response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
198
|
-
if (
|
|
212
|
+
if (response === void 0) {
|
|
199
213
|
const schemaReader = getSchemaReader();
|
|
200
214
|
if (schemaReader) {
|
|
201
215
|
const remotePath = getRemotePath(refObj.ref);
|
|
@@ -203,23 +217,24 @@ var SchemaCompiler = class {
|
|
|
203
217
|
if (s) {
|
|
204
218
|
s.id = remotePath;
|
|
205
219
|
const subreport = new Report(report);
|
|
206
|
-
if (
|
|
207
|
-
else
|
|
220
|
+
if (this.compileSchema(subreport, s)) response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
|
|
221
|
+
else for (let i = 0; i < subreport.errors.length; i++) report.errors.push(subreport.errors[i]);
|
|
208
222
|
}
|
|
209
223
|
}
|
|
210
224
|
}
|
|
211
|
-
if (
|
|
225
|
+
if (response === void 0) {
|
|
212
226
|
const hasNotValid = report.hasError("REMOTE_NOT_VALID", [refObj.ref]);
|
|
213
227
|
const isAbsolute = isAbsoluteUri(refObj.ref);
|
|
214
228
|
let isDownloaded = false;
|
|
215
229
|
const ignoreUnresolvableRemotes = this.validator.options.ignoreUnresolvableReferences === true;
|
|
216
230
|
if (isAbsolute) isDownloaded = this.validator.scache.checkCacheForUri(refObj.ref);
|
|
217
231
|
if (hasNotValid) {} else if (ignoreUnresolvableRemotes && isAbsolute) {} else if (isDownloaded) {} else {
|
|
218
|
-
|
|
232
|
+
const pathLen = refObj.path.length;
|
|
233
|
+
for (let i = 0; i < pathLen; i++) report.path.push(refObj.path[i]);
|
|
219
234
|
report.addError("UNRESOLVABLE_REFERENCE", [refObj.ref]);
|
|
220
|
-
report.path
|
|
235
|
+
report.path.length -= pathLen;
|
|
221
236
|
if (isValidExceptReferences && canMutateSchemaObject && !isUnsafeTarget(schema)) {
|
|
222
|
-
schema.__$missingReferences
|
|
237
|
+
schema.__$missingReferences ||= [];
|
|
223
238
|
schema.__$missingReferences.push(refObj);
|
|
224
239
|
}
|
|
225
240
|
}
|
|
@@ -234,13 +249,20 @@ var SchemaCompiler = class {
|
|
|
234
249
|
compileArrayOfSchemas(report, arr) {
|
|
235
250
|
let compiled = 0, lastLoopCompiled;
|
|
236
251
|
do {
|
|
237
|
-
|
|
252
|
+
let wi = 0;
|
|
253
|
+
for (let ri = 0; ri < report.errors.length; ri++) if (report.errors[ri].code !== "UNRESOLVABLE_REFERENCE") report.errors[wi++] = report.errors[ri];
|
|
254
|
+
report.errors.length = wi;
|
|
238
255
|
lastLoopCompiled = compiled;
|
|
239
256
|
compiled = this.compileArrayOfSchemasLoop(report, arr);
|
|
257
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
258
|
+
for (let i = 0; i < arr.length; i++) {
|
|
259
|
+
const schemaId = arr[i].id;
|
|
260
|
+
if (schemaId && !idMap.has(schemaId)) idMap.set(schemaId, arr[i]);
|
|
261
|
+
}
|
|
240
262
|
for (const sch of arr) if (sch.__$missingReferences) {
|
|
241
263
|
for (let idx2 = sch.__$missingReferences.length - 1; idx2 >= 0; idx2--) {
|
|
242
264
|
const refObj = sch.__$missingReferences[idx2];
|
|
243
|
-
const response =
|
|
265
|
+
const response = idMap.get(refObj.ref);
|
|
244
266
|
if (response) {
|
|
245
267
|
safeSetProperty(refObj.obj, `__${refObj.key}Resolved`, response);
|
|
246
268
|
sch.__$missingReferences.splice(idx2, 1);
|
|
@@ -256,10 +278,10 @@ var SchemaCompiler = class {
|
|
|
256
278
|
for (const schema of arr) {
|
|
257
279
|
const report = new Report(mainReport);
|
|
258
280
|
if (this.compileSchema(report, schema)) compiledCount++;
|
|
259
|
-
|
|
281
|
+
for (let i = 0; i < report.errors.length; i++) mainReport.errors.push(report.errors[i]);
|
|
260
282
|
}
|
|
261
283
|
return compiledCount;
|
|
262
284
|
}
|
|
263
285
|
};
|
|
264
286
|
//#endregion
|
|
265
|
-
export { SchemaCompiler };
|
|
287
|
+
export { SchemaCompiler, collectIds, collectReferences };
|
|
@@ -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;
|