zod-aot 0.0.3 → 0.0.4
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 +20 -19
- package/dist/cli/commands/check.d.ts +6 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +97 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +7 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +99 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/discovery.d.ts +11 -0
- package/dist/cli/discovery.d.ts.map +1 -0
- package/dist/cli/discovery.js +17 -0
- package/dist/cli/discovery.js.map +1 -0
- package/dist/cli/emitter.d.ts +19 -0
- package/dist/cli/emitter.d.ts.map +1 -0
- package/dist/cli/emitter.js +77 -0
- package/dist/cli/emitter.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +111 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/loader.d.ts +11 -0
- package/dist/cli/loader.d.ts.map +1 -0
- package/dist/cli/loader.js +52 -0
- package/dist/cli/loader.js.map +1 -0
- package/dist/cli/logger.d.ts +8 -0
- package/dist/cli/logger.d.ts.map +1 -0
- package/dist/cli/logger.js +33 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/codegen/context.d.ts +5 -0
- package/dist/codegen/context.d.ts.map +1 -1
- package/dist/codegen/context.js +11 -0
- package/dist/codegen/context.js.map +1 -1
- package/dist/compile.d.ts +14 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +21 -0
- package/dist/compile.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/unplugin/esbuild.d.ts +3 -0
- package/dist/unplugin/esbuild.d.ts.map +1 -0
- package/dist/unplugin/esbuild.js +3 -0
- package/dist/unplugin/esbuild.js.map +1 -0
- package/dist/unplugin/index.d.ts +4 -0
- package/dist/unplugin/index.d.ts.map +1 -0
- package/dist/unplugin/index.js +19 -0
- package/dist/unplugin/index.js.map +1 -0
- package/dist/unplugin/rollup.d.ts +3 -0
- package/dist/unplugin/rollup.d.ts.map +1 -0
- package/dist/unplugin/rollup.js +3 -0
- package/dist/unplugin/rollup.js.map +1 -0
- package/dist/unplugin/transform.d.ts +26 -0
- package/dist/unplugin/transform.d.ts.map +1 -0
- package/dist/unplugin/transform.js +134 -0
- package/dist/unplugin/transform.js.map +1 -0
- package/dist/unplugin/types.d.ts +7 -0
- package/dist/unplugin/types.d.ts.map +1 -0
- package/dist/unplugin/types.js +2 -0
- package/dist/unplugin/types.js.map +1 -0
- package/dist/unplugin/vite.d.ts +3 -0
- package/dist/unplugin/vite.d.ts.map +1 -0
- package/dist/unplugin/vite.js +3 -0
- package/dist/unplugin/vite.js.map +1 -0
- package/dist/unplugin/webpack.d.ts +3 -0
- package/dist/unplugin/webpack.d.ts.map +1 -0
- package/dist/unplugin/webpack.js +3 -0
- package/dist/unplugin/webpack.js.map +1 -0
- package/package.json +37 -3
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/zod-aot)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
|
-
No code changes required — keep your existing Zod schemas and get **2-
|
|
9
|
+
No code changes required — keep your existing Zod schemas and get **2-64x faster** validation.
|
|
10
10
|
|
|
11
11
|
## Why
|
|
12
12
|
|
|
@@ -27,18 +27,18 @@ Measured with `vitest bench` on Node.js (Apple M-series):
|
|
|
27
27
|
|
|
28
28
|
| Scenario | Zod v4 | zod-aot | Speedup |
|
|
29
29
|
|---|---|---|---|
|
|
30
|
-
| simple string | 10.
|
|
31
|
-
| string (min/max) | 5.
|
|
32
|
-
| number (int+positive) | 5.
|
|
33
|
-
| enum | 8.
|
|
34
|
-
| tuple [string, int, boolean] | 4.
|
|
35
|
-
| record\<string, number\> (5 keys) |
|
|
36
|
-
| discriminatedUnion (3 variants) | 3.0M ops/s |
|
|
37
|
-
| medium object (7 props, valid) | 1.7M ops/s | 6.
|
|
38
|
-
| medium object (7 props, invalid) |
|
|
39
|
-
| large object (10 nested items) |
|
|
40
|
-
| large object (100 nested items) | 11.
|
|
41
|
-
| event log (combined) |
|
|
30
|
+
| simple string | 10.4M ops/s | 17.9M ops/s | **1.7x** |
|
|
31
|
+
| string (min/max) | 5.3M ops/s | 17.6M ops/s | **3.3x** |
|
|
32
|
+
| number (int+positive) | 5.2M ops/s | 16.4M ops/s | **3.1x** |
|
|
33
|
+
| enum | 8.7M ops/s | 15.5M ops/s | **1.8x** |
|
|
34
|
+
| tuple [string, int, boolean] | 4.3M ops/s | 17.1M ops/s | **3.9x** |
|
|
35
|
+
| record\<string, number\> (5 keys) | 1.9M ops/s | 8.3M ops/s | **4.3x** |
|
|
36
|
+
| discriminatedUnion (3 variants) | 3.0M ops/s | 15.7M ops/s | **5.3x** |
|
|
37
|
+
| medium object (7 props, valid) | 1.7M ops/s | 6.6M ops/s | **4.0x** |
|
|
38
|
+
| medium object (7 props, invalid) | 65K ops/s | 1.5M ops/s | **23x** |
|
|
39
|
+
| large object (10 nested items) | 111K ops/s | 4.8M ops/s | **43x** |
|
|
40
|
+
| large object (100 nested items) | 11.9K ops/s | 713K ops/s | **60x** |
|
|
41
|
+
| event log (combined) | 431K ops/s | 5.0M ops/s | **12x** |
|
|
42
42
|
|
|
43
43
|
Performance gains scale with schema complexity. The `discriminatedUnion` optimization uses an O(1) `switch` dispatch instead of Zod's sequential trial approach.
|
|
44
44
|
|
|
@@ -376,9 +376,9 @@ These schema types contain JavaScript closures that cannot be compiled to static
|
|
|
376
376
|
|
|
377
377
|
- [x] Tier 2 type support (9 types: any, unknown, readonly, date, tuple, record, default, intersection, discriminatedUnion)
|
|
378
378
|
- [x] `discriminatedUnion` → O(1) switch statement optimization
|
|
379
|
-
- [
|
|
379
|
+
- [x] CLI (`npx zod-aot generate` / `npx zod-aot check`)
|
|
380
380
|
- [ ] Partial fallback (objects with some transform properties)
|
|
381
|
-
- [
|
|
381
|
+
- [x] unplugin integration (Vite / webpack / esbuild / Rollup)
|
|
382
382
|
- [ ] Watch mode
|
|
383
383
|
|
|
384
384
|
### Phase 3: Ecosystem
|
|
@@ -424,10 +424,11 @@ zod-aot/
|
|
|
424
424
|
│ ├── extractor/ # Extractor unit tests
|
|
425
425
|
│ ├── codegen/ # CodeGen unit tests
|
|
426
426
|
│ └── runtime.test.ts # Fallback tests
|
|
427
|
-
├── benchmarks/ # vitest bench
|
|
428
|
-
├──
|
|
429
|
-
│ ├──
|
|
430
|
-
│ └──
|
|
427
|
+
├── benchmarks/ # vitest bench + standalone scripts
|
|
428
|
+
│ ├── standalone/
|
|
429
|
+
│ │ ├── zod-only.ts # Standalone Zod benchmark
|
|
430
|
+
│ │ └── zod-aot.ts # Standalone zod-aot benchmark
|
|
431
|
+
│ └── ...
|
|
431
432
|
└── .github/workflows/ # CI + release automation
|
|
432
433
|
```
|
|
433
434
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check.ts"],"names":[],"mappings":"AASA,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AA2CD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDnE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { extractSchema } from "../../extractor/index.js";
|
|
5
|
+
import { discoverSchemas } from "../discovery.js";
|
|
6
|
+
import { logger } from "../logger.js";
|
|
7
|
+
function hasFallback(ir) {
|
|
8
|
+
if (ir.type === "fallback") {
|
|
9
|
+
return ir.reason;
|
|
10
|
+
}
|
|
11
|
+
if (ir.type === "object") {
|
|
12
|
+
for (const [key, prop] of Object.entries(ir.properties)) {
|
|
13
|
+
const reason = hasFallback(prop);
|
|
14
|
+
if (reason)
|
|
15
|
+
return `${reason} at .${key}`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (ir.type === "array") {
|
|
19
|
+
return hasFallback(ir.element);
|
|
20
|
+
}
|
|
21
|
+
if (ir.type === "optional" || ir.type === "nullable" || ir.type === "readonly") {
|
|
22
|
+
return hasFallback(ir.inner);
|
|
23
|
+
}
|
|
24
|
+
if (ir.type === "default") {
|
|
25
|
+
return hasFallback(ir.inner);
|
|
26
|
+
}
|
|
27
|
+
if (ir.type === "union" || ir.type === "discriminatedUnion") {
|
|
28
|
+
for (const opt of ir.options) {
|
|
29
|
+
const reason = hasFallback(opt);
|
|
30
|
+
if (reason)
|
|
31
|
+
return reason;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (ir.type === "tuple") {
|
|
35
|
+
for (const item of ir.items) {
|
|
36
|
+
const reason = hasFallback(item);
|
|
37
|
+
if (reason)
|
|
38
|
+
return reason;
|
|
39
|
+
}
|
|
40
|
+
if (ir.rest)
|
|
41
|
+
return hasFallback(ir.rest);
|
|
42
|
+
}
|
|
43
|
+
if (ir.type === "record") {
|
|
44
|
+
return hasFallback(ir.keyType) ?? hasFallback(ir.valueType);
|
|
45
|
+
}
|
|
46
|
+
if (ir.type === "intersection") {
|
|
47
|
+
return hasFallback(ir.left) ?? hasFallback(ir.right);
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
export async function runCheck(options) {
|
|
52
|
+
const files = [];
|
|
53
|
+
for (const input of options.inputs) {
|
|
54
|
+
const absPath = path.resolve(input);
|
|
55
|
+
const stat = await fs.promises.stat(absPath).catch(() => null);
|
|
56
|
+
if (!stat) {
|
|
57
|
+
logger.error(`File not found: ${input}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
if (stat.isDirectory()) {
|
|
61
|
+
logger.error("check command expects file paths, not directories.");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
files.push(absPath);
|
|
65
|
+
}
|
|
66
|
+
let hasCompilable = false;
|
|
67
|
+
for (const filePath of files) {
|
|
68
|
+
const relPath = path.relative(process.cwd(), filePath);
|
|
69
|
+
let schemas;
|
|
70
|
+
try {
|
|
71
|
+
schemas = await discoverSchemas(filePath);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
logger.error(`Failed to load ${relPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
if (schemas.length === 0) {
|
|
78
|
+
logger.warn(`${relPath}: no compile() calls found`);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
for (const s of schemas) {
|
|
82
|
+
const ir = extractSchema(s.schema);
|
|
83
|
+
const fallbackReason = hasFallback(ir);
|
|
84
|
+
if (fallbackReason) {
|
|
85
|
+
logger.warn(`${s.exportName} — partial (fallback: ${fallbackReason})`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
logger.success(`${s.exportName} — compilable`);
|
|
89
|
+
hasCompilable = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!hasCompilable) {
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/cli/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAUA,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AA0DD,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDzE"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { generateValidator } from "../../codegen/index.js";
|
|
5
|
+
import { extractSchema } from "../../extractor/index.js";
|
|
6
|
+
import { discoverSchemas } from "../discovery.js";
|
|
7
|
+
import { generateCompiledFileContent, resolveOutputPath, writeCompiledFile } from "../emitter.js";
|
|
8
|
+
import { logger } from "../logger.js";
|
|
9
|
+
/**
|
|
10
|
+
* Resolve input paths to a list of source files.
|
|
11
|
+
* If a path is a directory, find all .ts files (excluding .compiled.ts, .test.ts, node_modules).
|
|
12
|
+
*/
|
|
13
|
+
async function resolveInputFiles(inputs) {
|
|
14
|
+
const files = [];
|
|
15
|
+
for (const input of inputs) {
|
|
16
|
+
const absPath = path.resolve(input);
|
|
17
|
+
const stat = await fs.promises.stat(absPath).catch(() => null);
|
|
18
|
+
if (!stat) {
|
|
19
|
+
logger.error(`File not found: ${input}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
if (stat.isDirectory()) {
|
|
23
|
+
const found = await findSchemaFiles(absPath);
|
|
24
|
+
files.push(...found);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
files.push(absPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return files;
|
|
31
|
+
}
|
|
32
|
+
async function findSchemaFiles(dir) {
|
|
33
|
+
const results = [];
|
|
34
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
const fullPath = path.join(dir, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
if (entry.name === "node_modules" || entry.name === "dist" || entry.name.startsWith(".")) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const nested = await findSchemaFiles(fullPath);
|
|
42
|
+
results.push(...nested);
|
|
43
|
+
}
|
|
44
|
+
else if (entry.isFile() &&
|
|
45
|
+
/\.(?:ts|mts|js|mjs)$/.test(entry.name) &&
|
|
46
|
+
!entry.name.endsWith(".compiled.ts") &&
|
|
47
|
+
!entry.name.endsWith(".compiled.js") &&
|
|
48
|
+
!entry.name.endsWith(".test.ts") &&
|
|
49
|
+
!entry.name.endsWith(".test.js") &&
|
|
50
|
+
!entry.name.endsWith(".d.ts")) {
|
|
51
|
+
results.push(fullPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return results;
|
|
55
|
+
}
|
|
56
|
+
export async function runGenerate(options) {
|
|
57
|
+
const files = await resolveInputFiles(options.inputs);
|
|
58
|
+
if (files.length === 0) {
|
|
59
|
+
logger.warn("No source files found.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let totalSchemas = 0;
|
|
63
|
+
let totalFiles = 0;
|
|
64
|
+
for (const filePath of files) {
|
|
65
|
+
const relPath = path.relative(process.cwd(), filePath);
|
|
66
|
+
let schemas;
|
|
67
|
+
try {
|
|
68
|
+
schemas = await discoverSchemas(filePath);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
logger.error(`Failed to load ${relPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
if (schemas.length === 0) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const codegenResults = schemas.map((s) => {
|
|
78
|
+
const ir = extractSchema(s.schema);
|
|
79
|
+
const result = generateValidator(ir, s.exportName);
|
|
80
|
+
return { exportName: s.exportName, codegenResult: result };
|
|
81
|
+
});
|
|
82
|
+
const outputPath = resolveOutputPath(filePath, options.output);
|
|
83
|
+
const outputRelPath = path.relative(process.cwd(), outputPath);
|
|
84
|
+
const sourceRelPath = path.relative(path.dirname(outputPath), filePath);
|
|
85
|
+
const content = generateCompiledFileContent(codegenResults, sourceRelPath);
|
|
86
|
+
await writeCompiledFile(outputPath, content);
|
|
87
|
+
const schemaNames = schemas.map((s) => s.exportName).join(", ");
|
|
88
|
+
logger.success(`${relPath} -> ${outputRelPath} (${schemaNames})`);
|
|
89
|
+
totalSchemas += schemas.length;
|
|
90
|
+
totalFiles++;
|
|
91
|
+
}
|
|
92
|
+
if (totalFiles === 0) {
|
|
93
|
+
logger.warn("No compile() calls found in any source file.");
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
logger.info(`Generated ${totalSchemas} schema${totalSchemas > 1 ? "s" : ""} from ${totalFiles} file${totalFiles > 1 ? "s" : ""}.`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LoadOptions } from "./loader.js";
|
|
2
|
+
export interface DiscoveredSchema {
|
|
3
|
+
exportName: string;
|
|
4
|
+
schema: unknown;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Discover all compile() calls in a source file by importing it and
|
|
8
|
+
* scanning exports for CompiledSchema objects.
|
|
9
|
+
*/
|
|
10
|
+
export declare function discoverSchemas(filePath: string, options?: LoadOptions): Promise<DiscoveredSchema[]>;
|
|
11
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/cli/discovery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAW7B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isCompiledSchema } from "../compile.js";
|
|
2
|
+
import { loadSourceFile } from "./loader.js";
|
|
3
|
+
/**
|
|
4
|
+
* Discover all compile() calls in a source file by importing it and
|
|
5
|
+
* scanning exports for CompiledSchema objects.
|
|
6
|
+
*/
|
|
7
|
+
export async function discoverSchemas(filePath, options) {
|
|
8
|
+
const mod = await loadSourceFile(filePath, options);
|
|
9
|
+
const schemas = [];
|
|
10
|
+
for (const [exportName, value] of Object.entries(mod)) {
|
|
11
|
+
if (isCompiledSchema(value)) {
|
|
12
|
+
schemas.push({ exportName, schema: value.schema });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return schemas;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/cli/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAO7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAqB;IAErB,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACtD,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CodeGenResult } from "../codegen/context.js";
|
|
2
|
+
interface EmitSchema {
|
|
3
|
+
exportName: string;
|
|
4
|
+
codegenResult: CodeGenResult;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Generate the content of a .compiled.ts file from multiple schemas.
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateCompiledFileContent(schemas: EmitSchema[], sourceRelPath: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the output file path for a given input file.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveOutputPath(inputPath: string, outputFlag: string | undefined): string;
|
|
14
|
+
/**
|
|
15
|
+
* Write the compiled file content to disk.
|
|
16
|
+
*/
|
|
17
|
+
export declare function writeCompiledFile(outputPath: string, content: string): Promise<void>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/cli/emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAkDhG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAc3F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI1F"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { extractFunctionName } from "../codegen/context.js";
|
|
4
|
+
/**
|
|
5
|
+
* Generate the content of a .compiled.ts file from multiple schemas.
|
|
6
|
+
*/
|
|
7
|
+
export function generateCompiledFileContent(schemas, sourceRelPath) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
// Header
|
|
10
|
+
lines.push("// AUTO-GENERATED by zod-aot — DO NOT EDIT");
|
|
11
|
+
lines.push(`// Source: ${sourceRelPath}`);
|
|
12
|
+
lines.push("");
|
|
13
|
+
// Merge preambles — each schema's `code` field contains `/* zod-aot */` + preamble declarations
|
|
14
|
+
const preambleSet = new Set();
|
|
15
|
+
for (const schema of schemas) {
|
|
16
|
+
for (const line of schema.codegenResult.code.split("\n")) {
|
|
17
|
+
if (line.trim() !== "" && line.trim() !== "/* zod-aot */") {
|
|
18
|
+
preambleSet.add(line);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (preambleSet.size > 0) {
|
|
23
|
+
lines.push("/* zod-aot:preamble */");
|
|
24
|
+
for (const line of preambleSet) {
|
|
25
|
+
lines.push(line);
|
|
26
|
+
}
|
|
27
|
+
lines.push("");
|
|
28
|
+
}
|
|
29
|
+
// Function definitions
|
|
30
|
+
for (const schema of schemas) {
|
|
31
|
+
lines.push(schema.codegenResult.functionName);
|
|
32
|
+
lines.push("");
|
|
33
|
+
}
|
|
34
|
+
// Export wrappers
|
|
35
|
+
for (const schema of schemas) {
|
|
36
|
+
const fnName = extractFunctionName(schema.codegenResult.functionName);
|
|
37
|
+
lines.push(`export const ${schema.exportName} = {`);
|
|
38
|
+
lines.push(" parse(input: unknown) {");
|
|
39
|
+
lines.push(` const r = ${fnName}(input);`);
|
|
40
|
+
lines.push(" if (r.success) return r.data;");
|
|
41
|
+
lines.push(' throw Object.assign(new Error("Validation failed"), r.error);');
|
|
42
|
+
lines.push(" },");
|
|
43
|
+
lines.push(` safeParse: ${fnName},`);
|
|
44
|
+
lines.push(" is(input: unknown): boolean {");
|
|
45
|
+
lines.push(` return ${fnName}(input).success;`);
|
|
46
|
+
lines.push(" },");
|
|
47
|
+
lines.push("};");
|
|
48
|
+
lines.push("");
|
|
49
|
+
}
|
|
50
|
+
return lines.join("\n");
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the output file path for a given input file.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveOutputPath(inputPath, outputFlag) {
|
|
56
|
+
if (outputFlag) {
|
|
57
|
+
// If output flag ends with / or is a directory, put the compiled file inside it
|
|
58
|
+
if (outputFlag.endsWith("/") || outputFlag.endsWith(path.sep)) {
|
|
59
|
+
const baseName = path.basename(inputPath, path.extname(inputPath));
|
|
60
|
+
return path.join(outputFlag, `${baseName}.compiled.ts`);
|
|
61
|
+
}
|
|
62
|
+
return outputFlag;
|
|
63
|
+
}
|
|
64
|
+
// Default: replace .ts with .compiled.ts
|
|
65
|
+
const dir = path.dirname(inputPath);
|
|
66
|
+
const baseName = path.basename(inputPath, path.extname(inputPath));
|
|
67
|
+
return path.join(dir, `${baseName}.compiled.ts`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Write the compiled file content to disk.
|
|
71
|
+
*/
|
|
72
|
+
export async function writeCompiledFile(outputPath, content) {
|
|
73
|
+
const dir = path.dirname(outputPath);
|
|
74
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
75
|
+
await fs.promises.writeFile(outputPath, content, "utf-8");
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/cli/emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
4
|
+
const VERSION = "0.0.3";
|
|
5
|
+
function printUsage() {
|
|
6
|
+
// biome-ignore lint/suspicious/noConsole: CLI output
|
|
7
|
+
console.log(`
|
|
8
|
+
zod-aot v${VERSION} — Compile Zod schemas into zero-overhead validation functions
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
zod-aot generate <files...> [-o <output>]
|
|
12
|
+
zod-aot check <files...>
|
|
13
|
+
|
|
14
|
+
Commands:
|
|
15
|
+
generate Generate optimized validation code from compile() calls
|
|
16
|
+
check Check if schemas are compilable (dry-run)
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
-o, --output <path> Output file or directory
|
|
20
|
+
-h, --help Show this help message
|
|
21
|
+
-v, --version Show version number
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
zod-aot generate src/schemas.ts
|
|
25
|
+
zod-aot generate src/schemas.ts -o src/schemas.compiled.ts
|
|
26
|
+
zod-aot generate src/
|
|
27
|
+
zod-aot check src/schemas.ts
|
|
28
|
+
`.trim());
|
|
29
|
+
}
|
|
30
|
+
function parseArgs(argv) {
|
|
31
|
+
const args = argv.slice(2);
|
|
32
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
33
|
+
return { kind: "help" };
|
|
34
|
+
}
|
|
35
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
36
|
+
return { kind: "version" };
|
|
37
|
+
}
|
|
38
|
+
const command = args[0];
|
|
39
|
+
const rest = args.slice(1);
|
|
40
|
+
if (command === "generate") {
|
|
41
|
+
const inputs = [];
|
|
42
|
+
let output;
|
|
43
|
+
for (let i = 0; i < rest.length; i++) {
|
|
44
|
+
const arg = rest[i];
|
|
45
|
+
if (arg === "-o" || arg === "--output") {
|
|
46
|
+
i++;
|
|
47
|
+
const val = rest[i];
|
|
48
|
+
if (!val) {
|
|
49
|
+
logger.error("Missing value for --output");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
output = val;
|
|
53
|
+
}
|
|
54
|
+
else if (arg.startsWith("-")) {
|
|
55
|
+
logger.error(`Unknown option: ${arg}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
inputs.push(arg);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (inputs.length === 0) {
|
|
63
|
+
logger.error("No input files specified. Run 'zod-aot --help' for usage.");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
return { kind: "generate", options: { inputs, output } };
|
|
67
|
+
}
|
|
68
|
+
if (command === "check") {
|
|
69
|
+
const inputs = rest.filter((arg) => {
|
|
70
|
+
if (arg.startsWith("-")) {
|
|
71
|
+
logger.error(`Unknown option: ${arg}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
});
|
|
76
|
+
if (inputs.length === 0) {
|
|
77
|
+
logger.error("No input files specified. Run 'zod-aot --help' for usage.");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
return { kind: "check", options: { inputs } };
|
|
81
|
+
}
|
|
82
|
+
logger.error(`Unknown command: ${command}. Run 'zod-aot --help' for usage.`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
async function main() {
|
|
86
|
+
const command = parseArgs(process.argv);
|
|
87
|
+
switch (command.kind) {
|
|
88
|
+
case "help":
|
|
89
|
+
printUsage();
|
|
90
|
+
break;
|
|
91
|
+
case "version":
|
|
92
|
+
// biome-ignore lint/suspicious/noConsole: CLI output
|
|
93
|
+
console.log(VERSION);
|
|
94
|
+
break;
|
|
95
|
+
case "generate": {
|
|
96
|
+
const { runGenerate } = await import("./commands/generate.js");
|
|
97
|
+
await runGenerate(command.options);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case "check": {
|
|
101
|
+
const { runCheck } = await import("./commands/check.js");
|
|
102
|
+
await runCheck(command.options);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
void main().catch((err) => {
|
|
108
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface LoadOptions {
|
|
2
|
+
/** Append a cache-busting query parameter to bypass Node.js module cache (useful for HMR). */
|
|
3
|
+
cacheBust?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Dynamically import a source file (.ts or .js).
|
|
7
|
+
* - Bun/Deno: native TypeScript support, direct import
|
|
8
|
+
* - Node.js: uses tsx's register API for TypeScript files
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadSourceFile(filePath: string, options?: LoadOptions): Promise<Record<string, unknown>>;
|
|
11
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/cli/loader.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,WAAW;IAC1B,8FAA8F;IAC9F,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAkBlC"}
|