ata-validator 1.60.0 → 1.61.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/README.md +134 -6
- package/bin/ata.js +84 -0
- package/build.d.ts +29 -0
- package/build.mjs +2 -0
- package/compiled-bare-rich.d.ts +6 -0
- package/compiled-bare.d.ts +7 -0
- package/compiled-bare.js +5 -0
- package/compiled-bare.mjs +35 -0
- package/compiled-object.d.ts +11 -0
- package/compiled-object.js +6 -0
- package/compiled-object.mjs +3 -0
- package/compiled-plain.d.ts +16 -0
- package/compiled-plain.js +5 -0
- package/compiled-plain.mjs +3 -0
- package/compiled.d.ts +3 -1
- package/index.browser.mjs +2 -2
- package/index.bundle.mjs +2 -2
- package/index.d.ts +9 -0
- package/index.edge.mjs +2 -2
- package/index.js +48 -0
- package/index.mjs +1 -1
- package/index.node.mjs +1 -1
- package/lib/aot-build.js +81 -6
- package/lib/aot-impl.js +24 -21
- package/lib/bun-target.js +612 -0
- package/lib/codegen-engine.js +9 -3
- package/lib/combined-runtime.js +1 -1
- package/lib/compiled-bare-rich.js +54 -0
- package/lib/compiled-bare.js +44 -0
- package/lib/compiled-common.js +17 -2
- package/lib/compiled-defaults.browser.js +9 -0
- package/lib/compiled-defaults.js +8 -0
- package/lib/compiled-object.js +123 -0
- package/lib/compiled-plain.js +57 -0
- package/lib/compiled.js +2 -1
- package/lib/email-literal.js +29 -0
- package/lib/enrich-error.js +5 -1
- package/lib/error-codes.js +6 -76
- package/lib/formats-source.js +20 -3
- package/lib/formats.js +1 -1
- package/lib/js-compiler-errors.js +49 -10
- package/lib/js-compiler.js +92 -13
- package/lib/json-rejections.js +159 -0
- package/lib/native-codes.js +67 -0
- package/lib/native-message.js +8 -0
- package/lib/native.browser.js +11 -0
- package/lib/public-api.js +1 -0
- package/lib/rejections.js +13 -152
- package/lib/standard-schema.js +1 -1
- package/lib/tier0.js +1 -1
- package/lib/validator-core.js +46 -4
- package/lib/verify.js +386 -0
- package/lib/version.js +1 -1
- package/lite.js +1 -0
- package/lite.mjs +1 -1
- package/package.json +44 -9
package/README.md
CHANGED
|
@@ -12,11 +12,17 @@ JSON Schema validation that compiles for speed and still runs where code generat
|
|
|
12
12
|
|
|
13
13
|
## Who uses ata
|
|
14
14
|
|
|
15
|
-
Projects whose code depends on ata, from GitHub's dependency graph,
|
|
16
|
-
its
|
|
15
|
+
Projects whose code depends on ata, from GitHub's dependency graph, a framework that lists its
|
|
16
|
+
plugin, a form library that ships its resolver, and one company whose use is not public code,
|
|
17
|
+
with what each does with it:
|
|
17
18
|
|
|
19
|
+
- [Trendyol](https://github.com/Trendyol) validates configuration with ata in Puzzle, its
|
|
20
|
+
internal config tooling. The package is internal, so it is not in the public dependency
|
|
21
|
+
graph; this line rests on its maintainer.
|
|
18
22
|
- [Socket](https://github.com/SocketDev) uses ata, compiled ahead of time, in the shared build
|
|
19
23
|
tooling of its repositories.
|
|
24
|
+
- [React Hook Form](https://github.com/react-hook-form/resolvers) ships an ata resolver in
|
|
25
|
+
`@hookform/resolvers` (`@hookform/resolvers/ata-validator`), beside its other validators.
|
|
20
26
|
- [Fastify](https://fastify.dev/ecosystem/) lists the
|
|
21
27
|
[`fastify-ata`](https://github.com/ata-core/fastify-ata) plugin in its ecosystem.
|
|
22
28
|
- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form) ships an ata
|
|
@@ -48,7 +54,14 @@ resolves to an entry without the code generator through the `workerd` and `edge-
|
|
|
48
54
|
conditions: the same names and answers, and a Worker bundled by wrangler goes from 179.1 to
|
|
49
55
|
70.4 KiB gzipped.
|
|
50
56
|
|
|
51
|
-
In a browser
|
|
57
|
+
In a browser, compile with the bundler plugin. [`@ata-project/unplugin`](https://github.com/ata-core/unplugin-ata)
|
|
58
|
+
turns each `new Validator(schema)` whose schema it can read at build time into a compiled
|
|
59
|
+
validator that gives the same answers, and the runtime stays out of the page. A form with two
|
|
60
|
+
validators, one reading errors and one asking only for a verdict, bundles to 10.7 KB gzipped,
|
|
61
|
+
or 3.1 KB with `richErrors: false` on the one that reads errors, against 53.2 KB for the same
|
|
62
|
+
code on the runtime (esbuild, minified, the runtime with code splitting).
|
|
63
|
+
|
|
64
|
+
Without the plugin, the code generator is still not part of the page. Every schema starts on the
|
|
52
65
|
interpreted engine, which gives the same answers, and a validator called a thousand times within
|
|
53
66
|
a second loads the generator in the background, through a dynamic import that Vite, webpack and
|
|
54
67
|
Rollup put in a chunk of their own, and is rebuilt on generated code when the page is idle. A
|
|
@@ -68,7 +81,7 @@ details, and what Deno Deploy's refusal of dynamic code means for it, are in
|
|
|
68
81
|
|
|
69
82
|
Those four now agree with `validate()` on every case of the official suite, 3365 across three dialects. The native walker behind them does not handle every shape (`contains`, `unevaluatedProperties`, `patternProperties`, tuple `items`, cross-document `$ref`, a few formats), so for schemas using one of those the buffer APIs parse the bytes and answer through `validate()`; the list is in `lib/buffer-gate.js`. Typical request schemas stay on the zero-copy path. `npm test` holds the disagreement count at zero.
|
|
70
83
|
|
|
71
|
-
Where `new Function` is refused altogether, on Cloudflare Workers, Deno Deploy or under a strict Content-Security-Policy, ata drops to the interpreted engine and scores the same 1301 of 1301 with code generation blocked. No flags, and on Workers no `nodejs_compat` either. See [docs/edge-runtimes.md](docs/edge-runtimes.md).
|
|
84
|
+
Where `new Function` is refused altogether, on Cloudflare Workers, Deno Deploy or under a strict Content-Security-Policy, ata drops to the interpreted engine and scores the same 1301 of 1301 with code generation blocked. No flags, and on Workers no `nodejs_compat` either. See [docs/edge-runtimes.md](docs/edge-runtimes.md). Where generated code runs but slowly, as in an ahead-of-time compiled Bun executable, a module from `ata build` is plain JavaScript that imports nothing and calls no `new Function`: on Bun 1.4.0, import plus a first validation takes 0.66 ms with such a module against 10.70 ms with the runtime compiler (medians of 21 runs). [docs/proof-no-code-generation.md](docs/proof-no-code-generation.md) runs one schema in five of these places, Workers and a CSP page included, and shows the same answers from each.
|
|
72
85
|
|
|
73
86
|
Node has a switch for exactly that environment, so this takes thirty seconds to check for yourself, on ata or on whatever you use today:
|
|
74
87
|
|
|
@@ -643,7 +656,24 @@ checks takes 1.12 ms where the runtime takes 6.63 ms (median of 15 fresh process
|
|
|
643
656
|
SchemaStore's 977 schemas, 725 can be compiled away; the rest stay on the runtime. Where the code only calls `isValidObject()` or `isValidJSON()`, the plugin uses
|
|
644
657
|
`fromCompiledVerdict()` from `ata-validator/compiled-verdict` instead, which carries no error pipeline: a
|
|
645
658
|
small app that only asks for a boolean bundles to 2.6 KB gzipped, against 12.1 KB with the full wrapper, on
|
|
646
|
-
ata 1.40.0 with `@ata-project/unplugin` 0.5.0.
|
|
659
|
+
ata 1.40.0 with `@ata-project/unplugin` 0.5.0. Where it reads errors but never validates JSON text, the plugin
|
|
660
|
+
uses `fromCompiledObject()` from `ata-validator/compiled-object`, the full wrapper without
|
|
661
|
+
`validateJSON()` and `isValidJSON()` and the position map behind them; and the wrappers fill
|
|
662
|
+
defaults with the compiled module's own `applyDefaults`. A form app with one validator that reads
|
|
663
|
+
errors and one that asks for a boolean went from 16.7 to 13.9 KB gzipped (esbuild, minified),
|
|
664
|
+
ata 1.61.0 against master with `@ata-project/unplugin` 0.11.0 and the change. The wrappers on
|
|
665
|
+
their own: full 13.8 to 12.8 KB, without JSON entry points 10.9, verdict only 2.7 to 1.6.
|
|
666
|
+
A validator built with `{ richErrors: false }` is compiled away as well: the module writes its
|
|
667
|
+
errors in that plain shape (`compiledModuleFor(schema, { plainErrors: true })`) and
|
|
668
|
+
`fromCompiledPlain()` from `ata-validator/compiled-plain` hands them out as they are, with no
|
|
669
|
+
error pipeline in the bundle, 2.6 KB gzipped for the wrapper. Where the plugin sees a
|
|
670
|
+
validator only ever called (`v.validate(x)`, `v.isValidObject(x)`), never handed to other code,
|
|
671
|
+
it uses the bare wrappers of `ata-validator/compiled-bare` instead, which leave out Standard
|
|
672
|
+
Schema and the extension hook nothing can reach there: 0.3 KB gzipped for both, and
|
|
673
|
+
`ata-validator/compiled-bare-rich` for one that reads ata's own errors. The same form app
|
|
674
|
+
bundles to 10.7 KB gzipped, or 3.1 KB with `richErrors: false` on the validator that reads errors. The errors
|
|
675
|
+
then carry `keyword`, `instancePath`, `schemaPath`, `params` and `message`, as that option has
|
|
676
|
+
always given them, without `received`, `suggestion` or `docUrl`.
|
|
647
677
|
|
|
648
678
|
Programmatic API if you prefer to script it:
|
|
649
679
|
|
|
@@ -667,6 +697,103 @@ first request, so counting only registration would overstate the gap. The first
|
|
|
667
697
|
here comes in the same tick as setup; a server that listens first has the code generator
|
|
668
698
|
loaded by then. Reproduce with `node benchmark/bench_fastify_boot.mjs`.
|
|
669
699
|
|
|
700
|
+
A server that listens first also gets the engine warmed: once the event loop is free, if a
|
|
701
|
+
validator was built and not yet called, ata runs one check of a small schema, accepted and
|
|
702
|
+
rejected, so that V8 compiles the generator's functions and the error builders then rather
|
|
703
|
+
than on the first request. Measured on a four-field schema with the generator already
|
|
704
|
+
loaded: the first verdict 3.1 to 3.4 ms without it, 0.5 to 0.6 with it; the first error
|
|
705
|
+
list 6.7 against 0.8; a second route's first verdict 0.9 to 1.0 against 0.7 to 0.9. It costs
|
|
706
|
+
the process 1.5 to 2 ms of CPU once. A script that builds a validator and checks in the
|
|
707
|
+
same tick never runs it, and the timer is unref'd, so a finished script does not stay for
|
|
708
|
+
it; `ATA_NO_WARM=1` turns it off.
|
|
709
|
+
|
|
710
|
+
### Proving the build (`ata verify`)
|
|
711
|
+
|
|
712
|
+
A module written at build time is only a good idea if it answers as the
|
|
713
|
+
runtime it replaced. `ata verify` checks that on the project's own schemas:
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
npx ata verify 'schemas/*.json' --samples test/fixtures
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
For each schema it loads the module `ata build` wrote beside it, makes
|
|
720
|
+
documents from the schema (200 by default, half of them with one rule broken,
|
|
721
|
+
then a document on either side of each bound the schema states),
|
|
722
|
+
reads the project's sample documents (JSON files, JSON Lines, or a directory
|
|
723
|
+
of them), and has both the module and a `Validator` built from the schema now
|
|
724
|
+
answer every one. Verdicts and error lists have to agree; a module whose
|
|
725
|
+
schema hash no longer matches the schema is reported stale. The exit code is
|
|
726
|
+
non-zero on any disagreement, stale module or missing module, so the command
|
|
727
|
+
works as a CI step. This is the check that found the two silent divergences
|
|
728
|
+
fixed in 1.59.0 and 1.60.0, now in a form a project can run on every change.
|
|
729
|
+
It does not run the `.bun.ts` target, which needs Bun's compiler.
|
|
730
|
+
|
|
731
|
+
### Bun, compiled ahead of time
|
|
732
|
+
|
|
733
|
+
Bun's ahead-of-time compiler (`bun build --compile --aot`, an open pull
|
|
734
|
+
request as of October 2026) runs code that a library hands to `new Function`
|
|
735
|
+
through an interpreter. Measured with its pull request build on one schema
|
|
736
|
+
and 1024 parsed documents, nanoseconds per document (`benchmark/proof/aot`):
|
|
737
|
+
|
|
738
|
+
| | JIT | ahead of time |
|
|
739
|
+
|---|---|---|
|
|
740
|
+
| a module from `ata build --target bun` | 25 | 24 |
|
|
741
|
+
| `new Validator(schema)`, generated code | 28 | 492 |
|
|
742
|
+
| `new Validator(schema)`, interpreted engine | 52 | 80 |
|
|
743
|
+
|
|
744
|
+
So, in order of preference:
|
|
745
|
+
|
|
746
|
+
1. Compile the schema at build time. `@ata-project/unplugin/bun` does it in
|
|
747
|
+
`Bun.build`, including `Bun.build({ compile })`; `ata build` writes the
|
|
748
|
+
module by hand. The module is plain JavaScript and compiles with the
|
|
749
|
+
program: 24 ns, the same errors as the runtime.
|
|
750
|
+
2. Where the runtime `Validator` stays, let it take the interpreted engine.
|
|
751
|
+
It does so by itself when Bun reports `Bun.isAOT`, when the executable is
|
|
752
|
+
built with `--disallow-code-generation-from-strings` (the program then
|
|
753
|
+
counts as closed for the compiler, too), or when `ATA_ENGINE=interpreter`
|
|
754
|
+
is set: 80 ns against 492 for the generated code there.
|
|
755
|
+
3. Write the module for the compiler. `ata build schema.json --target bun`
|
|
756
|
+
writes it with a closed object's keys read once and compared with the
|
|
757
|
+
declared list in order (on a ten-item order with 1024 distinct documents,
|
|
758
|
+
10% of them invalid, 105 to 107 ns under the compiler against 223 for the
|
|
759
|
+
form V8 gets; on V8 the module keeps for...in, on Bun's JIT a plain count,
|
|
760
|
+
each the cheaper form there), and answers a rejection with the one-pass
|
|
761
|
+
error function (189 ns with the error list on that order, against 724
|
|
762
|
+
with the older collector), the form every other build takes only with
|
|
763
|
+
`--one-pass` since it is 20% larger gzipped. Beside the module it writes
|
|
764
|
+
`schema.compiled.bun.ts`: the schema as a TypeScript type (kinds,
|
|
765
|
+
properties and which are required, items and fixed tuples, literals,
|
|
766
|
+
local definitions as named types), `validate` and `isValid` with that
|
|
767
|
+
type on them, and `parse(text)`, which declares the type where it parses
|
|
768
|
+
and has the module check the content. Every check is the module's, and
|
|
769
|
+
the file is a type for the program, not a faster path: on that order,
|
|
770
|
+
with the pull request build of 2026-10-25, `isValid` 118 ns through the
|
|
771
|
+
file against 118 to 121 through the module, `parse` 564 to 574 against
|
|
772
|
+
570 to 578 for a plain parse and the module, and reading the parsed
|
|
773
|
+
object after a typed parse 593 to 595 against 587 to 591 after a plain
|
|
774
|
+
one. The file is for executables built with
|
|
775
|
+
`--aot`; a project points that compiler at it with an `"aot"` condition
|
|
776
|
+
in its `package.json` `imports`, which nothing else reads:
|
|
777
|
+
|
|
778
|
+
```json
|
|
779
|
+
{ "imports": { "#schemas/*": { "aot": "./schemas/*.bun.ts", "default": "./schemas/*.js" } } }
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
A schema no type can be written for (a remote `$ref`, `$dynamicRef`, a
|
|
783
|
+
root the type says nothing about) gets a warning and the plain module
|
|
784
|
+
alone.
|
|
785
|
+
|
|
786
|
+
The pull request carried its own typed validator until 2026-10-25, and
|
|
787
|
+
`--target bun` wrote the schema's rules as a type for it; it left the pull
|
|
788
|
+
request to return as a change of its own. `docs/API.md` has what ata keeps
|
|
789
|
+
for it. A schema's `pattern` is a `new RegExp` at run time in the runtime
|
|
790
|
+
`Validator`, which that compiler runs through its regular expression
|
|
791
|
+
interpreter; the module writes each pattern as a literal, which it compiles.
|
|
792
|
+
`--aot` makes TypeScript errors fatal; ata's declarations say `message?:
|
|
793
|
+
string` on an error, so read it as such. The numbers are from the pull
|
|
794
|
+
request build of 2026-10-24 on one machine and will be run again when the
|
|
795
|
+
compiler ships.
|
|
796
|
+
|
|
670
797
|
### Standard Schema V1
|
|
671
798
|
|
|
672
799
|
```javascript
|
|
@@ -745,9 +872,10 @@ Copy-paste recipes for the common frameworks. Most need 10-20 lines of glue. See
|
|
|
745
872
|
| Vite (build-time compile) | dedicated plugin | [`ata-vite`](https://github.com/ata-core/ata-vite), the Vite entry of the plugin above |
|
|
746
873
|
| Next.js (build-time compile) | webpack entry of the plugin above | `@ata-project/unplugin/webpack` in `next.config.js` |
|
|
747
874
|
| Hono | async middleware | [docs/integrations/hono.md](docs/integrations/hono.md) |
|
|
748
|
-
| Elysia |
|
|
875
|
+
| Elysia | Standard Schema V1 in the `body` slot | [docs/integrations/elysia.md](docs/integrations/elysia.md) |
|
|
749
876
|
| tRPC | Standard Schema V1 input | [docs/integrations/trpc.md](docs/integrations/trpc.md) |
|
|
750
877
|
| TanStack Form | Standard Schema V1 validator | [docs/integrations/tanstack-form.md](docs/integrations/tanstack-form.md) |
|
|
878
|
+
| React Hook Form | resolver | [`@hookform/resolvers/ata-validator`](https://github.com/react-hook-form/resolvers/tree/master/ata-validator) |
|
|
751
879
|
| Express | sync middleware | [docs/integrations/express.md](docs/integrations/express.md) |
|
|
752
880
|
| Koa | async ctx middleware | [docs/integrations/koa.md](docs/integrations/koa.md) |
|
|
753
881
|
| NestJS | validation pipe | [docs/integrations/nestjs.md](docs/integrations/nestjs.md) |
|
package/bin/ata.js
CHANGED
|
@@ -13,6 +13,15 @@ Usage:
|
|
|
13
13
|
ata build <glob>... [options] Compile a project's schemas (glob pattern) per file.
|
|
14
14
|
ata validate <schema> <data> [options] Validate a JSON data file against a schema.
|
|
15
15
|
ata migrate [dir] [options] Report what switching from ajv would change; --write applies it.
|
|
16
|
+
ata verify <glob>... [options] Check that each schema's compiled module answers as the runtime
|
|
17
|
+
does, on generated documents and the project's samples.
|
|
18
|
+
|
|
19
|
+
Verify options:
|
|
20
|
+
--generate <n> Documents made from each schema, half with one rule broken. Default: 200
|
|
21
|
+
--samples <path> A JSON, JSON Lines file or a directory of them, checked too (repeatable)
|
|
22
|
+
--seed <n> Seed for the generated documents. Default: 1
|
|
23
|
+
--json Report as JSON
|
|
24
|
+
--out-dir, --suffix, --format Where the modules are, as given to ata build
|
|
16
25
|
|
|
17
26
|
Validate options:
|
|
18
27
|
--pretty Render errors with source frames (default on TTY)
|
|
@@ -65,6 +74,9 @@ Build options:
|
|
|
65
74
|
--cache-file <path> Cache file for incremental builds (default: cache disabled)
|
|
66
75
|
--max-size <bytes> Fail build if any compiled module exceeds this gzipped size
|
|
67
76
|
--strict Treat any AOT-incompatible schema as a build error (default: skip + warn)
|
|
77
|
+
--target bun Write every module for Bun's ahead-of-time compiler, and beside
|
|
78
|
+
each a .bun.ts with the schema as a TypeScript type and a typed
|
|
79
|
+
parse(text); the plain module answers every check
|
|
68
80
|
--strict-schema Fail the build on schema authoring mistakes: unknown
|
|
69
81
|
keywords (with a spelling suggestion), keywords the
|
|
70
82
|
node's type makes inert, unresolvable local $refs,
|
|
@@ -117,6 +129,11 @@ function parseArgs(argv) {
|
|
|
117
129
|
if (a === '--check') { out.opts.check = true; continue; }
|
|
118
130
|
if (a === '--strict') { out.opts.strict = true; continue; }
|
|
119
131
|
if (a === '--strict-schema') { out.opts.strictSchema = true; continue; }
|
|
132
|
+
if (a === '--target') { out.opts.target = argv[++i]; continue; }
|
|
133
|
+
if (a === '--generate') { out.opts.generate = Number(argv[++i]); continue; }
|
|
134
|
+
if (a === '--samples') { (out.opts.samples = out.opts.samples || []).push(argv[++i]); continue; }
|
|
135
|
+
if (a === '--seed') { out.opts.seed = Number(argv[++i]); continue; }
|
|
136
|
+
if (a === '--json') { out.opts.json = true; continue; }
|
|
120
137
|
if (a === '--out-dir') { out.opts.outDir = argv[++i]; continue; }
|
|
121
138
|
if (a === '--suffix') { out.opts.suffix = argv[++i]; continue; }
|
|
122
139
|
if (a === '--cache-file') { out.opts.cacheFile = argv[++i]; continue; }
|
|
@@ -239,6 +256,15 @@ function cmdCompile(args) {
|
|
|
239
256
|
|
|
240
257
|
const { Validator } = require('..');
|
|
241
258
|
const aot = require('../lib/aot');
|
|
259
|
+
// `--target bun`: the module is written for JavaScriptCore, the engine the
|
|
260
|
+
// executable the target is for runs on.
|
|
261
|
+
if (args.opts.target === 'bun') {
|
|
262
|
+
require('../lib/js-compiler').setTargetEngine('jsc-aot');
|
|
263
|
+
// The executable's module answers rejections with the one-pass error
|
|
264
|
+
// function and carries no schema-source frames unless asked for.
|
|
265
|
+
if (args.opts.onePass === undefined) args.opts.onePass = true;
|
|
266
|
+
if (args.opts.source === undefined) args.opts.source = false;
|
|
267
|
+
}
|
|
242
268
|
let v;
|
|
243
269
|
try {
|
|
244
270
|
v = new Validator(schema);
|
|
@@ -277,6 +303,25 @@ function cmdCompile(args) {
|
|
|
277
303
|
const sizeBytes = Buffer.byteLength(src, 'utf8');
|
|
278
304
|
process.stdout.write(`ata: compiled ${input} -> ${output} (${sizeBytes.toLocaleString()} bytes, ${format}${abortEarly ? ', abort-early' : ''})\n`);
|
|
279
305
|
|
|
306
|
+
if (args.opts.target !== undefined) {
|
|
307
|
+
if (args.opts.target !== 'bun') {
|
|
308
|
+
reportCompileError(input, `--target must be bun (got ${JSON.stringify(args.opts.target)})`);
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
const { writeBunTarget, Declined } = require('../lib/bun-target');
|
|
312
|
+
const tn = (args.opts.name || path.basename(input, path.extname(input)).replace(/[^A-Za-z0-9_]/g, '_').replace(/^([a-z])/, (m) => m.toUpperCase())) || 'Data';
|
|
313
|
+
try {
|
|
314
|
+
const w = writeBunTarget({ schema, input, output, typeName: tn });
|
|
315
|
+
process.stdout.write(`ata: bun target -> ${w.bunPath} (for bun build --compile --aot)\n`);
|
|
316
|
+
} catch (e) {
|
|
317
|
+
if (!(e instanceof Declined)) throw e;
|
|
318
|
+
// No type can be written; the plain module stands alone.
|
|
319
|
+
const msg = `--target bun: ${e.message}; the plain module stands alone`;
|
|
320
|
+
if (args.opts.strict) { reportCompileError(input, msg); process.exit(1); }
|
|
321
|
+
process.stderr.write(`ata: warning: ${input}: ${msg}\n`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
280
325
|
// Emit paired declaration file unless --no-types.
|
|
281
326
|
// TypeScript resolution: .mjs -> .d.mts, .cjs -> .d.cts, .js -> .d.ts.
|
|
282
327
|
const emitTypes = args.opts.types !== false;
|
|
@@ -298,6 +343,10 @@ function cmdCompile(args) {
|
|
|
298
343
|
}
|
|
299
344
|
|
|
300
345
|
function cmdBuild(args) {
|
|
346
|
+
if (args.opts.target !== undefined && args.opts.target !== 'bun') {
|
|
347
|
+
process.stderr.write(`error: --target must be bun (got ${JSON.stringify(args.opts.target)})\n`);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
301
350
|
if (args._.length === 0) {
|
|
302
351
|
process.stderr.write('error: missing <glob>\n\n');
|
|
303
352
|
usage();
|
|
@@ -323,6 +372,7 @@ function cmdBuild(args) {
|
|
|
323
372
|
check: !!args.opts.check,
|
|
324
373
|
maxSize: args.opts.maxSize,
|
|
325
374
|
strict: !!args.opts.strict,
|
|
375
|
+
target: args.opts.target,
|
|
326
376
|
types: args.opts.types,
|
|
327
377
|
cacheFile: args.opts.cacheFile,
|
|
328
378
|
// Forward the explicit user choice (true / false / undefined). The
|
|
@@ -337,6 +387,8 @@ function cmdBuild(args) {
|
|
|
337
387
|
}
|
|
338
388
|
for (const c of report.compiled) {
|
|
339
389
|
process.stdout.write(`ata: ${c.input} -> ${c.output} (${c.bytes.toLocaleString()} bytes${c.errors === 'compact' ? ', shared errors' : c.errors === 'schema' ? ', schema module' : ''})\n`);
|
|
390
|
+
for (const t of (report.bunTargets || []).filter((t) => t.input === c.input)) process.stdout.write(`ata: bun target -> ${t.output} (for bun build --compile --aot)\n`);
|
|
391
|
+
for (const d of (report.bunDeclined || []).filter((d) => d.input === c.input)) process.stderr.write(`ata: warning: ${d.input}: ${d.reason}\n`);
|
|
340
392
|
}
|
|
341
393
|
if (report.runtime) {
|
|
342
394
|
process.stdout.write(`ata: error runtime -> ${report.runtime.output} (${report.runtime.bytes.toLocaleString()} bytes, shared by the modules above)\n`);
|
|
@@ -408,6 +460,33 @@ function cmdBuild(args) {
|
|
|
408
460
|
});
|
|
409
461
|
}
|
|
410
462
|
|
|
463
|
+
function cmdVerify (args) {
|
|
464
|
+
if (args._.length === 0) {
|
|
465
|
+
process.stderr.write('error: missing <glob>\n\n');
|
|
466
|
+
usage();
|
|
467
|
+
process.exit(1);
|
|
468
|
+
}
|
|
469
|
+
const buildLib = require('../lib/aot-build');
|
|
470
|
+
const { verifyOne, renderReport, ok } = require('../lib/verify');
|
|
471
|
+
const format = args.opts.format || 'esm';
|
|
472
|
+
(async () => {
|
|
473
|
+
const inputs = await buildLib.expandGlobs(args._);
|
|
474
|
+
if (inputs.length === 0) {
|
|
475
|
+
process.stderr.write(`error: no schema files match ${args._.join(' ')}\n`);
|
|
476
|
+
process.exit(1);
|
|
477
|
+
}
|
|
478
|
+
const reports = [];
|
|
479
|
+
for (const input of inputs) {
|
|
480
|
+
let schema;
|
|
481
|
+
try { schema = buildLib.parseSchemaFile(input); } catch (e) { reports.push({ schema: input, module: '', error: e.message, documents: 0, agree: 0, disagreements: [] }); continue; }
|
|
482
|
+
const moduleFile = buildLib.outputPathFor(input, { format, outDir: args.opts.outDir, suffix: args.opts.suffix });
|
|
483
|
+
reports.push(await verifyOne({ schemaFile: input, moduleFile, schema, generate: Number.isFinite(args.opts.generate) ? args.opts.generate : 200, seed: Number.isFinite(args.opts.seed) ? args.opts.seed : 1, samples: args.opts.samples || [] }));
|
|
484
|
+
}
|
|
485
|
+
process.stdout.write(renderReport(reports, { json: !!args.opts.json }) + '\n');
|
|
486
|
+
process.exit(reports.every(ok) ? 0 : 1);
|
|
487
|
+
})().catch((e) => { process.stderr.write(`error: ${e.message}\n`); process.exit(1); });
|
|
488
|
+
}
|
|
489
|
+
|
|
411
490
|
function cmdValidate (args) {
|
|
412
491
|
if (args._.length < 2) {
|
|
413
492
|
process.stderr.write('error: ata validate <schema> <data-file>\n');
|
|
@@ -508,6 +587,11 @@ function main() {
|
|
|
508
587
|
return;
|
|
509
588
|
}
|
|
510
589
|
|
|
590
|
+
if (cmd === 'verify') {
|
|
591
|
+
cmdVerify(args);
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
|
|
511
595
|
if (cmd === 'migrate') {
|
|
512
596
|
const { migrate, formatReport } = require('../lib/migrate');
|
|
513
597
|
const result = migrate(args._[0] || '.', { write: !!args.opts.write });
|
package/build.d.ts
CHANGED
|
@@ -204,3 +204,32 @@ export function compiledModuleFor(schema: unknown, opts?: { format?: 'esm' | 'cj
|
|
|
204
204
|
* ata-validator 1.37.0, where only calls without options can be.
|
|
205
205
|
*/
|
|
206
206
|
export const compiledOptions: readonly string[];
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The Bun target, for a build plugin: the schema as a TypeScript type and the
|
|
210
|
+
* `.bun.ts` module `ata build --target bun` writes beside a compiled module.
|
|
211
|
+
* With `tags: true` the type carries Bun's `Schema` tags and `residual` holds
|
|
212
|
+
* the schema of every rule the tagged type does not carry, the split made for
|
|
213
|
+
* Bun's `validate<T>`, which left the compiler's pull request on 2026-10-25
|
|
214
|
+
* and is to return as a change of its own; without tags `residual` is null.
|
|
215
|
+
*/
|
|
216
|
+
export const bunTarget: {
|
|
217
|
+
schemaToBunType(schema: unknown, opts?: { name?: string; aliasPrefix?: string; tags?: boolean; assertFormat?: boolean }): { name: string; type: string; aliases: Array<[string, string]>; residual: unknown | null; carried: string[] };
|
|
218
|
+
toBunModule(args: { schemaFile: string; moduleImport: string; typeName: string; typeSource: string; aliases: Array<[string, string]> }): string;
|
|
219
|
+
writeBunTarget(args: { schema: unknown; input: string; output: string; typeName: string }): { bunPath: string; definitions: number; carried: number };
|
|
220
|
+
Declined: new (reason: string, pointer: string) => Error & { reason: string; pointer: string };
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/** `ata verify` as functions: a compiled module held against the runtime on generated documents and samples. */
|
|
224
|
+
export const verify: {
|
|
225
|
+
verifyOne(args: { schemaFile: string; moduleFile: string; schema: unknown; generate?: number; seed?: number; samples?: string[] }): Promise<VerifyReport>;
|
|
226
|
+
verifySource(schema: unknown, src: string, opts?: { name?: string; format?: 'esm' | 'cjs'; generate?: number; seed?: number; samples?: string[] }): Promise<VerifyReport>;
|
|
227
|
+
generate(schema: unknown, count: number, seed: number): unknown[];
|
|
228
|
+
renderReport(reports: VerifyReport[], opts?: { json?: boolean }): string;
|
|
229
|
+
ok(report: VerifyReport): boolean;
|
|
230
|
+
};
|
|
231
|
+
export interface VerifyReport {
|
|
232
|
+
schema: string; module: string; documents: number; generated: number; samples: number; valid: number; agree: number;
|
|
233
|
+
disagreements: Array<{ source: string; document: string; runtime: string; module: string; runtimeIsValid: boolean; moduleIsValid: boolean } | { more: number }>;
|
|
234
|
+
stale: boolean; missing: boolean; ataVersion: string | null; error: string | null;
|
|
235
|
+
}
|
package/build.mjs
CHANGED
|
@@ -12,5 +12,7 @@ export const schemaHash = mod.schemaHash;
|
|
|
12
12
|
export const compiledEligible = mod.compiledEligible;
|
|
13
13
|
export const compiledSchemaFor = mod.compiledSchemaFor;
|
|
14
14
|
export const compiledModuleFor = mod.compiledModuleFor;
|
|
15
|
+
export const bunTarget = mod.bunTarget;
|
|
16
|
+
export const verify = mod.verify;
|
|
15
17
|
export const compiledOptions = mod.compiledOptions;
|
|
16
18
|
export default mod;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// ata-validator/compiled-bare-rich: the compiled-bare wrapper for a validator
|
|
2
|
+
// a bundler plugin sees only called, that reads ata's own errors.
|
|
3
|
+
import type { ValidationResult } from './index.js';
|
|
4
|
+
import type { CompiledModule } from './compiled.js';
|
|
5
|
+
|
|
6
|
+
export function bareRich<T = unknown>(mod: CompiledModule, schema: object | boolean, useDefaults?: boolean): { validate(data: unknown): ValidationResult<T>; isValidObject(data: unknown): data is T };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// ata-validator/compiled-bare: the smallest compiled-module wrappers, for a
|
|
2
|
+
// validator a bundler plugin sees used only through direct method calls.
|
|
3
|
+
import type { ValidationResult } from './index.js';
|
|
4
|
+
import type { CompiledModule } from './compiled.js';
|
|
5
|
+
|
|
6
|
+
export function bareVerdict(mod: CompiledModule, useDefaults?: boolean): { isValidObject(data: unknown): boolean };
|
|
7
|
+
export function barePlain<T = unknown>(mod: CompiledModule, useDefaults?: boolean): { validate(data: unknown): ValidationResult<T>; isValidObject(data: unknown): data is T };
|
package/compiled-bare.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// ata-validator/compiled-bare as an ES module of its own rather than a
|
|
2
|
+
// re-export of the CommonJS file: a bundler then has no CommonJS interop to
|
|
3
|
+
// add, which was more than half of the bundled size (662 to 315 bytes
|
|
4
|
+
// gzipped). The same functions as lib/compiled-bare.js;
|
|
5
|
+
// tests/test_compiled_bare.js holds the two to the same answers.
|
|
6
|
+
|
|
7
|
+
const EMPTY_ERRORS = Object.freeze([]);
|
|
8
|
+
const VERDICT_DISAGREES = Object.freeze({
|
|
9
|
+
valid: false,
|
|
10
|
+
errors: Object.freeze([Object.freeze({ keyword: 'validation', instancePath: '', schemaPath: '#', params: Object.freeze({}), message: 'schema validation failed' })]),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
function verdictOf(mod, useDefaults) {
|
|
14
|
+
const fill = useDefaults !== false && typeof mod.applyDefaults === 'function' ? mod.applyDefaults : null;
|
|
15
|
+
return fill ? (d) => { fill(d); return mod.isValid(d); } : mod.isValid;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function bareVerdict(mod, useDefaults) {
|
|
19
|
+
return { isValidObject: verdictOf(mod, useDefaults) };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function barePlain(mod, useDefaults) {
|
|
23
|
+
const isValid = verdictOf(mod, useDefaults);
|
|
24
|
+
const errFn = mod.validate;
|
|
25
|
+
return {
|
|
26
|
+
validate(data) {
|
|
27
|
+
if (isValid(data)) return { valid: true, data, errors: EMPTY_ERRORS };
|
|
28
|
+
const r = errFn(data);
|
|
29
|
+
return r && r.valid === false ? { valid: false, errors: r.errors } : VERDICT_DISAGREES;
|
|
30
|
+
},
|
|
31
|
+
isValidObject: isValid,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default { bareVerdict, barePlain };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// ata-validator/compiled-object: ata-validator/compiled without the JSON text
|
|
2
|
+
// entry points, for code that reads errors but never calls validateJSON().
|
|
3
|
+
import type { ValidationResult } from './index.js';
|
|
4
|
+
import type { CompiledModule, CompiledOptions } from './compiled.js';
|
|
5
|
+
|
|
6
|
+
export interface CompiledObjectValidator<T = unknown> {
|
|
7
|
+
validate(data: unknown): ValidationResult<T>;
|
|
8
|
+
isValidObject(data: unknown): data is T;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function fromCompiledObject<T = unknown>(mod: CompiledModule, schema: object, options?: CompiledOptions): CompiledObjectValidator<T>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// ata-validator/compiled-plain: the compiled-module wrapper for a Validator
|
|
2
|
+
// built with `richErrors: false`, for a module written with `plainErrors: true`.
|
|
3
|
+
import type { ValidationResult } from './index.js';
|
|
4
|
+
import type { CompiledModule } from './compiled.js';
|
|
5
|
+
|
|
6
|
+
export interface CompiledPlainValidator<T = unknown> {
|
|
7
|
+
validate(data: unknown): ValidationResult<T>;
|
|
8
|
+
isValidObject(data: unknown): data is T;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CompiledPlainOptions {
|
|
12
|
+
richErrors?: false;
|
|
13
|
+
useDefaults?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function fromCompiledPlain<T = unknown>(mod: CompiledModule, schema: object, options?: CompiledPlainOptions): CompiledPlainValidator<T>;
|
package/compiled.d.ts
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import type { ValidationResult } from './index.js';
|
|
4
4
|
|
|
5
5
|
export interface CompiledModule {
|
|
6
|
-
|
|
6
|
+
// A module's accepted result is frozen, so the array is read-only here;
|
|
7
|
+
// under Bun's ahead-of-time compiler a type error fails the build.
|
|
8
|
+
validate(data: unknown): { valid: boolean; errors: readonly unknown[] };
|
|
7
9
|
isValid(data: unknown): boolean;
|
|
8
10
|
}
|
|
9
11
|
|
package/index.browser.mjs
CHANGED
|
@@ -15,6 +15,6 @@ import { toTypeScript, renderPretty, renderCompact, toOutput, toRetryMessage, de
|
|
|
15
15
|
|
|
16
16
|
core._registerTiering(tiering.createTiering(() => import('./lib/codegen-engine.js')));
|
|
17
17
|
|
|
18
|
-
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, defineSchema } = core;
|
|
18
|
+
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, defineSchema, schemaOf } = core;
|
|
19
19
|
export { toTypeScript, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
|
20
|
-
export default { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
|
20
|
+
export default { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, schemaOf, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
package/index.bundle.mjs
CHANGED
|
@@ -10,6 +10,6 @@ import { toTypeScript, renderPretty, renderCompact, toOutput, toRetryMessage, de
|
|
|
10
10
|
|
|
11
11
|
core._registerCodegen(engine);
|
|
12
12
|
|
|
13
|
-
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, defineSchema } = core;
|
|
13
|
+
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, defineSchema, schemaOf } = core;
|
|
14
14
|
export { toTypeScript, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
|
15
|
-
export default { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
|
15
|
+
export default { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, schemaOf, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
package/index.d.ts
CHANGED
|
@@ -678,3 +678,12 @@ export function toTypeScript(schema: object, options?: { name?: string }): strin
|
|
|
678
678
|
* Requires TypeScript >= 5.0 for the `const` type parameter.
|
|
679
679
|
*/
|
|
680
680
|
export declare function defineSchema<const S extends JSONSchema>(schema: S): S;
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* The JSON Schema of a TypeScript type, written in at build time by
|
|
684
|
+
* `@ata-project/unplugin` from the type and the JSDoc tags on its properties
|
|
685
|
+
* (`@format email`, `@minimum 1`, `@pattern`, `@minLength`, `@maxItems`,
|
|
686
|
+
* `@asType integer`). `new Validator(schemaOf<User>())` then compiles like any
|
|
687
|
+
* static schema. Without the plugin the call throws: it has no run-time form.
|
|
688
|
+
*/
|
|
689
|
+
export declare function schemaOf<T>(): JSONSchema;
|
package/index.edge.mjs
CHANGED
|
@@ -8,6 +8,6 @@ import { toTypeScript, renderPretty, renderCompact, toOutput, toRetryMessage, de
|
|
|
8
8
|
|
|
9
9
|
core._registerAot(() => aotBrowser);
|
|
10
10
|
|
|
11
|
-
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, defineSchema } = core;
|
|
11
|
+
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, defineSchema, schemaOf } = core;
|
|
12
12
|
export { toTypeScript, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
|
13
|
-
export default { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
|
13
|
+
export default { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, schemaOf, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON };
|
package/index.js
CHANGED
|
@@ -20,6 +20,53 @@ core._setCodegenLoader(loadCodegen);
|
|
|
20
20
|
const warm = setTimeout(loadCodegen, 0);
|
|
21
21
|
if (typeof warm === 'object' && typeof warm.unref === 'function') warm.unref();
|
|
22
22
|
|
|
23
|
+
// A process whose first check comes after the event loop has turned, a
|
|
24
|
+
// server's first request, pays on that check for V8 compiling the generator's
|
|
25
|
+
// functions and the error builders: on a four-field schema 5 ms for the
|
|
26
|
+
// verdict and 7 to 10 ms for the first error list, measured with the
|
|
27
|
+
// generator already loaded. One check of a small schema, accepted and
|
|
28
|
+
// rejected, run once the loop is free, moves that off the request: 0.5 and
|
|
29
|
+
// 0.7 ms after it (the same warm-up as the browser build's, lib/tiering.js).
|
|
30
|
+
// It runs only where a validator was built and is still uncompiled when the
|
|
31
|
+
// loop turns: a script that builds one and checks in the same tick never runs
|
|
32
|
+
// it, and the timer is unref'd, so a finished script does not stay for it.
|
|
33
|
+
// ATA_NO_WARM=1 turns it off.
|
|
34
|
+
let built = null;
|
|
35
|
+
core._registerBuiltHook((v) => {
|
|
36
|
+
if (built === null) {
|
|
37
|
+
built = [];
|
|
38
|
+
const t = setTimeout(warmUp, 0);
|
|
39
|
+
if (typeof t === 'object' && typeof t.unref === 'function') t.unref();
|
|
40
|
+
}
|
|
41
|
+
if (built.length < 8) built.push(new WeakRef(v));
|
|
42
|
+
});
|
|
43
|
+
function warmUp () {
|
|
44
|
+
const list = built;
|
|
45
|
+
built = [];
|
|
46
|
+
core._registerBuiltHook(null);
|
|
47
|
+
if (process.env.ATA_NO_WARM === '1') return;
|
|
48
|
+
// Untouched: neither compiled for validate() nor a verdict or validate
|
|
49
|
+
// method read off it (the prototype's accessors bind the method on the
|
|
50
|
+
// instance at the first read, a verdict-only compile sets no other mark).
|
|
51
|
+
const untouched = (v) => !v._initialized && !Object.prototype.hasOwnProperty.call(v, 'isValidObject') && !Object.prototype.hasOwnProperty.call(v, 'validate');
|
|
52
|
+
if (!list.some((r) => { const v = r.deref(); return v !== undefined && untouched(v); })) return;
|
|
53
|
+
try {
|
|
54
|
+
const v = new core.Validator({
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: {
|
|
57
|
+
a: { type: 'string', minLength: 2, maxLength: 9, pattern: '^[a-z]+$', format: 'email' },
|
|
58
|
+
b: { type: 'integer', minimum: 1, maximum: 9 },
|
|
59
|
+
c: { type: 'array', items: { type: 'string' }, maxItems: 3 },
|
|
60
|
+
d: { const: true },
|
|
61
|
+
e: { type: 'object', properties: { f: { type: 'string' } }, required: ['f'] },
|
|
62
|
+
},
|
|
63
|
+
required: ['a', 'b'],
|
|
64
|
+
});
|
|
65
|
+
v.isValidObject({ a: 'ab@c.de', b: 2, c: ['x'], d: true, e: { f: 'x' } });
|
|
66
|
+
void v.validate({ a: '1', b: 0, c: [1], d: false, e: {} }).errors.length;
|
|
67
|
+
} catch { /* a warm-up never reaches the caller */ }
|
|
68
|
+
}
|
|
69
|
+
|
|
23
70
|
// The public names. lib/public-api.js holds the same for index.edge.js; they
|
|
24
71
|
// are written out here rather than required so that loading the package in
|
|
25
72
|
// Node reads one file fewer (tests/test_edge_entry.js and
|
|
@@ -91,6 +138,7 @@ module.exports = {
|
|
|
91
138
|
parseJSON: core.parseJSON,
|
|
92
139
|
toTypeScript,
|
|
93
140
|
defineSchema: core.defineSchema,
|
|
141
|
+
schemaOf: core.schemaOf,
|
|
94
142
|
renderPretty,
|
|
95
143
|
renderCompact,
|
|
96
144
|
toOutput,
|
package/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import mod from './index.js';
|
|
2
|
-
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON } = mod;
|
|
2
|
+
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, schemaOf, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON } = mod;
|
|
3
3
|
export default mod;
|
package/index.node.mjs
CHANGED
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
// static import they can follow.
|
|
7
7
|
import { createRequire } from 'node:module';
|
|
8
8
|
const mod = createRequire(import.meta.url)('./index.js');
|
|
9
|
-
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON } = mod;
|
|
9
|
+
export const { Validator, compile, validate, validateAsync, parseAsync, version, createPaddedBuffer, SIMDJSON_PADDING, parseJSON, toTypeScript, defineSchema, schemaOf, renderPretty, renderCompact, toOutput, toRetryMessage, describeSchema, renderJSON } = mod;
|
|
10
10
|
export default mod;
|