ata-validator 1.35.0 → 1.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/rejections.js CHANGED
@@ -6,7 +6,7 @@
6
6
  // and by the wrapper around a compiled module, so both report errors through
7
7
  // the same code.
8
8
 
9
- const { ordinalFor: schemaOrdinal } = require('./schema-order');
9
+ const { ordinalFor: schemaOrdinal, rankFor: schemaRank } = require('./schema-order');
10
10
  const { setDiagnosticSource: attachDiagnosticSource } = require('./diagnostic-source');
11
11
 
12
12
  // Rejection result with errors materialized on first read. The accessor
@@ -256,13 +256,17 @@ function stripOrdinal(e) {
256
256
 
257
257
  // Errors in schema declaration order. Each error's key is its schemaPath's
258
258
  // pre-order ordinal in the root schema: written into the literal by the code
259
- // generator (`_o`), looked up once per path otherwise. Most rejections come
260
- // out already ordered, and those return without sorting or allocating.
259
+ // generator (`_o`), looked up once per path otherwise. Errors behind the same
260
+ // `$ref` share the ordinal of that `$ref`, and among themselves go by their
261
+ // place in the target (rankFor), so they come out in the order they would
262
+ // inline, whichever engine produced them. Most rejections come out already
263
+ // ordered, and those return without sorting or allocating.
261
264
  function sortErrorsBySchemaOrder(rootSchema, errors) {
262
265
  const n = errors.length;
263
266
  const keys = new Array(n);
264
267
  let sorted = true;
265
268
  let prev = -1;
269
+ let prevPath = null;
266
270
  for (let i = 0; i < n; i++) {
267
271
  const e = errors[i];
268
272
  let o = typeof e._o === 'number' ? e._o : schemaOrdinal(rootSchema, e.schemaPath);
@@ -271,24 +275,40 @@ function sortErrorsBySchemaOrder(rootSchema, errors) {
271
275
  // which is where the rank comparison left it too.
272
276
  if (o === null) o = prev < 0 ? 0 : prev;
273
277
  keys[i] = o;
274
- if (o < prev) sorted = false;
278
+ if (o < prev || (o === prev && sorted && e.schemaPath !== prevPath && tieOrder(rootSchema, prevPath, e.schemaPath) > 0)) sorted = false;
275
279
  prev = o;
280
+ prevPath = e.schemaPath;
276
281
  }
277
282
  if (sorted) return errors;
278
283
  // Error lists are short. A stable insertion sort over the integer keys
279
- // moves the errors in tandem with no comparator calls and no index array.
284
+ // moves the errors in tandem with no index array; equal keys fall back to
285
+ // the rank only when the paths differ.
280
286
  const out = errors.slice();
281
287
  for (let i = 1; i < n; i++) {
282
288
  const k = keys[i];
283
289
  const e = out[i];
284
290
  let j = i - 1;
285
- while (j >= 0 && keys[j] > k) { keys[j + 1] = keys[j]; out[j + 1] = out[j]; j--; }
291
+ while (j >= 0 && (keys[j] > k || (keys[j] === k && tieOrder(rootSchema, out[j].schemaPath, e.schemaPath) > 0))) {
292
+ keys[j + 1] = keys[j]; out[j + 1] = out[j]; j--;
293
+ }
286
294
  keys[j + 1] = k;
287
295
  out[j + 1] = e;
288
296
  }
289
297
  return out;
290
298
  }
291
299
 
300
+ // Order of two paths with the same ordinal: positive when `a` belongs after
301
+ // `b`. Zero keeps them as they are, for identical paths and for paths
302
+ // outside this document.
303
+ function tieOrder(rootSchema, a, b) {
304
+ if (a === b) return 0;
305
+ const ra = schemaRank(rootSchema, a), rb = schemaRank(rootSchema, b);
306
+ if (ra === null || rb === null) return 0;
307
+ const m = Math.min(ra.length, rb.length);
308
+ for (let k = 0; k < m; k++) if (ra[k] !== rb[k]) return ra[k] - rb[k];
309
+ return ra.length - rb.length;
310
+ }
311
+
292
312
  // Resolved once. A require() inside the function was re-resolving the path
293
313
  // on every rejection, which the profile showed as internalModuleStat at the
294
314
  // top of the reject path, above the correlation it was loading.
@@ -11,6 +11,11 @@
11
11
  // generator can compute it once per error site instead of the reader
12
12
  // deriving it from the path string on every rejection.
13
13
  //
14
+ // A path that runs on through a `$ref` names keys the referencing node does
15
+ // not have. Its ordinal is that of the `$ref` key, which several paths then
16
+ // share; its rank carries on inside the target, and the reader uses the rank
17
+ // to order the paths that share an ordinal.
18
+ //
14
19
  // Both are memoized per root schema; a validator's root never changes.
15
20
 
16
21
  const _keyIndexCache = new WeakMap();
@@ -56,12 +61,12 @@ function computeRank(rootSchema, schemaPath) {
56
61
  const rank = [];
57
62
  let node = rootSchema;
58
63
  let start = 1;
64
+ let hops = 0;
59
65
  while (start <= schemaPath.length) {
60
66
  let end = schemaPath.indexOf('/', start);
61
67
  if (end < 0) end = schemaPath.length;
62
68
  if (end === start) { start = end + 1; continue; }
63
69
  const seg = unescapePointerSegment(schemaPath.slice(start, end));
64
- start = end + 1;
65
70
  if (node == null || typeof node !== 'object') break;
66
71
  if (Array.isArray(node)) {
67
72
  const idx = Number(seg);
@@ -70,14 +75,53 @@ function computeRank(rootSchema, schemaPath) {
70
75
  node = node[idx];
71
76
  } else {
72
77
  const idx = keyIndex(node, seg);
73
- if (idx < 0) break;
78
+ if (idx < 0) {
79
+ // An evaluation path runs on through a `$ref` into its target without
80
+ // naming it. Ranking the rest inside the target, as if the target sat
81
+ // under the `$ref` key, orders errors behind a reference by the
82
+ // target's declaration order, as they are ordered inline.
83
+ const target = hops < 64 ? localTarget(rootSchema, node) : null;
84
+ if (target === null) break;
85
+ hops++;
86
+ rank.push(keyIndex(node, '$ref'));
87
+ node = target;
88
+ continue;
89
+ }
74
90
  rank.push(idx);
75
91
  node = node[seg];
76
92
  }
93
+ start = end + 1;
77
94
  }
78
95
  return rank;
79
96
  }
80
97
 
98
+ // The schema a node's `$ref` names, when it is a pointer into this document.
99
+ function localTarget(rootSchema, node) {
100
+ const ref = node.$ref;
101
+ if (typeof ref !== 'string' || ref.charCodeAt(0) !== 35) return null;
102
+ if (ref.length > 1 && ref.charCodeAt(1) !== 47) return null;
103
+ let t = rootSchema;
104
+ let start = 2;
105
+ while (start <= ref.length && ref.length > 1) {
106
+ let end = ref.indexOf('/', start);
107
+ if (end < 0) end = ref.length;
108
+ let seg = ref.slice(start, end);
109
+ if (seg.indexOf('%') >= 0) { try { seg = decodeURIComponent(seg); } catch { return null; } }
110
+ seg = unescapePointerSegment(seg);
111
+ if (t === null || typeof t !== 'object') return null;
112
+ // Normalization renames draft-07 `definitions` to `$defs` and leaves the
113
+ // pointers as written; the resolvers read either name as the other.
114
+ if (!Object.prototype.hasOwnProperty.call(t, seg)) {
115
+ const alias = seg === 'definitions' ? '$defs' : seg === '$defs' ? 'definitions' : null;
116
+ if (alias === null || !Object.prototype.hasOwnProperty.call(t, alias)) return null;
117
+ seg = alias;
118
+ }
119
+ t = t[seg];
120
+ start = end + 1;
121
+ }
122
+ return t !== null && typeof t === 'object' && t !== node ? t : null;
123
+ }
124
+
81
125
  // Pre-order numbering of every node in the schema, keyed by its pointer as
82
126
  // it appears in a schemaPath (segments escaped). Built once per root, on the
83
127
  // first ask. Cyclic structures are guarded; a schema object can contain
@@ -115,13 +159,19 @@ function ordinalFor(rootSchema, schemaPath) {
115
159
  // Walk back to the longest prefix that exists. Paths through a keyword's
116
160
  // value that is a primitive, or through a key the schema does not have,
117
161
  // land on the nearest enclosing node.
162
+ // A path that runs on through a `$ref` lands on its `$ref` key, so errors
163
+ // behind a reference sort where the `$ref` is declared among its siblings;
164
+ // rankFor orders them among themselves.
118
165
  let p = schemaPath;
119
166
  while (true) {
120
167
  const cut = p.lastIndexOf('/');
121
168
  if (cut < 0) return 0;
122
169
  p = p.slice(0, cut);
123
170
  const o = map.get(p);
124
- if (o !== undefined) return o;
171
+ if (o !== undefined) {
172
+ const r = map.get(p + '/$ref');
173
+ return r !== undefined ? r : o;
174
+ }
125
175
  }
126
176
  }
127
177
 
@@ -30,137 +30,83 @@ const { isV1Dialect } = require("./dialect");
30
30
  const { classify } = require("./shape-classifier");
31
31
  const { buildTier0Plan, tier0Validate } = require("./tier0");
32
32
 
33
- // Extract default values from a schema tree. Returns a function that applies
34
- // defaults to an object in-place (mutates), or null if no defaults exist.
33
+ // The closure defaults pass. Only a validator without the generated
34
+ // preprocess pass calls it, so it loads on that first call; loading it with
35
+ // the core measured 0.07 ms of every process's start.
36
+ let _defaults = null;
35
37
  function buildDefaultsApplier(schema) {
36
- if (typeof schema !== "object" || schema === null) return null;
37
- const actions = [];
38
- collectDefaults(schema, actions);
39
- if (actions.length === 0) return null;
40
- return (data) => {
41
- for (let i = 0; i < actions.length; i++) actions[i](data);
42
- };
43
- }
44
-
45
- // Write an own property. Plain assignment of a key named `__proto__` does
46
- // not create a property at all: it hits the Object.prototype setter and
47
- // rewrites the object's prototype, which is how a schema could reach
48
- // Object.prototype itself. defineProperty has no such special case.
49
- function setOwn(obj, key, val) {
50
- if (key === "__proto__") {
51
- Object.defineProperty(obj, key, {
52
- value: val,
53
- writable: true,
54
- enumerable: true,
55
- configurable: true,
56
- });
57
- } else {
58
- obj[key] = val;
59
- }
60
- }
61
-
62
- function collectDefaults(schema, actions, path) {
63
- if (typeof schema !== "object" || schema === null) return;
64
- const props = schema.properties;
65
- if (!props) return;
66
- for (const [key, prop] of Object.entries(props)) {
67
- if (prop && typeof prop === "object" && prop.default !== undefined) {
68
- const defaultVal = prop.default;
69
- if (!path) {
70
- actions.push((data) => {
71
- if (typeof data === "object" && data !== null && !Object.hasOwn(data, key)) {
72
- setOwn(data,
73
- key,
74
- typeof defaultVal === "object" && defaultVal !== null
75
- ? JSON.parse(JSON.stringify(defaultVal))
76
- : defaultVal);
77
- }
78
- });
79
- } else {
80
- const parentPath = path;
81
- actions.push((data) => {
82
- let target = data;
83
- for (let j = 0; j < parentPath.length; j++) {
84
- if (typeof target !== "object" || target === null) return;
85
- // Own keys only. `target[key]` for an inherited name walks the
86
- // prototype chain: a parent named `__proto__` that the instance
87
- // does not carry resolved to Object.prototype, and the child
88
- // defaults were written onto it, for every object in the realm.
89
- if (!Object.hasOwn(target, parentPath[j])) return;
90
- target = target[parentPath[j]];
91
- }
92
- if (
93
- typeof target === "object" &&
94
- target !== null &&
95
- !Object.hasOwn(target, key)
96
- ) {
97
- setOwn(target,
98
- key,
99
- typeof defaultVal === "object" && defaultVal !== null
100
- ? JSON.parse(JSON.stringify(defaultVal))
101
- : defaultVal);
102
- }
103
- });
104
- }
105
- }
106
- // Recurse into nested object schemas
107
- if (prop && typeof prop === "object" && prop.properties) {
108
- collectDefaults(prop, actions, (path || []).concat(key));
109
- }
110
- }
38
+ if (_defaults === null) _defaults = require('./defaults');
39
+ return _defaults.buildDefaultsApplier(schema);
111
40
  }
112
41
 
113
42
  // Build a function that coerces property values to match schema types in-place.
114
43
  // Handles string→number, string→integer, string→boolean, number→string, boolean→string.
115
44
  function buildCoercer(schema) {
116
45
  if (typeof schema !== "object" || schema === null) return null;
117
- const actions = [];
118
- collectCoercions(schema, actions);
119
- if (actions.length === 0) return null;
120
- return (data) => {
121
- for (let i = 0; i < actions.length; i++) actions[i](data);
122
- };
46
+ const node = buildNodeCoercer(schema, new Set());
47
+ if (node === null) return null;
48
+ return (data) => { if (typeof data === "object" && data !== null) node(data); };
123
49
  }
124
50
 
125
- function collectCoercions(schema, actions, path) {
126
- if (typeof schema !== "object" || schema === null) return;
127
- const props = schema.properties;
128
- if (!props) return;
129
- for (const [key, prop] of Object.entries(props)) {
130
- if (!prop || typeof prop !== "object" || !prop.type) continue;
131
- const targetType = Array.isArray(prop.type) ? null : prop.type;
132
- if (!targetType) continue;
133
-
134
- const coerce = buildSingleCoercion(targetType);
135
- if (!coerce) continue;
51
+ // What to do with a value that sits at `schema`: coerce it (`scalar`) and then
52
+ // visit what is inside it (`inner`). Null when there is nothing.
53
+ function coercionFor(schema, seen) {
54
+ if (!schema || typeof schema !== "object") return null;
55
+ const scalar = schema.type && !Array.isArray(schema.type) ? buildSingleCoercion(schema.type) : null;
56
+ const inner = buildNodeCoercer(schema, seen);
57
+ return scalar || inner ? { scalar, inner } : null;
58
+ }
136
59
 
137
- if (!path) {
138
- actions.push((data) => {
139
- if (typeof data === "object" && data !== null && key in data) {
140
- const coerced = coerce(data[key]);
141
- if (coerced !== undefined) data[key] = coerced;
142
- }
143
- });
144
- } else {
145
- const parentPath = path;
146
- actions.push((data) => {
147
- let target = data;
148
- for (let j = 0; j < parentPath.length; j++) {
149
- if (typeof target !== "object" || target === null) return;
150
- target = target[parentPath[j]];
60
+ // The steps for the object or array at `schema`. `seen` stops a schema that
61
+ // contains itself through an inline cycle.
62
+ function buildNodeCoercer(schema, seen) {
63
+ if (seen.has(schema)) return null;
64
+ seen.add(schema);
65
+ const steps = [];
66
+ if (schema.properties) {
67
+ for (const [key, prop] of Object.entries(schema.properties)) {
68
+ // Assignment to `__proto__` would replace the prototype; the generated
69
+ // pass skips it for the same reason.
70
+ if (key === "__proto__") continue;
71
+ const c = coercionFor(prop, seen);
72
+ if (!c) continue;
73
+ const { scalar, inner } = c;
74
+ steps.push((o) => {
75
+ if (!(key in o)) return;
76
+ if (scalar) {
77
+ const v = scalar(o[key]);
78
+ if (v !== undefined) o[key] = v;
151
79
  }
152
- if (typeof target === "object" && target !== null && key in target) {
153
- const coerced = coerce(target[key]);
154
- if (coerced !== undefined) target[key] = coerced;
80
+ if (inner) {
81
+ const x = o[key];
82
+ if (typeof x === "object" && x !== null) inner(x);
155
83
  }
156
84
  });
157
85
  }
158
-
159
- // Recurse into nested object properties
160
- if (prop.properties) {
161
- collectCoercions(prop, actions, (path || []).concat(key));
86
+ }
87
+ if (schema.items && typeof schema.items === "object" && !Array.isArray(schema.items)) {
88
+ const c = coercionFor(schema.items, seen);
89
+ if (c) {
90
+ const { scalar, inner } = c;
91
+ steps.push((o) => {
92
+ if (!Array.isArray(o)) return;
93
+ for (let i = 0; i < o.length; i++) {
94
+ if (scalar) {
95
+ const v = scalar(o[i]);
96
+ if (v !== undefined) o[i] = v;
97
+ }
98
+ if (inner) {
99
+ const x = o[i];
100
+ if (typeof x === "object" && x !== null) inner(x);
101
+ }
102
+ }
103
+ });
162
104
  }
163
105
  }
106
+ seen.delete(schema);
107
+ if (steps.length === 0) return null;
108
+ if (steps.length === 1) return steps[0];
109
+ return (o) => { for (let i = 0; i < steps.length; i++) steps[i](o); };
164
110
  }
165
111
 
166
112
  function buildSingleCoercion(targetType) {
@@ -271,6 +217,11 @@ function codegenAvailable() {
271
217
 
272
218
  // Schema compilation cache: same schema string -> reuse compiled functions
273
219
  const _compileCache = new Map();
220
+ // Generated preprocess passes, keyed like _compileCache plus the options that
221
+ // shape the pass. Only passes that exist are kept: a schema with nothing to
222
+ // rewrite answers `null` quickly, and keeping that answer held its key, the
223
+ // whole schema text, for every such validator, 0.2 KB each.
224
+ const _preprocessCache = new Map();
274
225
 
275
226
  // Object identity cache: same schema object reference -> reuse entire compiled state
276
227
  // Skips JSON.stringify, cache lookup, and all setup. Near-zero cost for repeated schemas.
@@ -644,6 +595,16 @@ function _materializeSchema(self) {
644
595
  const raw = self._rawSchema;
645
596
  const options = self._options;
646
597
  let schemaObj = _normalizeCallerSchema(raw);
598
+ // `baseURI` is where the schema was retrieved from, the base its relative
599
+ // references resolve against when it declares no `$id` of its own. Draft-07
600
+ // ignores an `$id` beside a root `$ref`, so SchemaStore's schemas, which are
601
+ // written that way, lost their base and every relative reference in them
602
+ // failed to resolve; an editor always knows the address it downloaded a
603
+ // schema from. Set on a shallow copy, never on the caller's object.
604
+ if (typeof options.baseURI === 'string' && options.baseURI !== '' &&
605
+ schemaObj && typeof schemaObj === 'object' && !Array.isArray(schemaObj) && typeof schemaObj.$id !== 'string') {
606
+ schemaObj = { ...schemaObj, $id: options.baseURI };
607
+ }
647
608
  const isCallers = self._rawIsCallers && schemaObj === raw;
648
609
  if (options.assertFormat === false) {
649
610
  schemaObj = stripFormatAssertions(isCallers ? _deepCloneWithSymbols(schemaObj) : schemaObj);
@@ -935,10 +896,30 @@ class Validator {
935
896
  const preprocessSchema = resolveSchemaForPreprocess(schemaObj, this._schemaMap);
936
897
  // The mutator pass (defaults, coercion, removal) is generated source too,
937
898
  // with the schema's `default` values embedded; an interpreter-only
938
- // validator takes the closure mutators instead.
939
- let preprocess = this._interpretOnly || _codegen === null ? null : _codegen.buildPreprocess(preprocessSchema, options);
899
+ // validator takes the closure mutators instead. The generated pass is a
900
+ // function of the schema text, the referenced schemas and three options,
901
+ // and holds no state, so validators that share those share it, as they
902
+ // share the verdict function: a Fastify app repeats a body schema across
903
+ // routes, and generating and compiling the pass again for each was most of
904
+ // what a repeated schema cost to set up.
905
+ let preprocess = null;
906
+ if (!this._interpretOnly && _codegen !== null) {
907
+ const cacheable = !this._userFormats && !this._usesKeywords;
908
+ const ppKey = cacheable ? mapKey + '\u0000' + String(options.coerceTypes) + '|' + (options.useDefaults !== false) + '|' + String(options.removeAdditional) : null;
909
+ const hit = ppKey !== null ? _preprocessCache.get(ppKey) : undefined;
910
+ if (hit !== undefined) preprocess = hit;
911
+ else {
912
+ preprocess = _codegen.buildPreprocess(preprocessSchema, options) || null;
913
+ if (ppKey !== null && preprocess !== null) _preprocessCache.set(ppKey, preprocess);
914
+ }
915
+ }
940
916
  if (!preprocess) {
941
- const applyDefaults = options.useDefaults === false ? null : buildDefaultsApplier(preprocessSchema);
917
+ // A root schema whose text has no `default` has none to fill, and the
918
+ // defaults module then stays unloaded. One reached through a reference
919
+ // into another document is walked, since its defaults are not in this
920
+ // text.
921
+ const mayHaveDefaults = preprocessSchema !== schemaObj || this._schemaStr.includes('"default"');
922
+ const applyDefaults = options.useDefaults === false || !mayHaveDefaults ? null : buildDefaultsApplier(preprocessSchema);
942
923
  const applyCoerce = options.coerceTypes ? buildCoercer(preprocessSchema) : null;
943
924
  const applyRemove = options.removeAdditional
944
925
  ? buildRemover(preprocessSchema)
package/lib/version.js CHANGED
@@ -7,4 +7,4 @@
7
7
  //
8
8
  // Kept in lockstep with package.json by `tests/test_version_sync.js`.
9
9
 
10
- module.exports = '1.35.0';
10
+ module.exports = '1.36.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ata-validator",
3
- "version": "1.35.0",
3
+ "version": "1.36.1",
4
4
  "description": "JSON Schema validation that compiles for speed and still runs where code generation is blocked. Compiled and interpreted engines answer identically at 100% of the official suite. TypeScript inference, Standard Schema V1, and a build step that emits dependency-free modules.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -12,7 +12,10 @@
12
12
  "import": "./index.browser.mjs",
13
13
  "require": "./index.js"
14
14
  },
15
- "import": "./index.mjs",
15
+ "import": {
16
+ "module-sync": "./index.node.mjs",
17
+ "default": "./index.mjs"
18
+ },
16
19
  "require": "./index.js"
17
20
  },
18
21
  "./compat": {
@@ -56,7 +59,7 @@
56
59
  "release:check": "node scripts/regen-safe-regex-source.js && node tests/test_pack_purity.js && node scripts/check-doc-coverage.js && node tests/test_error_codes_lock.js && node tests/test_safe_regex_source_sync.js && node tests/test_version_sync.js",
57
60
  "build": "cmake-js build --target ata",
58
61
  "rebuild": "cmake-js rebuild --target ata",
59
- "test": "node test.js && node tests/test_removed_aot_methods.js && node tests/test_no_native.js && node tests/test_no_eval.js && node tests/test_property_dependencies.js && node tests/test_v1_dialect.js && node tests/test_buffer_path_parity.js && node tests/test_text_path_errors.js && node tests/test_compiled_parity.js && node tests/test_buffer_gate.js && node tests/test_scanner_differential.js && node tests/test_validate_json_scanner_cost.js && node tests/test_buffer_reject_cost.js && node tests/test_nan_verdict.js && node tests/test_remove_additional_nested.js && node tests/test_exclusive_bounds.js && node tests/test_engine_differential.js && node tests/test_error_shape_differential.js && node tests/test_output_format.js && node tests/test_retry_message.js && node tests/test_describe_schema.js && node tests/test_aot_parse.js && node tests/test_draft7_semantics.js && node tests/test_metaschema_ref.js && node tests/test_pure_js_unsupported.js && node tests/test_native_load_order.js && node tests/test_pack_purity.js && node tests/test_make_native_package.js && node tests/test_browser_nofs.js && node tests/test_browser_imports_guard.js && node tests/test_esm_exports.js && node tests/test_version_sync.js && node tests/test_native_loaded.js && node tests/test_native_lazy.js && node tests/test_safe_regex_source_sync.js && node tests/test_t_builder.js && node tests/test_async_refine.js && node tests/test_safe_regex.js && node tests/test_safe_regex_integration.js && node tests/test_aot_build.js && node tests/test_aot_differential.js && node tests/test_aot_cli_build.js && node tests/test_aot_cli_smoke.js && node tests/test_bundle_standalone.js && node tests/test_standalone_anyof.js && node tests/test_standalone_formats.js && node tests/test_aot_format_mode.js && node tests/test_aot_additional_props_errors.js && node tests/test_id_anchor_refs.js && node tests/test_engine_routing.js && node tests/test_engine_option.js && node tests/test_compile_cache_order.js && node tests/test_engine_diagnostic.js && node tests/test_format_engine_parity.js && node tests/test_error_accumulator_collision.js && node tests/test_uri_helper_parity.js && node tests/test_uri_fast_path.js && node tests/test_extend_verdict.js && node tests/test_ipv4_regex.js && node tests/test_ipv6_fast_path.js && node tests/test_nested_recursion_decline.js && node tests/test_generator_error_content.js && node tests/test_inherited_key_presence.js && node tests/test_proto_accessor.js && node tests/test_hybrid_tier.js && node tests/test_first_rejection_builds_one.js && node tests/test_container_local.js && node tests/test_one_shot_validate.js && node tests/test_fixed_pattern_inline.js && node tests/test_plan_source.js && node tests/test_fused_remove_additional.js && node tests/test_runtime_parse.js && node tests/test_formats_single_pass.js && node tests/test_email_format_cost.js && node tests/test_format_single_error.js && node tests/test_defs_pointer_alias.js && node tests/test_cross_doc_root_ref.js && node tests/test_codegen_entrypoint_agreement.js && node tests/test_hybrid_agreement.js && node tests/test_codegen_edge_shapes.js && node tests/test_deferred_def_scope.js && node tests/test_node_scoped_ctx_flags.js && node tests/test_fast_slot_exhaustion.js && node tests/test_ajv_errors.js && node tests/test_custom_keywords.js && node tests/test_strict_schema.js && node tests/test_aot_external_checks.js && node tests/test_ajv_parity.js && node tests/test_user_format_error_path.js && node tests/test_unevaluated_error_path.js && node tests/test_unevaluated_error_shape.js && node tests/test_pattern_properties_errors.js && node tests/test_additional_properties_scaling.js && node tests/test_additional_props_combined_cost.js && node tests/test_no_input_mutation.js && node tests/test_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.js && node tests/test_error_code_lookup.js && node tests/test_error_order.js && node tests/test_error_order_ordinal.js && node tests/test_rejection_shape.js && node tests/test_lazy_normalization.js && node tests/test_value_equality.js && node tests/test_vocabulary.js && node tests/test_schema_scan.js && node tests/test_lazy_errors.js && node tests/test_single_pass_errors.js && node tests/test_lazy_json_errors.js && node tests/test_lazy_instance.js && node tests/test_cyclic_input.js && node tests/test_native_error_codes.js && node tests/test_verdict_preprocess.js && node tests/test_lite_parity.js && node tests/test_lite_bundle_size.js && node tests/test_defaults_own_keys.js && node tests/test_plan_compiler.js && node tests/test_nullable.js && node tests/test_validate_and_parse.js && node tests/test_validate_data.js && node tests/test_enrich_error.js && node tests/test_enrich_received.js && node tests/test_rich_errors_optout.js && node tests/test_error_messages.js && node tests/test_source_positions.js && node tests/fuzz_positions.js && node tests/test_malformed_json_termination.js && node tests/test_data_positions.js && node tests/test_targeted_positions.js && node tests/test_position_map_cost.js && node tests/test_targeted_positions_cost.js && node tests/test_aot_staleness.js && node tests/test_file_positions.js && node tests/test_aot_positions_cost.js && node tests/test_schema_hash.js && node tests/test_render_shared.js && node tests/test_renderers.js && node tests/test_additive_fields.js && node tests/test_diagnostic_source.js && node tests/test_diagnose.js && node tests/test_correlate.js && node tests/test_diagnostics_score.js && node tests/test_runtime_error_dx.js && node tests/test_aot_error_dx.js && node tests/test_abort_early.js && node tests/test_branch_collapse.js && node tests/test_suggestions.js && node tests/test_cli_validate.js && node tests/test_cli_version.js && node benchmark/bench_aot_size.mjs",
62
+ "test": "node test.js && node tests/test_removed_aot_methods.js && node tests/test_no_native.js && node tests/test_no_eval.js && node tests/test_property_dependencies.js && node tests/test_v1_dialect.js && node tests/test_buffer_path_parity.js && node tests/test_text_path_errors.js && node tests/test_compiled_parity.js && node tests/test_buffer_gate.js && node tests/test_scanner_differential.js && node tests/test_validate_json_scanner_cost.js && node tests/test_buffer_reject_cost.js && node tests/test_nan_verdict.js && node tests/test_remove_additional_nested.js && node tests/test_exclusive_bounds.js && node tests/test_engine_differential.js && node tests/test_error_shape_differential.js && node tests/test_output_format.js && node tests/test_retry_message.js && node tests/test_describe_schema.js && node tests/test_aot_parse.js && node tests/test_draft7_semantics.js && node tests/test_metaschema_ref.js && node tests/test_pure_js_unsupported.js && node tests/test_native_load_order.js && node tests/test_pack_purity.js && node tests/test_make_native_package.js && node tests/test_browser_nofs.js && node tests/test_browser_imports_guard.js && node tests/test_esm_exports.js && node tests/test_version_sync.js && node tests/test_native_loaded.js && node tests/test_native_lazy.js && node tests/test_cold_start_modules.js && node tests/test_safe_regex_source_sync.js && node tests/test_t_builder.js && node tests/test_async_refine.js && node tests/test_safe_regex.js && node tests/test_safe_regex_integration.js && node tests/test_aot_build.js && node tests/test_aot_differential.js && node tests/test_aot_cli_build.js && node tests/test_aot_cli_smoke.js && node tests/test_bundle_standalone.js && node tests/test_standalone_anyof.js && node tests/test_standalone_formats.js && node tests/test_aot_format_mode.js && node tests/test_aot_additional_props_errors.js && node tests/test_id_anchor_refs.js && node tests/test_engine_routing.js && node tests/test_engine_option.js && node tests/test_compile_cache_order.js && node tests/test_engine_diagnostic.js && node tests/test_format_engine_parity.js && node tests/test_error_accumulator_collision.js && node tests/test_uri_helper_parity.js && node tests/test_uri_fast_path.js && node tests/test_extend_verdict.js && node tests/test_ipv4_regex.js && node tests/test_ipv6_fast_path.js && node tests/test_nested_recursion_decline.js && node tests/test_generator_error_content.js && node tests/test_inherited_key_presence.js && node tests/test_proto_accessor.js && node tests/test_hybrid_tier.js && node tests/test_first_rejection_builds_one.js && node tests/test_container_local.js && node tests/test_one_shot_validate.js && node tests/test_fixed_pattern_inline.js && node tests/test_plan_source.js && node tests/test_fused_remove_additional.js && node tests/test_runtime_parse.js && node tests/test_formats_single_pass.js && node tests/test_email_format_cost.js && node tests/test_format_single_error.js && node tests/test_defs_pointer_alias.js && node tests/test_cross_doc_root_ref.js && node tests/test_codegen_entrypoint_agreement.js && node tests/test_ref_annotation_siblings.js && node tests/test_gate_wrapped_schemas.js && node tests/test_pattern_message_escape.js && node tests/test_nested_defaults_engines.js && node tests/test_nested_coercion_parity.js && node tests/test_preprocess_cache.js && node tests/test_large_schema_codegen.js && node tests/test_base_uri.js && node tests/test_hoisted_def_recursion.js && node tests/test_hybrid_agreement.js && node tests/test_codegen_edge_shapes.js && node tests/test_deferred_def_scope.js && node tests/test_node_scoped_ctx_flags.js && node tests/test_fast_slot_exhaustion.js && node tests/test_ajv_errors.js && node tests/test_custom_keywords.js && node tests/test_strict_schema.js && node tests/test_aot_external_checks.js && node tests/test_ajv_parity.js && node tests/test_user_format_error_path.js && node tests/test_unevaluated_error_path.js && node tests/test_unevaluated_error_shape.js && node tests/test_pattern_properties_errors.js && node tests/test_additional_properties_scaling.js && node tests/test_additional_props_combined_cost.js && node tests/test_no_input_mutation.js && node tests/test_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.js && node tests/test_error_code_lookup.js && node tests/test_error_order.js && node tests/test_error_order_ordinal.js && node tests/test_ref_error_order.js && node tests/test_rejection_shape.js && node tests/test_lazy_normalization.js && node tests/test_value_equality.js && node tests/test_vocabulary.js && node tests/test_schema_scan.js && node tests/test_lazy_errors.js && node tests/test_single_pass_errors.js && node tests/test_lazy_json_errors.js && node tests/test_lazy_instance.js && node tests/test_cyclic_input.js && node tests/test_native_error_codes.js && node tests/test_verdict_preprocess.js && node tests/test_lite_parity.js && node tests/test_lite_bundle_size.js && node tests/test_defaults_own_keys.js && node tests/test_plan_compiler.js && node tests/test_nullable.js && node tests/test_validate_and_parse.js && node tests/test_validate_data.js && node tests/test_enrich_error.js && node tests/test_enrich_received.js && node tests/test_rich_errors_optout.js && node tests/test_error_messages.js && node tests/test_source_positions.js && node tests/fuzz_positions.js && node tests/test_malformed_json_termination.js && node tests/test_data_positions.js && node tests/test_targeted_positions.js && node tests/test_position_map_cost.js && node tests/test_targeted_positions_cost.js && node tests/test_aot_staleness.js && node tests/test_file_positions.js && node tests/test_aot_positions_cost.js && node tests/test_schema_hash.js && node tests/test_render_shared.js && node tests/test_renderers.js && node tests/test_additive_fields.js && node tests/test_diagnostic_source.js && node tests/test_diagnose.js && node tests/test_correlate.js && node tests/test_diagnostics_score.js && node tests/test_runtime_error_dx.js && node tests/test_aot_error_dx.js && node tests/test_abort_early.js && node tests/test_branch_collapse.js && node tests/test_suggestions.js && node tests/test_cli_validate.js && node tests/test_cli_version.js && node benchmark/bench_aot_size.mjs",
60
63
  "bench:size": "node benchmark/bench_aot_size.mjs",
61
64
  "test:suite": "node tests/run_suite.js && node tests/run_suite.js draft7 && node tests/run_suite.js v1",
62
65
  "test:compat": "node tests/test_compat.js",
@@ -73,7 +76,8 @@
73
76
  "test:aot-differential": "node tests/test_aot_differential.js",
74
77
  "test:aot-cli": "node tests/test_aot_cli_build.js",
75
78
  "test:json-suite": "node tests/run_json_test_suite.js",
76
- "bench:aot-vs-ajv": "node benchmark/bench_aot_vs_ajv.mjs"
79
+ "bench:aot-vs-ajv": "node benchmark/bench_aot_vs_ajv.mjs",
80
+ "test:schemastore": "node scripts/schemastore-differential.js"
77
81
  },
78
82
  "keywords": [
79
83
  "json",
@@ -106,6 +110,7 @@
106
110
  "files": [
107
111
  "index.js",
108
112
  "index.mjs",
113
+ "index.node.mjs",
109
114
  "index.browser.mjs",
110
115
  "index.d.ts",
111
116
  "aot.js",
@@ -129,13 +134,13 @@
129
134
  "LICENSE"
130
135
  ],
131
136
  "optionalDependencies": {
132
- "@ata-validator/native-darwin-arm64": "1.35.0",
133
- "@ata-validator/native-darwin-x64": "1.35.0",
134
- "@ata-validator/native-linux-arm64-gnu": "1.35.0",
135
- "@ata-validator/native-linux-arm64-musl": "1.35.0",
136
- "@ata-validator/native-linux-x64-gnu": "1.35.0",
137
- "@ata-validator/native-linux-x64-musl": "1.35.0",
138
- "@ata-validator/native-win32-x64": "1.35.0"
137
+ "@ata-validator/native-darwin-arm64": "1.36.1",
138
+ "@ata-validator/native-darwin-x64": "1.36.1",
139
+ "@ata-validator/native-linux-arm64-gnu": "1.36.1",
140
+ "@ata-validator/native-linux-arm64-musl": "1.36.1",
141
+ "@ata-validator/native-linux-x64-gnu": "1.36.1",
142
+ "@ata-validator/native-linux-x64-musl": "1.36.1",
143
+ "@ata-validator/native-win32-x64": "1.36.1"
139
144
  },
140
145
  "peerDependencies": {
141
146
  "yaml": "^2.0.0"