ata-validator 1.42.0 → 1.43.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.
@@ -90,6 +90,22 @@ const BASE_CHANGING = new Set(['$id', '$anchor', '$dynamicAnchor', '$dynamicRef'
90
90
  // it. Sized for a node per declared property of a large generated schema,
91
91
  // not just for hand-written ones.
92
92
  const MAX_NODES = 8192;
93
+ // See the size checks in compileScanner. One function past 64 KB is what V8's
94
+ // Maglev tier aborted on: SchemaStore scanners of 0.5 to 1 MB, single
95
+ // functions before references became calls. The total bounds the memory a
96
+ // scanner takes.
97
+ const MAX_FUNCTION_SOURCE = 64 * 1024;
98
+ const MAX_SOURCE = 2 * 1024 * 1024;
99
+ // A reference target is expanded at each reference while its expansions
100
+ // together are at most this much source, and called otherwise.
101
+ const INLINE_REF_MAX = 4096;
102
+ // An object member whose scan is more than this much source is moved into a
103
+ // function of its own (emitMember).
104
+ const SPLIT_MIN = 4 * 1024;
105
+ // The member source an object keeps inline before the rest move out.
106
+ const SPLIT_OBJECT = 16 * 1024;
107
+ // Declared names at least this long on average find a key's end with indexOf.
108
+ const INDEX_KEY_MIN_AVG = 10;
93
109
 
94
110
  // Each position in a tuple emits its own branch inside the element loop, so a
95
111
  // long one is both a lot of source and a linear test per element.
@@ -155,9 +171,19 @@ function resolveLocalRef(root, ref) {
155
171
  if (ref === '#') return root;
156
172
  if (!ref.startsWith('#/')) decline('$ref:not-local');
157
173
  let node = root;
174
+ let first = true;
158
175
  for (const rawToken of ref.slice(2).split('/')) {
159
- const token = decodeURIComponent(rawToken).split('~1').join('/').split('~0').join('~');
176
+ let token = decodeURIComponent(rawToken).split('~1').join('/').split('~0').join('~');
160
177
  if (node === null || typeof node !== 'object') decline('$ref:unresolved');
178
+ // Draft 7 schemas reach the scanner with `definitions` renamed to `$defs`
179
+ // (lib/draft7.js) and their references as written; the other engines
180
+ // read either name, and so does this. Without it no draft 7 schema that
181
+ // used a definition got a scanner.
182
+ if (first && node === root && !Array.isArray(node) && !Object.prototype.hasOwnProperty.call(node, token)) {
183
+ if (token === 'definitions' && Object.prototype.hasOwnProperty.call(node, '$defs')) token = '$defs';
184
+ else if (token === '$defs' && Object.prototype.hasOwnProperty.call(node, 'definitions')) token = 'definitions';
185
+ }
186
+ first = false;
161
187
  if (Array.isArray(node)) {
162
188
  if (!/^\d+$/.test(token)) decline('$ref:unresolved');
163
189
  node = node[Number(token)];
@@ -387,11 +413,45 @@ function spanHash(name) {
387
413
  // is a jump table.
388
414
  const HASH_DISPATCH_MIN = 48;
389
415
 
416
+ // The scan is first emitted as one function with every reference expanded
417
+ // where it is used, which is the fastest form: a call per member measured
418
+ // about twice the cost of csslintrc's scan, a small enum referenced thirty
419
+ // times. Only when a function would pass MAX_FUNCTION_SOURCE is it emitted
420
+ // again with large reference targets and large object members moved into
421
+ // functions of their own, so the source grows with the schema rather than
422
+ // with the number of references to it.
390
423
  function compileScanner(schema, options) {
391
424
  const opts = options || {};
425
+ const whole = build(schema, opts, false);
426
+ if (whole !== null || declineReason !== 'size') return finish(whole, opts);
427
+ return finish(build(schema, opts, true), opts);
428
+ }
429
+
430
+ function finish(built, opts) {
431
+ if (built === null) {
432
+ if (opts.onDecline) opts.onDecline(declineReason);
433
+ return null;
434
+ }
435
+ const { ctx, body } = built;
436
+ let fn;
437
+ try {
438
+ // eslint-disable-next-line no-new-func
439
+ fn = new Function('_h', '_r', ctx.subSource.join('\n') + '\nreturn function scan(s){\n' + body + '\n}')(ctx.helpers, require('./scan-runtime'));
440
+ } catch {
441
+ return null; // a runtime without code generation has no scanner, by design
442
+ }
443
+ return { scan: fn, source: body, helpers: ctx.helpers.length, functions: [body, ...ctx.subSource] };
444
+ }
445
+
446
+ function build(schema, opts, split) {
392
447
  const ctx = {
393
448
  uid: 0, helpers: [], userFormats: opts.userFormats || null,
394
449
  root: schema, refStack: [], nodes: 0,
450
+ // With `split`, reference targets map to null when expanded in place,
451
+ // else to the name of the function in subSource that scans one (see the
452
+ // $ref case in emitValue), and large members move out too (emitMember).
453
+ split, subs: new Map(), subSource: [], refCounts: split ? countRefs(schema) : null,
454
+ inlineBytes: new Map(),
395
455
  };
396
456
  declineReason = null;
397
457
  let body;
@@ -404,21 +464,19 @@ function compileScanner(schema, options) {
404
464
  out.push('if(i<len)return 0;');
405
465
  out.push('return 1;');
406
466
  body = out.join('\n');
467
+ // A function this large is a cost of its own, and V8's Maglev tier
468
+ // aborted the process compiling scanners of 500 KB and more (traefik,
469
+ // detekt from SchemaStore), in plain JavaScript, on Node 24 and 25, after
470
+ // about a hundred calls. Unsplit, past the bound the scan is emitted
471
+ // split; split, past either bound the schema has no scanner and the text
472
+ // path parses as it does without one.
473
+ if (body.length > MAX_FUNCTION_SOURCE || ctx.subSource.some((x) => x.length > MAX_FUNCTION_SOURCE)) decline('size');
474
+ if (body.length + ctx.subSource.reduce((n, x) => n + x.length, 0) > MAX_SOURCE) decline('size');
407
475
  } catch (e) {
408
- if (e === DECLINE) {
409
- if (opts.onDecline) opts.onDecline(declineReason);
410
- return null;
411
- }
476
+ if (e === DECLINE) return null;
412
477
  throw e;
413
478
  }
414
- let fn;
415
- try {
416
- // eslint-disable-next-line no-new-func
417
- fn = new Function('_h', '_r', 'return function scan(s){\n' + body + '\n}')(ctx.helpers, require('./scan-runtime'));
418
- } catch {
419
- return null; // a runtime without code generation has no scanner, by design
420
- }
421
- return { scan: fn, source: body, helpers: ctx.helpers.length };
479
+ return { ctx, body };
422
480
  }
423
481
 
424
482
  function emitValue(schema, ctx, out, depth) {
@@ -443,9 +501,51 @@ function emitValue(schema, ctx, out, depth) {
443
501
  const ref = schema.$ref;
444
502
  if (ctx.refStack.includes(ref)) decline('$ref:recursive');
445
503
  const target = resolveLocalRef(ctx.root, ref);
504
+ if (!ctx.split) {
505
+ ctx.refStack.push(ref);
506
+ emitValue(target, ctx, out, depth);
507
+ ctx.refStack.pop();
508
+ return;
509
+ }
510
+ // Split (see compileScanner): a target whose expansions add up to more
511
+ // than a little source is emitted once, as a function of its own, and
512
+ // called wherever it is referenced. Expanded at every reference, the
513
+ // source grows with the number of references rather than with the
514
+ // schema: SchemaStore's traefik and detekt reach the same definitions
515
+ // from hundreds of places, and their scanners came to 0.5 to 1 MB, which
516
+ // V8's Maglev tier aborted the process compiling.
517
+ const sub = ctx.subs.get(target);
518
+ if (sub !== undefined) {
519
+ if (sub === null) {
520
+ ctx.refStack.push(ref);
521
+ emitValue(target, ctx, out, depth);
522
+ ctx.refStack.pop();
523
+ } else {
524
+ emitSubCall(sub, ctx, out);
525
+ }
526
+ return;
527
+ }
528
+ const body = [];
446
529
  ctx.refStack.push(ref);
447
- emitValue(target, ctx, out, depth);
530
+ emitValue(target, ctx, body, depth);
448
531
  ctx.refStack.pop();
532
+ const text = body.join('\n');
533
+ // Expanded in place only while all its expansions together stay small:
534
+ // a small definition referenced from hundreds of places is source in
535
+ // hundreds of places.
536
+ if (text.length * (ctx.refCounts.get(ref) || 1) <= INLINE_REF_MAX) {
537
+ ctx.subs.set(target, null);
538
+ for (const line of body) out.push(line);
539
+ return;
540
+ }
541
+ const name = '_s' + (ctx.subSource.length + ctx.subs.size + ctx.uid++);
542
+ ctx.subs.set(target, name);
543
+ // The emitted scan of a value starts with `i` at its first character and
544
+ // `c` holding it, and ends with `i` past it; it answers 0 (invalid) or -1
545
+ // (bail) by returning. Here it returns the new position instead, which is
546
+ // at least 1, so the three cannot be confused.
547
+ ctx.subSource.push('function ' + name + '(s,i){var len=s.length,c=s.charCodeAt(i);\n' + text + '\nreturn i;}');
548
+ emitSubCall(name, ctx, out);
449
549
  return;
450
550
  }
451
551
 
@@ -478,6 +578,12 @@ function emitValue(schema, ctx, out, depth) {
478
578
  // present, not that it lists anything.
479
579
  let compositeAllowed = true;
480
580
  let compositeDelegate = null;
581
+ // The kinds the listed values have. A value of any other kind equals none
582
+ // of them, so its branch is left out and the value falls to the final
583
+ // `return 0`: csslintrc's `enum: [2, true, false]` used to scan strings
584
+ // only to reject them, at thirty references, and the dead branches alone
585
+ // pushed its scan past the size bound into calls.
586
+ let listedKinds = null;
481
587
  if (has('const') || has('enum')) {
482
588
  compositeAllowed = false;
483
589
  const listed = [];
@@ -486,6 +592,7 @@ function emitValue(schema, ctx, out, depth) {
486
592
  if (!Array.isArray(schema.enum)) decline('enum:not-array');
487
593
  for (const v of schema.enum) listed.push(v);
488
594
  }
595
+ listedKinds = new Set(listed.map((v) => (v === null ? 'null' : Array.isArray(v) ? 'array' : typeof v)));
489
596
  // An object or an array can only be compared as a whole. The scan steps
490
597
  // over that one subtree, parses its own text, and hands it to the check
491
598
  // the validator itself runs, so the document around it is still never
@@ -508,7 +615,7 @@ function emitValue(schema, ctx, out, depth) {
508
615
  + 'if(!' + compositeDelegate + '(_cv' + k + '))return 0;'
509
616
  + 'i=_ce' + k + ';c=s.charCodeAt(i);'];
510
617
  };
511
- if (allows(types, 'object')) {
618
+ if (allows(types, 'object') && (listedKinds === null || listedKinds.has('object'))) {
512
619
  if (compositeDelegate) branches.push(['c===123', compositeBranch()]);
513
620
  else if (!compositeAllowed) branches.push(['c===123', ['return 0;']]);
514
621
  else {
@@ -517,7 +624,7 @@ function emitValue(schema, ctx, out, depth) {
517
624
  branches.push(['c===123', b]);
518
625
  }
519
626
  }
520
- if (allows(types, 'array')) {
627
+ if (allows(types, 'array') && (listedKinds === null || listedKinds.has('array'))) {
521
628
  if (compositeDelegate) branches.push(['c===91', compositeBranch()]);
522
629
  else if (!compositeAllowed) branches.push(['c===91', ['return 0;']]);
523
630
  else {
@@ -526,22 +633,22 @@ function emitValue(schema, ctx, out, depth) {
526
633
  branches.push(['c===91', b]);
527
634
  }
528
635
  }
529
- if (allows(types, 'string')) {
636
+ if (allows(types, 'string') && (listedKinds === null || listedKinds.has('string'))) {
530
637
  const b = [];
531
638
  emitString(schema, ctx, b);
532
639
  branches.push(['c===34', b]);
533
640
  }
534
- if (allows(types, 'number')) {
641
+ if (allows(types, 'number') && (listedKinds === null || listedKinds.has('number'))) {
535
642
  const b = [];
536
643
  emitNumber(schema, ctx, b, types);
537
644
  branches.push(['c===45||(c>=48&&c<=57)', b]);
538
645
  }
539
- if (allows(types, 'boolean')) {
646
+ if (allows(types, 'boolean') && (listedKinds === null || listedKinds.has('boolean'))) {
540
647
  const b = [];
541
648
  emitLiteral(schema, ctx, b, 'boolean');
542
649
  branches.push(['c===116||c===102', b]);
543
650
  }
544
- if (allows(types, 'null')) {
651
+ if (allows(types, 'null') && (listedKinds === null || listedKinds.has('null'))) {
545
652
  const b = [];
546
653
  emitLiteral(schema, ctx, b, 'null');
547
654
  branches.push(['c===110', b]);
@@ -558,6 +665,42 @@ function emitValue(schema, ctx, out, depth) {
558
665
  out.push(parts.join('\n'));
559
666
  }
560
667
 
668
+ // How many times each `$ref` string occurs in the schema, for the expand or
669
+ // call decision. Schema positions and other values alike: a string that is not
670
+ // a reference is never looked up.
671
+ function countRefs(root) {
672
+ const counts = new Map();
673
+ const seen = new Set();
674
+ const walk = (n) => {
675
+ if (n === null || typeof n !== 'object' || seen.has(n)) return;
676
+ seen.add(n);
677
+ if (Array.isArray(n)) { for (const x of n) walk(x); return; }
678
+ if (typeof n.$ref === 'string') counts.set(n.$ref, (counts.get(n.$ref) || 0) + 1);
679
+ for (const k of Object.keys(n)) walk(n[k]);
680
+ };
681
+ walk(root);
682
+ return counts;
683
+ }
684
+
685
+ // A name with no character a JSON string would have to escape, so its raw
686
+ // text in a document is the name itself.
687
+ function plainName(name) {
688
+ for (let k = 0; k < name.length; k++) {
689
+ const c = name.charCodeAt(k);
690
+ if (c < 32 || c === 34 || c === 92) return false;
691
+ }
692
+ return true;
693
+ }
694
+
695
+ // A call answers invalid with the literal `return 0;`, as inline code does:
696
+ // an object member rewrites that text into its own failure path, which goes on
697
+ // scanning (a later duplicate key can replace the value), and a different
698
+ // spelling would end the whole scan instead.
699
+ function emitSubCall(name, ctx, out) {
700
+ const r = '_rq' + (ctx.uid++);
701
+ out.push('{var ' + r + '=' + name + '(s,i);if(' + r + '===-1)return -1;if(' + r + '===0)return 0;i=' + r + ';c=s.charCodeAt(i);}');
702
+ }
703
+
561
704
  // Any JSON value, validated as JSON and stepped over.
562
705
  function emitSkip(out) {
563
706
  out.push('{var _j=_r.skipValue(s,i);if(_j===-2)return -1;if(_j<0)return 0;i=_j;c=s.charCodeAt(i);}');
@@ -749,8 +892,27 @@ function emitArray(schema, ctx, out, depth) {
749
892
  // the rule reaches nested objects: an inner object's own verdict is a value
750
893
  // failure at the level above it.
751
894
  function emitMember(sub, ctx, out, depth, objId) {
752
- const lines = [];
895
+ let lines = [];
753
896
  emitValue(sub, ctx, lines, depth + 1);
897
+ // A large member value becomes a function of its own, so no one function
898
+ // grows with the whole schema: detekt nests hundreds of rule objects inline,
899
+ // no references involved. The value's code keeps its own labels and
900
+ // variables, so it moves as it is; the call answers invalid with
901
+ // `return 0;`, which the rewrite below turns into this member's failure.
902
+ // An object's members are judged together as well as one by one: thirty
903
+ // members just under SPLIT_MIN each would stay inline and add up to a
904
+ // function past the bound, so once the members kept inline in this object
905
+ // pass SPLIT_OBJECT, the rest move out whatever their size.
906
+ const size = lines.join('\n').length;
907
+ const kept = ctx.split ? (ctx.inlineBytes.get(objId) || 0) : 0;
908
+ if (ctx.split && (size > SPLIT_MIN || kept + size > SPLIT_OBJECT)) {
909
+ const name = '_s' + (ctx.subSource.length + ctx.subs.size + ctx.uid++);
910
+ ctx.subSource.push('function ' + name + '(s,i){var len=s.length,c=s.charCodeAt(i);\n' + lines.join('\n') + '\nreturn i;}');
911
+ lines = [];
912
+ emitSubCall(name, ctx, lines);
913
+ } else if (ctx.split) {
914
+ ctx.inlineBytes.set(objId, kept + size);
915
+ }
754
916
  const body = lines.join('\n');
755
917
  if (!body.includes('return 0;')) { out.push(body); return; }
756
918
  const label = '_mb' + (ctx.uid++);
@@ -828,10 +990,32 @@ function emitObject(schema, ctx, out, depth) {
828
990
  hashById = '_h[' + (ctx.helpers.length - 1) + ']';
829
991
  }
830
992
  }
831
- emitStringSpan(ctx, out, kn, false, hashById !== null);
832
- // A key written with an escape decodes to a name the raw span does not show,
833
- // so the dispatch below would read it as a different property.
834
- out.push('if(_x' + kn + ')return -1;');
993
+ // A key's end is found with indexOf, which is native, where the character
994
+ // loop below costs three compares a character: on csslintrc's 35 keys of
995
+ // twenty-odd characters the loop was most of the scan and made it slower
996
+ // than parsing. Every declared name is plain text, so a key that compares
997
+ // equal to one, character by character, is that name as written, and a
998
+ // key that does not is checked for an escape or a control character before
999
+ // it is read as additional. Either one bails, and so does a span that ends
1000
+ // on a backslash, since that quote may be escaped: the parser decides what
1001
+ // the key really is.
1002
+ // indexOf costs about the same whatever the key's length, the loop about a
1003
+ // nanosecond a character: on short keys the loop wins (problem-object's
1004
+ // `type`, `title`, `status` measured 10 to 15 percent slower by indexOf),
1005
+ // and from ten characters indexOf wins by 40 percent and more, so the
1006
+ // choice follows the declared names' average length.
1007
+ const indexKey = !useHash && names.length > 0 && names.every(plainName)
1008
+ && names.reduce((n, x) => n + x.length, 0) >= INDEX_KEY_MIN_AVG * names.length;
1009
+ if (indexKey) {
1010
+ // A quote with a backslash before it may be escaped, and then the key
1011
+ // goes on past it: bail before reading what follows as the colon.
1012
+ out.push('var _p' + kn + '=++i,_e' + kn + '=s.indexOf(\'"\',i);if(_e' + kn + '<0)return 0;if(s.charCodeAt(_e' + kn + '-1)===92)return -1;i=_e' + kn + ';c=s.charCodeAt(++i);');
1013
+ } else {
1014
+ emitStringSpan(ctx, out, kn, false, hashById !== null);
1015
+ // A key written with an escape decodes to a name the raw span does not
1016
+ // show, so the dispatch below would read it as a different property.
1017
+ out.push('if(_x' + kn + ')return -1;');
1018
+ }
835
1019
  out.push(WS);
836
1020
  out.push('if(c!==58)return 0;');
837
1021
  out.push('c=s.charCodeAt(++i);');
@@ -958,6 +1142,7 @@ function emitObject(schema, ctx, out, depth) {
958
1142
  additional.push(lines.join('\n').split('return 0;').join('return -1;'));
959
1143
  }
960
1144
 
1145
+ if (indexKey) additional.unshift('if(!_r.plainKey(s,_p' + kn + ',_e' + kn + '))return -1;');
961
1146
  out.push('switch(_kl' + kn + '){');
962
1147
  for (const [len, group] of byLen) {
963
1148
  out.push('case ' + len + ':{');
@@ -155,4 +155,16 @@ function span(s, p, e, escaped) {
155
155
  return JSON.parse(s.slice(p - 1, e + 1));
156
156
  }
157
157
 
158
- module.exports = { hex4, skipValue, skipString, skipNumber, span, MALFORMED, TOO_DEEP, MAX_SKIP_DEPTH };
158
+ // Whether the raw text of a key between `p` and `e` is its name as written:
159
+ // no escape, no control character. A scanner that found the key's end with
160
+ // indexOf calls this for a name it did not recognise; one it recognised was
161
+ // compared character by character against a name that has neither.
162
+ function plainKey(s, p, e) {
163
+ for (let k = p; k < e; k++) {
164
+ const c = s.charCodeAt(k);
165
+ if (c < 32 || c === 92) return false;
166
+ }
167
+ return true;
168
+ }
169
+
170
+ module.exports = { hex4, skipValue, skipString, skipNumber, span, plainKey, MALFORMED, TOO_DEEP, MAX_SKIP_DEPTH };
@@ -215,8 +215,27 @@ function codegenAvailable() {
215
215
  return _codegenAvailable;
216
216
  }
217
217
 
218
- // Schema compilation cache: same schema string -> reuse compiled functions
218
+ // Schema compilation cache: same schema string -> reuse compiled functions.
219
+ // It and the preprocess cache below are bounded, oldest out first. Unbounded,
220
+ // they held every schema's text, compiled functions and their sources for the
221
+ // life of the process: after compiling each of SchemaStore's schemas once and
222
+ // dropping the validators, 1.2 GB stayed on the heap. A schema compiled again
223
+ // after its entry left is compiled again, the cost of a miss and no more.
224
+ const CACHE_ENTRIES = 128;
225
+ const CACHE_KEY_CHARS = 16 * 1024 * 1024;
219
226
  const _compileCache = new Map();
227
+ // Adds an entry and drops the oldest past either bound. The key characters
228
+ // are counted on the map itself.
229
+ function _boundedSet(map, key, entry) {
230
+ if (!map.has(key)) map._chars = (map._chars || 0) + key.length;
231
+ map.set(key, entry);
232
+ while (map.size > CACHE_ENTRIES || (map._chars > CACHE_KEY_CHARS && map.size > 1)) {
233
+ const oldest = map.keys().next().value;
234
+ map.delete(oldest);
235
+ map._chars -= oldest.length;
236
+ }
237
+ }
238
+ function _compileCacheSet(key, entry) { _boundedSet(_compileCache, key, entry); }
220
239
  // Generated preprocess passes, keyed like _compileCache plus the options that
221
240
  // shape the pass. Only passes that exist are kept: a schema with nothing to
222
241
  // rewrite answers `null` quickly, and keeping that answer held its key, the
@@ -911,7 +930,7 @@ class Validator {
911
930
  // A function bound to this validator's keyword functions or formats is
912
931
  // not the schema's alone, so it is not shared through the cache.
913
932
  if (!uf && !this._keywords) {
914
- _compileCache.set(mapKey, { jsFn, combined: undefined, errFn: undefined, isCodegen: _isCodegen, full: false });
933
+ _compileCacheSet(mapKey, { jsFn, combined: undefined, errFn: undefined, isCodegen: _isCodegen, full: false });
915
934
  }
916
935
  }
917
936
  this._jsFn = jsFn;
@@ -938,7 +957,7 @@ class Validator {
938
957
  if (hit !== undefined) preprocess = hit;
939
958
  else {
940
959
  preprocess = _codegen.buildPreprocess(preprocessSchema, options) || null;
941
- if (ppKey !== null && preprocess !== null) _preprocessCache.set(ppKey, preprocess);
960
+ if (ppKey !== null && preprocess !== null) _boundedSet(_preprocessCache, ppKey, preprocess);
942
961
  }
943
962
  }
944
963
  if (!preprocess) {
@@ -2259,4 +2278,4 @@ module.exports = {
2259
2278
  // surface of `require('ata-validator')` is what it was.
2260
2279
  Object.defineProperty(module.exports, '_registerCodegen', { value: _registerCodegen, enumerable: false });
2261
2280
  // What the compiled paths in index.js need from this module.
2262
- Object.defineProperty(module.exports, '_internals', { value: { _jsonSyntaxRejection, ABORT_EARLY_RESULT, HYBRID_TIER_CALLS, SIMDJSON_THRESHOLD, VALID_RESULT, _bindEntry, _bindVerdict, _compileCache, _mustReject, _rememberInstance, _verboseWrap, compileCacheKey, getNative, isV1Dialect, resolveSchemaByPath }, enumerable: false });
2281
+ Object.defineProperty(module.exports, '_internals', { value: { _jsonSyntaxRejection, ABORT_EARLY_RESULT, HYBRID_TIER_CALLS, SIMDJSON_THRESHOLD, VALID_RESULT, _bindEntry, _bindVerdict, _compileCache, _compileCacheSet, _mustReject, _rememberInstance, _verboseWrap, compileCacheKey, getNative, isV1Dialect, resolveSchemaByPath }, enumerable: false });
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.42.0';
10
+ module.exports = '1.43.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ata-validator",
3
- "version": "1.42.0",
3
+ "version": "1.43.0",
4
4
  "description": "JSON Schema validator that compiles to plain JavaScript, still runs where code generation is blocked, and can be compiled away at build time. Passes the full official test suite.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -64,7 +64,7 @@
64
64
  "release:check": "node tests/test_pack_purity.js && node scripts/check-doc-coverage.js && node tests/test_error_codes_lock.js && node tests/test_safe_regex_embed.js && node tests/test_version_sync.js",
65
65
  "build": "cmake-js build --target ata",
66
66
  "rebuild": "cmake-js rebuild --target ata",
67
- "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_number_text_parity.js && node tests/test_text_path_errors.js && node tests/test_compiled_parity.js && node tests/test_compiled_extension_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_error_list_differential.js && node tests/test_output_format.js && node tests/test_standard_json_schema.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.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_buffer_apis_without_native.js && node tests/test_cold_start_modules.js && node tests/test_safe_regex_embed.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_regex_ecma_whitespace.js && node tests/test_regex_native_linear.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_encoded_refs.js && node tests/test_cross_doc_root_ref.js && node tests/test_codegen_entrypoint_agreement.js && node tests/test_schema_code_injection.js && node tests/test_aot_html_safe.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_alias_definitions.js && node tests/test_property_names_ref.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_custom_keyword_codegen.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_unevaluated_differential.js && node tests/fuzz_differential.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_error_read_paths.js && node tests/test_unique_items_error_pair.js && node tests/test_rich_errors_generated.js && node tests/test_captured_verdict_stub.js && node tests/test_generated_returns_rewrite.js && node tests/test_deep_pointer_refs.js && node tests/test_uneval_props_dynamic.js && node tests/test_one_pass_no_fallback.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_render_without_process.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_aot_source_frames.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 tests/test_collect_evaluated.js && node tests/test_differential_tiers.js && node tests/test_draft7.js && node tests/test_dual_path.js && node tests/test_keywords_codegen.js && node tests/test_ref_cross.js && node tests/test_shape_classifier.js && node tests/test_tier0.js && node benchmark/bench_aot_size.mjs",
67
+ "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_number_text_parity.js && node tests/test_text_path_errors.js && node tests/test_compiled_parity.js && node tests/test_compiled_extension_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_error_list_differential.js && node tests/test_output_format.js && node tests/test_standard_json_schema.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.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_buffer_apis_without_native.js && node tests/test_cold_start_modules.js && node tests/test_safe_regex_embed.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_regex_ecma_whitespace.js && node tests/test_regex_native_linear.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_encoded_refs.js && node tests/test_cross_doc_root_ref.js && node tests/test_codegen_entrypoint_agreement.js && node tests/test_schema_code_injection.js && node tests/test_aot_html_safe.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_alias_definitions.js && node tests/test_property_names_ref.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_custom_keyword_codegen.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_unevaluated_differential.js && node tests/fuzz_differential.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_error_read_paths.js && node tests/test_unique_items_error_pair.js && node tests/test_rich_errors_generated.js && node tests/test_captured_verdict_stub.js && node tests/test_generated_returns_rewrite.js && node tests/test_deep_pointer_refs.js && node tests/test_uneval_props_dynamic.js && node tests/test_one_pass_no_fallback.js && node tests/test_scanner_size_cap.js && node tests/test_scanner_index_keys.js && node tests/test_both_defs_containers.js && node tests/test_uneval_branch_counts.js && node tests/test_branch_verdicts.js && node tests/test_shared_definitions.js && node tests/test_compile_cache_bound.js && node tests/test_uneval_items_dynamic.js && node tests/test_escaped_property_names.js && node tests/test_ref_siblings_combined.js && node tests/test_unicode_property_patterns.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_render_without_process.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_aot_source_frames.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 tests/test_collect_evaluated.js && node tests/test_differential_tiers.js && node tests/test_draft7.js && node tests/test_dual_path.js && node tests/test_keywords_codegen.js && node tests/test_ref_cross.js && node tests/test_shape_classifier.js && node tests/test_tier0.js && node benchmark/bench_aot_size.mjs",
68
68
  "bench:size": "node benchmark/bench_aot_size.mjs",
69
69
  "test:suite": "node tests/run_suite.js && node tests/run_suite.js draft7 && node tests/run_suite.js v1",
70
70
  "test:compat": "node tests/test_compat.js",
@@ -143,13 +143,13 @@
143
143
  "LICENSE"
144
144
  ],
145
145
  "optionalDependencies": {
146
- "@ata-validator/native-darwin-arm64": "1.42.0",
147
- "@ata-validator/native-darwin-x64": "1.42.0",
148
- "@ata-validator/native-linux-arm64-gnu": "1.42.0",
149
- "@ata-validator/native-linux-arm64-musl": "1.42.0",
150
- "@ata-validator/native-linux-x64-gnu": "1.42.0",
151
- "@ata-validator/native-linux-x64-musl": "1.42.0",
152
- "@ata-validator/native-win32-x64": "1.42.0"
146
+ "@ata-validator/native-darwin-arm64": "1.43.0",
147
+ "@ata-validator/native-darwin-x64": "1.43.0",
148
+ "@ata-validator/native-linux-arm64-gnu": "1.43.0",
149
+ "@ata-validator/native-linux-arm64-musl": "1.43.0",
150
+ "@ata-validator/native-linux-x64-gnu": "1.43.0",
151
+ "@ata-validator/native-linux-x64-musl": "1.43.0",
152
+ "@ata-validator/native-win32-x64": "1.43.0"
153
153
  },
154
154
  "peerDependencies": {
155
155
  "yaml": "^2.0.0"