@depup/typebox 1.3.22-depup.0 → 1.3.27-depup.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.
Files changed (38) hide show
  1. package/README.md +2 -2
  2. package/build/compile/validator.d.mts +1 -1
  3. package/build/compile/validator.mjs +1 -1
  4. package/build/format/iri.mjs +5 -1
  5. package/build/schema/compile.d.mts +3 -2
  6. package/build/schema/compile.mjs +8 -8
  7. package/build/schema/engine/_context.d.mts +1 -6
  8. package/build/schema/engine/_context.mjs +9 -14
  9. package/build/schema/engine/_functions.mjs +1 -1
  10. package/build/schema/engine/_stack.d.mts +6 -2
  11. package/build/schema/engine/_stack.mjs +135 -32
  12. package/build/schema/engine/additionalProperties.mjs +1 -3
  13. package/build/schema/engine/allOf.mjs +2 -2
  14. package/build/schema/engine/anyOf.mjs +2 -2
  15. package/build/schema/engine/if.mjs +2 -2
  16. package/build/schema/engine/oneOf.mjs +2 -2
  17. package/build/schema/engine/propertyNames.mjs +1 -3
  18. package/build/schema/engine/ref.mjs +2 -2
  19. package/build/schema/engine/schema.mjs +6 -0
  20. package/build/schema/engine/unevaluatedItems.mjs +2 -2
  21. package/build/schema/engine/unevaluatedProperties.mjs +2 -2
  22. package/build/schema/errors.d.mts +2 -2
  23. package/build/schema/errors.mjs +7 -13
  24. package/build/schema/intern/index.d.mts +1 -0
  25. package/build/schema/intern/index.mjs +1 -0
  26. package/build/schema/intern/intern.d.mts +14 -0
  27. package/build/schema/intern/intern.mjs +259 -0
  28. package/build/schema/parse.d.mts +1 -0
  29. package/build/schema/parse.mjs +10 -5
  30. package/build/schema/resolve/resolve.d.mts +34 -3
  31. package/build/schema/resolve/resolve.mjs +198 -73
  32. package/build/schema/schema.d.mts +1 -0
  33. package/build/schema/schema.mjs +1 -0
  34. package/build/value/errors/errors.d.mts +2 -12
  35. package/build/value/errors/errors.mjs +2 -7
  36. package/changes.json +1 -1
  37. package/package.json +3 -3
  38. package/readme.md +9 -5
package/README.md CHANGED
@@ -13,8 +13,8 @@ npm install @depup/typebox
13
13
 
14
14
  | Field | Value |
15
15
  |-------|-------|
16
- | Original | [typebox](https://www.npmjs.com/package/typebox) @ 1.3.22 |
17
- | Processed | 2026-08-30 |
16
+ | Original | [typebox](https://www.npmjs.com/package/typebox) @ 1.3.27 |
17
+ | Processed | 2026-09-06 |
18
18
  | Smoke test | passed |
19
19
  | Deps updated | 0 |
20
20
 
@@ -18,7 +18,7 @@ export declare class Validator<Context extends TProperties = TProperties, Type e
18
18
  Check(value: unknown): value is Encode;
19
19
  /** Validates a value and returns it. Will throw if invalid. */
20
20
  Parse(value: unknown): Encode;
21
- /** Inspects a value and returns a detailed list of validation errors. */
21
+ /** Returns an array of validation errors for the given value. */
22
22
  Errors(value: unknown): TLocalizedValidationError[];
23
23
  /** Cleans a value using the Validator type. */
24
24
  Clean(value: unknown): unknown;
@@ -53,7 +53,7 @@ export class Validator {
53
53
  return Parser(this.Context(), this.Type(), value);
54
54
  throw new ParseError(value, this.Errors(value));
55
55
  }
56
- /** Inspects a value and returns a detailed list of validation errors. */
56
+ /** Returns an array of validation errors for the given value. */
57
57
  Errors(value) {
58
58
  if (this.IsAccelerated() && this.Check(value))
59
59
  return [];
@@ -2,6 +2,7 @@
2
2
  const IpvFutureMatchMaxLength = 2048;
3
3
  const IpvFutureMatch = /\[[vV][0-9a-fA-F]+\.[^\]]+\]/; // Guarded By IpvFutureMatchMaxLength
4
4
  const InvalidIriChars = /[\x00-\x20<>\^`{|}\\]/;
5
+ const InvalidPercentEncoding = /%(?![0-9a-fA-F]{2})/;
5
6
  // ------------------------------------------------------------------
6
7
  // NarrowIpvFuture
7
8
  //
@@ -26,6 +27,9 @@ export function IsIri(value) {
26
27
  // 1. Reject strings containing unencoded whitespace or illegal control characters.
27
28
  if (InvalidIriChars.test(value))
28
29
  return false;
29
- // 2. Delegate to the native URL parser, patching the IPvFuture edge case beforehand.
30
+ // 2. Reject malformed percent-encoding triplets.
31
+ if (InvalidPercentEncoding.test(value))
32
+ return false;
33
+ // 3. Delegate to the native URL parser, patching the IPvFuture edge case beforehand.
30
34
  return URL.canParse(NarrowIpvFuture(value));
31
35
  }
@@ -2,8 +2,9 @@ import { type TLocalizedValidationError } from '../error/index.mjs';
2
2
  import { type Static } from '../type/types/static.mjs';
3
3
  import * as Schema from './types/index.mjs';
4
4
  export declare class Validator<const Schema extends Schema.XSchema = Schema.XSchema, Value extends unknown = Static<Schema>> {
5
- private readonly buildResult;
6
5
  private readonly evaluateResult;
6
+ private readonly context;
7
+ private readonly schema;
7
8
  constructor(context: Record<string, Schema.XSchema>, schema: Schema);
8
9
  /** Returns true if this Validator is using JIT acceleration. */
9
10
  IsAccelerated(): boolean;
@@ -13,7 +14,7 @@ export declare class Validator<const Schema extends Schema.XSchema = Schema.XSch
13
14
  Check(value: unknown): value is Value;
14
15
  /** Validates a value and returns it. Will throw if invalid. */
15
16
  Parse(value: unknown): Value;
16
- /** Inspects a value and returns a detailed list of validation errors. */
17
+ /** Returns an array of validation errors for the given value. */
17
18
  Errors(value: unknown): [result: boolean, errors: TLocalizedValidationError[]];
18
19
  }
19
20
  /** Compiles this schema into a high performance Validator */
@@ -3,14 +3,15 @@
3
3
  import { Arguments } from '../system/arguments/index.mjs';
4
4
  import * as Build from './build.mjs';
5
5
  import { Errors } from './errors.mjs';
6
- import { ParseError } from './parse.mjs';
6
+ import { ThrowParseError } from './parse.mjs';
7
7
  // ------------------------------------------------------------------
8
8
  // Validator
9
9
  // ------------------------------------------------------------------
10
10
  export class Validator {
11
11
  constructor(context, schema) {
12
- this.buildResult = Build.Build(context, schema);
13
- this.evaluateResult = this.buildResult.Evaluate();
12
+ this.evaluateResult = Build.Build(context, schema).Evaluate();
13
+ this.context = context;
14
+ this.schema = schema;
14
15
  }
15
16
  /** Returns true if this Validator is using JIT acceleration. */
16
17
  IsAccelerated() {
@@ -18,7 +19,7 @@ export class Validator {
18
19
  }
19
20
  /** Returns the underlying Schema used to construct this Validator. */
20
21
  Schema() {
21
- return this.buildResult.Schema();
22
+ return this.schema;
22
23
  }
23
24
  /** Performs a type-guard check on the provided value. */
24
25
  Check(value) {
@@ -28,12 +29,11 @@ export class Validator {
28
29
  Parse(value) {
29
30
  if (this.evaluateResult.Check(value))
30
31
  return value;
31
- const [_result, errors] = Errors(this.buildResult.Context(), this.buildResult.Schema(), value);
32
- throw new ParseError(this.buildResult.Schema(), value, errors);
32
+ ThrowParseError(this.context, this.schema, value);
33
33
  }
34
- /** Inspects a value and returns a detailed list of validation errors. */
34
+ /** Returns an array of validation errors for the given value. */
35
35
  Errors(value) {
36
- return Errors(this.buildResult.Context(), this.buildResult.Schema(), value);
36
+ return Errors(this.context, this.schema, value);
37
37
  }
38
38
  }
39
39
  /** Compiles this schema into a high performance Validator */
@@ -21,15 +21,10 @@ export declare class CheckContext {
21
21
  GetKeys(): Set<string>;
22
22
  Merge(results: CheckContext[]): true;
23
23
  }
24
- export type ErrorContextCallback = (error: TValidationError) => unknown;
25
24
  export declare class ErrorContext extends CheckContext {
26
- private readonly callback;
27
- constructor(callback: ErrorContextCallback);
28
- AddError(error: TValidationError): false;
29
- }
30
- export declare class AccumulatedErrorContext extends ErrorContext {
31
25
  private readonly errors;
32
26
  constructor();
27
+ AtCapacity(): boolean;
33
28
  AddError(error: TValidationError): false;
34
29
  GetErrors(): TValidationError[];
35
30
  }
@@ -1,4 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
+ import { Settings } from '../../system/settings/index.mjs';
2
3
  import * as Schema from '../types/index.mjs';
3
4
  import { Guard as G, EmitGuard as E } from '../../guard/index.mjs';
4
5
  // ------------------------------------------------------------------
@@ -101,26 +102,20 @@ export class CheckContext {
101
102
  return true;
102
103
  }
103
104
  }
104
- export class ErrorContext extends CheckContext {
105
- constructor(callback) {
106
- super();
107
- this.callback = callback;
108
- }
109
- AddError(error) {
110
- this.callback(error);
111
- return false;
112
- }
113
- }
114
105
  // ------------------------------------------------------------------
115
- // AccumulatedErrorContext
106
+ // ErrorContext
116
107
  // ------------------------------------------------------------------
117
- export class AccumulatedErrorContext extends ErrorContext {
108
+ export class ErrorContext extends CheckContext {
118
109
  constructor() {
119
- super(error => this.errors.push(error));
110
+ super();
120
111
  this.errors = [];
121
112
  }
113
+ AtCapacity() {
114
+ return this.errors.length >= Settings.Get().maxErrors;
115
+ }
122
116
  AddError(error) {
123
- this.errors.push(error);
117
+ if (!this.AtCapacity())
118
+ this.errors.push(error);
124
119
  return false;
125
120
  }
126
121
  GetErrors() {
@@ -55,7 +55,7 @@ export function GetFunctions() {
55
55
  // CreateFunction
56
56
  // ------------------------------------------------------------------
57
57
  export function CreateFunction(stack, context, schema, value) {
58
- const name = CreateName(schema, stack.BaseURL().href);
58
+ const name = CreateName(schema, stack.LexicalBaseURL());
59
59
  const call = CreateCallExpression(context, schema, name, value);
60
60
  if (funcs.has(name))
61
61
  return call;
@@ -4,12 +4,16 @@ export declare class Stack {
4
4
  private readonly context;
5
5
  private readonly schema;
6
6
  private readonly ids;
7
+ private readonly resourceIds;
7
8
  private readonly anchors;
8
9
  private readonly recursiveAnchors;
9
10
  private readonly dynamicAnchors;
11
+ private readonly retrievedResources;
12
+ private readonly retrievedFrames;
13
+ private readonly resolvedResources;
14
+ private pendingResource;
10
15
  constructor(context: Record<PropertyKey, Schema.XSchema>, schema: Schema.XSchema);
11
- BaseURL(): URL;
12
- Base(): Schema.XSchemaObject;
16
+ LexicalBaseURL(): string;
13
17
  Push(schema: Schema.XSchema): void;
14
18
  Pop(schema: Schema.XSchema): void;
15
19
  Ref(ref: Schema.XRef): Schema.XSchema | undefined;
@@ -4,86 +4,163 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
- var _Stack_instances, _Stack_PushResourceAnchors, _Stack_PopResourceAnchors;
7
+ var _Stack_instances, _Stack_StackFrame, _Stack_ApplyRefResult, _Stack_BuildBase, _Stack_ResourceBaseURL, _Stack_ReferenceBaseURL, _Stack_LexicalSchema, _Stack_RegisterResourceAnchorArray, _Stack_UnregisterResourceAnchorArray, _Stack_RegisterResourceAnchors, _Stack_UnregisterResourceAnchors, _Stack_RegisterResource, _Stack_UnregisterResource, _Stack_EnterResolvedResource, _Stack_ExitResolvedResource;
8
8
  import * as Schema from '../types/index.mjs';
9
- import { Guard as G } from '../../guard/index.mjs';
9
+ import { Guard } from '../../guard/index.mjs';
10
10
  import { Resolve } from '../resolve/index.mjs';
11
+ // --------------------------------------------------------------------------
12
+ // Stack
13
+ //
14
+ // Tracks traversal state ($ids, $anchors, stack frames) and applies scope
15
+ // updates. Reference resolution rules ($ref, $dynamicRef) are delegated to
16
+ // the Resolve functions using state snapshots (Resolve.Scope).
17
+ // --------------------------------------------------------------------------
11
18
  export class Stack {
12
19
  constructor(context, schema) {
13
20
  _Stack_instances.add(this);
14
21
  this.context = context;
15
22
  this.schema = schema;
16
23
  this.ids = [];
24
+ this.resourceIds = [];
17
25
  this.anchors = [];
18
26
  this.recursiveAnchors = [];
19
27
  this.dynamicAnchors = [];
28
+ this.retrievedResources = new Map();
29
+ this.retrievedFrames = [];
30
+ this.resolvedResources = new Map();
31
+ this.pendingResource = true;
20
32
  }
21
33
  // ----------------------------------------------------------------
22
- // Base
34
+ // LexicalBaseURL
23
35
  // ----------------------------------------------------------------
24
- BaseURL() {
25
- return this.ids.reduce((result, schema) => new URL(schema.$id, result), Resolve.DefaultBase);
26
- }
27
- Base() {
28
- return this.ids[this.ids.length - 1] ?? this.schema;
36
+ LexicalBaseURL() {
37
+ return __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_BuildBase).call(this, this.ids);
29
38
  }
30
39
  // ----------------------------------------------------------------
31
- // Stack
40
+ // Push
32
41
  // ----------------------------------------------------------------
33
42
  Push(schema) {
34
43
  if (!Schema.IsSchemaObject(schema))
35
44
  return;
36
- if (Schema.IsId(schema)) {
37
- this.ids.push(schema);
38
- __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_PushResourceAnchors).call(this, schema);
39
- }
45
+ if (Schema.IsId(schema))
46
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_RegisterResource).call(this, schema);
40
47
  if (Schema.IsAnchor(schema))
41
48
  this.anchors.push(schema);
42
49
  if (Schema.IsRecursiveAnchorTrue(schema))
43
50
  this.recursiveAnchors.push(schema);
44
51
  if (Schema.IsDynamicAnchor(schema))
45
52
  this.dynamicAnchors.push(schema);
53
+ const retrievedResource = this.retrievedResources.get(schema);
54
+ if (retrievedResource) {
55
+ this.retrievedFrames.push({
56
+ schema: retrievedResource.root,
57
+ base: retrievedResource.base,
58
+ idDepth: this.ids.length,
59
+ resourceDepth: this.resourceIds.length
60
+ });
61
+ }
46
62
  }
63
+ // ----------------------------------------------------------------
64
+ // Pop
65
+ // ----------------------------------------------------------------
47
66
  Pop(schema) {
48
67
  if (!Schema.IsSchemaObject(schema))
49
68
  return;
50
- if (Schema.IsId(schema)) {
51
- this.ids.pop();
52
- __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_PopResourceAnchors).call(this, schema);
53
- }
69
+ if (Schema.IsId(schema))
70
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_UnregisterResource).call(this, schema);
54
71
  if (Schema.IsAnchor(schema))
55
72
  this.anchors.pop();
56
73
  if (Schema.IsRecursiveAnchorTrue(schema))
57
74
  this.recursiveAnchors.pop();
58
75
  if (Schema.IsDynamicAnchor(schema))
59
76
  this.dynamicAnchors.pop();
77
+ if (this.retrievedResources.has(schema))
78
+ this.retrievedFrames.pop();
79
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_ExitResolvedResource).call(this, schema);
60
80
  }
61
81
  // ----------------------------------------------------------------
62
82
  // Ref
63
83
  // ----------------------------------------------------------------
64
84
  Ref(ref) {
65
- const root = this.schema;
66
- return !ref.$ref.startsWith('#')
67
- ? Resolve.Ref(this.context, root, ref.$ref)
68
- : Resolve.Ref(this.context, this.Base(), ref.$ref);
85
+ const result = Resolve.ResolveRef(__classPrivateFieldGet(this, _Stack_instances, "m", _Stack_StackFrame).call(this), ref);
86
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_ApplyRefResult).call(this, result);
87
+ return result.schema;
69
88
  }
70
89
  // ----------------------------------------------------------------
71
90
  // RecursiveRef
72
91
  // ----------------------------------------------------------------
73
92
  RecursiveRef(recursiveRef) {
74
- return Schema.IsRecursiveAnchorTrue(this.Base())
75
- ? Resolve.Ref(this.context, this.recursiveAnchors[0], recursiveRef.$recursiveRef)
76
- : Resolve.Ref(this.context, this.Base(), recursiveRef.$recursiveRef);
93
+ const result = Resolve.ResolveRecursiveRef(__classPrivateFieldGet(this, _Stack_instances, "m", _Stack_StackFrame).call(this), recursiveRef);
94
+ if (result)
95
+ this.pendingResource = true;
96
+ return result;
77
97
  }
78
98
  // ----------------------------------------------------------------
79
99
  // DynamicRef
80
100
  // ----------------------------------------------------------------
81
101
  DynamicRef(dynamicRef) {
82
- const root = this.schema;
83
- return Resolve.DynamicRef(this.context, root, this.Base(), dynamicRef, this.dynamicAnchors);
102
+ const result = Resolve.ResolveDynamicRef(__classPrivateFieldGet(this, _Stack_instances, "m", _Stack_StackFrame).call(this), dynamicRef);
103
+ if (result)
104
+ this.pendingResource = true;
105
+ return result;
84
106
  }
85
107
  }
86
- _Stack_instances = new WeakSet(), _Stack_PushResourceAnchors = function _Stack_PushResourceAnchors(schema, isRoot = true) {
108
+ _Stack_instances = new WeakSet(), _Stack_StackFrame = function _Stack_StackFrame() {
109
+ return {
110
+ context: this.context,
111
+ root: this.schema,
112
+ ids: this.ids,
113
+ lexicalSchema: __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_LexicalSchema).call(this),
114
+ lexicalBase: this.LexicalBaseURL(),
115
+ referenceBase: __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_ReferenceBaseURL).call(this),
116
+ resourceBase: __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_ResourceBaseURL).call(this),
117
+ recursiveAnchors: this.recursiveAnchors,
118
+ dynamicAnchors: this.dynamicAnchors,
119
+ inRetrievedFrame: this.retrievedFrames.length > 0
120
+ };
121
+ }, _Stack_ApplyRefResult = function _Stack_ApplyRefResult(result) {
122
+ if (!Guard.IsUndefined(result.schema))
123
+ this.pendingResource = true;
124
+ if (!Guard.IsUndefined(result.resolvedResource)) {
125
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_EnterResolvedResource).call(this, result.resolvedResource.target, result.resolvedResource.resource);
126
+ }
127
+ if (!Guard.IsUndefined(result.retrievedResource)) {
128
+ this.retrievedResources.set(result.retrievedResource.target, {
129
+ base: result.retrievedResource.base,
130
+ root: result.retrievedResource.root
131
+ });
132
+ }
133
+ }, _Stack_BuildBase = function _Stack_BuildBase(stack) {
134
+ const frame = this.retrievedFrames[this.retrievedFrames.length - 1];
135
+ const base = frame ? new URL(frame.base) : new URL(Resolve.DefaultBase);
136
+ const scoped = frame ? stack.slice(frame.idDepth) : stack;
137
+ return scoped.reduce((result, schema) => new URL(schema.$id, result), base).href;
138
+ }, _Stack_ResourceBaseURL = function _Stack_ResourceBaseURL() {
139
+ const frame = this.retrievedFrames[this.retrievedFrames.length - 1];
140
+ if (!frame)
141
+ return __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_BuildBase).call(this, this.resourceIds);
142
+ return this.resourceIds.slice(frame.resourceDepth).reduce((result, schema) => new URL(schema.$id, result), new URL(frame.base)).href;
143
+ }, _Stack_ReferenceBaseURL = function _Stack_ReferenceBaseURL() {
144
+ if (this.retrievedFrames.length > 0)
145
+ return __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_ResourceBaseURL).call(this);
146
+ const lexical = this.ids[this.ids.length - 1];
147
+ if (lexical && !/^[A-Za-z][A-Za-z0-9+.-]*:/.test(lexical.$id))
148
+ return this.LexicalBaseURL();
149
+ return __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_ResourceBaseURL).call(this);
150
+ }, _Stack_LexicalSchema = function _Stack_LexicalSchema() {
151
+ const frame = this.retrievedFrames[this.retrievedFrames.length - 1];
152
+ if (frame)
153
+ return this.ids.length > frame.idDepth ? this.ids[this.ids.length - 1] : frame.schema;
154
+ return this.ids.length > 0 ? this.ids[this.ids.length - 1] : this.schema;
155
+ }, _Stack_RegisterResourceAnchorArray = function _Stack_RegisterResourceAnchorArray(schema) {
156
+ schema.forEach((schema) => __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_RegisterResourceAnchors).call(this, schema, false));
157
+ }, _Stack_UnregisterResourceAnchorArray = function _Stack_UnregisterResourceAnchorArray(schema) {
158
+ schema.forEach((schema) => __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_UnregisterResourceAnchors).call(this, schema, false));
159
+ }, _Stack_RegisterResourceAnchors = function _Stack_RegisterResourceAnchors(schema, isRoot = true) {
160
+ if (Schema.IsSchemaBoolean(schema))
161
+ return;
162
+ if (Guard.IsArray(schema))
163
+ return __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_RegisterResourceAnchorArray).call(this, schema);
87
164
  if (!Schema.IsSchemaObject(schema))
88
165
  return;
89
166
  const current = schema;
@@ -91,9 +168,13 @@ _Stack_instances = new WeakSet(), _Stack_PushResourceAnchors = function _Stack_P
91
168
  return;
92
169
  if (!isRoot && Schema.IsDynamicAnchor(current))
93
170
  this.dynamicAnchors.push(current);
94
- for (const key of G.Keys(current))
95
- __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_PushResourceAnchors).call(this, current[key], false);
96
- }, _Stack_PopResourceAnchors = function _Stack_PopResourceAnchors(schema, isRoot = true) {
171
+ for (const key of Guard.Keys(current))
172
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_RegisterResourceAnchors).call(this, current[key], false);
173
+ }, _Stack_UnregisterResourceAnchors = function _Stack_UnregisterResourceAnchors(schema, isRoot = true) {
174
+ if (Schema.IsSchemaBoolean(schema))
175
+ return;
176
+ if (Guard.IsArray(schema))
177
+ return __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_UnregisterResourceAnchorArray).call(this, schema);
97
178
  if (!Schema.IsSchemaObject(schema))
98
179
  return;
99
180
  const current = schema;
@@ -101,6 +182,28 @@ _Stack_instances = new WeakSet(), _Stack_PushResourceAnchors = function _Stack_P
101
182
  return;
102
183
  if (!isRoot && Schema.IsDynamicAnchor(current))
103
184
  this.dynamicAnchors.pop();
104
- for (const key of G.Keys(current))
105
- __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_PopResourceAnchors).call(this, current[key], false);
185
+ for (const key of Guard.Keys(current))
186
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_UnregisterResourceAnchors).call(this, current[key], false);
187
+ }, _Stack_RegisterResource = function _Stack_RegisterResource(schema) {
188
+ this.ids.push(schema);
189
+ const isResource = this.pendingResource;
190
+ this.pendingResource = false;
191
+ if (isResource)
192
+ this.resourceIds.push(schema);
193
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_RegisterResourceAnchors).call(this, schema, true);
194
+ }, _Stack_UnregisterResource = function _Stack_UnregisterResource(schema) {
195
+ this.ids.pop();
196
+ const isResource = this.resourceIds.length > 0 && Guard.IsEqual(this.resourceIds[this.resourceIds.length - 1], schema);
197
+ if (isResource)
198
+ this.resourceIds.pop();
199
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_UnregisterResourceAnchors).call(this, schema, true);
200
+ }, _Stack_EnterResolvedResource = function _Stack_EnterResolvedResource(target, resource) {
201
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_RegisterResource).call(this, resource);
202
+ this.resolvedResources.set(target, resource);
203
+ }, _Stack_ExitResolvedResource = function _Stack_ExitResolvedResource(target) {
204
+ if (!this.resolvedResources.has(target))
205
+ return;
206
+ const resource = this.resolvedResources.get(target);
207
+ __classPrivateFieldGet(this, _Stack_instances, "m", _Stack_UnregisterResource).call(this, resource);
208
+ this.resolvedResources.delete(target);
106
209
  };
@@ -2,7 +2,6 @@
2
2
  import * as S from '../types/index.mjs';
3
3
  import * as V from './_externals.mjs';
4
4
  import { Unique } from './_unique.mjs';
5
- import { AccumulatedErrorContext } from './_context.mjs';
6
5
  import { UnicodeRegExp } from './_regexp.mjs';
7
6
  import { EmitGuard as E, Guard as G } from '../../guard/index.mjs';
8
7
  import { BuildSchemaPushStack, CheckSchemaPushStack, ErrorSchemaPushStack } from './schema.mjs';
@@ -109,9 +108,8 @@ export function ErrorAdditionalProperties(stack, context, schemaPath, instancePa
109
108
  const isAdditionalProperties = G.EveryAll(G.Keys(value), 0, (key, _index) => {
110
109
  const nextSchemaPath = `${schemaPath}/additionalProperties`;
111
110
  const nextInstancePath = `${instancePath}/${key}`;
112
- const nextContext = new AccumulatedErrorContext();
113
111
  const isAdditionalProperty = regexp.test(key) ||
114
- (ErrorSchemaPushStack(stack, nextContext, nextSchemaPath, nextInstancePath, schema.additionalProperties, value[key]) && context.AddKey(key));
112
+ (ErrorSchemaPushStack(stack, context, nextSchemaPath, nextInstancePath, schema.additionalProperties, value[key]) && context.AddKey(key));
115
113
  if (!isAdditionalProperty)
116
114
  additionalProperties.push(key);
117
115
  return isAdditionalProperty;
@@ -1,5 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
- import { CheckContext, AccumulatedErrorContext } from './_context.mjs';
2
+ import { CheckContext, ErrorContext } from './_context.mjs';
3
3
  import { Reducer } from './_reducer.mjs';
4
4
  import { EmitGuard as E, Guard as G } from '../../guard/index.mjs';
5
5
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
@@ -34,7 +34,7 @@ export function ErrorAllOf(stack, context, schemaPath, instancePath, schema, val
34
34
  const failedContexts = [];
35
35
  const results = schema.allOf.reduce((result, schema, index) => {
36
36
  const nextSchemaPath = `${schemaPath}/allOf/${index}`;
37
- const nextContext = new AccumulatedErrorContext();
37
+ const nextContext = new ErrorContext();
38
38
  const isSchema = ErrorSchema(stack, nextContext, nextSchemaPath, instancePath, schema, value);
39
39
  if (!isSchema)
40
40
  failedContexts.push(nextContext);
@@ -1,5 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
- import { CheckContext, AccumulatedErrorContext } from './_context.mjs';
2
+ import { CheckContext, ErrorContext } from './_context.mjs';
3
3
  import { Reducer } from './_reducer.mjs';
4
4
  import { Guard as G, EmitGuard as E } from '../../guard/index.mjs';
5
5
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
@@ -33,7 +33,7 @@ export function CheckAnyOf(stack, context, schema, value) {
33
33
  export function ErrorAnyOf(stack, context, schemaPath, instancePath, schema, value) {
34
34
  const failedContexts = [];
35
35
  const results = schema.anyOf.reduce((result, schema, index) => {
36
- const nextContext = new AccumulatedErrorContext();
36
+ const nextContext = new ErrorContext();
37
37
  const nextSchemaPath = `${schemaPath}/anyOf/${index}`;
38
38
  const isSchema = ErrorSchema(stack, nextContext, nextSchemaPath, instancePath, schema, value);
39
39
  if (!isSchema)
@@ -1,6 +1,6 @@
1
1
  // deno-fmt-ignore-file
2
2
  import * as Schema from '../types/index.mjs';
3
- import { AccumulatedErrorContext } from './_context.mjs';
3
+ import { ErrorContext } from './_context.mjs';
4
4
  import { EmitGuard as E } from '../../guard/index.mjs';
5
5
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
6
6
  // ------------------------------------------------------------------
@@ -27,7 +27,7 @@ export function CheckIf(stack, context, schema, value) {
27
27
  export function ErrorIf(stack, context, schemaPath, instancePath, schema, value) {
28
28
  const thenSchema = Schema.IsThen(schema) ? schema.then : true;
29
29
  const elseSchema = Schema.IsElse(schema) ? schema.else : true;
30
- const trueContext = new AccumulatedErrorContext();
30
+ const trueContext = new ErrorContext();
31
31
  const isIf = ErrorSchema(stack, trueContext, `${schemaPath}/if`, instancePath, schema.if, value)
32
32
  ? ErrorSchema(stack, trueContext, `${schemaPath}/then`, instancePath, thenSchema, value) || context.AddError({
33
33
  keyword: 'if',
@@ -1,5 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
- import { CheckContext, AccumulatedErrorContext } from './_context.mjs';
2
+ import { CheckContext, ErrorContext } from './_context.mjs';
3
3
  import { Reducer } from './_reducer.mjs';
4
4
  import { EmitGuard as E, Guard as G } from '../../guard/index.mjs';
5
5
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
@@ -38,7 +38,7 @@ export function ErrorOneOf(stack, context, schemaPath, instancePath, schema, val
38
38
  const failedContexts = [];
39
39
  const passingSchemas = [];
40
40
  const passedContexts = schema.oneOf.reduce((result, schema, index) => {
41
- const nextContext = new AccumulatedErrorContext();
41
+ const nextContext = new ErrorContext();
42
42
  const nextSchemaPath = `${schemaPath}/oneOf/${index}`;
43
43
  const isSchema = ErrorSchema(stack, nextContext, nextSchemaPath, instancePath, schema, value);
44
44
  if (isSchema)
@@ -1,6 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { Unique } from './_unique.mjs';
3
- import { AccumulatedErrorContext } from './_context.mjs';
4
3
  import { EmitGuard as E, Guard as G } from '../../guard/index.mjs';
5
4
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
6
5
  // ------------------------------------------------------------------
@@ -24,8 +23,7 @@ export function ErrorPropertyNames(stack, context, schemaPath, instancePath, sch
24
23
  const isPropertyNames = G.EveryAll(G.Keys(value), 0, (key, _index) => {
25
24
  const nextInstancePath = `${instancePath}/${key}`;
26
25
  const nextSchemaPath = `${schemaPath}/propertyNames`;
27
- const nextContext = new AccumulatedErrorContext();
28
- const isPropertyName = ErrorSchema(stack, nextContext, nextSchemaPath, nextInstancePath, schema.propertyNames, key);
26
+ const isPropertyName = ErrorSchema(stack, context, nextSchemaPath, nextInstancePath, schema.propertyNames, key);
29
27
  if (!isPropertyName)
30
28
  propertyNames.push(key);
31
29
  return isPropertyName;
@@ -1,7 +1,7 @@
1
1
  // deno-fmt-ignore-file
2
2
  import * as Functions from './_functions.mjs';
3
3
  import * as Schema from '../types/index.mjs';
4
- import { CheckContext, AccumulatedErrorContext } from './_context.mjs';
4
+ import { CheckContext, ErrorContext } from './_context.mjs';
5
5
  import { EmitGuard as E } from '../../guard/index.mjs';
6
6
  import { CheckSchema, ErrorSchema } from './schema.mjs';
7
7
  // ------------------------------------------------------------------
@@ -42,7 +42,7 @@ export function CheckRef(stack, context, schema, value) {
42
42
  // ------------------------------------------------------------------
43
43
  export function ErrorRef(stack, context, _schemaPath, instancePath, schema, value) {
44
44
  const target = stack.Ref(schema) ?? false;
45
- const nextContext = new AccumulatedErrorContext();
45
+ const nextContext = new ErrorContext();
46
46
  const result = (Schema.IsSchema(target) && ErrorSchema(stack, nextContext, '#', instancePath, target, value));
47
47
  if (result)
48
48
  context.Merge([nextContext]);
@@ -308,6 +308,12 @@ export function ErrorSchemaPushStack(stack, context, schemaPath, instancePath, s
308
308
  return (context.Push() && ErrorSchema(stack, context, schemaPath, instancePath, schema, value)) && context.Pop();
309
309
  }
310
310
  export function ErrorSchema(stack, context, schemaPath, instancePath, schema, value) {
311
+ // Optimization: We can safely terminate here when the context is at capacity because we are unable to
312
+ // append additional errors. It is worth being mindful that logical keywords such as allOf, anyOf,
313
+ // oneOf pass a new context per operand, so the capacity check applies per context, not across the
314
+ // full set of errors accumulated by the schema as a whole. (review)
315
+ if (context.AtCapacity())
316
+ return false;
311
317
  stack.Push(schema);
312
318
  const result = (Schema.IsSchemaBoolean(schema)) ? ErrorSchemaBoolean(stack, context, schemaPath, instancePath, schema, value) : (!!(+(!Schema.IsType(schema) || ErrorType(stack, context, schemaPath, instancePath, schema, value)) &
313
319
  +(!(G.IsObject(value) && !G.IsArray(value)) || !!(+(!Schema.IsRequired(schema) || ErrorRequired(stack, context, schemaPath, instancePath, schema, value)) &
@@ -1,6 +1,6 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { Unique } from './_unique.mjs';
3
- import { AccumulatedErrorContext } from './_context.mjs';
3
+ import { ErrorContext } from './_context.mjs';
4
4
  import { Guard as G, EmitGuard as E } from '../../guard/index.mjs';
5
5
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
6
6
  // ------------------------------------------------------------------
@@ -35,7 +35,7 @@ export function ErrorUnevaluatedItems(stack, context, schemaPath, instancePath,
35
35
  const indices = context.GetIndices();
36
36
  const unevaluatedItems = [];
37
37
  const isUnevaluatedItems = G.EveryAll(value, 0, (item, index) => {
38
- const nextContext = new AccumulatedErrorContext();
38
+ const nextContext = new ErrorContext();
39
39
  const isEvaluatedItem = (indices.has(index) || ErrorSchema(stack, nextContext, schemaPath, instancePath, schema.unevaluatedItems, item))
40
40
  && context.AddIndex(index);
41
41
  if (!isEvaluatedItem)
@@ -1,6 +1,6 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { Unique } from './_unique.mjs';
3
- import { AccumulatedErrorContext } from './_context.mjs';
3
+ import { ErrorContext } from './_context.mjs';
4
4
  import { Guard as G, EmitGuard as E } from '../../guard/index.mjs';
5
5
  import { BuildSchema, CheckSchema, ErrorSchema } from './schema.mjs';
6
6
  // ------------------------------------------------------------------
@@ -35,7 +35,7 @@ export function ErrorUnevaluatedProperties(stack, context, schemaPath, instanceP
35
35
  const keys = context.GetKeys();
36
36
  const unevaluatedProperties = [];
37
37
  const isUnevaluatedProperties = G.EveryAll(G.Entries(value), 0, ([key, prop]) => {
38
- const nextContext = new AccumulatedErrorContext();
38
+ const nextContext = new ErrorContext();
39
39
  const isEvaluatedProperty = keys.has(key)
40
40
  || (ErrorSchema(stack, nextContext, schemaPath, instancePath, schema.unevaluatedProperties, prop) && context.AddKey(key));
41
41
  if (!isEvaluatedProperty)
@@ -1,6 +1,6 @@
1
1
  import { type TLocalizedValidationError } from '../error/index.mjs';
2
2
  import * as Schema from './types/index.mjs';
3
- /** Checks a value and returns validation errors */
3
+ /** Returns an array of validation errors for the given value. */
4
4
  export declare function Errors(schema: Schema.XSchema, value: unknown): [boolean, TLocalizedValidationError[]];
5
- /** Checks a value and returns validation errors */
5
+ /** Returns an array of validation errors for the given value. */
6
6
  export declare function Errors(context: Record<PropertyKey, Schema.XSchema>, schema: Schema.XSchema, value: unknown): [boolean, TLocalizedValidationError[]];