@depup/typebox 1.3.16-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 (55) 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/email.mjs +1 -1
  5. package/build/format/idna/idn-hostname.mjs +21 -1
  6. package/build/format/iri.mjs +5 -1
  7. package/build/format/json_pointer.d.mts +2 -2
  8. package/build/format/json_pointer.mjs +2 -2
  9. package/build/format/json_pointer_uri_fragment.d.mts +2 -2
  10. package/build/format/json_pointer_uri_fragment.mjs +2 -2
  11. package/build/format/relative_json_pointer.d.mts +2 -2
  12. package/build/format/relative_json_pointer.mjs +2 -2
  13. package/build/guard/emit.mjs +2 -4
  14. package/build/guard/guard.mjs +6 -18
  15. package/build/guard/string.mjs +16 -24
  16. package/build/schema/compile.d.mts +3 -2
  17. package/build/schema/compile.mjs +8 -8
  18. package/build/schema/engine/_context.d.mts +1 -6
  19. package/build/schema/engine/_context.mjs +9 -14
  20. package/build/schema/engine/_functions.mjs +1 -1
  21. package/build/schema/engine/_stack.d.mts +6 -2
  22. package/build/schema/engine/_stack.mjs +135 -32
  23. package/build/schema/engine/additionalProperties.mjs +16 -4
  24. package/build/schema/engine/allOf.mjs +2 -2
  25. package/build/schema/engine/anyOf.mjs +2 -2
  26. package/build/schema/engine/if.mjs +2 -2
  27. package/build/schema/engine/oneOf.mjs +2 -2
  28. package/build/schema/engine/propertyNames.mjs +1 -3
  29. package/build/schema/engine/ref.mjs +2 -2
  30. package/build/schema/engine/schema.mjs +6 -0
  31. package/build/schema/engine/unevaluatedItems.mjs +2 -2
  32. package/build/schema/engine/unevaluatedProperties.mjs +2 -2
  33. package/build/schema/errors.d.mts +2 -2
  34. package/build/schema/errors.mjs +7 -13
  35. package/build/schema/intern/index.d.mts +1 -0
  36. package/build/schema/intern/index.mjs +1 -0
  37. package/build/schema/intern/intern.d.mts +14 -0
  38. package/build/schema/intern/intern.mjs +259 -0
  39. package/build/schema/parse.d.mts +1 -0
  40. package/build/schema/parse.mjs +10 -5
  41. package/build/schema/resolve/resolve.d.mts +34 -3
  42. package/build/schema/resolve/resolve.mjs +198 -73
  43. package/build/schema/schema.d.mts +1 -0
  44. package/build/schema/schema.mjs +1 -0
  45. package/build/system/memory/assign.mjs +2 -1
  46. package/build/system/memory/create.mjs +3 -4
  47. package/build/system/memory/discard.mjs +2 -2
  48. package/build/system/memory/freeze.d.mts +4 -0
  49. package/build/system/memory/freeze.mjs +6 -0
  50. package/build/system/memory/update.mjs +3 -2
  51. package/build/value/errors/errors.d.mts +2 -12
  52. package/build/value/errors/errors.mjs +2 -7
  53. package/changes.json +1 -1
  54. package/package.json +3 -3
  55. package/readme.md +9 -5
@@ -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,12 +2,23 @@
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';
9
8
  // ------------------------------------------------------------------
10
- // Common: GetPropertiesPattern
9
+ // Optimization: IsAdditionalPropertiesIgnored
10
+ //
11
+ // We can ignore additionalProperties if the schema is true-like and
12
+ // we are not in an unevaluated context, noting that additional
13
+ // properties are considered tracked, evaluated keys.
14
+ // ------------------------------------------------------------------
15
+ function IsAdditionalPropertiesIgnored(context, additionalProperties) {
16
+ return !context.UseUnevaluated() &&
17
+ (G.IsEqual(additionalProperties, true) ||
18
+ (G.IsObject(additionalProperties) && G.IsEqual(G.Keys(additionalProperties).length, 0)));
19
+ }
20
+ // ------------------------------------------------------------------
21
+ // Optimization: GetPropertiesPattern
11
22
  //
12
23
  // Constructs a regular expression that matches all property keys
13
24
  // and pattern properties defined in a schema. This approach unifies
@@ -71,6 +82,8 @@ export function BuildAdditionalPropertiesStandard(stack, context, schema, value)
71
82
  // Build
72
83
  // ------------------------------------------------------------------
73
84
  export function BuildAdditionalProperties(stack, context, schema, value) {
85
+ if (IsAdditionalPropertiesIgnored(context, schema.additionalProperties))
86
+ return E.Constant(true);
74
87
  return CanAdditionalPropertiesFast(context, schema, value)
75
88
  ? BuildAdditionalPropertiesFast(context, schema, value)
76
89
  : BuildAdditionalPropertiesStandard(stack, context, schema, value);
@@ -95,9 +108,8 @@ export function ErrorAdditionalProperties(stack, context, schemaPath, instancePa
95
108
  const isAdditionalProperties = G.EveryAll(G.Keys(value), 0, (key, _index) => {
96
109
  const nextSchemaPath = `${schemaPath}/additionalProperties`;
97
110
  const nextInstancePath = `${instancePath}/${key}`;
98
- const nextContext = new AccumulatedErrorContext();
99
111
  const isAdditionalProperty = regexp.test(key) ||
100
- (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));
101
113
  if (!isAdditionalProperty)
102
114
  additionalProperties.push(key);
103
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[]];
@@ -1,24 +1,18 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { Arguments } from '../system/arguments/index.mjs';
3
- import { Settings } from '../system/settings/index.mjs';
4
- import { Get as LocaleGet } from '../system/locale/_config.mjs';
5
- import { Guard } from '../guard/index.mjs';
3
+ import { Get as GetLocalizationFunction } from '../system/locale/_config.mjs';
6
4
  import * as Engine from './engine/index.mjs';
7
- /** Checks a value and returns validation errors */
5
+ /** Returns an array of validation errors for the given value. */
8
6
  export function Errors(...args) {
9
7
  const [context, schema, value] = Arguments.Match(args, {
10
8
  3: (context, schema, value) => [context, schema, value],
11
9
  2: (schema, value) => [{}, schema, value]
12
10
  });
13
- const settings = Settings.Get();
14
- const locale = LocaleGet();
15
- const errors = [];
16
11
  const stack = new Engine.Stack(context, schema);
17
- const errorContext = new Engine.ErrorContext(error => {
18
- if (Guard.IsGreaterEqualThan(errors.length, settings.maxErrors))
19
- return;
20
- return errors.push({ ...error, message: locale(error) });
21
- });
12
+ const errorContext = new Engine.ErrorContext();
22
13
  const result = Engine.ErrorSchema(stack, errorContext, '#', '', schema, value);
23
- return [result, errors];
14
+ const errors = errorContext.GetErrors();
15
+ const locale = GetLocalizationFunction();
16
+ const localized = errors.map(error => ({ ...error, message: locale(error) }));
17
+ return [result, localized];
24
18
  }
@@ -0,0 +1 @@
1
+ export * from './intern.mjs';
@@ -0,0 +1 @@
1
+ export * from './intern.mjs';
@@ -0,0 +1,14 @@
1
+ import { type XStatic } from '../static/index.mjs';
2
+ import * as S from '../types/index.mjs';
3
+ export interface XIntern<Type extends unknown = unknown> {
4
+ '~unsafe': Type;
5
+ $ref: string;
6
+ $defs: Record<string, S.XSchemaObject>;
7
+ }
8
+ /**
9
+ * [Experimental] Performs a Common Subexpression Elimination (CSE) transform on the given
10
+ * schema. This function restructures the schema such that each distinct sub-schema is stored
11
+ * exactly once in a $defs object and keyed by content hash. This function can be used to
12
+ * both compress and optimize schemas prior to compilation.
13
+ */
14
+ export declare function Intern<const Schema extends S.XSchema>(schema: Schema): XIntern<XStatic<Schema>>;