zod-compiler 1.26.1 → 1.26.2

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.
@@ -2,21 +2,53 @@ import { SHARED_BLOCK_MARKER, createSharedSchemaPlan } from "./codegen/dedupe.js
2
2
  import { generateValidator } from "./codegen/index.js";
3
3
  import { extractSchema } from "./extract/index.js";
4
4
  //#region src/core/pipeline.ts
5
- /** Plan exact Set initializers used by at least two validators in this file. */
6
- function planSharedSetConstants(results, constantsByResult) {
5
+ /**
6
+ * Occurrences of a generated identifier in `source`, ignoring the longer names
7
+ * it is a prefix of — every generated name ends in `_<digits>`, so `__set_ks_1`
8
+ * would otherwise count itself inside `__set_ks_10`.
9
+ */
10
+ function referenceCount(source, name) {
11
+ let count = 0;
12
+ for (let at = source.indexOf(name); at !== -1; at = source.indexOf(name, at + name.length)) {
13
+ const next = source.charCodeAt(at + name.length);
14
+ if (!(next >= 48 && next <= 57)) count += 1;
15
+ }
16
+ return count;
17
+ }
18
+ /**
19
+ * Plan exact constant initializers used by at least two validators in this file.
20
+ *
21
+ * Names are assigned per kind (`__zcSet_0`, …) and ordered by initializer text,
22
+ * so a given file always produces the same names for the same content.
23
+ */
24
+ function planSharedConstants(results, constantsByResult) {
7
25
  const byInitializer = /* @__PURE__ */ new Map();
8
- for (const { codegenResult } of results) for (const constant of constantsByResult.get(codegenResult) ?? []) {
9
- const declaration = `var ${constant.name}=${constant.initializer};`;
10
- if (!codegenResult.code.includes(declaration)) continue;
11
- const users = byInitializer.get(constant.initializer);
12
- if (users === void 0) byInitializer.set(constant.initializer, /* @__PURE__ */ new Set([codegenResult]));
13
- else users.add(codegenResult);
26
+ for (const { codegenResult } of results) {
27
+ const source = `${codegenResult.code}\n${codegenResult.functionDef}`;
28
+ for (const constant of constantsByResult.get(codegenResult) ?? []) {
29
+ const declaration = `var ${constant.name}=${constant.initializer};`;
30
+ if (!source.includes(declaration)) continue;
31
+ if (referenceCount(source, constant.name) < 2) continue;
32
+ const entry = byInitializer.get(constant.initializer);
33
+ if (entry === void 0) byInitializer.set(constant.initializer, {
34
+ kind: constant.kind,
35
+ users: /* @__PURE__ */ new Set([codegenResult])
36
+ });
37
+ else entry.users.add(codegenResult);
38
+ }
14
39
  }
15
- const repeated = [...byInitializer.entries()].filter(([, users]) => users.size >= 2).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
16
- return new Map(repeated.map(([initializer], index) => [initializer, `__zcSet_${index}`]));
40
+ const repeated = [...byInitializer.entries()].filter(([, entry]) => entry.users.size >= 2).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
41
+ const nextIndex = /* @__PURE__ */ new Map();
42
+ return new Map(repeated.map(([initializer, entry]) => {
43
+ const index = nextIndex.get(entry.kind) ?? 0;
44
+ nextIndex.set(entry.kind, index + 1);
45
+ return [initializer, `__zc${entry.kind}_${index}`];
46
+ }));
17
47
  }
18
- function emitSharedSetConstants(sharedSetNames) {
19
- return [...sharedSetNames].map(([initializer, name]) => `var ${name}=/* @__PURE__ */${initializer};`).join("\n");
48
+ function emitSharedConstants(sharedConstantNames) {
49
+ return [...sharedConstantNames].map(([initializer, name]) => {
50
+ return `var ${name}=${initializer.startsWith("new ") ? "/* @__PURE__ */" : ""}${initializer};`;
51
+ }).join("\n");
20
52
  }
21
53
  /**
22
54
  * Run the extract → generate pipeline for each discovered schema.
@@ -24,9 +56,9 @@ function emitSharedSetConstants(sharedSetNames) {
24
56
  *
25
57
  * Pass 1 extracts every schema's IR and plans repeated slow walks. Pass 2
26
58
  * generates each validator, calling shared `__zcSw_N` functions instead of
27
- * re-inlining them. Exact Set initializers reported during generation are then
28
- * pooled when at least two validators use them. Files with no repetition keep
29
- * their original local declarations.
59
+ * re-inlining them. Exact constant initializers reported during generation are
60
+ * then pooled when at least two validators use them. Files with no repetition
61
+ * keep their original local declarations.
30
62
  */
31
63
  function compileSchemas(schemas, options) {
32
64
  const handle = (exportName, err) => {
@@ -50,17 +82,17 @@ function compileSchemas(schemas, options) {
50
82
  const generated = [];
51
83
  const constantsByResult = /* @__PURE__ */ new Map();
52
84
  for (const e of extracted) try {
53
- const setConstants = /* @__PURE__ */ new Map();
85
+ const constants = /* @__PURE__ */ new Map();
54
86
  const codegenResult = generateValidator(e.ir, e.exportName, {
55
87
  refCount: e.refEntries.length,
56
88
  mode: options.mode,
57
89
  sharedSchemas: plan,
58
90
  compact: options.compact,
59
- onSetConstant(constant) {
60
- setConstants.set(constant.name, constant);
91
+ onConstant(constant) {
92
+ constants.set(constant.name, constant);
61
93
  }
62
94
  });
63
- constantsByResult.set(codegenResult, [...setConstants.values()]);
95
+ constantsByResult.set(codegenResult, [...constants.values()]);
64
96
  generated.push({
65
97
  exportName: e.exportName,
66
98
  schema: e.schema,
@@ -71,35 +103,29 @@ function compileSchemas(schemas, options) {
71
103
  } catch (err) {
72
104
  handle(e.exportName, err);
73
105
  }
74
- const sharedSetNames = planSharedSetConstants(generated.map(({ exportName, codegenResult, refEntries }) => ({
106
+ const sharedConstantNames = planSharedConstants(generated.map(({ exportName, codegenResult, refEntries }) => ({
75
107
  exportName,
76
108
  codegenResult,
77
109
  refEntries
78
110
  })), constantsByResult);
79
- if (sharedSetNames.size > 0) for (const entry of generated) entry.codegenResult = generateValidator(entry.ir, entry.exportName, {
111
+ if (sharedConstantNames.size > 0) for (const entry of generated) entry.codegenResult = generateValidator(entry.ir, entry.exportName, {
80
112
  refCount: entry.refEntries.length,
81
113
  mode: options.mode,
82
114
  sharedSchemas: plan,
83
115
  compact: options.compact,
84
- sharedSetNames
85
- });
86
- const results = generated.map((entry) => {
87
- if (entry.codegenResult.rootDelegateRefIndex !== void 0) entry.refEntries.push({
88
- schema: entry.schema,
89
- accessPath: ""
90
- });
91
- return {
92
- exportName: entry.exportName,
93
- codegenResult: entry.codegenResult,
94
- refEntries: entry.refEntries
95
- };
116
+ sharedConstantNames
96
117
  });
97
- const sharedSetCode = emitSharedSetConstants(sharedSetNames);
118
+ const results = generated.map((entry) => ({
119
+ exportName: entry.exportName,
120
+ codegenResult: entry.codegenResult,
121
+ refEntries: entry.refEntries
122
+ }));
123
+ const sharedConstantCode = emitSharedConstants(sharedConstantNames);
98
124
  const slowWalkCode = plan?.code ?? "";
99
125
  return {
100
126
  schemas: results,
101
127
  shared: {
102
- code: sharedSetCode === "" ? slowWalkCode : slowWalkCode === "" ? `${SHARED_BLOCK_MARKER}\n${sharedSetCode}` : `${slowWalkCode}\n${sharedSetCode}`,
128
+ code: sharedConstantCode === "" ? slowWalkCode : slowWalkCode === "" ? `${SHARED_BLOCK_MARKER}\n${sharedConstantCode}` : `${slowWalkCode}\n${sharedConstantCode}`,
103
129
  usedHelpers: plan?.usedHelpers ?? /* @__PURE__ */ new Set()
104
130
  }
105
131
  };
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","names":[],"sources":["../../src/core/pipeline.ts"],"sourcesContent":["import type { CodeGenResult, CodegenMode, GeneratedSetConstant } from \"./codegen/context.js\";\nimport { createSharedSchemaPlan, SHARED_BLOCK_MARKER } from \"./codegen/dedupe.js\";\nimport { generateValidator } from \"./codegen/index.js\";\nimport type { RefEntry } from \"./extract/index.js\";\nimport { extractSchema } from \"./extract/index.js\";\nimport type { DiscoveredSchema, SchemaIR } from \"./types.js\";\n\n/** Result of compiling a single discovered schema through extract → generate pipeline. */\nexport interface CompiledSchemaInfo {\n exportName: string;\n codegenResult: CodeGenResult;\n refEntries: RefEntry[];\n}\n\n/** Module-scope declarations produced by file-level schema and constant dedup. */\nexport interface SharedSchemaBlock {\n /** Shared constants and `__zcSw_N` functions. Empty string when nothing repeats. */\n code: string;\n /** Runtime helper names referenced by the shared block (lean mode imports). */\n usedHelpers: Set<string>;\n}\n\n/** Output of {@link compileSchemas}: per-schema validators plus the file's shared block. */\nexport interface CompileSchemasResult {\n schemas: CompiledSchemaInfo[];\n shared: SharedSchemaBlock;\n}\n\nexport interface CompileSchemasOptions {\n /** \"inline\" for CLI .compiled.ts; \"lean\" for unplugin (imports from virtual:zod-compiler/runtime). */\n mode: CodegenMode;\n /**\n * Compact output (`output: \"compact\"`). Drop the compiled slow walk for\n * mutation-free, total-fast-path schemas and delegate their cold error path\n * to the retained Zod schema. Disables slow-walk sharing (delegated schemas\n * never emit a walk to share) and appends a root self-RefEntry per delegated\n * schema so `__rf[N]` resolves to the original Zod schema.\n */\n compact?: boolean | undefined;\n /** When provided, per-schema failures call this and continue. Otherwise the first error throws. */\n onError?: (exportName: string, error: Error) => void;\n}\n\n/** Plan exact Set initializers used by at least two validators in this file. */\nfunction planSharedSetConstants(\n results: readonly CompiledSchemaInfo[],\n constantsByResult: ReadonlyMap<CodeGenResult, readonly GeneratedSetConstant[]>,\n): ReadonlyMap<string, string> {\n const byInitializer = new Map<string, Set<CodeGenResult>>();\n for (const { codegenResult } of results) {\n for (const constant of constantsByResult.get(codegenResult) ?? []) {\n const declaration = `var ${constant.name}=${constant.initializer};`;\n // Fast-path generation can emit a Set before a later node aborts. Its\n // preamble is rolled back, so only collect declarations that survived.\n if (!codegenResult.code.includes(declaration)) continue;\n const users = byInitializer.get(constant.initializer);\n if (users === undefined) byInitializer.set(constant.initializer, new Set([codegenResult]));\n else users.add(codegenResult);\n }\n }\n\n const repeated = [...byInitializer.entries()]\n .filter(([, users]) => users.size >= 2)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return new Map(repeated.map(([initializer], index) => [initializer, `__zcSet_${index}`]));\n}\n\nfunction emitSharedSetConstants(sharedSetNames: ReadonlyMap<string, string>): string {\n return [...sharedSetNames]\n .map(([initializer, name]) => `var ${name}=/* @__PURE__ */${initializer};`)\n .join(\"\\n\");\n}\n\n/**\n * Run the extract → generate pipeline for each discovered schema.\n * Shared by CLI generate and unplugin transform.\n *\n * Pass 1 extracts every schema's IR and plans repeated slow walks. Pass 2\n * generates each validator, calling shared `__zcSw_N` functions instead of\n * re-inlining them. Exact Set initializers reported during generation are then\n * pooled when at least two validators use them. Files with no repetition keep\n * their original local declarations.\n */\nexport function compileSchemas(\n schemas: DiscoveredSchema[],\n options: CompileSchemasOptions,\n): CompileSchemasResult {\n const handle = (exportName: string, err: unknown): void => {\n if (options.onError) {\n options.onError(exportName, err instanceof Error ? err : new Error(String(err)));\n } else {\n throw err;\n }\n };\n\n // Pass 1: extract IR (and fallback refs) for every schema.\n const extracted: Array<{\n exportName: string;\n schema: unknown;\n ir: SchemaIR;\n refEntries: RefEntry[];\n }> = [];\n for (const s of schemas) {\n try {\n const refEntries: RefEntry[] = [];\n const ir = extractSchema(s.schema, refEntries);\n extracted.push({ exportName: s.exportName, schema: s.schema, ir, refEntries });\n } catch (err) {\n handle(s.exportName, err);\n }\n }\n\n // Compact mode delegates the cold error path of total-fast-path schemas to\n // zod, so they emit no slow walk to share — skip the plan (and the dead\n // shared functions it would generate for shapes that now only delegate).\n const plan = options.compact\n ? undefined\n : createSharedSchemaPlan(\n extracted.map((e) => e.ir),\n options.mode,\n );\n\n // Pass 2: generate each validator, sharing repeated slow walks via the plan\n // and observing which Set declarations survive codegen rollback.\n const generated: Array<{\n exportName: string;\n schema: unknown;\n ir: SchemaIR;\n refEntries: RefEntry[];\n codegenResult: CodeGenResult;\n }> = [];\n const constantsByResult = new Map<CodeGenResult, GeneratedSetConstant[]>();\n for (const e of extracted) {\n try {\n const setConstants = new Map<string, GeneratedSetConstant>();\n const codegenResult = generateValidator(e.ir, e.exportName, {\n refCount: e.refEntries.length,\n mode: options.mode,\n sharedSchemas: plan,\n compact: options.compact,\n onSetConstant(constant) {\n setConstants.set(constant.name, constant);\n },\n });\n constantsByResult.set(codegenResult, [...setConstants.values()]);\n generated.push({\n exportName: e.exportName,\n schema: e.schema,\n ir: e.ir,\n refEntries: e.refEntries,\n codegenResult,\n });\n } catch (err) {\n handle(e.exportName, err);\n }\n }\n\n const initialResults = generated.map(\n ({ exportName, codegenResult, refEntries }): CompiledSchemaInfo => ({\n exportName,\n codegenResult,\n refEntries,\n }),\n );\n const sharedSetNames = planSharedSetConstants(initialResults, constantsByResult);\n\n // Regenerate only when sharing is profitable. Selecting shared names before\n // emission avoids textual rewriting of generated JavaScript, where a user\n // enum string can legally contain text resembling a generated identifier.\n if (sharedSetNames.size > 0) {\n for (const entry of generated) {\n entry.codegenResult = generateValidator(entry.ir, entry.exportName, {\n refCount: entry.refEntries.length,\n mode: options.mode,\n sharedSchemas: plan,\n compact: options.compact,\n sharedSetNames,\n });\n }\n }\n\n const results: CompiledSchemaInfo[] = generated.map((entry) => {\n // Compact delegation appends the schema itself as a fresh root RefEntry\n // after the optional regeneration pass, keeping the reserved index stable.\n if (entry.codegenResult.rootDelegateRefIndex !== undefined) {\n entry.refEntries.push({ schema: entry.schema, accessPath: \"\" });\n }\n return {\n exportName: entry.exportName,\n codegenResult: entry.codegenResult,\n refEntries: entry.refEntries,\n };\n });\n\n const sharedSetCode = emitSharedSetConstants(sharedSetNames);\n const slowWalkCode = plan?.code ?? \"\";\n const sharedCode =\n sharedSetCode === \"\"\n ? slowWalkCode\n : slowWalkCode === \"\"\n ? `${SHARED_BLOCK_MARKER}\\n${sharedSetCode}`\n : `${slowWalkCode}\\n${sharedSetCode}`;\n\n return {\n schemas: results,\n shared: { code: sharedCode, usedHelpers: plan?.usedHelpers ?? new Set() },\n };\n}\n\n/**\n * Aggregate `usedHelpers` across multiple compiled schemas (typically all schemas in one file).\n * Used by the unplugin transform to construct a single import statement per file.\n */\nexport function aggregateUsedHelpers(schemas: CompiledSchemaInfo[]): Set<string> {\n const all = new Set<string>();\n for (const s of schemas) {\n for (const h of s.codegenResult.usedHelpers) all.add(h);\n }\n return all;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pipeline.js","names":[],"sources":["../../src/core/pipeline.ts"],"sourcesContent":["import type {\n CodeGenResult,\n CodegenMode,\n ConstantKind,\n GeneratedConstant,\n} from \"./codegen/context.js\";\nimport { createSharedSchemaPlan, SHARED_BLOCK_MARKER } from \"./codegen/dedupe.js\";\nimport { generateValidator } from \"./codegen/index.js\";\nimport type { RefEntry } from \"./extract/index.js\";\nimport { extractSchema } from \"./extract/index.js\";\nimport type { DiscoveredSchema, SchemaIR } from \"./types.js\";\n\n/** Result of compiling a single discovered schema through extract → generate pipeline. */\nexport interface CompiledSchemaInfo {\n exportName: string;\n codegenResult: CodeGenResult;\n refEntries: RefEntry[];\n}\n\n/** Module-scope declarations produced by file-level schema and constant dedup. */\nexport interface SharedSchemaBlock {\n /** Shared constants and `__zcSw_N` functions. Empty string when nothing repeats. */\n code: string;\n /** Runtime helper names referenced by the shared block (lean mode imports). */\n usedHelpers: Set<string>;\n}\n\n/** Output of {@link compileSchemas}: per-schema validators plus the file's shared block. */\nexport interface CompileSchemasResult {\n schemas: CompiledSchemaInfo[];\n shared: SharedSchemaBlock;\n}\n\nexport interface CompileSchemasOptions {\n /** \"inline\" for CLI .compiled.ts; \"lean\" for unplugin (imports from virtual:zod-compiler/runtime). */\n mode: CodegenMode;\n /**\n * Compact output (`output: \"compact\"`). Drop the compiled slow walk for\n * mutation-free, total-fast-path schemas and delegate their cold error path\n * to the retained Zod schema. Disables slow-walk sharing (delegated schemas\n * never emit a walk to share); delegated validators read the retained schema\n * through the `__zs` binding rather than through `__rf[]`.\n */\n compact?: boolean | undefined;\n /** When provided, per-schema failures call this and continue. Otherwise the first error throws. */\n onError?: (exportName: string, error: Error) => void;\n}\n\n/**\n * Occurrences of a generated identifier in `source`, ignoring the longer names\n * it is a prefix of — every generated name ends in `_<digits>`, so `__set_ks_1`\n * would otherwise count itself inside `__set_ks_10`.\n */\nfunction referenceCount(source: string, name: string): number {\n let count = 0;\n for (let at = source.indexOf(name); at !== -1; at = source.indexOf(name, at + name.length)) {\n const next = source.charCodeAt(at + name.length);\n if (!(next >= 48 && next <= 57)) count += 1;\n }\n return count;\n}\n\n/**\n * Plan exact constant initializers used by at least two validators in this file.\n *\n * Names are assigned per kind (`__zcSet_0`, …) and ordered by initializer text,\n * so a given file always produces the same names for the same content.\n */\nfunction planSharedConstants(\n results: readonly CompiledSchemaInfo[],\n constantsByResult: ReadonlyMap<CodeGenResult, readonly GeneratedConstant[]>,\n): ReadonlyMap<string, string> {\n const byInitializer = new Map<string, { kind: ConstantKind; users: Set<CodeGenResult> }>();\n for (const { codegenResult } of results) {\n const source = `${codegenResult.code}\\n${codegenResult.functionDef}`;\n for (const constant of constantsByResult.get(codegenResult) ?? []) {\n const declaration = `var ${constant.name}=${constant.initializer};`;\n // Fast-path generation can emit a constant before a later node aborts.\n // Its preamble is rolled back, so only collect declarations that survived.\n if (!source.includes(declaration)) continue;\n // A surviving declaration is not the same as a use. Two generators emit a\n // constant before they can decline — the build path names its FAIL\n // sentinel up front, and an abandoned fast-path walk leaves whatever it\n // declared behind — so a validator can hold a declaration it never reads.\n // Counting those as pool users hoisted constants nothing referenced, and\n // (worse) tripped the regeneration pass for a file that gained nothing by\n // it. Require the name to appear at least once beyond its own declaration.\n if (referenceCount(source, constant.name) < 2) continue;\n const entry = byInitializer.get(constant.initializer);\n if (entry === undefined) {\n byInitializer.set(constant.initializer, {\n kind: constant.kind,\n users: new Set([codegenResult]),\n });\n } else {\n entry.users.add(codegenResult);\n }\n }\n }\n\n const repeated = [...byInitializer.entries()]\n .filter(([, entry]) => entry.users.size >= 2)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n\n const nextIndex = new Map<ConstantKind, number>();\n return new Map(\n repeated.map(([initializer, entry]) => {\n const index = nextIndex.get(entry.kind) ?? 0;\n nextIndex.set(entry.kind, index + 1);\n return [initializer, `__zc${entry.kind}_${index}`];\n }),\n );\n}\n\nfunction emitSharedConstants(sharedConstantNames: ReadonlyMap<string, string>): string {\n return [...sharedConstantNames]\n .map(([initializer, name]) => {\n // `/* @__PURE__ */` earns its bytes only on a constructor call, where it\n // tells a bundler the declaration is droppable when nothing reads it. On a\n // plain object literal it is inert, and the annotation is longer than the\n // initializer it annotates.\n const pure = initializer.startsWith(\"new \") ? \"/* @__PURE__ */\" : \"\";\n return `var ${name}=${pure}${initializer};`;\n })\n .join(\"\\n\");\n}\n\n/**\n * Run the extract → generate pipeline for each discovered schema.\n * Shared by CLI generate and unplugin transform.\n *\n * Pass 1 extracts every schema's IR and plans repeated slow walks. Pass 2\n * generates each validator, calling shared `__zcSw_N` functions instead of\n * re-inlining them. Exact constant initializers reported during generation are\n * then pooled when at least two validators use them. Files with no repetition\n * keep their original local declarations.\n */\nexport function compileSchemas(\n schemas: DiscoveredSchema[],\n options: CompileSchemasOptions,\n): CompileSchemasResult {\n const handle = (exportName: string, err: unknown): void => {\n if (options.onError) {\n options.onError(exportName, err instanceof Error ? err : new Error(String(err)));\n } else {\n throw err;\n }\n };\n\n // Pass 1: extract IR (and fallback refs) for every schema.\n const extracted: Array<{\n exportName: string;\n schema: unknown;\n ir: SchemaIR;\n refEntries: RefEntry[];\n }> = [];\n for (const s of schemas) {\n try {\n const refEntries: RefEntry[] = [];\n const ir = extractSchema(s.schema, refEntries);\n extracted.push({ exportName: s.exportName, schema: s.schema, ir, refEntries });\n } catch (err) {\n handle(s.exportName, err);\n }\n }\n\n // Compact mode delegates the cold error path of total-fast-path schemas to\n // zod, so they emit no slow walk to share — skip the plan (and the dead\n // shared functions it would generate for shapes that now only delegate).\n const plan = options.compact\n ? undefined\n : createSharedSchemaPlan(\n extracted.map((e) => e.ir),\n options.mode,\n );\n\n // Pass 2: generate each validator, sharing repeated slow walks via the plan\n // and observing which constant declarations survive codegen rollback.\n const generated: Array<{\n exportName: string;\n schema: unknown;\n ir: SchemaIR;\n refEntries: RefEntry[];\n codegenResult: CodeGenResult;\n }> = [];\n const constantsByResult = new Map<CodeGenResult, GeneratedConstant[]>();\n for (const e of extracted) {\n try {\n const constants = new Map<string, GeneratedConstant>();\n const codegenResult = generateValidator(e.ir, e.exportName, {\n refCount: e.refEntries.length,\n mode: options.mode,\n sharedSchemas: plan,\n compact: options.compact,\n onConstant(constant) {\n constants.set(constant.name, constant);\n },\n });\n constantsByResult.set(codegenResult, [...constants.values()]);\n generated.push({\n exportName: e.exportName,\n schema: e.schema,\n ir: e.ir,\n refEntries: e.refEntries,\n codegenResult,\n });\n } catch (err) {\n handle(e.exportName, err);\n }\n }\n\n const initialResults = generated.map(\n ({ exportName, codegenResult, refEntries }): CompiledSchemaInfo => ({\n exportName,\n codegenResult,\n refEntries,\n }),\n );\n const sharedConstantNames = planSharedConstants(initialResults, constantsByResult);\n\n // Regenerate only when sharing is profitable. Selecting shared names before\n // emission avoids textual rewriting of generated JavaScript, where a user\n // enum string can legally contain text resembling a generated identifier.\n if (sharedConstantNames.size > 0) {\n for (const entry of generated) {\n entry.codegenResult = generateValidator(entry.ir, entry.exportName, {\n refCount: entry.refEntries.length,\n mode: options.mode,\n sharedSchemas: plan,\n compact: options.compact,\n sharedConstantNames,\n });\n }\n }\n\n const results: CompiledSchemaInfo[] = generated.map((entry) => ({\n exportName: entry.exportName,\n codegenResult: entry.codegenResult,\n refEntries: entry.refEntries,\n }));\n\n const sharedConstantCode = emitSharedConstants(sharedConstantNames);\n const slowWalkCode = plan?.code ?? \"\";\n const sharedCode =\n sharedConstantCode === \"\"\n ? slowWalkCode\n : slowWalkCode === \"\"\n ? `${SHARED_BLOCK_MARKER}\\n${sharedConstantCode}`\n : `${slowWalkCode}\\n${sharedConstantCode}`;\n\n return {\n schemas: results,\n shared: { code: sharedCode, usedHelpers: plan?.usedHelpers ?? new Set() },\n };\n}\n\n/**\n * Aggregate `usedHelpers` across multiple compiled schemas (typically all schemas in one file).\n * Used by the unplugin transform to construct a single import statement per file.\n */\nexport function aggregateUsedHelpers(schemas: CompiledSchemaInfo[]): Set<string> {\n const all = new Set<string>();\n for (const s of schemas) {\n for (const h of s.codegenResult.usedHelpers) all.add(h);\n }\n return all;\n}\n"],"mappings":"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"}
package/dist/jit.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jit.d.ts","names":[],"sources":["../src/jit.ts"],"mappings":";;;UA4EiB;;;;;;;EAOf;;;;;;;;;;;;;;;;;;;;;;;iBAwBc,IAAI,UAAU,SAC5B,QAAQ,GACR,UAAU,aACT,IAAI,eAAe,OAAO;;;;;;;;;;;;;;iBA2Gb,OAAO,iBAAiB,UAAU"}
1
+ {"version":3,"file":"jit.d.ts","names":[],"sources":["../src/jit.ts"],"mappings":";;;UA4EiB;;;;;;;EAOf;;;;;;;;;;;;;;;;;;;;;;;iBAwBc,IAAI,UAAU,SAC5B,QAAQ,GACR,UAAU,aACT,IAAI,eAAe,OAAO;;;;;;;;;;;;;;iBAkHb,OAAO,iBAAiB,UAAU"}
package/dist/jit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jit.js","names":["zodCore","zodConfig"],"sources":["../src/jit.ts"],"sourcesContent":["/**\n * Runtime compilation — the same extract → codegen pipeline the build plugin\n * runs, executed in-process and evaluated through `new Function`.\n *\n * The AOT paths (unplugin, CLI) need a build step to fire. Plenty of everyday\n * code has none: `tsx server.ts`, `node --experimental-strip-types`, a Jest\n * suite, a serverless handler bundled by someone else's toolchain, a library\n * that ships schemas to consumers. There `compile()` is a no-op and every parse\n * runs plain Zod. `jit()` closes that gap — one call, no build integration,\n * measured 3-25x on everyday schemas at ~0.1-0.2 ms of one-time compilation.\n *\n * Nothing here re-implements validation: {@link compileSchemas} and\n * {@link generateIIFE} are the exact modules the plugin and CLI use, so the\n * generated validator, its Zod parity and its performance are identical to what\n * a build would have emitted. The only difference is *when* the code is\n * produced.\n *\n * Compilation is LAZY by default: `jit()` installs accessors that compile on\n * the first read of a parse method and replace themselves with the compiled\n * ones. Importing a module of 500 schemas therefore costs nothing, and a\n * serverless invocation touching three of them pays for three.\n *\n * Runtime code generation is not always permitted — a strict CSP without\n * `unsafe-eval`, some edge runtimes. Zod v4 has the same constraint (its object\n * fast-pass is itself a `new Function`) and already exposes the two switches\n * for it: the `core.util.allowsEval` probe and `z.config({ jitless: true })`.\n * `jit()` honours both and degrades to plain Zod, so one setting governs both\n * compilers. Those targets are where the build plugin belongs anyway — it emits\n * the same validator with no runtime evaluation at all.\n */\n\nimport { config as zodConfig, core as zodCore, ZodRealError, type output, type ZodType } from \"zod\";\nimport {\n FAIL_CLASS_DECL,\n FAILZ_CLASS_DECL,\n FIN_DECL,\n FIN_DEFERRED_DECL,\n FINZ_DECL,\n generateIIFE,\n MK_VALIDATOR_DECL,\n ZOD_MSG_DECLARATION,\n} from \"./core/iife.js\";\nimport { compileSchemas } from \"./core/pipeline.js\";\nimport type { CompiledSchema } from \"./core/types.js\";\n\n/**\n * The declarations `ZOD_CONFIG_IMPORT` supplies to an emitted module, minus the\n * import itself — `zod`'s three bindings arrive as parameters instead, so the\n * evaluated code has no module scope to resolve. Byte-for-byte the same helper\n * source the CLI emitter writes into a `.compiled.ts`, so a JIT validator and\n * an AOT one share their entire runtime layer.\n */\nconst RUNTIME_PRELUDE = [\n ZOD_MSG_DECLARATION,\n FAIL_CLASS_DECL,\n MK_VALIDATOR_DECL,\n FIN_DECL,\n FIN_DEFERRED_DECL,\n FAILZ_CLASS_DECL,\n FINZ_DECL,\n].join(\"\\n\");\n\n/**\n * Methods `__zcMkv` installs. Each is fronted by a compile-on-read accessor\n * until the schema materializes.\n *\n * `~standard` earns its place: Zod builds it as a closure over `_zod.run`, not\n * over the schema's `safeParse` property, so a Standard Schema consumer (tRPC,\n * Hono, TanStack Form) that never touches `safeParse` would otherwise keep\n * running plain Zod forever behind a \"compiled\" schema.\n */\nconst SLOTS = [\"parse\", \"safeParse\", \"parseAsync\", \"safeParseAsync\", \"is\", \"~standard\"] as const;\n\n/** Schemas already handed to `jit()`, so a second call is a no-op rather than a recompile. */\nconst seen = new WeakSet<object>();\n\nexport interface JitOptions {\n /**\n * Compile immediately instead of on first use. Costs ~0.1-0.2 ms per schema\n * at import time; useful for a long-lived server that would rather pay during\n * startup than on the first request, or to surface a compilation failure\n * eagerly. Default `false`.\n */\n eager?: boolean | undefined;\n}\n\n/**\n * Compile `schema` in-process and install the compiled `parse` / `safeParse` /\n * `parseAsync` / `safeParseAsync` / `is` / `~standard` on it.\n *\n * Returns the SAME object — identity-preserving exactly as the build plugin is,\n * so `.shape`, `_zod`, `instanceof`, `z.toJSONSchema()`, `.meta()` and\n * composition into a larger schema all keep working, and every existing\n * reference to the schema picks the compiled methods up.\n *\n * ```ts\n * import { z } from \"zod\";\n * import { jit } from \"zod-compiler/jit\";\n *\n * export const UserSchema = jit(z.object({ name: z.string(), email: z.email() }));\n * UserSchema.safeParse(input); // compiled on this first call\n * ```\n *\n * Schemas the compiler cannot reproduce fall back to Zod per sub-schema, the\n * same way they do at build time; a schema that cannot be compiled at all is\n * left as plain Zod.\n */\nexport function jit<T extends ZodType>(\n schema: T,\n options?: JitOptions,\n): T & CompiledSchema<output<T>> {\n const target = schema as unknown as Record<string, unknown>;\n if (seen.has(target)) return schema as T & CompiledSchema<output<T>>;\n seen.add(target);\n\n if (options?.eager === true) {\n materialize(schema);\n return schema as T & CompiledSchema<output<T>>;\n }\n\n // Snapshot Zod's own descriptors first: materialize() restores them before\n // handing the object to `__zcMkv`, so the generated code sees a pristine\n // schema — it captures `~standard`'s original `validate` as its throw path,\n // and capturing a stub there would loop back into itself.\n const original = new Map<string, PropertyDescriptor | undefined>();\n for (const slot of SLOTS) {\n original.set(slot, Object.getOwnPropertyDescriptor(target, slot));\n }\n\n // Installing the accessors is the one step that can throw rather than degrade:\n // a slot locked non-configurable (a future Zod, another wrapper) makes\n // defineProperty raise, and `jit()` is called at module scope — so an\n // unhandled throw here takes down the importing app at boot. Roll back to\n // whatever Zod had and leave the schema alone instead.\n let pending = true;\n try {\n installAccessors(\n target,\n original,\n () => {\n if (!pending) return;\n pending = false;\n restore(target, original);\n materialize(schema);\n },\n () => {\n if (!pending) return;\n pending = false;\n // Restore EVERY slot, not just the one being written. A left-behind\n // accessor whose trigger has been cancelled would read `target[slot]`\n // and re-enter itself — unbounded recursion. This is the path the build\n // plugin takes when a file uses `jit()` too: `__zcMkv` assigns the parse\n // methods (cancelling here) and then reads `~standard`.\n restore(target, original);\n },\n );\n } catch {\n pending = false;\n restore(target, original);\n }\n\n return schema as T & CompiledSchema<output<T>>;\n}\n\n/**\n * Front every installed method with a compile-on-read accessor. `trigger`\n * materializes the schema, which replaces these accessors with the compiled\n * methods (or restores Zod's own), so the read that follows never re-enters.\n */\nfunction installAccessors(\n target: Record<string, unknown>,\n original: ReadonlyMap<string, PropertyDescriptor | undefined>,\n trigger: () => void,\n cancel: () => void,\n): void {\n for (const slot of SLOTS) {\n Object.defineProperty(target, slot, {\n configurable: true,\n // Preserve Zod's own visibility: parse/safeParse/... are enumerable own\n // properties, `~standard` is not. `is` does not exist on a Zod schema, so\n // it follows the non-enumerable convention `compile()` already uses.\n enumerable: original.get(slot)?.enumerable ?? false,\n get() {\n trigger();\n // Whatever now occupies the slot: the compiled method, or — if\n // compilation was impossible — Zod's own, put back by restore().\n return target[slot];\n },\n set(value: unknown) {\n // Someone overwrote a method before first use (a test double, another\n // wrapper). Their value wins, and compilation is cancelled outright —\n // materializing later would restore Zod's descriptors over it.\n cancel();\n Object.defineProperty(target, slot, {\n configurable: true,\n enumerable: original.get(slot)?.enumerable ?? false,\n value,\n writable: true,\n });\n },\n });\n }\n}\n\n/**\n * Compile every Zod schema found among an object's own values — typically a\n * module namespace, so a whole schema file opts in with one call:\n *\n * ```ts\n * import * as schemas from \"./schemas.js\";\n * jitAll(schemas);\n * ```\n *\n * The namespace object itself is never written to (a module namespace is\n * read-only); `jit()` mutates the schema objects it holds, which is what every\n * importer of that module already references.\n */\nexport function jitAll(schemas: object, options?: JitOptions): void {\n for (const value of Object.values(schemas)) {\n if (isZodSchema(value)) jit(value, options);\n }\n}\n\n/** Zod schemas carry `_zod.def`; the same probe auto-discovery uses at build time. */\nfunction isZodSchema(value: unknown): value is ZodType {\n if (typeof value !== \"object\" || value === null || !(\"_zod\" in value)) return false;\n const internal = (value as Record<string, unknown>)[\"_zod\"];\n return typeof internal === \"object\" && internal !== null && \"def\" in internal;\n}\n\n/** Put Zod's own descriptors back, dropping the compile-on-read accessors. */\nfunction restore(\n target: Record<string, unknown>,\n original: ReadonlyMap<string, PropertyDescriptor | undefined>,\n): void {\n for (const slot of SLOTS) {\n const descriptor = original.get(slot);\n if (descriptor === undefined) delete target[slot];\n else Object.defineProperty(target, slot, descriptor);\n }\n}\n\n/**\n * Whether runtime code generation is permitted here. Read per call, never\n * snapshotted: `z.config({ jitless: true })` runs in an entry point, after the\n * schema modules it imports have already been evaluated.\n */\nfunction codegenAllowed(): boolean {\n return zodCore.globalConfig.jitless !== true && zodCore.util.allowsEval.value;\n}\n\n/**\n * Run the pipeline and let the generated IIFE install its methods on `schema`.\n * Swallows failure: a schema that cannot be compiled keeps Zod's own methods,\n * which the caller already has, so there is nothing to report and nothing to\n * break.\n */\nfunction materialize(schema: unknown): void {\n if (!codegenAllowed()) return;\n try {\n buildValidator(schema);\n } catch {\n // Left as plain Zod. Deliberately silent: `jit()` is an optimization, and a\n // schema using a construct the compiler declines is a supported outcome,\n // not an error.\n }\n}\n\n/**\n * Generate the validator and evaluate it, reproducing the module a\n * `.compiled.ts` would have been: helper preamble, the file-level shared block,\n * then the `__zcMkv` IIFE whose `__rf[]` bases and install target are the live\n * schema object passed in as `__schema`.\n */\nfunction buildValidator(schema: unknown): void {\n const { schemas, shared } = compileSchemas([{ exportName: \"jit\", schema }], { mode: \"inline\" });\n const compiled = schemas[0];\n if (compiled === undefined) throw new Error(\"zod-compiler: schema produced no validator\");\n\n const body = [RUNTIME_PRELUDE, shared.code, `return ${generateIIFE(\"__schema\", compiled)};`].join(\n \"\\n\",\n );\n\n // The three bindings ZOD_CONFIG_IMPORT would have imported, passed in so the\n // evaluated code needs no module resolution of its own.\n // oxlint-disable-next-line no-new-func -- generating the validator IS the feature\n const factory = new Function(\n \"__zodCompilerConfig\",\n \"__zcCore\",\n \"__zcZodError\",\n \"__schema\",\n body,\n ) as (\n zodConfigFn: typeof zodConfig,\n zodCoreNs: typeof zodCore,\n zodErrorCtor: typeof ZodRealError,\n target: unknown,\n ) => unknown;\n\n factory(zodConfig, zodCore, ZodRealError, schema);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;;;;;;;;;AAWX,MAAM,QAAQ;CAAC;CAAS;CAAa;CAAc;CAAkB;CAAM;AAAW;;AAGtF,MAAM,uBAAO,IAAI,QAAgB;;;;;;;;;;;;;;;;;;;;;;AAiCjC,SAAgB,IACd,QACA,SAC+B;CAC/B,MAAM,SAAS;CACf,IAAI,KAAK,IAAI,MAAM,GAAG,OAAO;CAC7B,KAAK,IAAI,MAAM;CAEf,IAAI,SAAS,UAAU,MAAM;EAC3B,YAAY,MAAM;EAClB,OAAO;CACT;CAMA,MAAM,2BAAW,IAAI,IAA4C;CACjE,KAAK,MAAM,QAAQ,OACjB,SAAS,IAAI,MAAM,OAAO,yBAAyB,QAAQ,IAAI,CAAC;CAQlE,IAAI,UAAU;CACd,IAAI;EACF,iBACE,QACA,gBACM;GACJ,IAAI,CAAC,SAAS;GACd,UAAU;GACV,QAAQ,QAAQ,QAAQ;GACxB,YAAY,MAAM;EACpB,SACM;GACJ,IAAI,CAAC,SAAS;GACd,UAAU;GAMV,QAAQ,QAAQ,QAAQ;EAC1B,CACF;CACF,QAAQ;EACN,UAAU;EACV,QAAQ,QAAQ,QAAQ;CAC1B;CAEA,OAAO;AACT;;;;;;AAOA,SAAS,iBACP,QACA,UACA,SACA,QACM;CACN,KAAK,MAAM,QAAQ,OACjB,OAAO,eAAe,QAAQ,MAAM;EAClC,cAAc;EAId,YAAY,SAAS,IAAI,IAAI,CAAC,EAAE,cAAc;EAC9C,MAAM;GACJ,QAAQ;GAGR,OAAO,OAAO;EAChB;EACA,IAAI,OAAgB;GAIlB,OAAO;GACP,OAAO,eAAe,QAAQ,MAAM;IAClC,cAAc;IACd,YAAY,SAAS,IAAI,IAAI,CAAC,EAAE,cAAc;IAC9C;IACA,UAAU;GACZ,CAAC;EACH;CACF,CAAC;AAEL;;;;;;;;;;;;;;AAeA,SAAgB,OAAO,SAAiB,SAA4B;CAClE,KAAK,MAAM,SAAS,OAAO,OAAO,OAAO,GACvC,IAAI,YAAY,KAAK,GAAG,IAAI,OAAO,OAAO;AAE9C;;AAGA,SAAS,YAAY,OAAkC;CACrD,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,UAAU,QAAQ,OAAO;CAC9E,MAAM,WAAY,MAAkC;CACpD,OAAO,OAAO,aAAa,YAAY,aAAa,QAAQ,SAAS;AACvE;;AAGA,SAAS,QACP,QACA,UACM;CACN,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,aAAa,SAAS,IAAI,IAAI;EACpC,IAAI,eAAe,KAAA,GAAW,OAAO,OAAO;OACvC,OAAO,eAAe,QAAQ,MAAM,UAAU;CACrD;AACF;;;;;;AAOA,SAAS,iBAA0B;CACjC,OAAOA,KAAQ,aAAa,YAAY,QAAQA,KAAQ,KAAK,WAAW;AAC1E;;;;;;;AAQA,SAAS,YAAY,QAAuB;CAC1C,IAAI,CAAC,eAAe,GAAG;CACvB,IAAI;EACF,eAAe,MAAM;CACvB,QAAQ,CAIR;AACF;;;;;;;AAQA,SAAS,eAAe,QAAuB;CAC7C,MAAM,EAAE,SAAS,WAAW,eAAe,CAAC;EAAE,YAAY;EAAO;CAAO,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC;CAC9F,MAAM,WAAW,QAAQ;CACzB,IAAI,aAAa,KAAA,GAAW,MAAM,IAAI,MAAM,4CAA4C;CAExF,MAAM,OAAO;EAAC;EAAiB,OAAO;EAAM,UAAU,aAAa,YAAY,QAAQ,EAAE;CAAE,CAAC,CAAC,KAC3F,IACF;CAkBA,IAboB,SAClB,uBACA,YACA,gBACA,YACA,IAQI,CAAC,CAACC,QAAWD,MAAS,cAAc,MAAM;AAClD"}
1
+ {"version":3,"file":"jit.js","names":["zodCore","zodConfig"],"sources":["../src/jit.ts"],"sourcesContent":["/**\n * Runtime compilation — the same extract → codegen pipeline the build plugin\n * runs, executed in-process and evaluated through `new Function`.\n *\n * The AOT paths (unplugin, CLI) need a build step to fire. Plenty of everyday\n * code has none: `tsx server.ts`, `node --experimental-strip-types`, a Jest\n * suite, a serverless handler bundled by someone else's toolchain, a library\n * that ships schemas to consumers. There `compile()` is a no-op and every parse\n * runs plain Zod. `jit()` closes that gap — one call, no build integration,\n * measured 3-25x on everyday schemas at ~0.1-0.2 ms of one-time compilation.\n *\n * Nothing here re-implements validation: {@link compileSchemas} and\n * {@link generateIIFE} are the exact modules the plugin and CLI use, so the\n * generated validator, its Zod parity and its performance are identical to what\n * a build would have emitted. The only difference is *when* the code is\n * produced.\n *\n * Compilation is LAZY by default: `jit()` installs accessors that compile on\n * the first read of a parse method and replace themselves with the compiled\n * ones. Importing a module of 500 schemas therefore costs nothing, and a\n * serverless invocation touching three of them pays for three.\n *\n * Runtime code generation is not always permitted — a strict CSP without\n * `unsafe-eval`, some edge runtimes. Zod v4 has the same constraint (its object\n * fast-pass is itself a `new Function`) and already exposes the two switches\n * for it: the `core.util.allowsEval` probe and `z.config({ jitless: true })`.\n * `jit()` honours both and degrades to plain Zod, so one setting governs both\n * compilers. Those targets are where the build plugin belongs anyway — it emits\n * the same validator with no runtime evaluation at all.\n */\n\nimport { config as zodConfig, core as zodCore, ZodRealError, type output, type ZodType } from \"zod\";\nimport {\n FAIL_CLASS_DECL,\n FAILZ_CLASS_DECL,\n FIN_DECL,\n FIN_DEFERRED_DECL,\n FINZ_DECL,\n generateIIFE,\n MK_VALIDATOR_DECL,\n ZOD_MSG_DECLARATION,\n} from \"./core/iife.js\";\nimport { compileSchemas } from \"./core/pipeline.js\";\nimport type { CompiledSchema } from \"./core/types.js\";\n\n/**\n * The declarations `ZOD_CONFIG_IMPORT` supplies to an emitted module, minus the\n * import itself — `zod`'s three bindings arrive as parameters instead, so the\n * evaluated code has no module scope to resolve. Byte-for-byte the same helper\n * source the CLI emitter writes into a `.compiled.ts`, so a JIT validator and\n * an AOT one share their entire runtime layer.\n */\nconst RUNTIME_PRELUDE = [\n ZOD_MSG_DECLARATION,\n FAIL_CLASS_DECL,\n MK_VALIDATOR_DECL,\n FIN_DECL,\n FIN_DEFERRED_DECL,\n FAILZ_CLASS_DECL,\n FINZ_DECL,\n].join(\"\\n\");\n\n/**\n * Methods `__zcMkv` installs. Each is fronted by a compile-on-read accessor\n * until the schema materializes.\n *\n * `~standard` earns its place: Zod builds it as a closure over `_zod.run`, not\n * over the schema's `safeParse` property, so a Standard Schema consumer (tRPC,\n * Hono, TanStack Form) that never touches `safeParse` would otherwise keep\n * running plain Zod forever behind a \"compiled\" schema.\n */\nconst SLOTS = [\"parse\", \"safeParse\", \"parseAsync\", \"safeParseAsync\", \"is\", \"~standard\"] as const;\n\n/** Schemas already handed to `jit()`, so a second call is a no-op rather than a recompile. */\nconst seen = new WeakSet<object>();\n\nexport interface JitOptions {\n /**\n * Compile immediately instead of on first use. Costs ~0.1-0.2 ms per schema\n * at import time; useful for a long-lived server that would rather pay during\n * startup than on the first request, or to surface a compilation failure\n * eagerly. Default `false`.\n */\n eager?: boolean | undefined;\n}\n\n/**\n * Compile `schema` in-process and install the compiled `parse` / `safeParse` /\n * `parseAsync` / `safeParseAsync` / `is` / `~standard` on it.\n *\n * Returns the SAME object — identity-preserving exactly as the build plugin is,\n * so `.shape`, `_zod`, `instanceof`, `z.toJSONSchema()`, `.meta()` and\n * composition into a larger schema all keep working, and every existing\n * reference to the schema picks the compiled methods up.\n *\n * ```ts\n * import { z } from \"zod\";\n * import { jit } from \"zod-compiler/jit\";\n *\n * export const UserSchema = jit(z.object({ name: z.string(), email: z.email() }));\n * UserSchema.safeParse(input); // compiled on this first call\n * ```\n *\n * Schemas the compiler cannot reproduce fall back to Zod per sub-schema, the\n * same way they do at build time; a schema that cannot be compiled at all is\n * left as plain Zod.\n */\nexport function jit<T extends ZodType>(\n schema: T,\n options?: JitOptions,\n): T & CompiledSchema<output<T>> {\n const target = schema as unknown as Record<string, unknown>;\n if (seen.has(target)) return schema as T & CompiledSchema<output<T>>;\n seen.add(target);\n\n if (options?.eager === true) {\n materialize(schema);\n return schema as T & CompiledSchema<output<T>>;\n }\n\n // Snapshot Zod's own descriptors first: materialize() restores them before\n // handing the object to `__zcMkv`, so the generated code sees a pristine\n // schema — it captures the original `parseAsync` / `safeParseAsync` as its\n // throw paths, and capturing a stub there would loop back into itself.\n const original = new Map<string, PropertyDescriptor | undefined>();\n for (const slot of SLOTS) {\n original.set(slot, Object.getOwnPropertyDescriptor(target, slot));\n }\n\n // Installing the accessors is the one step that can throw rather than degrade:\n // a slot locked non-configurable (a future Zod, another wrapper) makes\n // defineProperty raise, and `jit()` is called at module scope — so an\n // unhandled throw here takes down the importing app at boot. Roll back to\n // whatever Zod had and leave the schema alone instead.\n let pending = true;\n try {\n installAccessors(\n target,\n original,\n () => {\n if (!pending) return;\n pending = false;\n restore(target, original);\n materialize(schema);\n },\n () => {\n if (!pending) return;\n pending = false;\n // Restore EVERY slot, not just the one being written. A left-behind\n // accessor whose trigger has been cancelled would read `target[slot]`\n // and re-enter itself — unbounded recursion, which is what a later read\n // of an untouched slot (`~standard`, from a Standard Schema consumer)\n // would otherwise hit.\n //\n // Reached only when something WRITES a slot before anything reads one: a\n // test double, another wrapper, or an AOT `safeParse` assigned directly.\n // The build plugin's own `__zcMkv` does not land here — its first\n // statement READS `parseAsync`/`safeParseAsync` to capture their\n // originals, so it triggers materialization and then overwrites the\n // compiled-by-jit methods with the compiled-by-plugin ones.\n restore(target, original);\n },\n );\n } catch {\n pending = false;\n restore(target, original);\n }\n\n return schema as T & CompiledSchema<output<T>>;\n}\n\n/**\n * Front every installed method with a compile-on-read accessor. `trigger`\n * materializes the schema, which replaces these accessors with the compiled\n * methods (or restores Zod's own), so the read that follows never re-enters.\n */\nfunction installAccessors(\n target: Record<string, unknown>,\n original: ReadonlyMap<string, PropertyDescriptor | undefined>,\n trigger: () => void,\n cancel: () => void,\n): void {\n for (const slot of SLOTS) {\n Object.defineProperty(target, slot, {\n configurable: true,\n // Preserve Zod's own visibility: parse/safeParse/... are enumerable own\n // properties, `~standard` is not. `is` does not exist on a Zod schema, so\n // it follows the non-enumerable convention `compile()` already uses.\n enumerable: original.get(slot)?.enumerable ?? false,\n get() {\n trigger();\n // Whatever now occupies the slot: the compiled method, or — if\n // compilation was impossible — Zod's own, put back by restore().\n return target[slot];\n },\n set(value: unknown) {\n // Someone overwrote a method before first use (a test double, another\n // wrapper). Their value wins, and compilation is cancelled outright —\n // materializing later would restore Zod's descriptors over it.\n cancel();\n Object.defineProperty(target, slot, {\n configurable: true,\n enumerable: original.get(slot)?.enumerable ?? false,\n value,\n writable: true,\n });\n },\n });\n }\n}\n\n/**\n * Compile every Zod schema found among an object's own values — typically a\n * module namespace, so a whole schema file opts in with one call:\n *\n * ```ts\n * import * as schemas from \"./schemas.js\";\n * jitAll(schemas);\n * ```\n *\n * The namespace object itself is never written to (a module namespace is\n * read-only); `jit()` mutates the schema objects it holds, which is what every\n * importer of that module already references.\n */\nexport function jitAll(schemas: object, options?: JitOptions): void {\n for (const value of Object.values(schemas)) {\n if (isZodSchema(value)) jit(value, options);\n }\n}\n\n/** Zod schemas carry `_zod.def`; the same probe auto-discovery uses at build time. */\nfunction isZodSchema(value: unknown): value is ZodType {\n if (typeof value !== \"object\" || value === null || !(\"_zod\" in value)) return false;\n const internal = (value as Record<string, unknown>)[\"_zod\"];\n return typeof internal === \"object\" && internal !== null && \"def\" in internal;\n}\n\n/** Put Zod's own descriptors back, dropping the compile-on-read accessors. */\nfunction restore(\n target: Record<string, unknown>,\n original: ReadonlyMap<string, PropertyDescriptor | undefined>,\n): void {\n for (const slot of SLOTS) {\n const descriptor = original.get(slot);\n if (descriptor === undefined) delete target[slot];\n else Object.defineProperty(target, slot, descriptor);\n }\n}\n\n/**\n * Whether runtime code generation is permitted here. Read per call, never\n * snapshotted: `z.config({ jitless: true })` runs in an entry point, after the\n * schema modules it imports have already been evaluated.\n */\nfunction codegenAllowed(): boolean {\n return zodCore.globalConfig.jitless !== true && zodCore.util.allowsEval.value;\n}\n\n/**\n * Run the pipeline and let the generated IIFE install its methods on `schema`.\n * Swallows failure: a schema that cannot be compiled keeps Zod's own methods,\n * which the caller already has, so there is nothing to report and nothing to\n * break.\n */\nfunction materialize(schema: unknown): void {\n if (!codegenAllowed()) return;\n try {\n buildValidator(schema);\n } catch {\n // Left as plain Zod. Deliberately silent: `jit()` is an optimization, and a\n // schema using a construct the compiler declines is a supported outcome,\n // not an error.\n }\n}\n\n/**\n * Generate the validator and evaluate it, reproducing the module a\n * `.compiled.ts` would have been: helper preamble, the file-level shared block,\n * then the `__zcMkv` IIFE whose `__rf[]` bases and install target are the live\n * schema object passed in as `__schema`.\n */\nfunction buildValidator(schema: unknown): void {\n const { schemas, shared } = compileSchemas([{ exportName: \"jit\", schema }], { mode: \"inline\" });\n const compiled = schemas[0];\n if (compiled === undefined) throw new Error(\"zod-compiler: schema produced no validator\");\n\n const body = [RUNTIME_PRELUDE, shared.code, `return ${generateIIFE(\"__schema\", compiled)};`].join(\n \"\\n\",\n );\n\n // The three bindings ZOD_CONFIG_IMPORT would have imported, passed in so the\n // evaluated code needs no module resolution of its own.\n // oxlint-disable-next-line no-new-func -- generating the validator IS the feature\n const factory = new Function(\n \"__zodCompilerConfig\",\n \"__zcCore\",\n \"__zcZodError\",\n \"__schema\",\n body,\n ) as (\n zodConfigFn: typeof zodConfig,\n zodCoreNs: typeof zodCore,\n zodErrorCtor: typeof ZodRealError,\n target: unknown,\n ) => unknown;\n\n factory(zodConfig, zodCore, ZodRealError, schema);\n}\n"],"mappings":"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"}
package/dist/runtime.d.ts CHANGED
@@ -51,3 +51,9 @@ export declare const __zcReE164: any;
51
51
  export declare const __zcReE164Src: any;
52
52
  export declare const __zcReGuid: any;
53
53
  export declare const __zcReGuidSrc: any;
54
+ export declare const __zcReIsoDate: any;
55
+ export declare const __zcReIsoDateSrc: any;
56
+ export declare const __zcReIsoTime: any;
57
+ export declare const __zcReIsoDateTime: any;
58
+ export declare const __zcReIsoDateTimeSrc: any;
59
+ export declare const __zcReIsoDuration: any;
package/dist/runtime.js CHANGED
@@ -2,7 +2,7 @@ import { config as __zodCompilerConfig, core as __zcCore, ZodRealError as __zcZo
2
2
  function __zcUw(m){return typeof m==="string"?m:(m===undefined||m===null?undefined:m.message);}var __zcMsg=function(iss){var c=__zodCompilerConfig(),m;if(c.customError){m=__zcUw(c.customError(iss));if(m!==undefined&&m!==null)return m;}if(c.localeError){m=__zcUw(c.localeError(iss));if(m!==undefined&&m!==null)return m;}return "Invalid input";};
3
3
  function __ZcFail(e,f,i){this.success=false;this._e=e;this._f=f;this._i=i;this._c=undefined;}Object.defineProperty(__ZcFail.prototype,"error",{configurable:true,get:function(){if(this._c)return this._c;var e=this._f!==null?this._f(this._i):this._e;for(var i=0;i<e.length;i++){if(e[i].message===undefined&&typeof __zcMsg==="function")e[i].message=__zcMsg(e[i]);delete e[i].input;delete e[i].continue;}return this._c=new __zcZodError(e);}});
4
4
  function __ZcFailZ(z,r,i){this.success=false;this._z=z;this._r=r;this._i=i;this._c=undefined;}Object.defineProperty(__ZcFailZ.prototype,"error",{configurable:true,get:function(){return this._c||(this._c=this._z.call(this._r,this._i).error);}});
5
- export function __zcMkv(fn,schema,fc,is){var w=schema||{};var zpa=w.parseAsync,zspa=w.safeParseAsync;w.parse=fc?function(input){if(fc(input))return input;var r=fn(input);if(r.success)return r.data;throw r.error;}:function(input){var r=fn(input);if(r.success)return r.data;throw r.error;};w.safeParse=fn;w.safeParseAsync=function(input){try{return Promise.resolve(fn(input));}catch(e){if(zspa)return zspa(input);throw e;}};w.parseAsync=fc?function(input){try{if(fc(input))return Promise.resolve(input);var r=fn(input);if(r.success)return Promise.resolve(r.data);return Promise.reject(r.error);}catch(e){if(zpa)return zpa(input);throw e;}}:function(input){try{var r=fn(input);if(r.success)return Promise.resolve(r.data);return Promise.reject(r.error);}catch(e){if(zpa)return zpa(input);throw e;}};w.is=is||function(input){return fn(input).success;};var s=w["~standard"],zv=s&&s.validate;Object.defineProperty(w,"~standard",{configurable:true,value:{version:1,vendor:(s&&s.vendor)||"zod",validate:function(input){var r;try{if(fc&&fc(input))return{value:input};r=fn(input);}catch(e){if(zv)return zv(input);throw e;}return r.success?{value:r.data}:{issues:r.error.issues};}}});return w;}
5
+ export function __zcMkv(fn,schema,fc,is){var w=schema||{};var zpa=w.parseAsync,zspa=w.safeParseAsync;w.parse=fc?function(input){if(fc(input))return input;var r=fn(input);if(r.success)return r.data;throw r.error;}:function(input){var r=fn(input);if(r.success)return r.data;throw r.error;};w.safeParse=fn;w.safeParseAsync=function(input){try{return Promise.resolve(fn(input));}catch(e){if(zspa)return zspa(input);throw e;}};w.parseAsync=fc?function(input){try{if(fc(input))return Promise.resolve(input);var r=fn(input);if(r.success)return Promise.resolve(r.data);return Promise.reject(r.error);}catch(e){if(zpa)return zpa(input);throw e;}}:function(input){try{var r=fn(input);if(r.success)return Promise.resolve(r.data);return Promise.reject(r.error);}catch(e){if(zpa)return zpa(input);throw e;}};w.is=is||function(input){return fn(input).success;};Object.defineProperty(w,"~standard",{configurable:true,value:{version:1,vendor:"zod",validate:function(input){var r;try{if(fc&&fc(input))return{value:input};r=fn(input);}catch(e){if(zspa)return zspa(input).then(function(q){return q.success?{value:q.data}:{issues:q.error.issues};});throw e;}return r.success?{value:r.data}:{issues:r.error.issues};}}});return w;}
6
6
  export function __zcFin(e,d){if(!e.length)return{success:true,data:d};return new __ZcFail(e,null,null);}
7
7
  export function __zcFinD(f,inp){return new __ZcFail(null,f,inp);}
8
8
  export function __zcFinZ(z,r,i){return new __ZcFailZ(z,r,i);}
@@ -53,3 +53,9 @@ export const __zcReE164=new RegExp("^\\+[1-9]\\d\\d\\d\\d\\d\\d\\d?\\d?\\d?\\d?\
53
53
  export const __zcReE164Src="/^\\+[1-9]\\d{6,14}$/";
54
54
  export const __zcReGuid=new RegExp("^([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])$");
55
55
  export const __zcReGuidSrc="/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/";
56
+ export const __zcReIsoDate=new RegExp("^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d\\d\\d\\d-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$");
57
+ export const __zcReIsoDateSrc="/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$/";
58
+ export const __zcReIsoTime=new RegExp("^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?$");
59
+ export const __zcReIsoDateTime=new RegExp("^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d\\d\\d\\d-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$");
60
+ export const __zcReIsoDateTimeSrc="/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/";
61
+ export const __zcReIsoDuration=new RegExp("^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$");
@@ -1,5 +1,5 @@
1
- import { FAILZ_CLASS_DECL, FAIL_CLASS_DECL, FINZ_DECL, FIN_DECL, FIN_DEFERRED_DECL, MK_VALIDATOR_DECL, ZOD_CONFIG_IMPORT, ZOD_MSG_DECLARATION } from "../core/iife.js";
2
1
  import { WELL_KNOWN_REGEXES, fastTestSource } from "../core/codegen/well-known-regex.js";
2
+ import { FAILZ_CLASS_DECL, FAIL_CLASS_DECL, FINZ_DECL, FIN_DECL, FIN_DEFERRED_DECL, MK_VALIDATOR_DECL, ZOD_CONFIG_IMPORT, ZOD_MSG_DECLARATION } from "../core/iife.js";
3
3
  import { ISSUE_DECLS, RUNTIME_HELPER_DECLS, ZC_SR_RUN_DECL } from "../core/codegen/issue-decls.js";
4
4
  //#region src/unplugin/virtual.ts
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod-compiler",
3
- "version": "1.26.1",
3
+ "version": "1.26.2",
4
4
  "description": "Compile Zod schemas into zero-overhead validation functions",
5
5
  "keywords": [
6
6
  "aot",