ata-validator 0.21.0 → 1.0.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.
- package/CHANGELOG.md +30 -0
- package/README.md +17 -3
- package/bin/ata.js +2 -1
- package/build.d.ts +4 -4
- package/index.d.ts +0 -9
- package/index.js +4 -18
- package/lib/aot-build.js +4 -4
- package/lib/version.js +1 -1
- package/package.json +5 -5
- package/prebuilds/ata-darwin-arm64/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-arm64/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-arm64-musl/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-x64/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-x64-musl/node-napi-v10.node +0 -0
- package/prebuilds/ata-win32-x64/node-napi-v10.node +0 -0
- package/scripts/regen-safe-regex-source.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
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.0.0 - 2026-07-15
|
|
6
|
+
|
|
7
|
+
1.0 is a stability commitment, not a feature release. The API surface, the error result shape, and the error code registry are now covered by the semver guarantees in [docs/STABILITY.md](docs/STABILITY.md).
|
|
8
|
+
|
|
9
|
+
### Removed
|
|
10
|
+
|
|
11
|
+
- `Validator.prototype.toStandalone()` and `Validator.prototype.toStandaloneModule()`, deprecated in 0.22.0. Use `toStandaloneModule()`/`bundleStandalone()`/`bundleCompact()` from `ata-validator/build`. See [docs/migration-to-1.0.md](docs/migration-to-1.0.md).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Node.js 20 or newer is required. Node 18 reached end of life in April 2025.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- [docs/STABILITY.md](docs/STABILITY.md): semver, deprecation, and error-code guarantees.
|
|
20
|
+
- README "Known limitations" section documenting the deliberate 1.x scope edges.
|
|
21
|
+
|
|
22
|
+
## 0.22.0 - 2026-07-14
|
|
23
|
+
|
|
24
|
+
### Deprecated
|
|
25
|
+
|
|
26
|
+
- `Validator.prototype.toStandalone()` and `Validator.prototype.toStandaloneModule()` now emit a one-time DeprecationWarning. Both will be removed in 1.0. The replacements have been stable since 0.19: `toStandaloneModule()`/`bundleStandalone()`/`bundleCompact()` from `ata-validator/build`, and the `Validator.bundle*()` statics.
|
|
27
|
+
|
|
28
|
+
## 0.21.0 - 2026-06-01
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- `errorMessage` keyword for custom error messages. A string on a subschema replaces the message for any failing keyword there; an object overrides per keyword, with `required` keyed by missing property name and `_` as fallback. `code`, `keyword`, and `path` fields are untouched. Schemas without `errorMessage` pay nothing; the override pass is only installed when one is present.
|
|
33
|
+
- Async refinement: `t.refine(schema, fn, { message, path })` attaches an async (or sync) check that runs through `validateAsync`/`parseAsync` after structural validation passes. `new Validator(schema)` ignores the refinement marker, so plain structural validation is unchanged. Failing refinements surface as errors with `keyword: 'refine'`.
|
|
34
|
+
|
|
5
35
|
## 0.20.1 - 2026-05-27
|
|
6
36
|
|
|
7
37
|
### Fixed
|
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@ JSON Schema validation with first-class TypeScript and zero runtime cost. AOT co
|
|
|
5
5
|
[](https://www.npmjs.com/package/ata-validator)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
+
1.0 is a stability commitment: see [docs/STABILITY.md](docs/STABILITY.md) for the semver, deprecation, and error-code guarantees.
|
|
9
|
+
|
|
8
10
|
## Quick start
|
|
9
11
|
|
|
10
12
|
```bash
|
|
@@ -359,10 +361,9 @@ Programmatic API if you prefer to script it:
|
|
|
359
361
|
|
|
360
362
|
```javascript
|
|
361
363
|
const fs = require('fs');
|
|
362
|
-
const {
|
|
364
|
+
const { toStandaloneModule } = require('ata-validator/build');
|
|
363
365
|
|
|
364
|
-
|
|
365
|
-
fs.writeFileSync('./user.validator.mjs', v.toStandaloneModule({ format: 'esm' }));
|
|
366
|
+
fs.writeFileSync('./user.validator.mjs', toStandaloneModule(schema, { format: 'esm' }));
|
|
366
367
|
```
|
|
367
368
|
|
|
368
369
|
**Fastify startup (10 routes cold): ajv 12.6ms → ata 0.5ms (24x faster boot, no build step required)**
|
|
@@ -446,6 +447,19 @@ Copy-paste recipes for the common frameworks. Most need 10-20 lines of glue. See
|
|
|
446
447
|
|
|
447
448
|
`email`, `date`, `date-time`, `time`, `uri`, `uri-reference`, `ipv4`, `ipv6`, `uuid`, `hostname`
|
|
448
449
|
|
|
450
|
+
### Known limitations
|
|
451
|
+
|
|
452
|
+
The 98.5% Draft 2020-12 pass rate excludes areas that are deliberate scope decisions for 1.x:
|
|
453
|
+
|
|
454
|
+
- **Remote `$ref` over the network** is not fetched. Register cross-schema refs explicitly with `schemas: [...]` or `addSchema()`.
|
|
455
|
+
- **`$vocabulary`** is not implemented; custom vocabularies are ignored rather than enforced.
|
|
456
|
+
- **`contentEncoding` / `contentMediaType` / `contentSchema`** are annotation-only, as the spec permits, and are not validated.
|
|
457
|
+
- **`minLength`/`maxLength`** count UTF-16 code units, not grapheme clusters.
|
|
458
|
+
- **Infinite-loop detection** suite cases are skipped; circular `$ref` chains are cut off by a recursion depth guard instead.
|
|
459
|
+
- **`default`** optional suite tests are excluded; ata applies `default` values to validated data, where the spec treats `default` as a non-enforcing annotation.
|
|
460
|
+
|
|
461
|
+
If one of these blocks you, open an issue; scope decisions get revisited with real use cases.
|
|
462
|
+
|
|
449
463
|
## Building from Source
|
|
450
464
|
|
|
451
465
|
### Development prerequisites
|
package/bin/ata.js
CHANGED
|
@@ -181,6 +181,7 @@ function cmdCompile(args) {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
const { Validator } = require('..');
|
|
184
|
+
const aot = require('../lib/aot');
|
|
184
185
|
let v;
|
|
185
186
|
try {
|
|
186
187
|
v = new Validator(schema);
|
|
@@ -199,7 +200,7 @@ function cmdCompile(args) {
|
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
202
|
const schemaFile = path.relative(process.cwd(), input) || input;
|
|
202
|
-
const src =
|
|
203
|
+
const src = aot.toStandaloneModule(v, { format, abortEarly, source, sourceMap, schemaFile });
|
|
203
204
|
if (!src) {
|
|
204
205
|
reportCompileError(input, 'schema is too complex for standalone compilation');
|
|
205
206
|
process.exit(1);
|
package/build.d.ts
CHANGED
|
@@ -69,13 +69,13 @@ export interface WatchHandle {
|
|
|
69
69
|
export function watch(opts: BuildOptions, onReport?: (r: BuildReport) => void): Promise<WatchHandle>;
|
|
70
70
|
|
|
71
71
|
// --- AOT primitives ---
|
|
72
|
-
// Programmatic counterparts to `Validator.bundleStandalone` / `bundleCompact
|
|
73
|
-
//
|
|
74
|
-
//
|
|
72
|
+
// Programmatic counterparts to `Validator.bundleStandalone` / `bundleCompact`.
|
|
73
|
+
// Kept here so callers that only want the build surface (e.g. a bundler
|
|
74
|
+
// plugin) don't have to import the full runtime.
|
|
75
75
|
|
|
76
76
|
export interface BundleStandaloneOptions {
|
|
77
77
|
format?: 'cjs' | 'esm';
|
|
78
|
-
formats?: Record<string, (value:
|
|
78
|
+
formats?: Record<string, (value: string) => boolean>;
|
|
79
79
|
verbose?: boolean;
|
|
80
80
|
}
|
|
81
81
|
|
package/index.d.ts
CHANGED
|
@@ -411,15 +411,6 @@ export interface Validator<T = unknown> {
|
|
|
411
411
|
/** Single-thread NDJSON batch validation. Requires native addon. */
|
|
412
412
|
isValidNDJSON(ndjsonBuffer: Buffer): boolean[];
|
|
413
413
|
|
|
414
|
-
/** Generate a standalone JS module string for zero-compile loading. Returns null if schema can't be standalone-compiled. */
|
|
415
|
-
toStandalone(): string | null;
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Generate a self-contained module string with `validate`/`isValid` exports.
|
|
419
|
-
* The output has zero runtime dependency on ata-validator.
|
|
420
|
-
*/
|
|
421
|
-
toStandaloneModule(options?: { format?: 'esm' | 'cjs'; abortEarly?: boolean }): string | null;
|
|
422
|
-
|
|
423
414
|
/** Standard Schema V1 interface, compatible with Fastify, tRPC, TanStack, etc. */
|
|
424
415
|
readonly "~standard": StandardSchemaV1Props;
|
|
425
416
|
}
|
package/index.js
CHANGED
|
@@ -290,9 +290,9 @@ const ABORT_EARLY_RESULT = Object.freeze({
|
|
|
290
290
|
|
|
291
291
|
// `_CP_LEN_SOURCE`, the safe-regex embed, and the AOT helpers that consume them
|
|
292
292
|
// now live in `lib/aot.js` — keeping this file free of `fs`/`path`/`__dirname`
|
|
293
|
-
// references so a default import never touches disk. The
|
|
294
|
-
//
|
|
295
|
-
//
|
|
293
|
+
// references so a default import never touches disk. The static AOT methods
|
|
294
|
+
// further down lazily require `./lib/aot`, so they pay nothing until a user
|
|
295
|
+
// calls `bundleStandalone`/`bundle`/etc.
|
|
296
296
|
|
|
297
297
|
// Above this size, simdjson On Demand (selective field access) beats JSON.parse
|
|
298
298
|
// (which must materialize the full JS object tree). Buffer.from + NAPI ~2x faster.
|
|
@@ -1165,20 +1165,6 @@ class Validator {
|
|
|
1165
1165
|
}
|
|
1166
1166
|
}
|
|
1167
1167
|
|
|
1168
|
-
// --- AOT pre-compilation ---
|
|
1169
|
-
// The bodies of `toStandalone` and `toStandaloneModule` live in `lib/aot.js`
|
|
1170
|
-
// so this entry stays free of `fs`/`path`/`__dirname`. The lazy require runs
|
|
1171
|
-
// only on first call, never during a plain `import 'ata-validator'`. Browser
|
|
1172
|
-
// bundlers swap `lib/aot.js` with `lib/aot.browser.js`, which throws a
|
|
1173
|
-
// pointed error instead of attempting to read source from disk.
|
|
1174
|
-
toStandalone() {
|
|
1175
|
-
return require('./lib/aot').toStandalone(this);
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
toStandaloneModule(opts) {
|
|
1179
|
-
return require('./lib/aot').toStandaloneModule(this, opts);
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
1168
|
// Load a pre-compiled standalone module. Zero schema compilation.
|
|
1183
1169
|
// No NAPI, no native compile — pure JS. Startup in microseconds.
|
|
1184
1170
|
// Usage: const v = Validator.fromStandalone(require('./compiled.js'), schema, opts)
|
|
@@ -1504,5 +1490,5 @@ module.exports = {
|
|
|
1504
1490
|
renderPretty,
|
|
1505
1491
|
renderCompact,
|
|
1506
1492
|
renderJSON,
|
|
1507
|
-
attachSuggestions,
|
|
1493
|
+
attachSuggestions, // internal: used by the renderers; not public API
|
|
1508
1494
|
};
|
package/lib/aot-build.js
CHANGED
|
@@ -138,7 +138,7 @@ async function build(opts) {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
const schemaFile = path.relative(process.cwd(), input) || input;
|
|
141
|
-
const src =
|
|
141
|
+
const src = aot.toStandaloneModule(v, {
|
|
142
142
|
format,
|
|
143
143
|
abortEarly: !!opts.abortEarly,
|
|
144
144
|
source,
|
|
@@ -233,9 +233,9 @@ async function watch(opts, onReport) {
|
|
|
233
233
|
|
|
234
234
|
// AOT primitives also surface here so consumers can do
|
|
235
235
|
// import { bundleStandalone, toStandaloneModule, bundleCompact } from 'ata-validator/build'
|
|
236
|
-
// without poking at the Validator class. The
|
|
237
|
-
//
|
|
238
|
-
// programmatic alias for code that wants the build surface in one place.
|
|
236
|
+
// without poking at the Validator class. The class-bound statics (Validator.bundleStandalone,
|
|
237
|
+
// Validator.bundle, Validator.bundleCompact) remain available from the default entry; this
|
|
238
|
+
// build entry is the programmatic alias for code that wants the build surface in one place.
|
|
239
239
|
const aot = require('./aot');
|
|
240
240
|
|
|
241
241
|
function bundleStandalone(schemas, opts) {
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
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",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"rebuild": "cmake-js rebuild --target ata",
|
|
49
49
|
"prebuild": "pkg-prebuilds-copy --baseDir build/Release --source ata.node --name=ata --strip --napi_version=10",
|
|
50
50
|
"prebuild-all": "npm run prebuild -- --arch x64 && npm run prebuild -- --arch arm64",
|
|
51
|
-
"test": "node test.js && node tests/test_no_native.js && node tests/test_browser_nofs.js && node tests/test_browser_imports_guard.js && node tests/test_version_sync.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_additional_props_errors.js && node tests/test_id_anchor_refs.js && node tests/test_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.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_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_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",
|
|
51
|
+
"test": "node test.js && node tests/test_removed_aot_methods.js && node tests/test_no_native.js && node tests/test_browser_nofs.js && node tests/test_browser_imports_guard.js && node tests/test_version_sync.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_additional_props_errors.js && node tests/test_id_anchor_refs.js && node tests/test_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.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_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_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",
|
|
52
52
|
"bench:size": "node benchmark/bench_aot_size.mjs",
|
|
53
53
|
"test:suite": "node tests/run_suite.js",
|
|
54
54
|
"test:compat": "node tests/test_compat.js",
|
|
@@ -86,14 +86,14 @@
|
|
|
86
86
|
"license": "MIT",
|
|
87
87
|
"repository": {
|
|
88
88
|
"type": "git",
|
|
89
|
-
"url": "git+https://github.com/
|
|
89
|
+
"url": "git+https://github.com/ata-core/ata-validator.git"
|
|
90
90
|
},
|
|
91
91
|
"bugs": {
|
|
92
|
-
"url": "https://github.com/
|
|
92
|
+
"url": "https://github.com/ata-core/ata-validator/issues"
|
|
93
93
|
},
|
|
94
94
|
"homepage": "https://ata-validator.com",
|
|
95
95
|
"engines": {
|
|
96
|
-
"node": ">=
|
|
96
|
+
"node": ">=20.0.0"
|
|
97
97
|
},
|
|
98
98
|
"files": [
|
|
99
99
|
"index.js",
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
@@ -13,7 +13,7 @@ const fs = require('fs');
|
|
|
13
13
|
const path = require('path');
|
|
14
14
|
|
|
15
15
|
const root = path.resolve(__dirname, '..');
|
|
16
|
-
const src = fs.readFileSync(path.join(root, 'lib', 'safe-regex.js'), 'utf8');
|
|
16
|
+
const src = fs.readFileSync(path.join(root, 'lib', 'safe-regex.js'), 'utf8').replace(/\r\n/g, '\n');
|
|
17
17
|
|
|
18
18
|
const out =
|
|
19
19
|
"'use strict';\n\n" +
|