ata-validator 1.16.0 → 1.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
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.1 - 2026-09-12
6
+
7
+ ### Fixed
8
+
9
+ - 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.
10
+
5
11
  ## 1.16.0 - 2026-09-12
6
12
 
7
13
  ### Added
@@ -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.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ata-validator",
3
- "version": "1.16.0",
3
+ "version": "1.16.1",
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_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.1",
126
+ "@ata-validator/native-darwin-x64": "1.16.1",
127
+ "@ata-validator/native-linux-arm64-gnu": "1.16.1",
128
+ "@ata-validator/native-linux-arm64-musl": "1.16.1",
129
+ "@ata-validator/native-linux-x64-gnu": "1.16.1",
130
+ "@ata-validator/native-linux-x64-musl": "1.16.1",
131
+ "@ata-validator/native-win32-x64": "1.16.1"
132
132
  },
133
133
  "peerDependencies": {
134
134
  "yaml": "^2.0.0"