ata-validator 0.13.3 → 0.14.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 +33 -0
- package/index.d.ts +16 -19
- package/package.json +8 -3
- 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/check-prebuilds.js +54 -0
- package/prebuilds/darwin-arm64/ata-validator.node +0 -0
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
|
+
## 0.14.0 - 2026-05-16
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Generic `Validator<T>` with type predicate `isValidObject(data): data is T`. Pairs naturally with TypeBox, Zod-from-JSON-Schema, Valibot, or hand-written types over JSON Schema literals.
|
|
10
|
+
- `ValidationResult<T>` and `ValidateAndParseResult<T>` are discriminated unions. On the `valid: true` branch the parsed data is typed; on `valid: false` the `errors` array carries the diagnostic information.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Type-level only: accessing `result.data` (or `result.value` on `validateAndParse`) without first checking `result.valid` is now a TypeScript compile error. Runtime behavior is unchanged. The previous shape returned `undefined` in that position, so this surfaces an existing latent bug at compile time.
|
|
15
|
+
|
|
16
|
+
### Notes
|
|
17
|
+
|
|
18
|
+
- Pure `.d.ts` change. No JS, C++, AOT, or CLI behavior is affected. Bundle size unchanged. Runtime performance unchanged.
|
|
19
|
+
|
|
20
|
+
## 0.13.4 — 2026-05-14
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **macOS arm64 prebuild shipped with an invalid code signature.** The release workflow runs `pkg-prebuilds-copy --strip`, which on macOS runs `strip -Sx` on the addon. `strip` rewrites the Mach-O and invalidates the ad-hoc signature the linker applied, and it does not re-sign. arm64 macOS refuses to load unsigned code, so `require('ata-validator')` was killed with `SIGKILL (Code Signature Invalid)` the moment the binding loader called into the addon. Only `0.12.6` reached users this way because it was the one release published through CI rather than locally. The workflow now re-signs and verifies the macOS prebuild after `strip`, and `codesign --verify` gates the job so a broken signature cannot ship. Fixes #23.
|
|
25
|
+
- **macOS x64 prebuild was never produced.** The prebuild matrix used `macos-14` for the x64 leg, but `macos-14` runners are Apple Silicon only, so that leg built an arm64 binary mislabeled as x64 and no `darwin-x64` prebuild ever ended up in the tarball.
|
|
26
|
+
|
|
27
|
+
### Removed
|
|
28
|
+
|
|
29
|
+
- **macOS x64 prebuild.** `macos-13` GitHub runners, the only ones that build x64 natively, are no longer reliably available. Since no published version ever shipped a working `darwin-x64` prebuild, this is not a regression. Intel Mac users fall back to the JS engine, which still works, only the buffer APIs are slower.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **`prepublishOnly` now blocks tarballs missing platform prebuilds.** A local `npm publish` only carries the publisher's own platform, silently dropping every other prebuild. Publishing now fails unless all seven platform prebuilds are present, and when run on a Mac it also verifies the darwin code signatures.
|
|
34
|
+
|
|
5
35
|
## 0.13.3 — 2026-05-13
|
|
6
36
|
|
|
7
37
|
### Fixed
|
package/README.md
CHANGED
|
@@ -90,6 +90,39 @@ v.isValidParallel(ndjson); // bool[]
|
|
|
90
90
|
v.countValid(ndjson); // number
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
### Type-safe schemas
|
|
94
|
+
|
|
95
|
+
`Validator` is generic. Pair it with any schema authoring tool, or a hand-written type, to get TypeScript narrowing in your handler code.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { Type, type Static } from '@sinclair/typebox'
|
|
99
|
+
import { Validator } from 'ata-validator'
|
|
100
|
+
|
|
101
|
+
const UserSchema = Type.Object({
|
|
102
|
+
id: Type.Integer({ minimum: 1 }),
|
|
103
|
+
name: Type.String({ minLength: 1 }),
|
|
104
|
+
email: Type.String({ format: 'email' }),
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
type User = Static<typeof UserSchema>
|
|
108
|
+
|
|
109
|
+
const v = new Validator<User>(UserSchema)
|
|
110
|
+
|
|
111
|
+
if (v.isValidObject(data)) {
|
|
112
|
+
// data is narrowed to User, no cast needed
|
|
113
|
+
console.log(data.name)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const result = v.validate(data)
|
|
117
|
+
if (result.valid) {
|
|
118
|
+
// result.data is User
|
|
119
|
+
} else {
|
|
120
|
+
// result.errors: ValidationError[]
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The same pattern works with Zod-from-JSON-Schema, Valibot, or a hand-written `type User = {...}` alongside a JSON Schema literal. `Validator<T>` makes no library-specific assumption.
|
|
125
|
+
|
|
93
126
|
### Cross-Schema `$ref`
|
|
94
127
|
|
|
95
128
|
```javascript
|
package/index.d.ts
CHANGED
|
@@ -15,16 +15,13 @@ export interface ValidationError {
|
|
|
15
15
|
/** A user-supplied format checker. Receives the candidate value, returns true if valid. */
|
|
16
16
|
export type FormatChecker = (value: string) => boolean;
|
|
17
17
|
|
|
18
|
-
export
|
|
19
|
-
valid:
|
|
20
|
-
errors: ValidationError[];
|
|
21
|
-
}
|
|
18
|
+
export type ValidationResult<T = unknown> =
|
|
19
|
+
| { valid: true; data: T; errors: ValidationError[] }
|
|
20
|
+
| { valid: false; data?: never; errors: ValidationError[] };
|
|
22
21
|
|
|
23
|
-
export
|
|
24
|
-
valid:
|
|
25
|
-
value: unknown;
|
|
26
|
-
errors: ValidationError[];
|
|
27
|
-
}
|
|
22
|
+
export type ValidateAndParseResult<T = unknown> =
|
|
23
|
+
| { valid: true; value: T; errors: ValidationError[] }
|
|
24
|
+
| { valid: false; value: unknown; errors: ValidationError[] };
|
|
28
25
|
|
|
29
26
|
export interface ValidatorOptions {
|
|
30
27
|
coerceTypes?: boolean;
|
|
@@ -74,26 +71,26 @@ export interface StandaloneModule {
|
|
|
74
71
|
errFn: ((data: unknown, allErrors?: boolean) => ValidationResult) | null;
|
|
75
72
|
}
|
|
76
73
|
|
|
77
|
-
export class Validator {
|
|
74
|
+
export class Validator<T = unknown> {
|
|
78
75
|
constructor(schema: object | string, options?: ValidatorOptions);
|
|
79
76
|
|
|
80
77
|
/** Add a schema to the registry for cross-schema $ref resolution */
|
|
81
78
|
addSchema(schema: object): void;
|
|
82
79
|
|
|
83
80
|
/** Validate data, returns result with errors. Applies defaults, coerceTypes, removeAdditional. */
|
|
84
|
-
validate(data: unknown): ValidationResult
|
|
81
|
+
validate(data: unknown): ValidationResult<T>;
|
|
85
82
|
|
|
86
83
|
/** Fast boolean check via JS codegen or tier 0 interpreter. No error collection. */
|
|
87
|
-
isValidObject(data: unknown):
|
|
84
|
+
isValidObject(data: unknown): data is T;
|
|
88
85
|
|
|
89
86
|
/** Validate a JSON string. Uses simdjson fast path for large documents. */
|
|
90
|
-
validateJSON(jsonString: string): ValidationResult
|
|
87
|
+
validateJSON(jsonString: string): ValidationResult<T>;
|
|
91
88
|
|
|
92
89
|
/** Fast boolean check for a JSON string */
|
|
93
90
|
isValidJSON(jsonString: string): boolean;
|
|
94
91
|
|
|
95
92
|
/** Parse JSON with simdjson + validate against schema. Returns parsed value and validation result. Requires native addon. */
|
|
96
|
-
validateAndParse(jsonString: string | Buffer): ValidateAndParseResult
|
|
93
|
+
validateAndParse(jsonString: string | Buffer): ValidateAndParseResult<T>;
|
|
97
94
|
|
|
98
95
|
/** Ultra-fast buffer validation via native addon */
|
|
99
96
|
isValid(input: Buffer | Uint8Array | string): boolean;
|
|
@@ -128,7 +125,7 @@ export class Validator {
|
|
|
128
125
|
toStandaloneModule(options?: { format?: 'esm' | 'cjs'; abortEarly?: boolean }): string | null;
|
|
129
126
|
|
|
130
127
|
/** Load a pre-compiled standalone module. Zero schema compilation at startup. */
|
|
131
|
-
static fromStandalone(mod: StandaloneModule, schema: object | string, options?: ValidatorOptions): Validator
|
|
128
|
+
static fromStandalone<T = unknown>(mod: StandaloneModule, schema: object | string, options?: ValidatorOptions): Validator<T>;
|
|
132
129
|
|
|
133
130
|
/** Bundle multiple schemas into a single JS module string. Load with Validator.loadBundle(). */
|
|
134
131
|
static bundle(schemas: object[], options?: ValidatorOptions): string;
|
|
@@ -155,16 +152,16 @@ export class Validator {
|
|
|
155
152
|
}
|
|
156
153
|
|
|
157
154
|
/** One-shot validate: creates a Validator, validates data, returns result. */
|
|
158
|
-
export function validate(
|
|
155
|
+
export function validate<T = unknown>(
|
|
159
156
|
schema: object | string,
|
|
160
157
|
data: unknown
|
|
161
|
-
): ValidationResult
|
|
158
|
+
): ValidationResult<T>;
|
|
162
159
|
|
|
163
160
|
/** Fast compile: returns a validate function directly. WeakMap cached, second call with same schema is near-zero cost. */
|
|
164
|
-
export function compile(
|
|
161
|
+
export function compile<T = unknown>(
|
|
165
162
|
schema: object | string,
|
|
166
163
|
options?: ValidatorOptions
|
|
167
|
-
): (data: unknown) => ValidationResult
|
|
164
|
+
): (data: unknown) => ValidationResult<T>;
|
|
168
165
|
|
|
169
166
|
/** Parse JSON using simdjson (native addon) or JSON.parse (fallback). */
|
|
170
167
|
export function parseJSON(jsonString: string | Buffer): unknown;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Ultra-fast JSON Schema validator. 5x faster validation, 159,000x faster compilation. Works without native addon. Cross-schema $ref, Draft 2020-12 + Draft 7, V8-optimized JS codegen, simdjson, RE2, multi-core. Standard Schema V1 compatible.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -36,11 +36,12 @@
|
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"install": "node scripts/install.js",
|
|
39
|
+
"prepublishOnly": "node scripts/check-prebuilds.js",
|
|
39
40
|
"build": "cmake-js build --target ata",
|
|
40
41
|
"rebuild": "cmake-js rebuild --target ata",
|
|
41
42
|
"prebuild": "pkg-prebuilds-copy --baseDir build/Release --source ata.node --name=ata --strip --napi_version=10",
|
|
42
43
|
"prebuild-all": "npm run prebuild -- --arch x64 && npm run prebuild -- --arch arm64",
|
|
43
|
-
"test": "node test.js && node tests/test_no_native.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",
|
|
44
|
+
"test": "node test.js && node tests/test_no_native.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_typed_validator_runner.js",
|
|
44
45
|
"test:suite": "node tests/run_suite.js",
|
|
45
46
|
"test:compat": "node tests/test_compat.js",
|
|
46
47
|
"test:standard-schema": "node tests/test_standard_schema.js",
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"test:ts": "node tests/test_ts_gen.js",
|
|
49
50
|
"test:ts-corpus": "node tests/test_ts_corpus.js",
|
|
50
51
|
"test:ts-differential": "node tests/test_ts_differential.js",
|
|
52
|
+
"test:typed": "node tests/test_typed_validator_runner.js",
|
|
51
53
|
"bench": "node benchmark/bench_large.js",
|
|
52
54
|
"fuzz": "node tests/fuzz_differential.js",
|
|
53
55
|
"fuzz:long": "FUZZ_ITERATIONS=100000 node tests/fuzz_differential.js",
|
|
@@ -118,10 +120,13 @@
|
|
|
118
120
|
"yaml": "^2.0.0"
|
|
119
121
|
},
|
|
120
122
|
"peerDependenciesMeta": {
|
|
121
|
-
"yaml": {
|
|
123
|
+
"yaml": {
|
|
124
|
+
"optional": true
|
|
125
|
+
}
|
|
122
126
|
},
|
|
123
127
|
"devDependencies": {
|
|
124
128
|
"@sinclair/typebox": "^0.34.49",
|
|
129
|
+
"@types/node": "^25.8.0",
|
|
125
130
|
"cmake-js": "^8.0.0",
|
|
126
131
|
"mitata": "^1.0.34",
|
|
127
132
|
"typebox": "^1.1.7",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Refuse to publish a tarball that is missing platform prebuilds.
|
|
4
|
+
// Local `npm publish` only carries whatever the publisher's machine built,
|
|
5
|
+
// which silently drops every other platform's prebuild from the tarball.
|
|
6
|
+
// Publishing must go through the release workflow so all platforms are present.
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const cp = require('child_process');
|
|
11
|
+
|
|
12
|
+
const required = [
|
|
13
|
+
'ata-linux-x64',
|
|
14
|
+
'ata-linux-arm64',
|
|
15
|
+
'ata-linux-x64-musl',
|
|
16
|
+
'ata-linux-arm64-musl',
|
|
17
|
+
'ata-darwin-arm64',
|
|
18
|
+
'ata-win32-x64',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const root = path.resolve(__dirname, '..');
|
|
22
|
+
const missing = required.filter(
|
|
23
|
+
(dir) => !fs.existsSync(path.join(root, 'prebuilds', dir, 'node-napi-v10.node')),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (missing.length) {
|
|
27
|
+
console.error(
|
|
28
|
+
'\n[ata-validator] Refusing to publish, missing prebuilds:\n' +
|
|
29
|
+
missing.map((d) => ' - ' + d).join('\n') +
|
|
30
|
+
'\n\nPublish through the GitHub release workflow so every platform is built.\n',
|
|
31
|
+
);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// When publishing from a Mac, verify the darwin code signatures too. strip
|
|
36
|
+
// invalidates the linker signature, and an unsigned arm64 addon is killed on
|
|
37
|
+
// load. The release workflow re-signs and verifies, this is the local net.
|
|
38
|
+
if (process.platform === 'darwin') {
|
|
39
|
+
for (const dir of required) {
|
|
40
|
+
if (!dir.startsWith('ata-darwin-')) continue;
|
|
41
|
+
const f = path.join(root, 'prebuilds', dir, 'node-napi-v10.node');
|
|
42
|
+
const r = cp.spawnSync('codesign', ['--verify', f], { encoding: 'utf8' });
|
|
43
|
+
if (r.status !== 0) {
|
|
44
|
+
console.error(
|
|
45
|
+
'\n[ata-validator] Refusing to publish, invalid code signature:\n' +
|
|
46
|
+
' ' + f + '\n' + (r.stderr || '').trim() +
|
|
47
|
+
'\n\nRe-sign with: codesign --force --sign - "' + f + '"\n',
|
|
48
|
+
);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log('[ata-validator] prebuilds present for all ' + required.length + ' platforms');
|
|
Binary file
|