z-schema 12.1.1 → 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.
Files changed (110) hide show
  1. package/README.md +2 -2
  2. package/bin/z-schema +4 -5
  3. package/cjs/{index.js → index.cjs} +696 -687
  4. package/cjs/{index.d.ts → index.d.cts} +47 -26
  5. package/dist/{errors.d.mts → errors.d.ts} +2 -2
  6. package/dist/{errors.mjs → errors.js} +1 -2
  7. package/dist/{format-validators.mjs → format-validators.js} +43 -36
  8. package/dist/{index.d.mts → index.d.ts} +9 -9
  9. package/dist/{index.mjs → index.js} +3 -3
  10. package/dist/{json-schema-versions.d.mts → json-schema-versions.d.ts} +34 -3
  11. package/dist/{json-schema.d.mts → json-schema.d.ts} +7 -7
  12. package/dist/{json-schema.mjs → json-schema.js} +7 -12
  13. package/dist/{json-validation.mjs → json-validation.js} +143 -127
  14. package/dist/{report.d.mts → report.d.ts} +7 -8
  15. package/dist/{report.mjs → report.js} +28 -31
  16. package/dist/{schema-cache.d.mts → schema-cache.d.ts} +4 -4
  17. package/dist/{schema-cache.mjs → schema-cache.js} +10 -11
  18. package/dist/{schema-compiler.d.mts → schema-compiler.d.ts} +4 -4
  19. package/dist/{schema-compiler.mjs → schema-compiler.js} +95 -77
  20. package/dist/{schema-validator.d.mts → schema-validator.d.ts} +5 -5
  21. package/dist/{schema-validator.mjs → schema-validator.js} +138 -166
  22. package/dist/utils/{array.mjs → array.js} +4 -3
  23. package/dist/utils/{base64.mjs → base64.js} +3 -2
  24. package/dist/utils/{clone.mjs → clone.js} +18 -20
  25. package/dist/utils/{hostname.mjs → hostname.js} +19 -22
  26. package/dist/utils/{json.mjs → json.js} +11 -7
  27. package/dist/utils/{schema-regex.mjs → schema-regex.js} +5 -5
  28. package/dist/utils/{time.mjs → time.js} +5 -5
  29. package/dist/utils/unicode.js +22 -0
  30. package/dist/utils/{what-is.mjs → what-is.js} +1 -2
  31. package/dist/validation/{array.mjs → array.js} +18 -20
  32. package/dist/validation/{combinators.mjs → combinators.js} +16 -16
  33. package/dist/validation/{numeric.mjs → numeric.js} +11 -11
  34. package/dist/validation/{object.mjs → object.js} +35 -34
  35. package/dist/validation/{ref.mjs → ref.js} +4 -4
  36. package/dist/validation/{shared.mjs → shared.js} +12 -11
  37. package/dist/validation/{string.mjs → string.js} +32 -32
  38. package/dist/validation/type.js +34 -0
  39. package/dist/{z-schema-base.d.mts → z-schema-base.d.ts} +11 -12
  40. package/dist/{z-schema-base.mjs → z-schema-base.js} +45 -40
  41. package/dist/{z-schema-options.d.mts → z-schema-options.d.ts} +3 -3
  42. package/dist/{z-schema-options.mjs → z-schema-options.js} +4 -4
  43. package/dist/{z-schema-reader.d.mts → z-schema-reader.d.ts} +1 -1
  44. package/dist/{z-schema-versions.mjs → z-schema-versions.js} +21 -21
  45. package/dist/{z-schema.d.mts → z-schema.d.ts} +5 -13
  46. package/dist/{z-schema.mjs → z-schema.js} +37 -47
  47. package/package.json +25 -23
  48. package/src/errors.ts +1 -2
  49. package/src/format-validators.ts +139 -59
  50. package/src/json-schema-versions.ts +56 -2
  51. package/src/json-schema.ts +10 -9
  52. package/src/json-validation.ts +189 -146
  53. package/src/report.ts +37 -49
  54. package/src/schema-cache.ts +13 -13
  55. package/src/schema-compiler.ts +170 -117
  56. package/src/schema-validator.ts +239 -238
  57. package/src/utils/array.ts +9 -6
  58. package/src/utils/base64.ts +13 -2
  59. package/src/utils/clone.ts +28 -30
  60. package/src/utils/date.ts +6 -3
  61. package/src/utils/hostname.ts +27 -27
  62. package/src/utils/json.ts +16 -9
  63. package/src/utils/properties.ts +2 -2
  64. package/src/utils/schema-regex.ts +4 -4
  65. package/src/utils/time.ts +5 -5
  66. package/src/utils/unicode.ts +12 -5
  67. package/src/utils/what-is.ts +1 -5
  68. package/src/validation/array.ts +24 -22
  69. package/src/validation/combinators.ts +14 -14
  70. package/src/validation/numeric.ts +14 -28
  71. package/src/validation/object.ts +32 -36
  72. package/src/validation/ref.ts +5 -6
  73. package/src/validation/shared.ts +22 -21
  74. package/src/validation/string.ts +29 -39
  75. package/src/validation/type.ts +17 -17
  76. package/src/z-schema-base.ts +49 -38
  77. package/src/z-schema-options.ts +4 -3
  78. package/src/z-schema.ts +35 -45
  79. package/umd/ZSchema.js +723 -697
  80. package/umd/ZSchema.min.js +2 -2
  81. package/umd/package.json +3 -0
  82. package/dist/utils/unicode.mjs +0 -12
  83. package/dist/validation/type.mjs +0 -32
  84. /package/dist/{format-validators.d.mts → format-validators.d.ts} +0 -0
  85. /package/dist/{json-schema-versions.mjs → json-schema-versions.js} +0 -0
  86. /package/dist/schemas/{draft-04-schema.mjs → draft-04-schema.js} +0 -0
  87. /package/dist/schemas/{draft-06-schema.mjs → draft-06-schema.js} +0 -0
  88. /package/dist/schemas/{draft-07-schema.mjs → draft-07-schema.js} +0 -0
  89. /package/dist/schemas/{draft-2019-09-meta-applicator.mjs → draft-2019-09-meta-applicator.js} +0 -0
  90. /package/dist/schemas/{draft-2019-09-meta-content.mjs → draft-2019-09-meta-content.js} +0 -0
  91. /package/dist/schemas/{draft-2019-09-meta-core.mjs → draft-2019-09-meta-core.js} +0 -0
  92. /package/dist/schemas/{draft-2019-09-meta-format.mjs → draft-2019-09-meta-format.js} +0 -0
  93. /package/dist/schemas/{draft-2019-09-meta-meta-data.mjs → draft-2019-09-meta-meta-data.js} +0 -0
  94. /package/dist/schemas/{draft-2019-09-meta-validation.mjs → draft-2019-09-meta-validation.js} +0 -0
  95. /package/dist/schemas/{draft-2019-09-schema.mjs → draft-2019-09-schema.js} +0 -0
  96. /package/dist/schemas/{draft-2020-12-meta-applicator.mjs → draft-2020-12-meta-applicator.js} +0 -0
  97. /package/dist/schemas/{draft-2020-12-meta-content.mjs → draft-2020-12-meta-content.js} +0 -0
  98. /package/dist/schemas/{draft-2020-12-meta-core.mjs → draft-2020-12-meta-core.js} +0 -0
  99. /package/dist/schemas/{draft-2020-12-meta-format-annotation.mjs → draft-2020-12-meta-format-annotation.js} +0 -0
  100. /package/dist/schemas/{draft-2020-12-meta-format-assertion.mjs → draft-2020-12-meta-format-assertion.js} +0 -0
  101. /package/dist/schemas/{draft-2020-12-meta-meta-data.mjs → draft-2020-12-meta-meta-data.js} +0 -0
  102. /package/dist/schemas/{draft-2020-12-meta-unevaluated.mjs → draft-2020-12-meta-unevaluated.js} +0 -0
  103. /package/dist/schemas/{draft-2020-12-meta-validation.mjs → draft-2020-12-meta-validation.js} +0 -0
  104. /package/dist/schemas/{draft-2020-12-schema.mjs → draft-2020-12-schema.js} +0 -0
  105. /package/dist/utils/{constants.mjs → constants.js} +0 -0
  106. /package/dist/utils/{date.mjs → date.js} +0 -0
  107. /package/dist/utils/{properties.mjs → properties.js} +0 -0
  108. /package/dist/utils/{symbols.mjs → symbols.js} +0 -0
  109. /package/dist/utils/{uri.mjs → uri.js} +0 -0
  110. /package/dist/{z-schema-reader.mjs → z-schema-reader.js} +0 -0
@@ -1,13 +1,13 @@
1
- import { Report } from "./report.mjs";
2
- import { ZSchemaBase } from "./z-schema-base.mjs";
3
- import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.mjs";
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.mjs";
2
- import { findId, getId } from "./json-schema.mjs";
3
- import { deepClone } from "./utils/clone.mjs";
4
- import { decodeJSONPointer } from "./utils/json.mjs";
5
- import { Report } from "./report.mjs";
6
- import { normalizeOptions } from "./z-schema-options.mjs";
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.id;
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
- let _schema;
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) ? false : true;
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.mjs";
2
- import { ZSchemaBase } from "./z-schema-base.mjs";
3
- import { JsonSchemaInternal } from "./json-schema-versions.mjs";
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.mjs";
2
- import { NON_SCHEMA_KEYWORDS, getId, isInternalKey } from "./json-schema.mjs";
3
- import { Report } from "./report.mjs";
4
- import { getSchemaReader } from "./z-schema-reader.mjs";
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.includes(obj);
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(node);
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: node
74
+ obj: schemaNode
40
75
  };
41
76
  if (type === "absolute" || type === "root" && isAbsoluteUri(nodeId)) id.absoluteUri = nodeId;
42
- else if (type === "root" && typeof node.id === "string" && isAbsoluteUri(node.id) && node.id !== nodeId) id.absoluteUri = resolveSchemaScopeId(node.id, node, nodeId);
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
- id.absoluteParent = scope.filter((x) => x.type === "absolute" || x.type === "root" && x.absoluteUri).slice(-1)[0];
45
- if (id.absoluteParent) id.absoluteUri = resolveSchemaScopeId(id.absoluteParent.absoluteUri || id.absoluteParent.id, node, id.id);
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(node)) {
53
- if (isInternalKey(key) || NON_SCHEMA_KEYWORDS.includes(key)) continue;
54
- walk(node[key], scope, _depth + 1);
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 = results || [];
63
- scope = scope || [];
64
- path = path || [];
65
- options = 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" && typeof obj.__$refResolved === "undefined";
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[scope.length - 1] : void 0;
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[scope.length - 1], obj.$ref),
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" && typeof obj.__$recursiveRefResolved === "undefined") results.push({
85
- ref: resolveReference(scope[scope.length - 1], obj.$recursiveRef),
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" && typeof obj.__$dynamicRefResolved === "undefined") results.push({
91
- ref: resolveReference(scope[scope.length - 1], obj.$dynamicRef),
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" && typeof obj.__$schemaResolved === "undefined") results.push({
97
- ref: resolveReference(scope[scope.length - 1], obj.$schema),
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) || NON_SCHEMA_KEYWORDS.includes(key)) continue;
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 (typeof loadedSchema === "undefined") {
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.forEach((s) => this.collectAndCacheIds(s));
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
- else if (!options?.noCache) this.collectAndCacheIds(schema);
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) === false) schema.__$compiled = void 0;
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 (typeof response === "undefined") {
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 (!this.compileSchema(subreport, s)) report.errors = report.errors.concat(subreport.errors);
207
- else response = this.validator.scache.getSchemaByUri(report, refObj.ref, schema);
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 (typeof response === "undefined") {
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
- report.path.push(...refObj.path);
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 = report.path.slice(0, -refObj.path.length);
231
+ report.path.length -= pathLen;
221
232
  if (isValidExceptReferences && canMutateSchemaObject && !isUnsafeTarget(schema)) {
222
- schema.__$missingReferences = 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
- report.errors = report.errors.filter((e) => e.code !== "UNRESOLVABLE_REFERENCE");
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 = arr.find((x) => x.id === refObj.ref);
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
- mainReport.errors = mainReport.errors.concat(report.errors);
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.mjs";
2
- import { Report } from "./report.mjs";
3
- import { ZSchemaBase } from "./z-schema-base.mjs";
4
- import { JsonSchemaInternal } from "./json-schema-versions.mjs";
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;