Skip to content

v0.15.0

Choose a tag to compare

@mertcanaltin mertcanaltin released this 17 May 23:25
· 41 commits to master since this release

v0.15.0 ships compiler-grade error messages for JSON Schema validation. Every error now carries a stable code, a code-frame pointing at the offending schema line, another pointing at the offending bytes in the request payload, and (when ata is confident) a suggestion. The output is tsc --pretty / rustc shaped, not the structured-JSON wall of text validators have shipped for a decade.

The frame is possible because ata is AOT-compiled: the schema file path, line, and column travel into the compiled validator. Runtime validators get the same frame when constructed with { source: { path, content } }. Bundle size on production builds (NODE_ENV=production or --no-source) is unchanged from v0.14.

error[ATA3001]: value does not match format "email"
  --> schemas/user.json:5:7
   |
 5 |       "email": { "type": "string", "format": "email" }
   |       ^   expected format 'email'
   |
  --> input, byte 23
   |
 1 | { "name": "M", "email": "not-an-email", "age": -3 }
   |                         ^^^^^^^^^^^^^^   got "not-an-email"
   |
   = help: missing '@' and domain part
   = note: see https://ata-validator.com/e/ATA3001

Added

  • ATA#### error code registry. 46 stable codes covering type, shape, constraint, format, composition, ref, enum, and system categories. Every error gets one. Permalinks at https://ata-validator.com/e/<CODE>. Full registry in docs/error-codes.md.
  • Renderer API. renderPretty, renderCompact, and renderJSON exported from ata-validator. Pretty is rustc-style; compact is one line per error (CI-grep-friendly); JSON is structured for tooling. TTY auto-picks pretty, pipes auto-pick compact.
  • ata validate <schema> <data> CLI subcommand. Runs a schema against a JSON data file, exits 0/1, prints via the active renderer. Flags: --pretty, --compact, --format=json, --max-errors, --color, --no-color.
  • Schema source frames. schemaSource: { file, line, col, text } on every error. AOT-compiled validators bake the frame at codegen time. Runtime validators get parity with new Validator(schema, { source: { path, content } }).
  • Request payload frames. dataFrame: { byteOffset, length, line, col, text } whenever validateJSON() was called with a string or Buffer. Zero cost on the valid path, JS-side reparse only on failure.
  • oneOf / anyOf collapse. Branching failures collapse to a single best-branch error (ATA4001 / ATA4002 / ATA4003) instead of the full branch-tree explosion. The closest matching variant's errors stay available under branchErrors. allOf errors continue to surface every failing branch.
  • Suggestions. A new suggestion field nudges users when ata is confident: typo against enum, missing-required typo close to a present key, format-violation hint, type-coercion nudge. Runtime validators populate automatically. AOT consumers call attachSuggestions(errors, data) to keep AOT bundles at zero size growth.
  • ata compile / ata build flags. New --source / --no-source. ata build --dual emits both a source-mapped artifact (*.compiled.mjs) and a stripped one (*.compiled.min.mjs) in a single run. Source is on by default in development, off when NODE_ENV=production so production bundles stay at the v0.14 size baseline.
  • Size budget gate. npm run bench:size enforces a gzipped-byte budget over the AOT codegen output. Baseline at benchmark/baselines/aot-size.json; gates derive from the baseline with 1.5x headroom.
  • richErrors: false opt-out. new Validator(schema, { richErrors: false }) returns the v0.14 error shape byte-for-byte. For users who built log dashboards or alerts on the prior shape.
  • release:check npm script. Runs prebuilds, doc-coverage, and error-code lockfile checks in strict mode before publish.

Changed

  • prepublishOnly now chains check-prebuilds, check-doc-coverage, and the error-code lockfile test.
  • ata compile and ata build failures route through the renderer with code ATA9002, so command-line schema errors look the same as runtime ones.
  • abortEarly: true returns the existing short-circuit stub with code: 'ATA9000'. Measured 68.95x faster than full enrichment on the same payload; the perf gate (in tests/test_abort_early.js) asserts at least 3x.

Notes

  • Backward compatibility. New fields are additive. result.errors[i].message, .path, .keyword, .schemaPath, .instancePath, .dataPath, .params, and .parentSchema are unchanged. Existing code consumers and the ata-validator/compat AJV-shim do not need to migrate.
  • Log scrapers. If you serialize result.errors directly into logs, line size will grow because of the new fields. Pipe through renderCompact for a stable one-line format, or pass richErrors: false for the v0.14 shape.
  • Production bundle size. Source-mapped variants (.compiled.mjs) add up to ~200 gzipped bytes for a 10-field schema. Production builds (NODE_ENV=production or --no-source) emit the no-source variant; size unchanged.
  • Companion releases. A fastify-ata release wires the new error format into Fastify route responses.