ata-validator 1.31.1 → 1.31.2

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/compat.js CHANGED
@@ -22,7 +22,7 @@ const { resolvePointer } = require('./lib/pointer.js');
22
22
 
23
23
  const { Validator } = require('./index');
24
24
  const { METASCHEMAS } = require('./lib/metaschemas');
25
- const { createShaper } = require('./lib/compat-errors');
25
+ const { createShaper, asReferenceKeyword } = require('./lib/compat-errors');
26
26
 
27
27
  const DRAFT7 = 'http://json-schema.org/draft-07/schema#';
28
28
  const DRAFT2020 = 'https://json-schema.org/draft/2020-12/schema';
@@ -185,7 +185,7 @@ class Ata {
185
185
  validate.errors = null;
186
186
  return true;
187
187
  }
188
- let errors = shaper === null ? result.errors : shaper(result.errors, data);
188
+ let errors = shaper === null ? result.errors.map(asReferenceKeyword) : shaper(result.errors, data);
189
189
  // Errors the shaper synthesises, the `if` wrapper among them, are built
190
190
  // from the group rather than carried up from the validator, so verbose
191
191
  // mode has to fill in the value they point at here or they would be the
@@ -133,6 +133,16 @@ function escapePointer(s) {
133
133
  // validate() already reports them so.
134
134
  const WRAPPERS = new Set(['anyOf', 'oneOf', 'propertyNames', 'contains', 'not', 'if']);
135
135
 
136
+ // ata names the keyword of a false schema `not`, at the root and nested alike,
137
+ // which is what its own error codes and every consumer switch on. The
138
+ // reference names it `false schema`. The root case used to come out of the
139
+ // code generator as `false schema` by an inconsistency that has since been
140
+ // fixed, so this shim matched the reference there and not for a nested false
141
+ // schema; the rename here makes both match.
142
+ function asReferenceKeyword(e) {
143
+ return e.keyword === 'not' && e.message === 'boolean schema is false' ? { ...e, keyword: 'false schema' } : e;
144
+ }
145
+
136
146
  function createShaper({ Validator, rootId, rootDoc, schemas, options, allErrors, macroKeywords }) {
137
147
  const branchCache = new Map();
138
148
  const branchValidator = (pointer) => {
@@ -360,11 +370,11 @@ function createShaper({ Validator, rootId, rootDoc, schemas, options, allErrors,
360
370
  }
361
371
 
362
372
  return function shapeErrors(errors, data) {
363
- const shaped = shape(errors, data, '');
373
+ const shaped = shape(errors, data, '').map(asReferenceKeyword);
364
374
  if (allErrors) return shaped;
365
375
  const n = groupEnd(shaped);
366
376
  return shaped.slice(0, n);
367
377
  };
368
378
  }
369
379
 
370
- module.exports = { createShaper, sortLikeReference, REFERENCE_ORDER };
380
+ module.exports = { createShaper, sortLikeReference, REFERENCE_ORDER, asReferenceKeyword };
@@ -157,10 +157,31 @@ const DOC_BASE = 'https://ata-validator.com/e/'
157
157
  // reader sorts by without deriving it from the path. Empty when the path is
158
158
  // not into the root document.
159
159
  function ordinalField (ctx, schemaPath) {
160
- const o = ctx && ctx.rootSchema ? ordinalFor(ctx.rootSchema, schemaPath) : null
160
+ const o = ctx && ctx.rootSchema ? ordinalFor(ctx.rootSchema, unescapeSp(schemaPath)) : null
161
161
  return o === null ? '' : `,_o:${o}`
162
162
  }
163
163
 
164
+ // A schema path as the generators hold it is text for a single-quoted source
165
+ // literal: ptrSeg put a backslash before every backslash and quote in a key.
166
+ // Anything that uses the path as a value, the ordinal lookup and the frozen
167
+ // error objects below, has to take that backslash off again, or a key such as
168
+ // `it's` reads as `it\'s` and the error names a path that does not exist.
169
+ // The value of a string literal the generators built for source. One that does
170
+ // not parse on its own (a key with a raw line break) would not parse inside the
171
+ // generated function either, so the generator declines, as it would have when
172
+ // that function failed to build.
173
+ function literalValue (lit) {
174
+ try {
175
+ return Function('return ' + lit)()
176
+ } catch {
177
+ throw DECLINE
178
+ }
179
+ }
180
+
181
+ function unescapeSp (sp) {
182
+ return sp.indexOf('\\') === -1 ? sp : sp.replace(/\\(.)/g, '$1')
183
+ }
184
+
164
185
  function buildErrorLiteral (opts) {
165
186
  const { keyword, format, schemaPath, sourceMap } = opts
166
187
  let code = (keyword === 'format' && format) ? codeFor('format', format) : codeFor(keyword)
@@ -340,7 +361,7 @@ function compileToJS(schema, defs, schemaMap) {
340
361
  // required applies to objects only; other types are ignored.
341
362
  if (schema.required && Array.isArray(schema.required)) {
342
363
  for (const key of schema.required) {
343
- checks.push((d) => typeof d !== 'object' || d === null || Array.isArray(d) || d[key] !== undefined)
364
+ checks.push((d) => typeof d !== 'object' || d === null || Array.isArray(d) || hasOwnKey(d, key))
344
365
  }
345
366
  }
346
367
 
@@ -350,7 +371,7 @@ function compileToJS(schema, defs, schemaMap) {
350
371
  const propCheck = compileToJS(prop, rootDefs)
351
372
  if (!propCheck) return null // bail if sub-schema too complex
352
373
  checks.push((d) => {
353
- if (typeof d !== 'object' || d === null || !(key in d)) return true
374
+ if (typeof d !== 'object' || d === null || !hasOwnKey(d, key)) return true
354
375
  return propCheck(d[key])
355
376
  })
356
377
  }
@@ -387,9 +408,9 @@ function compileToJS(schema, defs, schemaMap) {
387
408
  if (schema.dependentRequired) {
388
409
  for (const [key, deps] of Object.entries(schema.dependentRequired)) {
389
410
  checks.push((d) => {
390
- if (typeof d !== 'object' || d === null || !(key in d)) return true
411
+ if (typeof d !== 'object' || d === null || !hasOwnKey(d, key)) return true
391
412
  for (let i = 0; i < deps.length; i++) {
392
- if (!(deps[i] in d)) return false
413
+ if (!hasOwnKey(d, deps[i])) return false
393
414
  }
394
415
  return true
395
416
  })
@@ -872,6 +893,44 @@ const FORMAT_CHECKS = {
872
893
  }
873
894
 
874
895
  // Dangerous JS property names that exist on Object.prototype
896
+ // Presence is an own-property question: `required: ['toString']` is not
897
+ // satisfied by `{}`. `'k' in v` and `v.k !== undefined` both answer yes for a
898
+ // name found on the prototype chain, which accepted documents the interpreted
899
+ // engine rejects. Object.hasOwn would be exact but is not inlined, about 5 ns
900
+ // a key against well under 1 for `in`, so the check is split:
901
+ // - a name on Object.prototype (and `__proto__`) is always checked with
902
+ // hasOwnProperty; these are rare in schemas and known when compiling;
903
+ // - any other name can only be inherited from a prototype that is not
904
+ // Object.prototype, so an ordinary object answers with `in` and one
905
+ // comparison of its prototype, and anything else, a class instance, a
906
+ // null-prototype object, one from another realm, pays for hasOwnProperty.
907
+ // `v.__proto__` is read rather than Object.getPrototypeOf(v) because the engine
908
+ // inlines the accessor and not the call (0.8 ns against 8 for eleven keys). An
909
+ // object whose own `__proto__` is a data property reads that value, which is
910
+ // not Object.prototype, so it takes the exact path.
911
+ const PROTO_NAMES = new Set([...Object.getOwnPropertyNames(Object.prototype), '__proto__'])
912
+ // Declared once per compiled function and called by name: spelled out at each
913
+ // property, the test grew a 50-property module by a tenth. Both are small
914
+ // enough for the engine to inline.
915
+ const OWN_HELPERS = 'const _hop=Object.prototype.hasOwnProperty;' +
916
+ 'function _own(o,k){return o.__proto__===Object.prototype?k in o:_hop.call(o,k)}'
917
+ function ownKeyExpr (ctx, v, key) {
918
+ hoistOnce(ctx, '_ownHoisted', OWN_HELPERS)
919
+ const k = JSON.stringify(key)
920
+ return PROTO_NAMES.has(key) ? `_hop.call(${v},${k})` : `_own(${v},${k})`
921
+ }
922
+ // For a value already read as `v[key]` and found not to be undefined: whether
923
+ // it came from `v` itself. Same test; `in` is already known to hold.
924
+ function ownGuard (ctx, v, key) {
925
+ return ownKeyExpr(ctx, v, key)
926
+ }
927
+ // The same test at run time, for the closure compiler.
928
+ const _hop = Object.prototype.hasOwnProperty
929
+ function hasOwnKey (d, key) {
930
+ if (PROTO_NAMES.has(key)) return _hop.call(d, key)
931
+ return key in d && (d.__proto__ === Object.prototype || _hop.call(d, key))
932
+ }
933
+
875
934
  const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'toString', 'valueOf',
876
935
  'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString'])
877
936
 
@@ -2077,24 +2136,34 @@ function genCode(schema, v, lines, ctx, knownType) {
2077
2136
  const hoisted = {} // key -> access expression
2078
2137
  if (schema.required && schema.properties && isObj) {
2079
2138
  const reqChecks = []
2139
+ const typed = []
2080
2140
  for (const key of schema.required) {
2081
2141
  hoisted[key] = `${v}[${JSON.stringify(key)}]`
2082
2142
  const prop = schema.properties[key]
2083
2143
  const hasTypeCheck = prop && (prop.type || prop.enum || prop.const !== undefined)
2084
- if (!hasTypeCheck) {
2085
- reqChecks.push(`${v}[${JSON.stringify(key)}]===undefined`)
2144
+ // A typed property needs no separate presence check on an ordinary
2145
+ // object: its type check fails on undefined. A name on Object.prototype
2146
+ // is never absent that way, and it is checked explicitly.
2147
+ if (!hasTypeCheck || PROTO_NAMES.has(key)) {
2148
+ reqChecks.push(`!${ownKeyExpr(ctx, v, key)}`)
2149
+ } else {
2150
+ typed.push(key)
2086
2151
  }
2087
2152
  }
2088
2153
  if (reqChecks.length > 0) {
2089
2154
  lines.push(`if(${reqChecks.join('||')})return false`)
2090
2155
  }
2156
+ // On an object with another prototype the typed ones may be inherited.
2157
+ if (typed.length > 0) {
2158
+ hoistOnce(ctx, '_ownHoisted', OWN_HELPERS)
2159
+ lines.push(`if(${v}.__proto__!==Object.prototype&&!(${typed.map((k) => `_hop.call(${v},${JSON.stringify(k)})`).join('&&')}))return false`)
2160
+ }
2091
2161
  } else if (schema.required && schema.required.length > 0) {
2162
+ const checks = schema.required.map(key => `!${ownKeyExpr(ctx, v, key)}`)
2092
2163
  if (isObj) {
2093
- const checks = schema.required.map(key => `${v}[${JSON.stringify(key)}]===undefined`)
2094
2164
  lines.push(`if(${checks.join('||')})return false`)
2095
2165
  } else {
2096
2166
  // required applies to objects only; other types are ignored.
2097
- const checks = schema.required.map(key => `${v}[${JSON.stringify(key)}]===undefined`)
2098
2167
  lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&(${checks.join('||')}))return false`)
2099
2168
  }
2100
2169
  }
@@ -2287,8 +2356,8 @@ function genCode(schema, v, lines, ctx, knownType) {
2287
2356
  // dependentRequired
2288
2357
  if (schema.dependentRequired) {
2289
2358
  for (const [key, deps] of Object.entries(schema.dependentRequired)) {
2290
- const depChecks = deps.map(d => `!('${esc(d)}' in ${v})`).join('||')
2291
- lines.push(`if(${objGuard}'${esc(key)}' in ${v}&&(${depChecks}))return false`)
2359
+ const depChecks = deps.map(d => `!${ownKeyExpr(ctx, v, d)}`).join('||')
2360
+ lines.push(`if(${objGuard}${ownKeyExpr(ctx, v, key)}&&(${depChecks}))return false`)
2292
2361
  }
2293
2362
  }
2294
2363
 
@@ -2425,7 +2494,7 @@ function genCode(schema, v, lines, ctx, knownType) {
2425
2494
  if (schema.dependentSchemas) {
2426
2495
  for (const [key, depSchema] of Object.entries(schema.dependentSchemas)) {
2427
2496
  const guard = isObj ? '' : `typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&`
2428
- lines.push(`if(${guard}${JSON.stringify(key)} in ${v}){`)
2497
+ lines.push(`if(${guard}${ownKeyExpr(ctx, v, key)}){`)
2429
2498
  ctx.condDepth = (ctx.condDepth || 0) + 1
2430
2499
  genCode(depSchema, v, lines, ctx, effectiveType)
2431
2500
  ctx.condDepth--
@@ -2491,7 +2560,7 @@ function genCode(schema, v, lines, ctx, knownType) {
2491
2560
  // Optional — hoist to local, check undefined
2492
2561
  const oi = ctx.varCounter++
2493
2562
  const local = `_o${oi}`
2494
- lines.push(`{const ${local}=${v}[${JSON.stringify(key)}];if(${local}!==undefined){`)
2563
+ lines.push(`{const ${local}=${v}[${JSON.stringify(key)}];if(${local}!==undefined&&${ownGuard(ctx, v, key)}){`)
2495
2564
  const combined = tryGenCombined(prop, local, ctx)
2496
2565
  if (combined) {
2497
2566
  lines.push(combined)
@@ -2500,7 +2569,7 @@ function genCode(schema, v, lines, ctx, knownType) {
2500
2569
  }
2501
2570
  lines.push(`}}`)
2502
2571
  } else {
2503
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${JSON.stringify(key)} in ${v}){`)
2572
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${ownKeyExpr(ctx, v, key)}){`)
2504
2573
  genCode(prop, `${v}[${JSON.stringify(key)}]`, lines, ctx)
2505
2574
  lines.push(`}`)
2506
2575
  }
@@ -2864,7 +2933,7 @@ function genCode(schema, v, lines, ctx, knownType) {
2864
2933
  for (const [trigger, depSchema] of Object.entries(schema.dependentSchemas)) {
2865
2934
  const depResult = collectEvaluated(depSchema, ctx.schemaMap, ctx.rootDefs)
2866
2935
  if (depResult.props && depResult.props.length > 0) {
2867
- lines.push(`if(${JSON.stringify(trigger)} in ${v}){${depResult.props.map(k => `${evVar}[${JSON.stringify(k)}]=1`).join(';')}}`)
2936
+ lines.push(`if(${ownKeyExpr(ctx, v, trigger)}){${depResult.props.map(k => `${evVar}[${JSON.stringify(k)}]=1`).join(';')}}`)
2868
2937
  }
2869
2938
  }
2870
2939
  const inner = `for(var _k in ${v}){if(!${evVar}[_k])return false}`
@@ -3462,7 +3531,7 @@ function compileToJSCodegenWithErrors(schema, schemaMap, userFormats, sourceOpts
3462
3531
  if (typeof schema === 'boolean') {
3463
3532
  return schema
3464
3533
  ? () => ({ valid: true, errors: [] })
3465
- : () => ({ valid: false, errors: [{ keyword: 'false schema', instancePath: '', schemaPath: '#', params: {}, message: 'boolean schema is false' }] })
3534
+ : () => ({ valid: false, errors: [{ keyword: 'not', instancePath: '', schemaPath: '#', params: {}, message: 'boolean schema is false' }] })
3466
3535
  }
3467
3536
  if (typeof schema !== 'object' || schema === null) return null
3468
3537
  if (!sharedCodegenGate(schema, schemaMap)) return null
@@ -3823,7 +3892,7 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
3823
3892
  const reqSp = `${schemaPrefix}/required`
3824
3893
  const reqLit = buildErrorLiteral({ keyword: 'required', schemaPath: reqSp, sourceMap: ctx.sourceMap })
3825
3894
  for (const key of schema.required) {
3826
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&!(${JSON.stringify(key)} in ${v})){_e.push({code:'${reqLit.codeStr}',keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${reqSp}'${ordinalField(ctx, `${reqSp}`)},params:{missingProperty:'${esc(key)}'},message:"must have required property '${esc(key)}'",docUrl:'${reqLit.docUrl}'${reqLit.frame}});if(!_all)return{valid:false,errors:_e}}`)
3895
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&!${ownKeyExpr(ctx, v, key)}){_e.push({code:'${reqLit.codeStr}',keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${reqSp}'${ordinalField(ctx, `${reqSp}`)},params:{missingProperty:'${esc(key)}'},message:"must have required property '${esc(key)}'",docUrl:'${reqLit.docUrl}'${reqLit.frame}});if(!_all)return{valid:false,errors:_e}}`)
3827
3896
  }
3828
3897
  }
3829
3898
 
@@ -4040,7 +4109,7 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4040
4109
  const drLit = buildErrorLiteral({ keyword: 'dependentRequired', schemaPath: drSp, sourceMap: ctx.sourceMap })
4041
4110
  for (const [key, deps] of Object.entries(schema.dependentRequired)) {
4042
4111
  for (const dep of deps) {
4043
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${JSON.stringify(key)} in ${v}&&!(${JSON.stringify(dep)} in ${v})){_e.push({code:'${drLit.codeStr}',keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${drSp}'${ordinalField(ctx, `${drSp}`)},params:{missingProperty:'${esc(dep)}'},message:"must have required property '${esc(dep)}'",docUrl:'${drLit.docUrl}'${drLit.frame}});if(!_all)return{valid:false,errors:_e}}`)
4112
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${ownKeyExpr(ctx, v, key)}&&!${ownKeyExpr(ctx, v, dep)}){_e.push({code:'${drLit.codeStr}',keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${drSp}'${ordinalField(ctx, `${drSp}`)},params:{missingProperty:'${esc(dep)}'},message:"must have required property '${esc(dep)}'",docUrl:'${drLit.docUrl}'${drLit.frame}});if(!_all)return{valid:false,errors:_e}}`)
4044
4113
  }
4045
4114
  }
4046
4115
  }
@@ -4049,7 +4118,7 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4049
4118
  if (schema.properties) {
4050
4119
  for (const [key, prop] of Object.entries(schema.properties)) {
4051
4120
  const childPath = childPathExpr(pathExpr, ptrSeg(key))
4052
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${JSON.stringify(key)} in ${v}){`)
4121
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${ownKeyExpr(ctx, v, key)}){`)
4053
4122
  genCodeE(prop, `${v}[${JSON.stringify(key)}]`, childPath, lines, ctx, schemaPrefix+'/properties/'+ptrSeg(key))
4054
4123
  lines.push(`}`)
4055
4124
  }
@@ -4118,7 +4187,7 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4118
4187
  // dependentSchemas
4119
4188
  if (schema.dependentSchemas) {
4120
4189
  for (const [key, depSchema] of Object.entries(schema.dependentSchemas)) {
4121
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${JSON.stringify(key)} in ${v}){`)
4190
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${ownKeyExpr(ctx, v, key)}){`)
4122
4191
  genCodeE(depSchema, v, pathExpr, lines, ctx, schemaPrefix+'/dependentSchemas/'+ptrSeg(key))
4123
4192
  lines.push(`}`)
4124
4193
  }
@@ -4286,7 +4355,7 @@ function compileToJSCombined(schema, VALID_RESULT, schemaMap, userFormats) {
4286
4355
  if (typeof schema === 'boolean') {
4287
4356
  return schema
4288
4357
  ? () => VALID_RESULT
4289
- : () => ({ valid: false, errors: [{ keyword: 'false schema', instancePath: '', schemaPath: '#', params: {}, message: 'boolean schema is false' }] })
4358
+ : () => ({ valid: false, errors: [{ keyword: 'not', instancePath: '', schemaPath: '#', params: {}, message: 'boolean schema is false' }] })
4290
4359
  }
4291
4360
  if (typeof schema !== 'object' || schema === null) return null
4292
4361
  if (!sharedCodegenGate(schema, schemaMap)) return null
@@ -4473,14 +4542,28 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4473
4542
  // Static error: pre-allocate as frozen closure variable
4474
4543
  const ei = ctx.varCounter++
4475
4544
  const errVar = `_E${ei}`
4476
- const pathVal = pathExpr ? pathExpr.slice(1, -1) : ''
4477
- const msgVal = msgCode.slice(1, -1)
4545
+ // The path and message are source literals; evaluate them rather than
4546
+ // strip the quotes, so an escaped quote or backslash in a key comes
4547
+ // out as the character and not as the escape.
4548
+ let pathVal, msgVal
4549
+ try {
4550
+ pathVal = pathExpr ? Function('return ' + pathExpr)() : ''
4551
+ msgVal = Function('return ' + msgCode)()
4552
+ } catch {
4553
+ // Not a literal that parses on its own (a key with a raw line break):
4554
+ // leave it to the inline form below, which declines the same way the
4555
+ // whole function would.
4556
+ pathVal = undefined
4557
+ }
4558
+ if (pathVal !== undefined) {
4559
+ const spVal = unescapeSp(sp)
4478
4560
  ctx.closureVars.push(errVar)
4479
- const o = ordinalFor(ctx.rootSchema, sp)
4480
- const lit = {keyword, instancePath: pathVal, schemaPath: sp, params: Object.freeze(paramsVal), message: msgVal}
4561
+ const o = ordinalFor(ctx.rootSchema, spVal)
4562
+ const lit = {keyword, instancePath: pathVal, schemaPath: spVal, params: Object.freeze(paramsVal), message: msgVal}
4481
4563
  if (o !== null) lit._o = o
4482
4564
  ctx.closureVals.push(Object.freeze(lit))
4483
4565
  return `(_e||(_e=[])).push(${errVar})`
4566
+ }
4484
4567
  }
4485
4568
  }
4486
4569
  // Dynamic path (e.g., array index): inline as before
@@ -4543,15 +4626,22 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4543
4626
  destructKeys.push(`${JSON.stringify(key)}:${lv}`)
4544
4627
  }
4545
4628
  }
4546
- if (destructKeys.length > 0) lines.push(`const{${destructKeys.join(',')}}=${v}`)
4629
+ if (destructKeys.length > 0) {
4630
+ lines.push(`let{${destructKeys.join(',')}}=${v}`)
4631
+ // A value the object only inherits reads as absent, here and in the
4632
+ // property checks that use the same local below.
4633
+ for (const key of schema.required) {
4634
+ if (hoisted[key]) lines.push(`if(${hoisted[key]}!==undefined&&!${ownGuard(ctx, v, key)})${hoisted[key]}=undefined`)
4635
+ }
4636
+ }
4547
4637
  for (const key of schema.required) {
4548
- const check = hoisted[key] ? `${hoisted[key]}===undefined` : `${v}[${JSON.stringify(key)}]===undefined`
4638
+ const check = hoisted[key] ? `${hoisted[key]}===undefined` : `!${ownKeyExpr(ctx, v, key)}`
4549
4639
  if (isStaticPath) {
4550
4640
  const ei = ctx.varCounter++
4551
4641
  const errVar = `_E${ei}`
4552
- const pathVal = pathExpr ? pathExpr.slice(1, -1) : ''
4642
+ const pathVal = pathExpr ? literalValue(pathExpr) : ''
4553
4643
  ctx.closureVars.push(errVar)
4554
- ctx.closureVals.push(Object.freeze({keyword: 'required', instancePath: pathVal, schemaPath: `${schemaPrefix}/required`, params: Object.freeze({missingProperty: key}), message: `must have required property '${key}'`}))
4644
+ ctx.closureVals.push(Object.freeze({keyword: 'required', instancePath: pathVal, schemaPath: unescapeSp(`${schemaPrefix}/required`), params: Object.freeze({missingProperty: key}), message: `must have required property '${key}'`}))
4555
4645
  lines.push(`if(${check}){(_e||(_e=[])).push(${errVar})}`)
4556
4646
  } else {
4557
4647
  lines.push(`if(${check}){(_e||(_e=[])).push({keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/required'${ordinalField(ctx, `${schemaPrefix}/required`)},params:{missingProperty:'${esc(key)}'},message:"must have required property '${esc(key)}'"})}`)
@@ -4563,12 +4653,12 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4563
4653
  if (isStatic) {
4564
4654
  const ei = ctx.varCounter++
4565
4655
  const errVar = `_E${ei}`
4566
- const pathVal = pathExpr ? pathExpr.slice(1, -1) : ''
4656
+ const pathVal = pathExpr ? literalValue(pathExpr) : ''
4567
4657
  ctx.closureVars.push(errVar)
4568
- ctx.closureVals.push(Object.freeze({keyword: 'required', instancePath: pathVal, schemaPath: `${schemaPrefix}/required`, params: Object.freeze({missingProperty: key}), message: `must have required property '${key}'`}))
4569
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&!(${JSON.stringify(key)} in ${v})){(_e||(_e=[])).push(${errVar})}`)
4658
+ ctx.closureVals.push(Object.freeze({keyword: 'required', instancePath: pathVal, schemaPath: unescapeSp(`${schemaPrefix}/required`), params: Object.freeze({missingProperty: key}), message: `must have required property '${key}'`}))
4659
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&!${ownKeyExpr(ctx, v, key)}){(_e||(_e=[])).push(${errVar})}`)
4570
4660
  } else {
4571
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&!(${JSON.stringify(key)} in ${v})){(_e||(_e=[])).push({keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/required'${ordinalField(ctx, `${schemaPrefix}/required`)},params:{missingProperty:'${esc(key)}'},message:"must have required property '${esc(key)}'"})}`)
4661
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&!${ownKeyExpr(ctx, v, key)}){(_e||(_e=[])).push({keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/required'${ordinalField(ctx, `${schemaPrefix}/required`)},params:{missingProperty:'${esc(key)}'},message:"must have required property '${esc(key)}'"})}`)
4572
4662
  }
4573
4663
  }
4574
4664
  }
@@ -4728,12 +4818,12 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4728
4818
  if (isStatic) {
4729
4819
  const ei = ctx.varCounter++
4730
4820
  const errVar = `_E${ei}`
4731
- const pathVal = pathExpr ? pathExpr.slice(1, -1) : ''
4821
+ const pathVal = pathExpr ? literalValue(pathExpr) : ''
4732
4822
  ctx.closureVars.push(errVar)
4733
- ctx.closureVals.push(Object.freeze({keyword: 'required', instancePath: pathVal, schemaPath: `${schemaPrefix}/dependentRequired`, params: Object.freeze({missingProperty: dep}), message: `must have required property '${dep}'`}))
4734
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${JSON.stringify(key)} in ${v}&&!(${JSON.stringify(dep)} in ${v})){(_e||(_e=[])).push(${errVar})}`)
4823
+ ctx.closureVals.push(Object.freeze({keyword: 'required', instancePath: pathVal, schemaPath: unescapeSp(`${schemaPrefix}/dependentRequired`), params: Object.freeze({missingProperty: dep}), message: `must have required property '${dep}'`}))
4824
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${ownKeyExpr(ctx, v, key)}&&!${ownKeyExpr(ctx, v, dep)}){(_e||(_e=[])).push(${errVar})}`)
4735
4825
  } else {
4736
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${JSON.stringify(key)} in ${v}&&!(${JSON.stringify(dep)} in ${v})){(_e||(_e=[])).push({keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/dependentRequired'${ordinalField(ctx, `${schemaPrefix}/dependentRequired`)},params:{missingProperty:'${esc(dep)}'},message:"must have required property '${esc(dep)}'"})}`)
4826
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&${ownKeyExpr(ctx, v, key)}&&!${ownKeyExpr(ctx, v, dep)}){(_e||(_e=[])).push({keyword:'required',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/dependentRequired'${ordinalField(ctx, `${schemaPrefix}/dependentRequired`)},params:{missingProperty:'${esc(dep)}'},message:"must have required property '${esc(dep)}'"})}`)
4737
4827
  }
4738
4828
  }
4739
4829
  }
@@ -4745,16 +4835,17 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4745
4835
  const pv = hoisted[key] || `${v}[${JSON.stringify(key)}]`
4746
4836
  const childPath = childPathExpr(pathExpr, ptrSeg(key))
4747
4837
  if (requiredSet.has(key) && isObj) {
4748
- lines.push(`if(${pv}!==undefined){`)
4838
+ // A hoisted local was already cleared if the value is only inherited.
4839
+ lines.push(`if(${pv}!==undefined${hoisted[key] ? '' : '&&' + ownGuard(ctx, v, key)}){`)
4749
4840
  genCodeC(prop, pv, childPath, lines, ctx, schemaPrefix+'/properties/'+ptrSeg(key))
4750
4841
  lines.push(`}`)
4751
4842
  } else if (isObj) {
4752
4843
  const oi = ctx.varCounter++
4753
- lines.push(`{const _o${oi}=${v}[${JSON.stringify(key)}];if(_o${oi}!==undefined){`)
4844
+ lines.push(`{const _o${oi}=${v}[${JSON.stringify(key)}];if(_o${oi}!==undefined&&${ownGuard(ctx, v, key)}){`)
4754
4845
  genCodeC(prop, `_o${oi}`, childPath, lines, ctx, schemaPrefix+'/properties/'+ptrSeg(key))
4755
4846
  lines.push(`}}`)
4756
4847
  } else {
4757
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${JSON.stringify(key)} in ${v}){`)
4848
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${ownKeyExpr(ctx, v, key)}){`)
4758
4849
  genCodeC(prop, `${v}[${JSON.stringify(key)}]`, childPath, lines, ctx, schemaPrefix+'/properties/'+ptrSeg(key))
4759
4850
  lines.push(`}`)
4760
4851
  }
@@ -4870,7 +4961,7 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
4870
4961
  // dependentSchemas
4871
4962
  if (schema.dependentSchemas) {
4872
4963
  for (const [key, depSchema] of Object.entries(schema.dependentSchemas)) {
4873
- lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${JSON.stringify(key)} in ${v}){`)
4964
+ lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&${ownKeyExpr(ctx, v, key)}){`)
4874
4965
  genCodeC(depSchema, v, pathExpr, lines, ctx, schemaPrefix+'/dependentSchemas/'+ptrSeg(key))
4875
4966
  lines.push(`}`)
4876
4967
  }
@@ -69,6 +69,15 @@ function isTier0Object(schema) {
69
69
  for (const r of schema.required) if (typeof r !== 'string') return false;
70
70
  }
71
71
  const props = schema.properties;
72
+ // The tier-0 validator checks presence through the per-property constraints,
73
+ // so a required name with no entry in properties was never checked at all:
74
+ // `{ type: 'object', required: ['id'] }` accepted `{}` until the schema moved
75
+ // to generated code, and for good when the generator declined it.
76
+ if (schema.required !== undefined) {
77
+ for (const r of schema.required) {
78
+ if (props === undefined || props === null || typeof props !== 'object' || !Object.prototype.hasOwnProperty.call(props, r)) return false;
79
+ }
80
+ }
72
81
  if (props === undefined) return true;
73
82
  if (typeof props !== 'object' || props === null || Array.isArray(props)) return false;
74
83
  const keys = Object.keys(props);
package/lib/tier0.js CHANGED
@@ -41,6 +41,12 @@ const F_MULT = 16;
41
41
 
42
42
  // Build a constraint tuple for one primitive-typed property.
43
43
  // All fields have the same layout so every constraint shares one hidden class.
44
+ // Names found on Object.prototype. For these a read of data[key] finds the
45
+ // inherited value on every ordinary object, so presence is asked of the object
46
+ // itself; see ownKeyExpr in js-compiler.js.
47
+ const PROTO_NAMES = new Set([...Object.getOwnPropertyNames(Object.prototype), '__proto__']);
48
+ const _hop = Object.prototype.hasOwnProperty;
49
+
44
50
  function primConstraint(key, propSchema) {
45
51
  const t = propSchema.type;
46
52
  const hasEnum = Array.isArray(propSchema.enum);
@@ -53,6 +59,7 @@ function primConstraint(key, propSchema) {
53
59
  if (typeof propSchema.multipleOf === 'number') numFlags |= F_MULT;
54
60
  return {
55
61
  key,
62
+ protoName: PROTO_NAMES.has(key),
56
63
  typeMask: TYPE_MASK[t] | 0,
57
64
  numFlags,
58
65
  hasEnum,
@@ -159,7 +166,10 @@ function tier0ValidateObject(plan, data) {
159
166
  let seenMask = 0;
160
167
  for (let i = 0; i < n; i++) {
161
168
  const c = cs[i];
162
- const v = data[c.key];
169
+ let v = data[c.key];
170
+ // Presence is an own-property question: a value the object inherits is
171
+ // treated as absent, as the interpreted engine treats it.
172
+ if (v !== undefined && (c.protoName || data.__proto__ !== Object.prototype) && !_hop.call(data, c.key)) v = undefined;
163
173
  if (v === undefined) {
164
174
  if (reqMask & (1 << i)) return false;
165
175
  continue;
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.31.1';
10
+ module.exports = '1.31.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ata-validator",
3
- "version": "1.31.1",
3
+ "version": "1.31.2",
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",
@@ -51,7 +51,7 @@
51
51
  "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",
52
52
  "build": "cmake-js build --target ata",
53
53
  "rebuild": "cmake-js rebuild --target ata",
54
- "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_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_version_sync.js && node tests/test_native_loaded.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_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_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",
54
+ "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_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_version_sync.js && node tests/test_native_loaded.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_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_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",
55
55
  "bench:size": "node benchmark/bench_aot_size.mjs",
56
56
  "test:suite": "node tests/run_suite.js && node tests/run_suite.js draft7 && node tests/run_suite.js v1",
57
57
  "test:compat": "node tests/test_compat.js",
@@ -121,13 +121,13 @@
121
121
  "LICENSE"
122
122
  ],
123
123
  "optionalDependencies": {
124
- "@ata-validator/native-darwin-arm64": "1.31.1",
125
- "@ata-validator/native-darwin-x64": "1.31.1",
126
- "@ata-validator/native-linux-arm64-gnu": "1.31.1",
127
- "@ata-validator/native-linux-arm64-musl": "1.31.1",
128
- "@ata-validator/native-linux-x64-gnu": "1.31.1",
129
- "@ata-validator/native-linux-x64-musl": "1.31.1",
130
- "@ata-validator/native-win32-x64": "1.31.1"
124
+ "@ata-validator/native-darwin-arm64": "1.31.2",
125
+ "@ata-validator/native-darwin-x64": "1.31.2",
126
+ "@ata-validator/native-linux-arm64-gnu": "1.31.2",
127
+ "@ata-validator/native-linux-arm64-musl": "1.31.2",
128
+ "@ata-validator/native-linux-x64-gnu": "1.31.2",
129
+ "@ata-validator/native-linux-x64-musl": "1.31.2",
130
+ "@ata-validator/native-win32-x64": "1.31.2"
131
131
  },
132
132
  "peerDependencies": {
133
133
  "yaml": "^2.0.0"