ata-validator 1.16.0 → 1.16.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/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to ata-validator are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/), and this project adheres to semantic versioning.
4
4
 
5
+ ## 1.16.2 - 2026-09-12
6
+
7
+ ### Fixed
8
+
9
+ - A schema with `unevaluatedProperties` or `unevaluatedItems` reported every failure as one placeholder error, `{ code: 'unevaluated', message: 'unevaluated property or item' }`, with no `keyword` and no `instancePath`. The generated code answers the verdict for these schemas but the error generator declines them, and the error path then fell into a stub instead of the interpreted engine, which reports them correctly. A wrong type, a missing required property, a bad format or an enum miss under a root `unevaluatedProperties: false` all came back as that one line, so anything mapping errors by keyword and path saw nothing useful. Failing data is now re-validated by the interpreted engine on that path, as it already was without the native addon for other declined shapes. Verdicts were never affected. Found by a user comparing error output on a generated config schema. `tests/test_unevaluated_error_path.js` holds the generated-code path to the interpreter's errors on five shapes, in all three engine modes.
10
+
11
+ ## 1.16.1 - 2026-09-12
12
+
13
+ ### Fixed
14
+
15
+ - A custom format (`formats: { name: fn }`, or `addFormat` on the compat class) next to a shape the combined code generator declines, such as an `anyOf` sibling, threw `_uf_<name> is not defined` on the first invalid document instead of reporting the format error. The error-path code generator emitted the call to the format checker without binding it; it now takes the checkers as bound parameters like the other two entry points. Verdicts were never affected, only the error path, and only on that combination. Present since custom formats were added; caught by the 1.16.0 clean-install check. `tests/test_user_format_error_path.js` covers it.
16
+
5
17
  ## 1.16.0 - 2026-09-12
6
18
 
7
19
  ### Added
package/index.js CHANGED
@@ -1057,12 +1057,14 @@ class Validator {
1057
1057
  }]
1058
1058
  };
1059
1059
  };
1060
+ // The error generator declines unevaluated*; the interpreted engine
1061
+ // reports those schemas correctly, so failing data is re-validated
1062
+ // there. This used to be a placeholder error with no keyword and no
1063
+ // path, which hid whatever had actually failed.
1060
1064
  const errFn =
1061
1065
  safeErrFn ||
1062
- (hasUnevaluated
1063
- ? (d) => ({ valid: jsFn(d), errors: jsFn(d) ? [] : [{ code: 'unevaluated', path: '', message: 'unevaluated property or item' }] })
1064
- : !native
1065
- ? jsOnlyFallback
1066
+ (hasUnevaluated || !native
1067
+ ? jsOnlyFallback
1066
1068
  : hasDynRef
1067
1069
  ? (d) => {
1068
1070
  this._ensureNative();
@@ -3194,6 +3194,9 @@ function compileToJSCodegenWithErrors(schema, schemaMap, userFormats, sourceOpts
3194
3194
  if (needsBaseTracking(schema, schemaMap, new Set())) return null
3195
3195
 
3196
3196
  const ctx = { varCounter: 0, helperCode: [], rootDefs: eRootDefs, refStack: new Set(), schemaMap: schemaMap || null, anchors: eAnchors, rootSchema: schema, userFormats: userFormats || null,
3197
+ // Custom format checkers referenced by the body, bound as
3198
+ // closure parameters below the way the other entry points do.
3199
+ closureVars: [], closureVals: [],
3197
3200
  sourceMap: (sourceOpts && sourceOpts.sourceMap && sourceOpts.schemaFile)
3198
3201
  ? { file: sourceOpts.schemaFile, map: sourceOpts.sourceMap }
3199
3202
  : null }
@@ -3241,16 +3244,35 @@ function compileToJSCodegenWithErrors(schema, schemaMap, userFormats, sourceOpts
3241
3244
  }
3242
3245
  try {
3243
3246
  let fn
3247
+ // Custom format checkers come in as leading parameters, bound once here,
3248
+ // so the body's `_uf_<name>(...)` calls resolve. Without a binding the
3249
+ // first invalid document threw a ReferenceError instead of reporting.
3250
+ const cvars = ctx.closureVars
3251
+ const cvals = ctx.closureVals
3244
3252
  if (ctx.usesSafeRe) {
3245
3253
  // Inlined helperCode references __ataSafeRe; bind the safe-regex factory.
3246
3254
  // Standalone keeps the inline _errSource — the embed defines __ataSafeRe.
3247
- const built = new Function('__ataSafeRe', 'd', '_all', body)
3248
- fn = (d, _all) => built(compileSafe, d, _all)
3255
+ const built = new Function(...cvars, '__ataSafeRe', 'd', '_all', body)
3256
+ fn = cvars.length
3257
+ ? (d, _all) => built(...cvals, compileSafe, d, _all)
3258
+ : (d, _all) => built(compileSafe, d, _all)
3259
+ } else if (cvars.length) {
3260
+ const built = new Function(...cvars, 'd', '_all', body)
3261
+ fn = (d, _all) => built(...cvals, d, _all)
3249
3262
  } else {
3250
3263
  fn = new Function('d', '_all', body)
3251
3264
  }
3252
3265
  fn._errSource = body
3253
3266
  fn._usesSafeRe = !!ctx.usesSafeRe
3267
+ if (cvars.length) {
3268
+ fn._formatClosures = cvars.map((name, i) => {
3269
+ let format = null
3270
+ for (const key of Object.keys(ctx.userFormats)) {
3271
+ if (ctx.userFormats[key] === cvals[i]) { format = key; break }
3272
+ }
3273
+ return { name, fn: cvals[i], format }
3274
+ })
3275
+ }
3254
3276
  return fn
3255
3277
  } catch {
3256
3278
  return null
@@ -3538,11 +3560,16 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
3538
3560
  const fmtCode = fc(v, isStr, ctx).replace(/return false/g, `{${failPush};break _fmt${ri}}`)
3539
3561
  lines.push(`_fmt${ri}:{${fmtCode}}`)
3540
3562
  } else if (ctx.userFormats && typeof ctx.userFormats[schema.format] === 'function') {
3541
- // User-supplied format checker on the error path. Same closure plumbing
3542
- // as the boolean codegen — but error codegen has no closure factory, so
3543
- // bundle output serializes the function via Function#toString separately.
3563
+ // User-supplied format checker on the error path: the same closure
3564
+ // plumbing as the boolean codegen. The function is bound as a parameter
3565
+ // of the compiled error function; bundle output serializes it via
3566
+ // Function#toString separately.
3544
3567
  const safeName = schema.format.replace(/[^a-zA-Z0-9_]/g, '_')
3545
3568
  const closureName = `_uf_${safeName}`
3569
+ if (ctx.closureVars && !ctx.closureVars.includes(closureName)) {
3570
+ ctx.closureVars.push(closureName)
3571
+ ctx.closureVals.push(ctx.userFormats[schema.format])
3572
+ }
3546
3573
  const guard = isStr ? '' : `typeof ${v}==='string'&&`
3547
3574
  lines.push(`if(${guard}!${closureName}(${v})){${failPush}}`)
3548
3575
  }
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.16.0';
10
+ module.exports = '1.16.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ata-validator",
3
- "version": "1.16.0",
3
+ "version": "1.16.2",
4
4
  "description": "JSON Schema validation with first-class TypeScript and zero runtime cost. AOT compile to per-schema ESM modules with zero validator dependency. Generic Validator<T> for TypeBox/Zod/Valibot composition. Optional runtime API. Standard Schema V1 compatible.",
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_buffer_reject_cost.js && node tests/test_nan_verdict.js && node tests/test_remove_additional_nested.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_diagnostic.js && node tests/test_format_engine_parity.js && node tests/test_formats_single_pass.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_ajv_errors.js && node tests/test_custom_keywords.js && node tests/test_ajv_parity.js && node tests/test_pattern_properties_errors.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_value_equality.js && node tests/test_vocabulary.js && node tests/test_schema_scan.js && node tests/test_lazy_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_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_data_positions.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_buffer_reject_cost.js && node tests/test_nan_verdict.js && node tests/test_remove_additional_nested.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_diagnostic.js && node tests/test_format_engine_parity.js && node tests/test_formats_single_pass.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_ajv_errors.js && node tests/test_custom_keywords.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_pattern_properties_errors.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_value_equality.js && node tests/test_vocabulary.js && node tests/test_schema_scan.js && node tests/test_lazy_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_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_data_positions.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",
@@ -122,13 +122,13 @@
122
122
  "LICENSE"
123
123
  ],
124
124
  "optionalDependencies": {
125
- "@ata-validator/native-darwin-arm64": "1.16.0",
126
- "@ata-validator/native-darwin-x64": "1.16.0",
127
- "@ata-validator/native-linux-arm64-gnu": "1.16.0",
128
- "@ata-validator/native-linux-arm64-musl": "1.16.0",
129
- "@ata-validator/native-linux-x64-gnu": "1.16.0",
130
- "@ata-validator/native-linux-x64-musl": "1.16.0",
131
- "@ata-validator/native-win32-x64": "1.16.0"
125
+ "@ata-validator/native-darwin-arm64": "1.16.2",
126
+ "@ata-validator/native-darwin-x64": "1.16.2",
127
+ "@ata-validator/native-linux-arm64-gnu": "1.16.2",
128
+ "@ata-validator/native-linux-arm64-musl": "1.16.2",
129
+ "@ata-validator/native-linux-x64-gnu": "1.16.2",
130
+ "@ata-validator/native-linux-x64-musl": "1.16.2",
131
+ "@ata-validator/native-win32-x64": "1.16.2"
132
132
  },
133
133
  "peerDependencies": {
134
134
  "yaml": "^2.0.0"