zod-compiler 1.23.8 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"hoist.js","names":[],"sources":["../../src/unplugin/hoist.ts"],"sourcesContent":["import type { AnyNode, Expression, Options } from \"acorn\";\nimport { Parser } from \"acorn\";\nimport { applyEdits, type Edit, type Insertion } from \"./edits.js\";\n\n/**\n * Hoist Zod schema construction out of functions to module scope —\n * equivalent of babel-plugin-zod-hoist.\n *\n * Schemas built inside function bodies are re-constructed on every call:\n *\n * function getSchema() {\n * return z.object({ name: z.string() }); // rebuilt per call\n * }\n *\n * becomes\n *\n * const _zh_94b7f5c1 = z.object({ name: z.string() });\n * function getSchema() {\n * return _zh_94b7f5c1; // built once\n * }\n *\n * Safety rules (babel-plugin-zod-hoist's `canSafelyHoist`, hardened for\n * lexical analysis):\n * - A free identifier must be an import or a KNOWN_GLOBALS member, and must\n * never be bound anywhere in the file (function params, locals, catch\n * clauses, class names, module-level const/let/var — hoisting above those\n * would change meaning or hit the TDZ). The babel plugin additionally\n * allows arbitrary unbound identifiers because it has real scope\n * information; this port's binding collector is lexical, so an unknown\n * bare name is treated as a possibly-missed binding rather than a global\n * (a wrong guess crashes at module load with a ReferenceError).\n * `this`/`super` disqualify anywhere. Eager `await`/`yield` also\n * disqualify (stricter than the babel plugin, which never encounters\n * them: hoisting one would emit top-level await / orphaned yield).\n * - Eligible roots: any binding imported from zod, an imported identifier\n * matching /ZodSchema$/, or an imported identifier whose chain contains\n * an inline z.* reference (e.g. `Base.extend({ a: z.string() })`).\n * - Nesting (babel's `isNestedInZodCall`): the interior of a zod-rooted\n * chain never hoists separately — it goes with the outer schema or not at\n * all. Chains rooted elsewhere (`sql.type(...)`, `api.get(...)`) do NOT\n * suppress their arguments: when the outer chain is rejected, an inner\n * `z.object({...})` still hoists on its own.\n * - Declarations are inserted at the top of the module (after shebang and\n * directive prologue). Imports are initialized before module code runs,\n * so referencing them from above their textual position is safe.\n * - Names are content-hashed, so identical schemas dedupe to one binding.\n *\n * The source is TypeScript, which acorn cannot fully parse — candidates are\n * located with a string/comment/depth-aware scanner and extracted with\n * parseExpressionAt (the same technique as the autoDiscover rewrite).\n * Anything unparseable (TS generics, `as` casts) is skipped: a miss leaves\n * the schema unhoisted, never breaks the code.\n */\n\n/**\n * Imported identifiers matching this pattern are treated as schema roots.\n *\n * The default must keep implying a \"Zod\" substring: it is one of the three\n * triggers the transform hook's `code` filter (ZOD_MENTION in transform.ts)\n * is a superset of. A default that matched, say, `/Schema$/` would make\n * hoistable files without any \"zod\" mention invisible to bundlers with native\n * hook filters. (A *user-supplied* pattern is handled — it drops the filter.)\n */\nexport const SCHEMA_NAME_PATTERN = /ZodSchema$/;\n\n/**\n * Module specifiers whose bindings count as the zod namespace. Every entry\n * must contain \"zod\" for the same reason as SCHEMA_NAME_PATTERN above; both\n * are pinned by `describe(\"code filter soundness\")` in the transform tests.\n */\nexport const ZOD_MODULES = new Set([\"zod\", \"zod/v3\", \"zod/v4\", \"zod/mini\", \"zod/v4/mini\"]);\n\n/** How an imported local binding maps onto its source module. */\nexport interface ImportDetail {\n /** Module specifier (`\"zod\"`, `\"./shapes\"`). */\n specifier: string;\n /** Exported name the binding refers to; `\"*\"` for namespace imports, `\"default\"` for default imports. */\n imported: string;\n}\n\ninterface ImportBindings {\n /** Every runtime (non-type) imported binding name. */\n all: Set<string>;\n /** Bindings imported from a zod module (usually just `z`). */\n zod: Set<string>;\n /** Local binding name → source module/export, for build-time evaluation. */\n details: Map<string, ImportDetail>;\n}\n\n/**\n * Collect runtime import bindings with a regex over import statements.\n * Type-only imports and `type` specifiers are excluded — they cannot be\n * referenced at runtime, so excluding them keeps the capture rule sound.\n */\nexport function collectImportBindings(code: string): ImportBindings {\n const all = new Set<string>();\n const zod = new Set<string>();\n const details = new Map<string, ImportDetail>();\n const importPattern = /import\\s+(type\\s+)?([^'\";]+?)\\s+from\\s*[\"']([^\"']+)[\"']/g;\n\n for (const match of code.matchAll(importPattern)) {\n const [, typeOnly, clause, specifier] = match;\n if (typeOnly || clause === undefined || specifier === undefined) continue;\n const isZod = ZOD_MODULES.has(specifier);\n for (const { local, imported } of parseImportClause(clause)) {\n all.add(local);\n if (isZod) zod.add(local);\n details.set(local, { specifier, imported });\n }\n }\n return { all, zod, details };\n}\n\n/** Extract local binding names (with their source export) from an import clause. */\nfunction parseImportClause(clause: string): Array<{ local: string; imported: string }> {\n const names: Array<{ local: string; imported: string }> = [];\n const namedStart = clause.indexOf(\"{\");\n\n // Default import and/or namespace import before the named group\n const head = namedStart === -1 ? clause : clause.slice(0, namedStart);\n for (const part of head.split(\",\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const ns = trimmed.match(/^\\*\\s*as\\s+([A-Za-z_$][\\w$]*)$/);\n if (ns?.[1]) {\n names.push({ local: ns[1], imported: \"*\" });\n } else if (/^[A-Za-z_$][\\w$]*$/.test(trimmed)) {\n names.push({ local: trimmed, imported: \"default\" });\n }\n }\n\n if (namedStart !== -1) {\n const namedEnd = clause.indexOf(\"}\", namedStart);\n const inner = clause.slice(namedStart + 1, namedEnd === -1 ? undefined : namedEnd);\n for (const part of inner.split(\",\")) {\n const spec = part.trim();\n if (!spec || spec.startsWith(\"type \")) continue;\n // `a as b` binds b; plain `a` binds a\n const asMatch = spec.match(/^([A-Za-z_$][\\w$]*)\\s+as\\s+([A-Za-z_$][\\w$]*)$/);\n if (asMatch?.[1] && asMatch[2]) {\n names.push({ local: asMatch[2], imported: asMatch[1] });\n } else if (/^[A-Za-z_$][\\w$]*$/.test(spec)) {\n names.push({ local: spec, imported: spec });\n }\n }\n }\n return names;\n}\n\n/** Deterministic FNV-1a 32-bit hash, hex-encoded. */\nfunction fnv1a(text: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, \"0\");\n}\n\ninterface Candidate {\n /** Offset of the root identifier. */\n index: number;\n /** Bracket/brace/paren depth at the offset (0 = top level). */\n depth: number;\n /** The root identifier text. */\n name: string;\n /**\n * The candidate directly follows `=>` — a concise arrow body. Even at\n * depth 0 (`const make = () => z.object(...)`) it re-evaluates per call.\n */\n afterArrow: boolean;\n}\n\n/**\n * Char-code identifier/whitespace classes for the scanner hot loops — a\n * regex `.test()` per character dominated scan time once the acorn parses\n * were gone. The ident classes are deliberately ASCII-only (`[A-Za-z_$]` /\n * `[\\w$]`, matching the scanner's historical regexes); the space check falls\n * back to `/\\s/` for the rare non-ASCII code points it matches (NBSP, BOM,\n * U+2028...).\n */\nfunction isIdentStartCode(c: number): boolean {\n return (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || c === 95 || c === 36;\n}\nfunction isIdentPartCode(c: number): boolean {\n return (\n (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || (c >= 48 && c <= 57) || c === 95 || c === 36\n );\n}\nfunction isSpaceCode(c: number): boolean {\n if (c === 32 || (c >= 9 && c <= 13)) return true;\n return c > 127 && /\\s/.test(String.fromCharCode(c));\n}\n\n/** After these tokens a `/` starts a regex literal, not division. */\nconst REGEX_PRECEDING_KEYWORDS = new Set([\n \"return\",\n \"typeof\",\n \"instanceof\",\n \"in\",\n \"of\",\n \"new\",\n \"delete\",\n \"void\",\n \"throw\",\n \"do\",\n \"else\",\n \"case\",\n \"yield\",\n \"await\",\n]);\n\n/** Is `/` after this token division (true) or a regex literal (false)? */\nfunction isDivisionContext(lastToken: string): boolean {\n if (lastToken === \")\" || lastToken === \"]\") return true;\n if (/^[\"'`]$/.test(lastToken)) return true;\n if (/^[\\w$]+$/.test(lastToken)) return !REGEX_PRECEDING_KEYWORDS.has(lastToken);\n return false;\n}\n\ninterface ScanResult {\n candidates: Candidate[];\n /**\n * Lazily builds the source with comments, string/template-string contents,\n * and regex literals masked to spaces (offsets preserved). Used for\n * binding-name collection so JSDoc examples and string contents never\n * count. Lazy because it is only needed when a candidate survives to\n * shadow-checking — schema modules (everything masked at depth 0) never\n * pay for it.\n */\n stripped: () => string;\n}\n\n/**\n * Scan the source for candidate root identifiers (`z`, `FooZodSchema`, ...)\n * followed by a `.`, tracking string/template/comment state and nesting\n * depth. Depth 0 candidates are top-level initializers — already evaluated\n * once — and are recorded only so their extents mask nested candidates.\n */\nfunction scanSource(code: string, roots: Set<string>): ScanResult {\n const candidates: Candidate[] = [];\n // Masked extents as flat [from, to) pairs, pushed in scan order (monotonic,\n // non-overlapping) — materialized into a stripped string only on demand.\n const maskRanges: number[] = [];\n const mask = (from: number, to: number): void => {\n maskRanges.push(from, to);\n };\n let depth = 0;\n // Template literals interleave string and expression states; the stack\n // records the brace depth at which each `${` opened so the matching `}`\n // resumes string state.\n const templateStack: number[] = [];\n let lastToken = \"\";\n let i = 0;\n\n while (i < code.length) {\n const ch = code[i] as string;\n const next = code[i + 1];\n\n // Comments\n if (ch === \"/\" && next === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n const end = nl === -1 ? code.length : nl + 1;\n mask(i, end);\n i = end;\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n const close = code.indexOf(\"*/\", i + 2);\n const end = close === -1 ? code.length : close + 2;\n mask(i, end);\n i = end;\n continue;\n }\n if (ch === \"/\") {\n if (!isDivisionContext(lastToken)) {\n const end = skipRegexLiteral(code, i);\n mask(i, end);\n i = end;\n lastToken = \")\"; // a regex literal is an operand\n continue;\n }\n lastToken = ch;\n i++;\n continue;\n }\n // Strings\n if (ch === '\"' || ch === \"'\") {\n const end = skipString(code, i, ch);\n mask(i, end);\n i = end;\n lastToken = ch;\n continue;\n }\n // Template literals\n if (ch === \"`\") {\n const end = skipTemplateChunk(code, i + 1, templateStack, depth);\n mask(i, end);\n i = end;\n lastToken = \"`\";\n continue;\n }\n if (\n templateStack.length > 0 &&\n ch === \"}\" &&\n depth === templateStack[templateStack.length - 1]\n ) {\n // End of a ${ } expression — back into template string state\n templateStack.pop();\n const end = skipTemplateChunk(code, i + 1, templateStack, depth);\n mask(i, end);\n i = end;\n lastToken = \"`\";\n continue;\n }\n\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n lastToken = ch;\n i++;\n continue;\n }\n if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n lastToken = ch;\n i++;\n continue;\n }\n\n if (isIdentStartCode(code.charCodeAt(i)) && !isIdentPartCode(code.charCodeAt(i - 1))) {\n let j = i + 1;\n while (j < code.length && isIdentPartCode(code.charCodeAt(j))) j++;\n const word = code.slice(i, j);\n // Skip whitespace to check for the member access\n let k = j;\n while (k < code.length && isSpaceCode(code.charCodeAt(k))) k++;\n if (roots.has(word) && code[k] === \".\" && lastToken !== \".\") {\n candidates.push({ index: i, depth, name: word, afterArrow: lastToken === \"=>\" });\n }\n lastToken = word;\n i = j;\n continue;\n }\n\n if (!isSpaceCode(code.charCodeAt(i))) {\n lastToken = ch === \">\" && lastToken === \"=\" ? \"=>\" : ch;\n }\n i++;\n }\n\n const stripped = (): string => {\n if (maskRanges.length === 0) return code;\n let out = \"\";\n let prev = 0;\n for (let r = 0; r < maskRanges.length; r += 2) {\n const from = maskRanges[r] as number;\n const to = maskRanges[r + 1] as number;\n out += code.slice(prev, from) + code.slice(from, to).replace(/[^\\n]/g, \" \");\n prev = to;\n }\n return out + code.slice(prev);\n };\n return { candidates, stripped };\n}\n\nfunction skipString(code: string, start: number, quote: string): number {\n for (let i = start + 1; i < code.length; i++) {\n if (code[i] === \"\\\\\") {\n i++;\n } else if (code[i] === quote || code[i] === \"\\n\") {\n return i + 1;\n }\n }\n return code.length;\n}\n\n/**\n * Skip a template string chunk; returns the offset after the closing\n * `` ` `` or after a `${`, recording the current depth so the scanner can\n * recognize the matching `}` later.\n */\nfunction skipTemplateChunk(\n code: string,\n start: number,\n templateStack: number[],\n depth: number,\n): number {\n for (let i = start; i < code.length; i++) {\n if (code[i] === \"\\\\\") {\n i++;\n } else if (code[i] === \"`\") {\n return i + 1;\n } else if (code[i] === \"$\" && code[i + 1] === \"{\") {\n templateStack.push(depth);\n return i + 2;\n }\n }\n return code.length;\n}\n\nfunction skipRegexLiteral(code: string, start: number): number {\n let inClass = false;\n for (let i = start + 1; i < code.length; i++) {\n const ch = code[i];\n if (ch === \"\\\\\") {\n i++;\n } else if (ch === \"[\") {\n inClass = true;\n } else if (ch === \"]\") {\n inClass = false;\n } else if (ch === \"/\" && !inClass) {\n return i + 1;\n } else if (ch === \"\\n\") {\n // Not a regex after all (unterminated) — treat as division\n return start + 1;\n }\n }\n return code.length;\n}\n\n/**\n * Cheap chain-extent scan: from a root identifier, advance past the longest\n * member/call/tagged-template chain (`.x`, `?.x`, `!`, `(...)`, `[...]`,\n * `` `...` ``). Used to mask the interior of depth-0 chains WITHOUT an acorn\n * parse: schema modules are mostly top-level declarations, and parsing each\n * one only to discard it under the depth-0 rule dominated cold hoist cost in\n * a field report (hoist 37–46s vs discover 12–16s across ~7k transforms).\n * May overshoot an AST-exact end only across TS-only syntax (postfix `!`);\n * stops at anything else it does not recognize (`<` generics, operators) —\n * an undershoot leaves interior candidates to their own depth-0/eligibility\n * rules, an overshoot only widens the mask over an expression that already\n * evaluates once at module scope.\n */\nfunction findChainEnd(code: string, identStart: number): number {\n let i = identStart;\n while (i < code.length && isIdentPartCode(code.charCodeAt(i))) i++;\n\n const skipTrivia = (): void => {\n for (;;) {\n while (i < code.length && isSpaceCode(code.charCodeAt(i))) i++;\n if (code[i] === \"/\" && code[i + 1] === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n i = nl === -1 ? code.length : nl + 1;\n } else if (code[i] === \"/\" && code[i + 1] === \"*\") {\n const close = code.indexOf(\"*/\", i + 2);\n i = close === -1 ? code.length : close + 2;\n } else {\n return;\n }\n }\n };\n\n // Advance past one balanced construct starting at `(`, `[`, or a template\n // backtick — mirroring scanSource's string/template/regex/comment rules.\n const skipNested = (): void => {\n let depth = 0;\n const templateStack: number[] = [];\n let lastToken = \"\";\n while (i < code.length) {\n const ch = code[i] as string;\n const next = code[i + 1];\n if (ch === \"/\" && next === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n i = nl === -1 ? code.length : nl + 1;\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n const close = code.indexOf(\"*/\", i + 2);\n i = close === -1 ? code.length : close + 2;\n continue;\n }\n if (ch === \"/\") {\n if (!isDivisionContext(lastToken)) {\n i = skipRegexLiteral(code, i);\n lastToken = \")\";\n continue;\n }\n lastToken = ch;\n i++;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n i = skipString(code, i, ch);\n lastToken = ch;\n continue;\n }\n if (ch === \"`\") {\n i = skipTemplateChunk(code, i + 1, templateStack, depth);\n lastToken = \"`\";\n if (depth === 0 && templateStack.length === 0) return;\n continue;\n }\n if (\n templateStack.length > 0 &&\n ch === \"}\" &&\n depth === templateStack[templateStack.length - 1]\n ) {\n templateStack.pop();\n i = skipTemplateChunk(code, i + 1, templateStack, depth);\n lastToken = \"`\";\n if (depth === 0 && templateStack.length === 0) return;\n continue;\n }\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n lastToken = ch;\n i++;\n continue;\n }\n if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n lastToken = ch;\n i++;\n if (depth === 0 && templateStack.length === 0) return;\n continue;\n }\n if (isIdentStartCode(code.charCodeAt(i)) && !isIdentPartCode(code.charCodeAt(i - 1))) {\n let j = i + 1;\n while (j < code.length && isIdentPartCode(code.charCodeAt(j))) j++;\n lastToken = code.slice(i, j);\n i = j;\n continue;\n }\n if (!isSpaceCode(code.charCodeAt(i))) {\n lastToken = ch === \">\" && lastToken === \"=\" ? \"=>\" : ch;\n }\n i++;\n }\n };\n\n for (;;) {\n skipTrivia();\n const ch = code[i];\n if (ch === \".\" || (ch === \"?\" && code[i + 1] === \".\")) {\n i += ch === \".\" ? 1 : 2;\n skipTrivia();\n while (i < code.length && isIdentPartCode(code.charCodeAt(i))) i++;\n continue;\n }\n if (ch === \"!\") {\n i++;\n continue;\n }\n if (ch === \"(\" || ch === \"[\" || ch === \"`\") {\n skipNested();\n continue;\n }\n return i;\n }\n}\n\n/**\n * Parse a single assignment-level expression at `pos` — the same entry point\n * acorn's own parseExpressionAt uses, one precedence level down. At\n * expression level a trailing comma in an argument position\n * (`sql.type(z.object({...}),\\n)`) starts a sequence-expression parse that\n * throws on the surrounding `)`; assignment level treats the comma as\n * trailing garbage and stops cleanly. parseMaybeAssign is the entry point\n * the acorn plugin ecosystem overrides — stable across versions.\n */\nfunction parseAssignmentAt(code: string, pos: number): Expression {\n interface ParserInternals {\n nextToken(): void;\n parseMaybeAssign(): Expression;\n }\n const parser = new (Parser as unknown as new (\n options: Options,\n input: string,\n startPos?: number,\n ) => ParserInternals)({ ecmaVersion: \"latest\", sourceType: \"module\" }, code, pos);\n parser.nextToken();\n return parser.parseMaybeAssign();\n}\n\n/**\n * Narrow a parsed expression to the largest call chain starting at `start`.\n * The parse can overshoot into surrounding operators\n * (`z.string().min(1) || fallback` parses as a LogicalExpression) — descend\n * through same-start children until a CallExpression is found.\n */\nfunction narrowToCallChain(node: Expression, start: number): Expression | null {\n let current: AnyNode = node;\n while (current.start === start) {\n if (current.type === \"CallExpression\") return current as Expression;\n const child = sameStartChild(current, start);\n if (!child) return null;\n current = child;\n }\n return null;\n}\n\nfunction sameStartChild(node: AnyNode, start: number): AnyNode | null {\n const record = node as unknown as Record<string, unknown>;\n for (const key of [\"left\", \"object\", \"callee\", \"test\", \"tag\", \"expression\", \"expressions\"]) {\n const value = record[key];\n const child = Array.isArray(value) ? value[0] : value;\n if (\n typeof child === \"object\" &&\n child !== null &&\n (child as AnyNode).start === start &&\n typeof (child as AnyNode).type === \"string\"\n ) {\n return child as AnyNode;\n }\n }\n return null;\n}\n\n/**\n * Walk a member/call chain down to its base identifier, collecting the\n * non-computed method names along the spine. Computed members\n * (`base[name]()`) are unanalyzable — the chain is rejected.\n */\nfunction describeChain(node: Expression): { root: string; methods: string[] } | null {\n const methods: string[] = [];\n let current: AnyNode = node;\n while (true) {\n if (current.type === \"CallExpression\") {\n current = current.callee;\n } else if (current.type === \"MemberExpression\") {\n if (current.computed || current.property.type !== \"Identifier\") return null;\n methods.push(current.property.name);\n current = current.object;\n } else if (current.type === \"Identifier\") {\n return { root: current.name, methods };\n } else {\n return null;\n }\n }\n}\n\n/**\n * Combinators eligible on non-z chain bases (babel-plugin-zod-hoist's\n * SCHEMA_COMBINATOR_METHODS, verbatim) — `Base.extend({...})`,\n * `Base.pick({...})`, `UserZodSchema.optional()`, ...\n */\nconst COMBINATOR_METHODS = new Set([\n \"and\",\n \"array\",\n \"brand\",\n \"catchall\",\n \"deepPartial\",\n \"describe\",\n \"extend\",\n \"merge\",\n \"nullable\",\n \"nullish\",\n \"omit\",\n \"optional\",\n \"or\",\n \"partial\",\n \"passthrough\",\n \"pick\",\n \"readonly\",\n \"refine\",\n \"required\",\n \"strict\",\n \"strip\",\n \"superRefine\",\n \"transform\",\n]);\n\n/**\n * Methods that evaluate data rather than construct schemas. Hoisting one\n * would move the evaluation (and any throw) to module load.\n */\nconst PARSE_METHODS = new Set([\n \"parse\",\n \"safeParse\",\n \"parseAsync\",\n \"safeParseAsync\",\n \"decode\",\n \"encode\",\n \"decodeAsync\",\n \"encodeAsync\",\n]);\n\n/**\n * Standard globals a hoisted expression may reference (eager or deferred —\n * babel-parity behaviors like hoisting `z.date().default(new Date())` rely\n * on Date/Math being recognized).\n *\n * The babel plugin allows ANY unbound identifier because it has real scope\n * information; this port's binding collector is a lexical approximation, so\n * an unknown bare name must be assumed to be a binding the collector missed\n * — hoisting it would crash at module load with\n * `ReferenceError: <name> is not defined`. A fixed allowlist converts that\n * failure mode into a missed optimization.\n */\nconst KNOWN_GLOBALS = new Set([\n \"globalThis\",\n \"NaN\",\n \"Infinity\",\n \"Math\",\n \"Number\",\n \"String\",\n \"Boolean\",\n \"Array\",\n \"Object\",\n \"JSON\",\n \"Date\",\n \"RegExp\",\n \"BigInt\",\n \"Symbol\",\n \"Map\",\n \"Set\",\n \"WeakMap\",\n \"WeakSet\",\n \"Promise\",\n \"Proxy\",\n \"Reflect\",\n \"Intl\",\n \"Error\",\n \"TypeError\",\n \"RangeError\",\n \"SyntaxError\",\n \"EvalError\",\n \"URIError\",\n \"AggregateError\",\n \"ArrayBuffer\",\n \"Uint8Array\",\n \"parseInt\",\n \"parseFloat\",\n \"isNaN\",\n \"isFinite\",\n \"encodeURI\",\n \"decodeURI\",\n \"encodeURIComponent\",\n \"decodeURIComponent\",\n \"structuredClone\",\n \"URL\",\n \"URLSearchParams\",\n \"TextEncoder\",\n \"TextDecoder\",\n \"atob\",\n \"btoa\",\n \"crypto\",\n \"console\",\n \"process\",\n \"Buffer\",\n]);\n\ninterface CaptureAnalysis {\n /** Free identifiers referenced in eager (immediately evaluated) positions. */\n eagerFree: Set<string>;\n /** Free identifiers referenced only inside nested function bodies. */\n deferredFree: Set<string>;\n /** Disqualifying constructs (`this`/`super` anywhere; `await`/`yield` in eager positions). */\n impure: boolean;\n}\n\n/**\n * Scope-aware free-variable analysis of an expression. Nested function\n * params and local declarations are bound names, not captures — so\n * `z.string().refine((v) => v.length > 0)` has no free variables beyond `z`.\n * References inside nested function bodies are tracked separately: they\n * evaluate per call even after hoisting, so safe globals are allowed there.\n */\nfunction analyzeCaptures(expr: Expression): CaptureAnalysis {\n const eagerFree = new Set<string>();\n const deferredFree = new Set<string>();\n let impure = false;\n\n function patternNames(node: AnyNode, into: Set<string>): void {\n switch (node.type) {\n case \"Identifier\":\n into.add(node.name);\n return;\n case \"ObjectPattern\":\n for (const prop of node.properties) {\n if (prop.type === \"Property\") patternNames(prop.value, into);\n else patternNames(prop.argument, into);\n }\n return;\n case \"ArrayPattern\":\n for (const el of node.elements) {\n if (el) patternNames(el, into);\n }\n return;\n case \"AssignmentPattern\":\n patternNames(node.left, into);\n return;\n case \"RestElement\":\n patternNames(node.argument, into);\n return;\n default:\n return;\n }\n }\n\n function collectFunctionScope(body: AnyNode, into: Set<string>): void {\n // Flatten block scoping into the function scope — over-approximating\n // bound names can only suppress a hoist's free set, and the failure\n // mode is a loud ReferenceError, never silent misvalidation.\n const stack: AnyNode[] = [body];\n while (stack.length > 0) {\n const node = stack.pop();\n if (!node || typeof node !== \"object\") continue;\n if (node.type === \"VariableDeclaration\") {\n for (const decl of node.declarations) patternNames(decl.id, into);\n } else if (node.type === \"FunctionDeclaration\" || node.type === \"ClassDeclaration\") {\n if (node.id) into.add(node.id.name);\n continue; // do not descend into nested declarations' bodies here\n } else if (node.type === \"FunctionExpression\" || node.type === \"ArrowFunctionExpression\") {\n continue; // nested functions get their own scope in visit()\n }\n for (const value of Object.values(node as unknown as Record<string, unknown>)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (typeof item === \"object\" && item !== null && \"type\" in item) {\n stack.push(item as AnyNode);\n }\n }\n } else if (typeof value === \"object\" && value !== null && \"type\" in value) {\n stack.push(value as AnyNode);\n }\n }\n }\n }\n\n function visit(node: AnyNode, scopes: Set<string>[], deferred: boolean): void {\n switch (node.type) {\n case \"Identifier\": {\n const name = node.name;\n if (name !== \"undefined\" && !scopes.some((s) => s.has(name))) {\n (deferred ? deferredFree : eagerFree).add(name);\n }\n return;\n }\n case \"ThisExpression\":\n case \"Super\":\n // Arrows bind `this` lexically — hoisting changes it even when the\n // reference sits inside a callback. Always disqualifying.\n impure = true;\n return;\n case \"AwaitExpression\":\n case \"YieldExpression\":\n // Eager occurrences cannot be moved to module scope: hoisting would\n // emit top-level await (broken in CJS output) or an orphaned yield.\n // (Stricter than the babel plugin, whose suite never exercises\n // these.) Deferred occurrences run per call — fine to move.\n if (!deferred) {\n impure = true;\n return;\n }\n break;\n case \"MemberExpression\":\n visit(node.object, scopes, deferred);\n if (node.computed) visit(node.property, scopes, deferred);\n return;\n case \"Property\":\n if (node.computed) visit(node.key, scopes, deferred);\n visit(node.value, scopes, deferred);\n return;\n case \"FunctionExpression\":\n case \"ArrowFunctionExpression\": {\n const scope = new Set<string>();\n for (const param of node.params) patternNames(param, scope);\n if (node.type === \"FunctionExpression\" && node.id) scope.add(node.id.name);\n collectFunctionScope(node.body, scope);\n visit(node.body, [...scopes, scope], true);\n return;\n }\n default:\n break;\n }\n for (const value of Object.values(node as unknown as Record<string, unknown>)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (typeof item === \"object\" && item !== null && \"type\" in item) {\n visit(item as AnyNode, scopes, deferred);\n }\n }\n } else if (typeof value === \"object\" && value !== null && \"type\" in value) {\n visit(value as AnyNode, scopes, deferred);\n }\n }\n }\n\n visit(expr, [], false);\n return { eagerFree, deferredFree, impure };\n}\n\n/** Offset after the shebang and directive prologue (\"use client\", ...). */\nfunction insertionOffset(code: string): number {\n let i = 0;\n if (code.startsWith(\"#!\")) {\n const nl = code.indexOf(\"\\n\");\n i = nl === -1 ? code.length : nl + 1;\n }\n while (true) {\n // Skip whitespace and comments between directives\n while (i < code.length) {\n const ch = code[i] as string;\n if (/\\s/.test(ch)) {\n i++;\n } else if (ch === \"/\" && code[i + 1] === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n i = nl === -1 ? code.length : nl + 1;\n } else if (ch === \"/\" && code[i + 1] === \"*\") {\n const end = code.indexOf(\"*/\", i + 2);\n i = end === -1 ? code.length : end + 2;\n } else {\n break;\n }\n }\n const directive = code.slice(i).match(/^([\"'])use [^\"'\\n]*\\1\\s*;?[^\\S\\n]*\\n?/);\n if (!directive) return i;\n i += directive[0].length;\n }\n}\n\n/** Keywords that precede `( ... ) {` without binding anything. */\nconst NON_BINDING_KEYWORDS =\n \"if|for|while|switch|return|typeof|await|yield|new|do|else|case|in|of|delete|void\";\n\n/**\n * Conservative shadow detection: collect every identifier appearing in a\n * binding-like position — function/method/arrow parameter lists, catch\n * clauses, class names, const/let/var declarator patterns. The scanner has\n * no scope information, so an import referenced from a hoisted expression\n * must resolve to that import everywhere; a name that is ever re-bound\n * cannot be trusted and disqualifies hoists referencing it.\n *\n * Collection is depth-aware and multiline (balanced delimiter scanning, not\n * line-bounded regexes): multiline destructuring declarations and parameter\n * defaults containing calls are real production patterns whose bindings a\n * line-based collector misses — and a missed binding here used to mean a\n * hoist referencing it crashed at module load (`ReferenceError`).\n * Over-collection (type names, destructuring default values, for-of\n * iterables) is deliberate and safe: it can only suppress a hoist.\n */\nfunction collectBoundNames(code: string): Set<string> {\n const bound = new Set<string>();\n\n // Per top-level-comma piece, keep only the binding side: names before any\n // top-level `:` (type annotation) or `=` (default/initializer). Inside\n // destructuring patterns the `:`/`=` sit at depth > 0, so the whole\n // pattern is collected (renames and default values over-collect — safe).\n const addBindingSegment = (segment: string): void => {\n let depth = 0;\n let pieceStart = 0;\n let cut = -1;\n const flush = (end: number): void => {\n const prefix = segment.slice(pieceStart, cut === -1 ? end : cut);\n for (const id of prefix.matchAll(/[A-Za-z_$][\\w$]*/g)) {\n bound.add(id[0]);\n }\n cut = -1;\n };\n for (let i = 0; i < segment.length; i++) {\n const ch = segment[i];\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n } else if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n } else if (depth === 0 && ch === \",\") {\n flush(i);\n pieceStart = i + 1;\n } else if (depth === 0 && cut === -1 && (ch === \":\" || ch === \"=\")) {\n cut = i;\n }\n }\n flush(segment.length);\n };\n\n /** Balanced `( ... )` span starting at `open` (must point at `(`). */\n const parenSpan = (open: number): { inner: string; end: number } | null => {\n let depth = 0;\n for (let i = open; i < code.length; i++) {\n const ch = code[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) return { inner: code.slice(open + 1, i), end: i };\n }\n }\n return null;\n };\n\n // function f(a, b) / function (a = call()) — balanced + multiline\n for (const m of code.matchAll(/\\bfunction\\b/g)) {\n let i = m.index + m[0].length;\n while (i < code.length && code[i] !== \"(\" && code[i] !== \"{\" && code[i] !== \";\") i++;\n if (code[i] !== \"(\") continue;\n const span = parenSpan(i);\n if (span) addBindingSegment(span.inner);\n }\n // (a, b) => / (a = call()): Ret => — balanced params located from the arrow\n for (const m of code.matchAll(/=>/g)) {\n let i = m.index - 1;\n while (i >= 0 && /\\s/.test(code[i] as string)) i--;\n if (i < 0) continue;\n let closeAt = -1;\n if (code[i] === \")\") {\n closeAt = i;\n } else {\n // Possible return-type annotation between `)` and `=>`:\n // `(a): Promise<T> =>`. Find the nearest `)` whose gap to the arrow\n // looks like a type annotation; give up otherwise (over-approximation\n // elsewhere keeps this safe).\n const before = code.slice(0, m.index);\n const lastClose = before.lastIndexOf(\")\");\n if (lastClose !== -1 && /^\\s*:[^(){};]*$/.test(before.slice(lastClose + 1))) {\n closeAt = lastClose;\n }\n }\n if (closeAt === -1) continue;\n // walk back to the matching `(`\n let depth = 0;\n for (let j = closeAt; j >= 0; j--) {\n const ch = code[j];\n if (ch === \")\") depth++;\n else if (ch === \"(\") {\n depth--;\n if (depth === 0) {\n addBindingSegment(code.slice(j + 1, closeAt));\n break;\n }\n }\n }\n }\n // bare arrow param: a =>\n for (const m of code.matchAll(/([A-Za-z_$][\\w$]*)\\s*=>/g)) {\n bound.add(m[1] ?? \"\");\n }\n // method(a, b) { / method(a = call()): Ret { — excluding control flow.\n // The balanced span must be directly followed by `{` (after an optional\n // return type), which call expressions essentially never are.\n const methodAnchor = new RegExp(\n String.raw`(?<![.\\w$])(?!(?:${NON_BINDING_KEYWORDS})\\b)[A-Za-z_$][\\w$]*\\s*\\(`,\n \"g\",\n );\n for (const m of code.matchAll(methodAnchor)) {\n const span = parenSpan(m.index + m[0].length - 1);\n if (!span) continue;\n const after = code.slice(span.end + 1);\n if (/^\\s*(?::[^{};()]*)?\\{/.test(after)) addBindingSegment(span.inner);\n }\n // catch (e)\n for (const m of code.matchAll(/\\bcatch\\s*\\(/g)) {\n const span = parenSpan(m.index + m[0].length - 1);\n if (span) addBindingSegment(span.inner);\n }\n // class names are TDZ bindings (function declarations hoist, classes don't)\n for (const m of code.matchAll(/\\bclass\\s+([A-Za-z_$][\\w$]*)/g)) {\n bound.add(m[1] ?? \"\");\n }\n // const/let/var declarator patterns — balanced + multiline. The span runs\n // to the first top-level `;` (or an unbalanced closer: for-headers), so\n // `const {\\n inputSchema,\\n} = getSchemas();` collects inputSchema.\n for (const m of code.matchAll(/\\b(?:const|let|var)\\b/g)) {\n const start = m.index + m[0].length;\n let depth = 0;\n let end = code.length;\n for (let i = start; i < code.length; i++) {\n const ch = code[i];\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n } else if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n if (depth < 0) {\n end = i;\n break;\n }\n } else if (depth === 0 && ch === \";\") {\n end = i;\n break;\n }\n }\n addBindingSegment(code.slice(start, end));\n }\n return bound;\n}\n\nexport interface HoistOptions {\n /**\n * Imported identifiers matching this pattern are treated as schema chain\n * roots even without an inline z.* reference. A string is compiled as a\n * RegExp source; null disables name-based matching.\n * @default /ZodSchema$/\n */\n schemaNamePattern?: RegExp | string | null | undefined;\n /**\n * Fired when the file has hoist-relevant roots and the full source scan\n * actually runs — i.e., real parse-level work happened (as opposed to the\n * microsecond import-collection bail). The disk cache uses this to decide\n * that even a null transform result is worth persisting: re-deriving\n * \"nothing to hoist\" costs a full scan per zod-importing file per run.\n */\n onScan?: (() => void) | undefined;\n}\n\n/**\n * Free-variable analysis of a hoisted expression's source text, for the\n * build-time compile step. Returns null when the text does not parse (it\n * always should — it was extracted by this module).\n */\nexport function analyzeHoistedExpression(\n text: string,\n): { eagerFree: Set<string>; deferredFree: Set<string> } | null {\n try {\n const parsed = parseAssignmentAt(text, 0);\n const { eagerFree, deferredFree, impure } = analyzeCaptures(parsed);\n if (impure) return null;\n return { eagerFree, deferredFree };\n } catch {\n return null;\n }\n}\n\n/** A schema construction hoisted to module scope. */\nexport interface HoistedSchema {\n /** Module-scope binding name (`_zh_<hash>`). */\n name: string;\n /** Source text of the hoisted construction expression. */\n text: string;\n}\n\nexport interface HoistResult {\n /** The rewritten source. */\n code: string;\n /** One entry per hoisted declaration, in declaration order. */\n schemas: HoistedSchema[];\n /**\n * The splices (input coordinates) that produced `code`, for sourcemap\n * generation: expression → `_zh_*` replacements plus the declaration-block\n * insertion. `code === applyEdits(input, edits, insert)` by construction.\n */\n edits: Edit[];\n insert: Insertion;\n}\n\n/**\n * Hoist eligible Zod schema expressions to module scope.\n * Returns the rewritten source, or null when nothing was hoisted.\n */\nexport function hoistZodSchemas(code: string, options?: HoistOptions): string | null {\n return hoistZodSchemasMeta(code, options)?.code ?? null;\n}\n\n/**\n * hoistZodSchemas + metadata about each hoisted declaration, so the\n * transform can compile the hoisted schemas into optimized validators.\n */\nexport function hoistZodSchemasMeta(code: string, options?: HoistOptions): HoistResult | null {\n // Idempotency: a file carrying hoisted declarations IS this pass's output.\n // Plain hoists are naturally inert on re-runs (depth-0 masking), but a\n // compiled hoisted decl embeds its original z.* expression inside the IIFE\n // (depth > 0) — re-hoisting it would emit a duplicate _zh_ declaration.\n if (/\\bconst _zh_[0-9a-f]{8} = /.test(code)) return null;\n\n const imports = collectImportBindings(code);\n if (imports.all.size === 0) return null;\n\n const rawPattern = options?.schemaNamePattern;\n const namePattern =\n rawPattern === null\n ? null\n : rawPattern === undefined\n ? SCHEMA_NAME_PATTERN\n : typeof rawPattern === \"string\"\n ? new RegExp(rawPattern)\n : rawPattern;\n\n const roots = new Set<string>(imports.zod);\n if (namePattern) {\n for (const name of imports.all) {\n if (namePattern.test(name)) roots.add(name);\n }\n }\n // Imported roots that only qualify via an inline z.* reference in the\n // chain are validated per-expression below; scan them as candidates too.\n if (imports.zod.size > 0) {\n for (const name of imports.all) roots.add(name);\n }\n if (roots.size === 0) return null;\n\n options?.onScan?.();\n const { candidates, stripped } = scanSource(code, roots);\n if (candidates.length === 0) return null;\n\n let boundNames: Set<string> | undefined;\n function isShadowed(name: string): boolean {\n boundNames ??= collectBoundNames(stripped());\n return boundNames.has(name);\n }\n\n interface Hoist {\n start: number;\n end: number;\n name: string;\n }\n const hoists: Hoist[] = [];\n const declByText = new Map<string, string>();\n let consumedUntil = 0;\n\n for (const candidate of candidates) {\n if (candidate.index < consumedUntil) continue;\n\n // Masking (babel-plugin-zod-hoist nesting semantics):\n // - Depth-0 chains are top-level statements/initializers — already\n // evaluated once per module load, nothing to gain — and their interior\n // must not hoist separately either. Exception: concise arrow bodies\n // (`const make = () => z.object(...)`) re-run per call.\n // Their extent comes from the cheap scanner (findChainEnd), NOT acorn:\n // schema modules are mostly top-level declarations, and an acorn parse\n // per declaration only to discard it dominated cold hoist cost.\n // - Zod-rooted chains mask their interior REGARDLESS of eligibility (an\n // inner z.string() of `z.object({ a: z.string(), b: local })` belongs\n // to the outer schema — babel's isNestedInZodCall).\n // - Chains rooted elsewhere (`sql.type(...)`, `api.get(...)`,\n // `Base.extend(...)`) mask their interior only when actually hoisted:\n // a rejected outer chain leaves its arguments free, so the inner\n // `z.object({...})` of `sql.type(z.object({...}))` hoists on its own.\n if (candidate.depth === 0 && !candidate.afterArrow) {\n consumedUntil = findChainEnd(code, candidate.index);\n continue;\n }\n\n let parsed: Expression;\n try {\n parsed = parseAssignmentAt(code, candidate.index);\n } catch {\n continue;\n }\n let chain = narrowToCallChain(parsed, candidate.index);\n if (!chain) continue;\n\n const rootIsZod = imports.zod.has(candidate.name);\n\n if (rootIsZod) consumedUntil = chain.end;\n\n // Peel trailing parse calls: for `z.object({...}).safeParse(input)`,\n // hoist the construction and leave `.safeParse(input)` — with its\n // local-variable arguments — at the call site.\n let described = describeChain(chain);\n while (\n chain !== null &&\n described !== null &&\n described.methods.length > 0 &&\n PARSE_METHODS.has(described.methods[0] as string)\n ) {\n const callee: AnyNode | null = chain.type === \"CallExpression\" ? chain.callee : null;\n const inner: AnyNode | null =\n callee !== null && callee.type === \"MemberExpression\" ? callee.object : null;\n chain = inner !== null && inner.type === \"CallExpression\" ? (inner as Expression) : null;\n described = chain === null ? null : describeChain(chain);\n }\n if (chain === null || described === null) continue;\n // Tighten the zod-rooted mask to the peeled construction extent: the\n // arguments of a peeled `.parse(...)` are not part of the schema, so\n // candidates inside them stay free (babel traverses execution-method\n // arguments normally).\n if (rootIsZod) consumedUntil = chain.end;\n if (described.root !== candidate.name) continue;\n if (described.methods.some((m) => PARSE_METHODS.has(m))) continue;\n\n const rootMatchesPattern = namePattern?.test(candidate.name) === true;\n // Non-z bases must look like schema derivation: the chain must START\n // with a combinator (`Base.extend({...}).optional()` qualifies via\n // extend), so an arbitrary imported object with a z-mentioning argument\n // (`api.get(z.string())`) is never hoisted. describeChain records\n // methods outermost-first — the deepest method is last.\n const deepestMethod = described.methods[described.methods.length - 1];\n if (!rootIsZod && (deepestMethod === undefined || !COMBINATOR_METHODS.has(deepestMethod))) {\n continue;\n }\n\n const { eagerFree, deferredFree, impure } = analyzeCaptures(chain);\n if (impure) continue;\n // Capture rule (babel-plugin-zod-hoist's canSafelyHoist, hardened): a\n // free name is safe only when it is an import or a recognized standard\n // global, and is never re-bound anywhere in the file (no scope info, so\n // a name bound in ANY function cannot be trusted to mean the import —\n // over-rejection only costs a missed hoist). The babel plugin also\n // allows arbitrary unbound identifiers, but it has real scope analysis;\n // here an unknown bare name is more likely a binding the lexical\n // collector missed than a genuine global, and hoisting it would crash\n // at module load (`ReferenceError: <name> is not defined`).\n let eligible = true;\n for (const name of eagerFree) {\n if ((!imports.all.has(name) && !KNOWN_GLOBALS.has(name)) || isShadowed(name)) {\n eligible = false;\n break;\n }\n }\n if (eligible) {\n for (const name of deferredFree) {\n if ((!imports.all.has(name) && !KNOWN_GLOBALS.has(name)) || isShadowed(name)) {\n eligible = false;\n break;\n }\n }\n }\n if (!eligible) continue;\n\n // Non-zod, non-pattern roots qualify only when the chain itself\n // references a zod binding (`Base.extend({ a: z.string() })`).\n if (!rootIsZod && !rootMatchesPattern) {\n let referencesZod = false;\n for (const name of eagerFree) {\n if (imports.zod.has(name)) {\n referencesZod = true;\n break;\n }\n }\n for (const name of deferredFree) {\n if (imports.zod.has(name)) {\n referencesZod = true;\n break;\n }\n }\n if (!referencesZod) continue;\n }\n\n const text = code.slice(candidate.index, chain.end);\n let declName = declByText.get(text);\n if (!declName) {\n declName = `_zh_${fnv1a(text)}`;\n declByText.set(text, declName);\n }\n hoists.push({ start: candidate.index, end: chain.end, name: declName });\n // Non-zod-rooted chains mask their interior only on success — the inner\n // parts are consumed by this hoist's replacement.\n consumedUntil = Math.max(consumedUntil, chain.end);\n }\n\n if (hoists.length === 0) return null;\n\n const decls = [...declByText.entries()]\n .map(([text, name]) => `const ${name} = ${text};`)\n .join(\"\\n\");\n // The insertion offset is identical in input and output coordinates: the\n // directive prologue precedes every statement, and all hoist replacements\n // sit inside statements.\n const edits: Edit[] = hoists.map((h) => ({ start: h.start, end: h.end, text: h.name }));\n const insert: Insertion = { offset: insertionOffset(code), text: `${decls}\\n` };\n return {\n code: applyEdits(code, edits, insert),\n schemas: [...declByText.entries()].map(([text, name]) => ({ name, text })),\n edits,\n insert,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"hoist.js","names":[],"sources":["../../src/unplugin/hoist.ts"],"sourcesContent":["import type { AnyNode, Expression, Options } from \"acorn\";\nimport { Parser } from \"acorn\";\nimport { applyEdits, type Edit, type Insertion, moduleHeadOffset } from \"./edits.js\";\n\n/**\n * Hoist Zod schema construction out of functions to module scope —\n * equivalent of babel-plugin-zod-hoist.\n *\n * Schemas built inside function bodies are re-constructed on every call:\n *\n * function getSchema() {\n * return z.object({ name: z.string() }); // rebuilt per call\n * }\n *\n * becomes\n *\n * const _zh_94b7f5c1 = z.object({ name: z.string() });\n * function getSchema() {\n * return _zh_94b7f5c1; // built once\n * }\n *\n * Safety rules (babel-plugin-zod-hoist's `canSafelyHoist`, hardened for\n * lexical analysis):\n * - A free identifier must be an import or a KNOWN_GLOBALS member, and must\n * never be bound anywhere in the file (function params, locals, catch\n * clauses, class names, module-level const/let/var — hoisting above those\n * would change meaning or hit the TDZ). The babel plugin additionally\n * allows arbitrary unbound identifiers because it has real scope\n * information; this port's binding collector is lexical, so an unknown\n * bare name is treated as a possibly-missed binding rather than a global\n * (a wrong guess crashes at module load with a ReferenceError).\n * `this`/`super` disqualify anywhere. Eager `await`/`yield` also\n * disqualify (stricter than the babel plugin, which never encounters\n * them: hoisting one would emit top-level await / orphaned yield).\n * - Eligible roots: any binding imported from zod, an imported identifier\n * matching /ZodSchema$/, or an imported identifier whose chain contains\n * an inline z.* reference (e.g. `Base.extend({ a: z.string() })`).\n * - Nesting (babel's `isNestedInZodCall`): the interior of a zod-rooted\n * chain never hoists separately — it goes with the outer schema or not at\n * all. Chains rooted elsewhere (`sql.type(...)`, `api.get(...)`) do NOT\n * suppress their arguments: when the outer chain is rejected, an inner\n * `z.object({...})` still hoists on its own.\n * - Declarations are inserted at the top of the module (after shebang and\n * directive prologue). Imports are initialized before module code runs,\n * so referencing them from above their textual position is safe.\n * - Names are content-hashed, so identical schemas dedupe to one binding.\n *\n * The source is TypeScript, which acorn cannot fully parse — candidates are\n * located with a string/comment/depth-aware scanner and extracted with\n * parseExpressionAt (the same technique as the autoDiscover rewrite).\n * Anything unparseable (TS generics, `as` casts) is skipped: a miss leaves\n * the schema unhoisted, never breaks the code.\n */\n\n/**\n * Imported identifiers matching this pattern are treated as schema roots.\n *\n * The default must keep implying a \"Zod\" substring: it is one of the three\n * triggers the transform hook's `code` filter (ZOD_MENTION in transform.ts)\n * is a superset of. A default that matched, say, `/Schema$/` would make\n * hoistable files without any \"zod\" mention invisible to bundlers with native\n * hook filters. (A *user-supplied* pattern is handled — it drops the filter.)\n */\nexport const SCHEMA_NAME_PATTERN = /ZodSchema$/;\n\n/**\n * Module specifiers whose bindings count as the zod namespace. Every entry\n * must contain \"zod\" for the same reason as SCHEMA_NAME_PATTERN above; both\n * are pinned by `describe(\"code filter soundness\")` in the transform tests.\n */\nexport const ZOD_MODULES = new Set([\"zod\", \"zod/v3\", \"zod/v4\", \"zod/mini\", \"zod/v4/mini\"]);\n\n/** How an imported local binding maps onto its source module. */\nexport interface ImportDetail {\n /** Module specifier (`\"zod\"`, `\"./shapes\"`). */\n specifier: string;\n /** Exported name the binding refers to; `\"*\"` for namespace imports, `\"default\"` for default imports. */\n imported: string;\n}\n\ninterface ImportBindings {\n /** Every runtime (non-type) imported binding name. */\n all: Set<string>;\n /** Bindings imported from a zod module (usually just `z`). */\n zod: Set<string>;\n /** Local binding name → source module/export, for build-time evaluation. */\n details: Map<string, ImportDetail>;\n}\n\n/**\n * Collect runtime import bindings with a regex over import statements.\n * Type-only imports and `type` specifiers are excluded — they cannot be\n * referenced at runtime, so excluding them keeps the capture rule sound.\n */\nexport function collectImportBindings(code: string): ImportBindings {\n const all = new Set<string>();\n const zod = new Set<string>();\n const details = new Map<string, ImportDetail>();\n const importPattern = /import\\s+(type\\s+)?([^'\";]+?)\\s+from\\s*[\"']([^\"']+)[\"']/g;\n\n for (const match of code.matchAll(importPattern)) {\n const [, typeOnly, clause, specifier] = match;\n if (typeOnly || clause === undefined || specifier === undefined) continue;\n const isZod = ZOD_MODULES.has(specifier);\n for (const { local, imported } of parseImportClause(clause)) {\n all.add(local);\n if (isZod) zod.add(local);\n details.set(local, { specifier, imported });\n }\n }\n return { all, zod, details };\n}\n\n/** Extract local binding names (with their source export) from an import clause. */\nfunction parseImportClause(clause: string): Array<{ local: string; imported: string }> {\n const names: Array<{ local: string; imported: string }> = [];\n const namedStart = clause.indexOf(\"{\");\n\n // Default import and/or namespace import before the named group\n const head = namedStart === -1 ? clause : clause.slice(0, namedStart);\n for (const part of head.split(\",\")) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const ns = trimmed.match(/^\\*\\s*as\\s+([A-Za-z_$][\\w$]*)$/);\n if (ns?.[1]) {\n names.push({ local: ns[1], imported: \"*\" });\n } else if (/^[A-Za-z_$][\\w$]*$/.test(trimmed)) {\n names.push({ local: trimmed, imported: \"default\" });\n }\n }\n\n if (namedStart !== -1) {\n const namedEnd = clause.indexOf(\"}\", namedStart);\n const inner = clause.slice(namedStart + 1, namedEnd === -1 ? undefined : namedEnd);\n for (const part of inner.split(\",\")) {\n const spec = part.trim();\n if (!spec || spec.startsWith(\"type \")) continue;\n // `a as b` binds b; plain `a` binds a\n const asMatch = spec.match(/^([A-Za-z_$][\\w$]*)\\s+as\\s+([A-Za-z_$][\\w$]*)$/);\n if (asMatch?.[1] && asMatch[2]) {\n names.push({ local: asMatch[2], imported: asMatch[1] });\n } else if (/^[A-Za-z_$][\\w$]*$/.test(spec)) {\n names.push({ local: spec, imported: spec });\n }\n }\n }\n return names;\n}\n\n/** Deterministic FNV-1a 32-bit hash, hex-encoded. */\nfunction fnv1a(text: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, \"0\");\n}\n\ninterface Candidate {\n /** Offset of the root identifier. */\n index: number;\n /** Bracket/brace/paren depth at the offset (0 = top level). */\n depth: number;\n /** The root identifier text. */\n name: string;\n /**\n * The candidate directly follows `=>` — a concise arrow body. Even at\n * depth 0 (`const make = () => z.object(...)`) it re-evaluates per call.\n */\n afterArrow: boolean;\n}\n\n/**\n * Char-code identifier/whitespace classes for the scanner hot loops — a\n * regex `.test()` per character dominated scan time once the acorn parses\n * were gone. The ident classes are deliberately ASCII-only (`[A-Za-z_$]` /\n * `[\\w$]`, matching the scanner's historical regexes); the space check falls\n * back to `/\\s/` for the rare non-ASCII code points it matches (NBSP, BOM,\n * U+2028...).\n */\nfunction isIdentStartCode(c: number): boolean {\n return (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || c === 95 || c === 36;\n}\nfunction isIdentPartCode(c: number): boolean {\n return (\n (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || (c >= 48 && c <= 57) || c === 95 || c === 36\n );\n}\nfunction isSpaceCode(c: number): boolean {\n if (c === 32 || (c >= 9 && c <= 13)) return true;\n return c > 127 && /\\s/.test(String.fromCharCode(c));\n}\n\n/** After these tokens a `/` starts a regex literal, not division. */\nconst REGEX_PRECEDING_KEYWORDS = new Set([\n \"return\",\n \"typeof\",\n \"instanceof\",\n \"in\",\n \"of\",\n \"new\",\n \"delete\",\n \"void\",\n \"throw\",\n \"do\",\n \"else\",\n \"case\",\n \"yield\",\n \"await\",\n]);\n\n/** Is `/` after this token division (true) or a regex literal (false)? */\nfunction isDivisionContext(lastToken: string): boolean {\n if (lastToken === \")\" || lastToken === \"]\") return true;\n if (/^[\"'`]$/.test(lastToken)) return true;\n if (/^[\\w$]+$/.test(lastToken)) return !REGEX_PRECEDING_KEYWORDS.has(lastToken);\n return false;\n}\n\ninterface ScanResult {\n candidates: Candidate[];\n /**\n * Lazily builds the source with comments, string/template-string contents,\n * and regex literals masked to spaces (offsets preserved). Used for\n * binding-name collection so JSDoc examples and string contents never\n * count. Lazy because it is only needed when a candidate survives to\n * shadow-checking — schema modules (everything masked at depth 0) never\n * pay for it.\n */\n stripped: () => string;\n}\n\n/**\n * Scan the source for candidate root identifiers (`z`, `FooZodSchema`, ...)\n * followed by a `.`, tracking string/template/comment state and nesting\n * depth. Depth 0 candidates are top-level initializers — already evaluated\n * once — and are recorded only so their extents mask nested candidates.\n */\nfunction scanSource(code: string, roots: Set<string>): ScanResult {\n const candidates: Candidate[] = [];\n // Masked extents as flat [from, to) pairs, pushed in scan order (monotonic,\n // non-overlapping) — materialized into a stripped string only on demand.\n const maskRanges: number[] = [];\n const mask = (from: number, to: number): void => {\n maskRanges.push(from, to);\n };\n let depth = 0;\n // Template literals interleave string and expression states; the stack\n // records the brace depth at which each `${` opened so the matching `}`\n // resumes string state.\n const templateStack: number[] = [];\n let lastToken = \"\";\n let i = 0;\n\n while (i < code.length) {\n const ch = code[i] as string;\n const next = code[i + 1];\n\n // Comments\n if (ch === \"/\" && next === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n const end = nl === -1 ? code.length : nl + 1;\n mask(i, end);\n i = end;\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n const close = code.indexOf(\"*/\", i + 2);\n const end = close === -1 ? code.length : close + 2;\n mask(i, end);\n i = end;\n continue;\n }\n if (ch === \"/\") {\n if (!isDivisionContext(lastToken)) {\n const end = skipRegexLiteral(code, i);\n mask(i, end);\n i = end;\n lastToken = \")\"; // a regex literal is an operand\n continue;\n }\n lastToken = ch;\n i++;\n continue;\n }\n // Strings\n if (ch === '\"' || ch === \"'\") {\n const end = skipString(code, i, ch);\n mask(i, end);\n i = end;\n lastToken = ch;\n continue;\n }\n // Template literals\n if (ch === \"`\") {\n const end = skipTemplateChunk(code, i + 1, templateStack, depth);\n mask(i, end);\n i = end;\n lastToken = \"`\";\n continue;\n }\n if (\n templateStack.length > 0 &&\n ch === \"}\" &&\n depth === templateStack[templateStack.length - 1]\n ) {\n // End of a ${ } expression — back into template string state\n templateStack.pop();\n const end = skipTemplateChunk(code, i + 1, templateStack, depth);\n mask(i, end);\n i = end;\n lastToken = \"`\";\n continue;\n }\n\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n lastToken = ch;\n i++;\n continue;\n }\n if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n lastToken = ch;\n i++;\n continue;\n }\n\n if (isIdentStartCode(code.charCodeAt(i)) && !isIdentPartCode(code.charCodeAt(i - 1))) {\n let j = i + 1;\n while (j < code.length && isIdentPartCode(code.charCodeAt(j))) j++;\n const word = code.slice(i, j);\n // Skip whitespace to check for the member access\n let k = j;\n while (k < code.length && isSpaceCode(code.charCodeAt(k))) k++;\n if (roots.has(word) && code[k] === \".\" && lastToken !== \".\") {\n candidates.push({ index: i, depth, name: word, afterArrow: lastToken === \"=>\" });\n }\n lastToken = word;\n i = j;\n continue;\n }\n\n if (!isSpaceCode(code.charCodeAt(i))) {\n lastToken = ch === \">\" && lastToken === \"=\" ? \"=>\" : ch;\n }\n i++;\n }\n\n const stripped = (): string => {\n if (maskRanges.length === 0) return code;\n let out = \"\";\n let prev = 0;\n for (let r = 0; r < maskRanges.length; r += 2) {\n const from = maskRanges[r] as number;\n const to = maskRanges[r + 1] as number;\n out += code.slice(prev, from) + code.slice(from, to).replace(/[^\\n]/g, \" \");\n prev = to;\n }\n return out + code.slice(prev);\n };\n return { candidates, stripped };\n}\n\nfunction skipString(code: string, start: number, quote: string): number {\n for (let i = start + 1; i < code.length; i++) {\n if (code[i] === \"\\\\\") {\n i++;\n } else if (code[i] === quote || code[i] === \"\\n\") {\n return i + 1;\n }\n }\n return code.length;\n}\n\n/**\n * Skip a template string chunk; returns the offset after the closing\n * `` ` `` or after a `${`, recording the current depth so the scanner can\n * recognize the matching `}` later.\n */\nfunction skipTemplateChunk(\n code: string,\n start: number,\n templateStack: number[],\n depth: number,\n): number {\n for (let i = start; i < code.length; i++) {\n if (code[i] === \"\\\\\") {\n i++;\n } else if (code[i] === \"`\") {\n return i + 1;\n } else if (code[i] === \"$\" && code[i + 1] === \"{\") {\n templateStack.push(depth);\n return i + 2;\n }\n }\n return code.length;\n}\n\nfunction skipRegexLiteral(code: string, start: number): number {\n let inClass = false;\n for (let i = start + 1; i < code.length; i++) {\n const ch = code[i];\n if (ch === \"\\\\\") {\n i++;\n } else if (ch === \"[\") {\n inClass = true;\n } else if (ch === \"]\") {\n inClass = false;\n } else if (ch === \"/\" && !inClass) {\n return i + 1;\n } else if (ch === \"\\n\") {\n // Not a regex after all (unterminated) — treat as division\n return start + 1;\n }\n }\n return code.length;\n}\n\n/**\n * Cheap chain-extent scan: from a root identifier, advance past the longest\n * member/call/tagged-template chain (`.x`, `?.x`, `!`, `(...)`, `[...]`,\n * `` `...` ``). Used to mask the interior of depth-0 chains WITHOUT an acorn\n * parse: schema modules are mostly top-level declarations, and parsing each\n * one only to discard it under the depth-0 rule dominated cold hoist cost in\n * a field report (hoist 37–46s vs discover 12–16s across ~7k transforms).\n * May overshoot an AST-exact end only across TS-only syntax (postfix `!`);\n * stops at anything else it does not recognize (`<` generics, operators) —\n * an undershoot leaves interior candidates to their own depth-0/eligibility\n * rules, an overshoot only widens the mask over an expression that already\n * evaluates once at module scope.\n */\nfunction findChainEnd(code: string, identStart: number): number {\n let i = identStart;\n while (i < code.length && isIdentPartCode(code.charCodeAt(i))) i++;\n\n const skipTrivia = (): void => {\n for (;;) {\n while (i < code.length && isSpaceCode(code.charCodeAt(i))) i++;\n if (code[i] === \"/\" && code[i + 1] === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n i = nl === -1 ? code.length : nl + 1;\n } else if (code[i] === \"/\" && code[i + 1] === \"*\") {\n const close = code.indexOf(\"*/\", i + 2);\n i = close === -1 ? code.length : close + 2;\n } else {\n return;\n }\n }\n };\n\n // Advance past one balanced construct starting at `(`, `[`, or a template\n // backtick — mirroring scanSource's string/template/regex/comment rules.\n const skipNested = (): void => {\n let depth = 0;\n const templateStack: number[] = [];\n let lastToken = \"\";\n while (i < code.length) {\n const ch = code[i] as string;\n const next = code[i + 1];\n if (ch === \"/\" && next === \"/\") {\n const nl = code.indexOf(\"\\n\", i);\n i = nl === -1 ? code.length : nl + 1;\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n const close = code.indexOf(\"*/\", i + 2);\n i = close === -1 ? code.length : close + 2;\n continue;\n }\n if (ch === \"/\") {\n if (!isDivisionContext(lastToken)) {\n i = skipRegexLiteral(code, i);\n lastToken = \")\";\n continue;\n }\n lastToken = ch;\n i++;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n i = skipString(code, i, ch);\n lastToken = ch;\n continue;\n }\n if (ch === \"`\") {\n i = skipTemplateChunk(code, i + 1, templateStack, depth);\n lastToken = \"`\";\n if (depth === 0 && templateStack.length === 0) return;\n continue;\n }\n if (\n templateStack.length > 0 &&\n ch === \"}\" &&\n depth === templateStack[templateStack.length - 1]\n ) {\n templateStack.pop();\n i = skipTemplateChunk(code, i + 1, templateStack, depth);\n lastToken = \"`\";\n if (depth === 0 && templateStack.length === 0) return;\n continue;\n }\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n lastToken = ch;\n i++;\n continue;\n }\n if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n lastToken = ch;\n i++;\n if (depth === 0 && templateStack.length === 0) return;\n continue;\n }\n if (isIdentStartCode(code.charCodeAt(i)) && !isIdentPartCode(code.charCodeAt(i - 1))) {\n let j = i + 1;\n while (j < code.length && isIdentPartCode(code.charCodeAt(j))) j++;\n lastToken = code.slice(i, j);\n i = j;\n continue;\n }\n if (!isSpaceCode(code.charCodeAt(i))) {\n lastToken = ch === \">\" && lastToken === \"=\" ? \"=>\" : ch;\n }\n i++;\n }\n };\n\n for (;;) {\n skipTrivia();\n const ch = code[i];\n if (ch === \".\" || (ch === \"?\" && code[i + 1] === \".\")) {\n i += ch === \".\" ? 1 : 2;\n skipTrivia();\n while (i < code.length && isIdentPartCode(code.charCodeAt(i))) i++;\n continue;\n }\n if (ch === \"!\") {\n i++;\n continue;\n }\n if (ch === \"(\" || ch === \"[\" || ch === \"`\") {\n skipNested();\n continue;\n }\n return i;\n }\n}\n\n/**\n * Parse a single assignment-level expression at `pos` — the same entry point\n * acorn's own parseExpressionAt uses, one precedence level down. At\n * expression level a trailing comma in an argument position\n * (`sql.type(z.object({...}),\\n)`) starts a sequence-expression parse that\n * throws on the surrounding `)`; assignment level treats the comma as\n * trailing garbage and stops cleanly. parseMaybeAssign is the entry point\n * the acorn plugin ecosystem overrides — stable across versions.\n */\nfunction parseAssignmentAt(code: string, pos: number): Expression {\n interface ParserInternals {\n nextToken(): void;\n parseMaybeAssign(): Expression;\n }\n const parser = new (Parser as unknown as new (\n options: Options,\n input: string,\n startPos?: number,\n ) => ParserInternals)({ ecmaVersion: \"latest\", sourceType: \"module\" }, code, pos);\n parser.nextToken();\n return parser.parseMaybeAssign();\n}\n\n/**\n * Narrow a parsed expression to the largest call chain starting at `start`.\n * The parse can overshoot into surrounding operators\n * (`z.string().min(1) || fallback` parses as a LogicalExpression) — descend\n * through same-start children until a CallExpression is found.\n */\nfunction narrowToCallChain(node: Expression, start: number): Expression | null {\n let current: AnyNode = node;\n while (current.start === start) {\n if (current.type === \"CallExpression\") return current as Expression;\n const child = sameStartChild(current, start);\n if (!child) return null;\n current = child;\n }\n return null;\n}\n\nfunction sameStartChild(node: AnyNode, start: number): AnyNode | null {\n const record = node as unknown as Record<string, unknown>;\n for (const key of [\"left\", \"object\", \"callee\", \"test\", \"tag\", \"expression\", \"expressions\"]) {\n const value = record[key];\n const child = Array.isArray(value) ? value[0] : value;\n if (\n typeof child === \"object\" &&\n child !== null &&\n (child as AnyNode).start === start &&\n typeof (child as AnyNode).type === \"string\"\n ) {\n return child as AnyNode;\n }\n }\n return null;\n}\n\n/**\n * Walk a member/call chain down to its base identifier, collecting the\n * non-computed method names along the spine. Computed members\n * (`base[name]()`) are unanalyzable — the chain is rejected.\n */\nfunction describeChain(node: Expression): { root: string; methods: string[] } | null {\n const methods: string[] = [];\n let current: AnyNode = node;\n while (true) {\n if (current.type === \"CallExpression\") {\n current = current.callee;\n } else if (current.type === \"MemberExpression\") {\n if (current.computed || current.property.type !== \"Identifier\") return null;\n methods.push(current.property.name);\n current = current.object;\n } else if (current.type === \"Identifier\") {\n return { root: current.name, methods };\n } else {\n return null;\n }\n }\n}\n\n/**\n * Combinators eligible on non-z chain bases (babel-plugin-zod-hoist's\n * SCHEMA_COMBINATOR_METHODS, verbatim) — `Base.extend({...})`,\n * `Base.pick({...})`, `UserZodSchema.optional()`, ...\n */\nconst COMBINATOR_METHODS = new Set([\n \"and\",\n \"array\",\n \"brand\",\n \"catchall\",\n \"deepPartial\",\n \"describe\",\n \"extend\",\n \"merge\",\n \"nullable\",\n \"nullish\",\n \"omit\",\n \"optional\",\n \"or\",\n \"partial\",\n \"passthrough\",\n \"pick\",\n \"readonly\",\n \"refine\",\n \"required\",\n \"strict\",\n \"strip\",\n \"superRefine\",\n \"transform\",\n]);\n\n/**\n * Methods that evaluate data rather than construct schemas. Hoisting one\n * would move the evaluation (and any throw) to module load.\n */\nconst PARSE_METHODS = new Set([\n \"parse\",\n \"safeParse\",\n \"parseAsync\",\n \"safeParseAsync\",\n \"decode\",\n \"encode\",\n \"decodeAsync\",\n \"encodeAsync\",\n]);\n\n/**\n * Standard globals a hoisted expression may reference (eager or deferred —\n * babel-parity behaviors like hoisting `z.date().default(new Date())` rely\n * on Date/Math being recognized).\n *\n * The babel plugin allows ANY unbound identifier because it has real scope\n * information; this port's binding collector is a lexical approximation, so\n * an unknown bare name must be assumed to be a binding the collector missed\n * — hoisting it would crash at module load with\n * `ReferenceError: <name> is not defined`. A fixed allowlist converts that\n * failure mode into a missed optimization.\n */\nconst KNOWN_GLOBALS = new Set([\n \"globalThis\",\n \"NaN\",\n \"Infinity\",\n \"Math\",\n \"Number\",\n \"String\",\n \"Boolean\",\n \"Array\",\n \"Object\",\n \"JSON\",\n \"Date\",\n \"RegExp\",\n \"BigInt\",\n \"Symbol\",\n \"Map\",\n \"Set\",\n \"WeakMap\",\n \"WeakSet\",\n \"Promise\",\n \"Proxy\",\n \"Reflect\",\n \"Intl\",\n \"Error\",\n \"TypeError\",\n \"RangeError\",\n \"SyntaxError\",\n \"EvalError\",\n \"URIError\",\n \"AggregateError\",\n \"ArrayBuffer\",\n \"Uint8Array\",\n \"parseInt\",\n \"parseFloat\",\n \"isNaN\",\n \"isFinite\",\n \"encodeURI\",\n \"decodeURI\",\n \"encodeURIComponent\",\n \"decodeURIComponent\",\n \"structuredClone\",\n \"URL\",\n \"URLSearchParams\",\n \"TextEncoder\",\n \"TextDecoder\",\n \"atob\",\n \"btoa\",\n \"crypto\",\n \"console\",\n \"process\",\n \"Buffer\",\n]);\n\ninterface CaptureAnalysis {\n /** Free identifiers referenced in eager (immediately evaluated) positions. */\n eagerFree: Set<string>;\n /** Free identifiers referenced only inside nested function bodies. */\n deferredFree: Set<string>;\n /** Disqualifying constructs (`this`/`super` anywhere; `await`/`yield` in eager positions). */\n impure: boolean;\n}\n\n/**\n * Scope-aware free-variable analysis of an expression. Nested function\n * params and local declarations are bound names, not captures — so\n * `z.string().refine((v) => v.length > 0)` has no free variables beyond `z`.\n * References inside nested function bodies are tracked separately: they\n * evaluate per call even after hoisting, so safe globals are allowed there.\n */\nfunction analyzeCaptures(expr: Expression): CaptureAnalysis {\n const eagerFree = new Set<string>();\n const deferredFree = new Set<string>();\n let impure = false;\n\n function patternNames(node: AnyNode, into: Set<string>): void {\n switch (node.type) {\n case \"Identifier\":\n into.add(node.name);\n return;\n case \"ObjectPattern\":\n for (const prop of node.properties) {\n if (prop.type === \"Property\") patternNames(prop.value, into);\n else patternNames(prop.argument, into);\n }\n return;\n case \"ArrayPattern\":\n for (const el of node.elements) {\n if (el) patternNames(el, into);\n }\n return;\n case \"AssignmentPattern\":\n patternNames(node.left, into);\n return;\n case \"RestElement\":\n patternNames(node.argument, into);\n return;\n default:\n return;\n }\n }\n\n function collectFunctionScope(body: AnyNode, into: Set<string>): void {\n // Flatten block scoping into the function scope — over-approximating\n // bound names can only suppress a hoist's free set, and the failure\n // mode is a loud ReferenceError, never silent misvalidation.\n const stack: AnyNode[] = [body];\n while (stack.length > 0) {\n const node = stack.pop();\n if (!node || typeof node !== \"object\") continue;\n if (node.type === \"VariableDeclaration\") {\n for (const decl of node.declarations) patternNames(decl.id, into);\n } else if (node.type === \"FunctionDeclaration\" || node.type === \"ClassDeclaration\") {\n if (node.id) into.add(node.id.name);\n continue; // do not descend into nested declarations' bodies here\n } else if (node.type === \"FunctionExpression\" || node.type === \"ArrowFunctionExpression\") {\n continue; // nested functions get their own scope in visit()\n }\n for (const value of Object.values(node as unknown as Record<string, unknown>)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (typeof item === \"object\" && item !== null && \"type\" in item) {\n stack.push(item as AnyNode);\n }\n }\n } else if (typeof value === \"object\" && value !== null && \"type\" in value) {\n stack.push(value as AnyNode);\n }\n }\n }\n }\n\n function visit(node: AnyNode, scopes: Set<string>[], deferred: boolean): void {\n switch (node.type) {\n case \"Identifier\": {\n const name = node.name;\n if (name !== \"undefined\" && !scopes.some((s) => s.has(name))) {\n (deferred ? deferredFree : eagerFree).add(name);\n }\n return;\n }\n case \"ThisExpression\":\n case \"Super\":\n // Arrows bind `this` lexically — hoisting changes it even when the\n // reference sits inside a callback. Always disqualifying.\n impure = true;\n return;\n case \"AwaitExpression\":\n case \"YieldExpression\":\n // Eager occurrences cannot be moved to module scope: hoisting would\n // emit top-level await (broken in CJS output) or an orphaned yield.\n // (Stricter than the babel plugin, whose suite never exercises\n // these.) Deferred occurrences run per call — fine to move.\n if (!deferred) {\n impure = true;\n return;\n }\n break;\n case \"MemberExpression\":\n visit(node.object, scopes, deferred);\n if (node.computed) visit(node.property, scopes, deferred);\n return;\n case \"Property\":\n if (node.computed) visit(node.key, scopes, deferred);\n visit(node.value, scopes, deferred);\n return;\n case \"FunctionExpression\":\n case \"ArrowFunctionExpression\": {\n const scope = new Set<string>();\n for (const param of node.params) patternNames(param, scope);\n if (node.type === \"FunctionExpression\" && node.id) scope.add(node.id.name);\n collectFunctionScope(node.body, scope);\n visit(node.body, [...scopes, scope], true);\n return;\n }\n default:\n break;\n }\n for (const value of Object.values(node as unknown as Record<string, unknown>)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (typeof item === \"object\" && item !== null && \"type\" in item) {\n visit(item as AnyNode, scopes, deferred);\n }\n }\n } else if (typeof value === \"object\" && value !== null && \"type\" in value) {\n visit(value as AnyNode, scopes, deferred);\n }\n }\n }\n\n visit(expr, [], false);\n return { eagerFree, deferredFree, impure };\n}\n\n/** Keywords that precede `( ... ) {` without binding anything. */\nconst NON_BINDING_KEYWORDS =\n \"if|for|while|switch|return|typeof|await|yield|new|do|else|case|in|of|delete|void\";\n\n/**\n * Conservative shadow detection: collect every identifier appearing in a\n * binding-like position — function/method/arrow parameter lists, catch\n * clauses, class names, const/let/var declarator patterns. The scanner has\n * no scope information, so an import referenced from a hoisted expression\n * must resolve to that import everywhere; a name that is ever re-bound\n * cannot be trusted and disqualifies hoists referencing it.\n *\n * Collection is depth-aware and multiline (balanced delimiter scanning, not\n * line-bounded regexes): multiline destructuring declarations and parameter\n * defaults containing calls are real production patterns whose bindings a\n * line-based collector misses — and a missed binding here used to mean a\n * hoist referencing it crashed at module load (`ReferenceError`).\n * Over-collection (type names, destructuring default values, for-of\n * iterables) is deliberate and safe: it can only suppress a hoist.\n */\nfunction collectBoundNames(code: string): Set<string> {\n const bound = new Set<string>();\n\n // Per top-level-comma piece, keep only the binding side: names before any\n // top-level `:` (type annotation) or `=` (default/initializer). Inside\n // destructuring patterns the `:`/`=` sit at depth > 0, so the whole\n // pattern is collected (renames and default values over-collect — safe).\n const addBindingSegment = (segment: string): void => {\n let depth = 0;\n let pieceStart = 0;\n let cut = -1;\n const flush = (end: number): void => {\n const prefix = segment.slice(pieceStart, cut === -1 ? end : cut);\n for (const id of prefix.matchAll(/[A-Za-z_$][\\w$]*/g)) {\n bound.add(id[0]);\n }\n cut = -1;\n };\n for (let i = 0; i < segment.length; i++) {\n const ch = segment[i];\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n } else if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n } else if (depth === 0 && ch === \",\") {\n flush(i);\n pieceStart = i + 1;\n } else if (depth === 0 && cut === -1 && (ch === \":\" || ch === \"=\")) {\n cut = i;\n }\n }\n flush(segment.length);\n };\n\n /** Balanced `( ... )` span starting at `open` (must point at `(`). */\n const parenSpan = (open: number): { inner: string; end: number } | null => {\n let depth = 0;\n for (let i = open; i < code.length; i++) {\n const ch = code[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) return { inner: code.slice(open + 1, i), end: i };\n }\n }\n return null;\n };\n\n // function f(a, b) / function (a = call()) — balanced + multiline\n for (const m of code.matchAll(/\\bfunction\\b/g)) {\n let i = m.index + m[0].length;\n while (i < code.length && code[i] !== \"(\" && code[i] !== \"{\" && code[i] !== \";\") i++;\n if (code[i] !== \"(\") continue;\n const span = parenSpan(i);\n if (span) addBindingSegment(span.inner);\n }\n // (a, b) => / (a = call()): Ret => — balanced params located from the arrow\n for (const m of code.matchAll(/=>/g)) {\n let i = m.index - 1;\n while (i >= 0 && /\\s/.test(code[i] as string)) i--;\n if (i < 0) continue;\n let closeAt = -1;\n if (code[i] === \")\") {\n closeAt = i;\n } else {\n // Possible return-type annotation between `)` and `=>`:\n // `(a): Promise<T> =>`. Find the nearest `)` whose gap to the arrow\n // looks like a type annotation; give up otherwise (over-approximation\n // elsewhere keeps this safe).\n const before = code.slice(0, m.index);\n const lastClose = before.lastIndexOf(\")\");\n if (lastClose !== -1 && /^\\s*:[^(){};]*$/.test(before.slice(lastClose + 1))) {\n closeAt = lastClose;\n }\n }\n if (closeAt === -1) continue;\n // walk back to the matching `(`\n let depth = 0;\n for (let j = closeAt; j >= 0; j--) {\n const ch = code[j];\n if (ch === \")\") depth++;\n else if (ch === \"(\") {\n depth--;\n if (depth === 0) {\n addBindingSegment(code.slice(j + 1, closeAt));\n break;\n }\n }\n }\n }\n // bare arrow param: a =>\n for (const m of code.matchAll(/([A-Za-z_$][\\w$]*)\\s*=>/g)) {\n bound.add(m[1] ?? \"\");\n }\n // method(a, b) { / method(a = call()): Ret { — excluding control flow.\n // The balanced span must be directly followed by `{` (after an optional\n // return type), which call expressions essentially never are.\n const methodAnchor = new RegExp(\n String.raw`(?<![.\\w$])(?!(?:${NON_BINDING_KEYWORDS})\\b)[A-Za-z_$][\\w$]*\\s*\\(`,\n \"g\",\n );\n for (const m of code.matchAll(methodAnchor)) {\n const span = parenSpan(m.index + m[0].length - 1);\n if (!span) continue;\n const after = code.slice(span.end + 1);\n if (/^\\s*(?::[^{};()]*)?\\{/.test(after)) addBindingSegment(span.inner);\n }\n // catch (e)\n for (const m of code.matchAll(/\\bcatch\\s*\\(/g)) {\n const span = parenSpan(m.index + m[0].length - 1);\n if (span) addBindingSegment(span.inner);\n }\n // class names are TDZ bindings (function declarations hoist, classes don't)\n for (const m of code.matchAll(/\\bclass\\s+([A-Za-z_$][\\w$]*)/g)) {\n bound.add(m[1] ?? \"\");\n }\n // const/let/var declarator patterns — balanced + multiline. The span runs\n // to the first top-level `;` (or an unbalanced closer: for-headers), so\n // `const {\\n inputSchema,\\n} = getSchemas();` collects inputSchema.\n for (const m of code.matchAll(/\\b(?:const|let|var)\\b/g)) {\n const start = m.index + m[0].length;\n let depth = 0;\n let end = code.length;\n for (let i = start; i < code.length; i++) {\n const ch = code[i];\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") {\n depth++;\n } else if (ch === \")\" || ch === \"]\" || ch === \"}\") {\n depth--;\n if (depth < 0) {\n end = i;\n break;\n }\n } else if (depth === 0 && ch === \";\") {\n end = i;\n break;\n }\n }\n addBindingSegment(code.slice(start, end));\n }\n return bound;\n}\n\nexport interface HoistOptions {\n /**\n * Imported identifiers matching this pattern are treated as schema chain\n * roots even without an inline z.* reference. A string is compiled as a\n * RegExp source; null disables name-based matching.\n * @default /ZodSchema$/\n */\n schemaNamePattern?: RegExp | string | null | undefined;\n /**\n * Fired when the file has hoist-relevant roots and the full source scan\n * actually runs — i.e., real parse-level work happened (as opposed to the\n * microsecond import-collection bail). The disk cache uses this to decide\n * that even a null transform result is worth persisting: re-deriving\n * \"nothing to hoist\" costs a full scan per zod-importing file per run.\n */\n onScan?: (() => void) | undefined;\n}\n\n/**\n * Free-variable analysis of a hoisted expression's source text, for the\n * build-time compile step. Returns null when the text does not parse (it\n * always should — it was extracted by this module).\n */\nexport function analyzeHoistedExpression(\n text: string,\n): { eagerFree: Set<string>; deferredFree: Set<string> } | null {\n try {\n const parsed = parseAssignmentAt(text, 0);\n const { eagerFree, deferredFree, impure } = analyzeCaptures(parsed);\n if (impure) return null;\n return { eagerFree, deferredFree };\n } catch {\n return null;\n }\n}\n\n/** A schema construction hoisted to module scope. */\nexport interface HoistedSchema {\n /** Module-scope binding name (`_zh_<hash>`). */\n name: string;\n /** Source text of the hoisted construction expression. */\n text: string;\n}\n\nexport interface HoistResult {\n /** The rewritten source. */\n code: string;\n /** One entry per hoisted declaration, in declaration order. */\n schemas: HoistedSchema[];\n /**\n * The splices (input coordinates) that produced `code`, for sourcemap\n * generation: expression → `_zh_*` replacements plus the declaration-block\n * insertion. `code === applyEdits(input, edits, insert)` by construction.\n */\n edits: Edit[];\n insert: Insertion;\n}\n\n/**\n * Hoist eligible Zod schema expressions to module scope.\n * Returns the rewritten source, or null when nothing was hoisted.\n */\nexport function hoistZodSchemas(code: string, options?: HoistOptions): string | null {\n return hoistZodSchemasMeta(code, options)?.code ?? null;\n}\n\n/**\n * hoistZodSchemas + metadata about each hoisted declaration, so the\n * transform can compile the hoisted schemas into optimized validators.\n */\nexport function hoistZodSchemasMeta(code: string, options?: HoistOptions): HoistResult | null {\n // Idempotency: a file carrying hoisted declarations IS this pass's output.\n // Plain hoists are naturally inert on re-runs (depth-0 masking), but a\n // compiled hoisted decl embeds its original z.* expression inside the IIFE\n // (depth > 0) — re-hoisting it would emit a duplicate _zh_ declaration.\n if (/\\bconst _zh_[0-9a-f]{8} = /.test(code)) return null;\n\n const imports = collectImportBindings(code);\n if (imports.all.size === 0) return null;\n\n const rawPattern = options?.schemaNamePattern;\n const namePattern =\n rawPattern === null\n ? null\n : rawPattern === undefined\n ? SCHEMA_NAME_PATTERN\n : typeof rawPattern === \"string\"\n ? new RegExp(rawPattern)\n : rawPattern;\n\n const roots = new Set<string>(imports.zod);\n if (namePattern) {\n for (const name of imports.all) {\n if (namePattern.test(name)) roots.add(name);\n }\n }\n // Imported roots that only qualify via an inline z.* reference in the\n // chain are validated per-expression below; scan them as candidates too.\n if (imports.zod.size > 0) {\n for (const name of imports.all) roots.add(name);\n }\n if (roots.size === 0) return null;\n\n options?.onScan?.();\n const { candidates, stripped } = scanSource(code, roots);\n if (candidates.length === 0) return null;\n\n let boundNames: Set<string> | undefined;\n function isShadowed(name: string): boolean {\n boundNames ??= collectBoundNames(stripped());\n return boundNames.has(name);\n }\n\n interface Hoist {\n start: number;\n end: number;\n name: string;\n }\n const hoists: Hoist[] = [];\n const declByText = new Map<string, string>();\n let consumedUntil = 0;\n\n for (const candidate of candidates) {\n if (candidate.index < consumedUntil) continue;\n\n // Masking (babel-plugin-zod-hoist nesting semantics):\n // - Depth-0 chains are top-level statements/initializers — already\n // evaluated once per module load, nothing to gain — and their interior\n // must not hoist separately either. Exception: concise arrow bodies\n // (`const make = () => z.object(...)`) re-run per call.\n // Their extent comes from the cheap scanner (findChainEnd), NOT acorn:\n // schema modules are mostly top-level declarations, and an acorn parse\n // per declaration only to discard it dominated cold hoist cost.\n // - Zod-rooted chains mask their interior REGARDLESS of eligibility (an\n // inner z.string() of `z.object({ a: z.string(), b: local })` belongs\n // to the outer schema — babel's isNestedInZodCall).\n // - Chains rooted elsewhere (`sql.type(...)`, `api.get(...)`,\n // `Base.extend(...)`) mask their interior only when actually hoisted:\n // a rejected outer chain leaves its arguments free, so the inner\n // `z.object({...})` of `sql.type(z.object({...}))` hoists on its own.\n if (candidate.depth === 0 && !candidate.afterArrow) {\n consumedUntil = findChainEnd(code, candidate.index);\n continue;\n }\n\n let parsed: Expression;\n try {\n parsed = parseAssignmentAt(code, candidate.index);\n } catch {\n continue;\n }\n let chain = narrowToCallChain(parsed, candidate.index);\n if (!chain) continue;\n\n const rootIsZod = imports.zod.has(candidate.name);\n\n if (rootIsZod) consumedUntil = chain.end;\n\n // Peel trailing parse calls: for `z.object({...}).safeParse(input)`,\n // hoist the construction and leave `.safeParse(input)` — with its\n // local-variable arguments — at the call site.\n let described = describeChain(chain);\n while (\n chain !== null &&\n described !== null &&\n described.methods.length > 0 &&\n PARSE_METHODS.has(described.methods[0] as string)\n ) {\n const callee: AnyNode | null = chain.type === \"CallExpression\" ? chain.callee : null;\n const inner: AnyNode | null =\n callee !== null && callee.type === \"MemberExpression\" ? callee.object : null;\n chain = inner !== null && inner.type === \"CallExpression\" ? (inner as Expression) : null;\n described = chain === null ? null : describeChain(chain);\n }\n if (chain === null || described === null) continue;\n // Tighten the zod-rooted mask to the peeled construction extent: the\n // arguments of a peeled `.parse(...)` are not part of the schema, so\n // candidates inside them stay free (babel traverses execution-method\n // arguments normally).\n if (rootIsZod) consumedUntil = chain.end;\n if (described.root !== candidate.name) continue;\n if (described.methods.some((m) => PARSE_METHODS.has(m))) continue;\n\n const rootMatchesPattern = namePattern?.test(candidate.name) === true;\n // Non-z bases must look like schema derivation: the chain must START\n // with a combinator (`Base.extend({...}).optional()` qualifies via\n // extend), so an arbitrary imported object with a z-mentioning argument\n // (`api.get(z.string())`) is never hoisted. describeChain records\n // methods outermost-first — the deepest method is last.\n const deepestMethod = described.methods[described.methods.length - 1];\n if (!rootIsZod && (deepestMethod === undefined || !COMBINATOR_METHODS.has(deepestMethod))) {\n continue;\n }\n\n const { eagerFree, deferredFree, impure } = analyzeCaptures(chain);\n if (impure) continue;\n // Capture rule (babel-plugin-zod-hoist's canSafelyHoist, hardened): a\n // free name is safe only when it is an import or a recognized standard\n // global, and is never re-bound anywhere in the file (no scope info, so\n // a name bound in ANY function cannot be trusted to mean the import —\n // over-rejection only costs a missed hoist). The babel plugin also\n // allows arbitrary unbound identifiers, but it has real scope analysis;\n // here an unknown bare name is more likely a binding the lexical\n // collector missed than a genuine global, and hoisting it would crash\n // at module load (`ReferenceError: <name> is not defined`).\n let eligible = true;\n for (const name of eagerFree) {\n if ((!imports.all.has(name) && !KNOWN_GLOBALS.has(name)) || isShadowed(name)) {\n eligible = false;\n break;\n }\n }\n if (eligible) {\n for (const name of deferredFree) {\n if ((!imports.all.has(name) && !KNOWN_GLOBALS.has(name)) || isShadowed(name)) {\n eligible = false;\n break;\n }\n }\n }\n if (!eligible) continue;\n\n // Non-zod, non-pattern roots qualify only when the chain itself\n // references a zod binding (`Base.extend({ a: z.string() })`).\n if (!rootIsZod && !rootMatchesPattern) {\n let referencesZod = false;\n for (const name of eagerFree) {\n if (imports.zod.has(name)) {\n referencesZod = true;\n break;\n }\n }\n for (const name of deferredFree) {\n if (imports.zod.has(name)) {\n referencesZod = true;\n break;\n }\n }\n if (!referencesZod) continue;\n }\n\n const text = code.slice(candidate.index, chain.end);\n let declName = declByText.get(text);\n if (!declName) {\n declName = `_zh_${fnv1a(text)}`;\n declByText.set(text, declName);\n }\n hoists.push({ start: candidate.index, end: chain.end, name: declName });\n // Non-zod-rooted chains mask their interior only on success — the inner\n // parts are consumed by this hoist's replacement.\n consumedUntil = Math.max(consumedUntil, chain.end);\n }\n\n if (hoists.length === 0) return null;\n\n const decls = [...declByText.entries()]\n .map(([text, name]) => `const ${name} = ${text};`)\n .join(\"\\n\");\n // The insertion offset is identical in input and output coordinates: the\n // directive prologue precedes every statement, and all hoist replacements\n // sit inside statements.\n const edits: Edit[] = hoists.map((h) => ({ start: h.start, end: h.end, text: h.name }));\n const insert: Insertion = { offset: moduleHeadOffset(code), text: `${decls}\\n` };\n return {\n code: applyEdits(code, edits, insert),\n schemas: [...declByText.entries()].map(([text, name]) => ({ name, text })),\n edits,\n insert,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","names":[],"sources":["../../src/unplugin/transform.ts"],"mappings":";;;;UA6BiB;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;cAyFW,wBAAsB;;;;iBA+CnB,gBAAgB,YAAY,UAAU;;;;;;;;;;;;;cA6BzC;EAAuB,SAAS;EAAU,SAAS;;;;;;;;iBAgChD,oBAAoB,UAAU,2BAA2B;iBAOzD,IAAI;UAUH;EACf;EACA,KAAK;;;;;;;iBAQe,cACpB,cACA,YACA,SAAS,mBACR;;;;;;iBAUmB,qBACpB,cACA,YACA,SAAS,mBACR,QAAQ;;;;iBAiXK,cACd,cACA,SAAS,sBACT;EAAY;;;;;;iBAiDE,kBAAkB,cAAc;;;;;iBAgBhC,0BACd,cACA,SAAS,sBACT;EAAY;;;;;;iBAuCE,oBAAoB"}
1
+ {"version":3,"file":"transform.d.ts","names":[],"sources":["../../src/unplugin/transform.ts"],"mappings":";;;;UA6BiB;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;cAsHW,wBAAsB;;;;iBA+CnB,gBAAgB,YAAY,UAAU;;;;;;;;;;;;;cA6BzC;EAAuB,SAAS;EAAU,SAAS;;;;;;;;iBAgChD,oBAAoB,UAAU,2BAA2B;iBAOzD,IAAI;UAUH;EACf;EACA,KAAK;;;;;;;iBAQe,cACpB,cACA,YACA,SAAS,mBACR;;;;;;iBAUmB,qBACpB,cACA,YACA,SAAS,mBACR,QAAQ;;;;iBAqXK,cACd,cACA,SAAS,sBACT;EAAY;;;;;;iBAiDE,kBAAkB,cAAc;;;;;iBAgBhC,0BACd,cACA,SAAS,sBACT;EAAY;;;;;;iBAuCE,oBAAoB"}
@@ -4,7 +4,7 @@ import { FAILZ_CLASS_DECL, FAIL_CLASS_DECL, FINZ_DECL, FIN_DECL, FIN_DEFERRED_DE
4
4
  import "../core/codegen/dedupe.js";
5
5
  import { aggregateUsedHelpers, compileSchemas } from "../core/pipeline.js";
6
6
  import { mayExportSchemas } from "../static-filter.js";
7
- import { applyEdits } from "./edits.js";
7
+ import { applyEdits, moduleHeadOffset } from "./edits.js";
8
8
  import { hoistZodSchemasMeta } from "./hoist.js";
9
9
  import { compileHoistedSchemas } from "./hoist-compile.js";
10
10
  import { VIRTUAL_RUNTIME_ID } from "./virtual.js";
@@ -29,31 +29,56 @@ var StagedTransform = class {
29
29
  this.source = source;
30
30
  }
31
31
  apply(edits, insert) {
32
- this.applyThen(edits, insert === void 0 ? void 0 : () => insert);
32
+ this.stage(edits, (s) => {
33
+ if (insert === void 0) return false;
34
+ s.appendLeft(insert.offset, insert.text);
35
+ return true;
36
+ });
33
37
  }
34
38
  /**
35
- * Apply `edits`, then let `deferred` derive one more insertion from the
36
- * resulting text — both inside ONE stage.
39
+ * Apply `edits`, then prepend `deferred`'s text to the module head — both
40
+ * inside ONE stage.
37
41
  *
38
42
  * The head injection (runtime import + shared dedup block) has to be decided
39
43
  * from the REWRITTEN source, because `computeRuntimePrefix` probes it for
40
44
  * already-present markers. Staging it separately made a whole second
41
45
  * `generateMap` over the full generated output — for what is only a prepend at
42
- * offset 0 — and then forced `remapping` to compose the two. Together those
43
- * were the dominant cost of a transform: on a 320-schema project they ran to
44
- * 64% of total wall time, more than discovery and codegen combined. Deferring
46
+ * the module head — and then forced `remapping` to compose the two. Together
47
+ * those were the dominant cost of a transform: on a 320-schema project they ran
48
+ * to 64% of total wall time, more than discovery and codegen combined. Deferring
45
49
  * the insertion into the same MagicString buys byte-identical output and an
46
50
  * equivalent map for one generation and no composition — 1.6x (small schemas)
47
51
  * to 3.4x (large ones) on the transform, scaling with how much code a file
48
52
  * emits, since that is what both costs are proportional to.
53
+ *
54
+ * `deferred` returns TEXT, not an `Insertion`: `appendLeft` resolves offsets
55
+ * against the PRE-edit text while `deferred` is shown the POST-edit text, so a
56
+ * callback-supplied offset would be in the wrong coordinate system. Deriving it
57
+ * here from `this.current` keeps the two in step by construction.
49
58
  */
50
59
  applyThen(edits, deferred) {
60
+ this.stage(edits, (s, rewritten) => {
61
+ const head = deferred?.(rewritten());
62
+ if (head === void 0) return false;
63
+ s.appendLeft(moduleHeadOffset(this.current), head);
64
+ return true;
65
+ });
66
+ }
67
+ /**
68
+ * One stage: apply `edits` to a fresh MagicString, let `inject` add at most
69
+ * one insertion, then commit the text and its map. `inject` reports whether
70
+ * it inserted, so a no-op stage can be skipped entirely.
71
+ *
72
+ * `rewritten` is a thunk, not a string: materializing it costs a full
73
+ * `toString()` over generated-code-sized input, and the injectors that do not
74
+ * read it (every `apply()` call) must not pay for it.
75
+ */
76
+ stage(edits, inject) {
51
77
  const s = new MagicString(this.current);
52
78
  for (const e of edits) if (e.start === e.end) s.appendLeft(e.start, e.text);
53
79
  else s.overwrite(e.start, e.end, e.text);
54
- const insert = deferred?.(edits.length === 0 ? this.current : s.toString());
55
- if (insert !== void 0) s.appendLeft(insert.offset, insert.text);
56
- if (edits.length === 0 && insert === void 0) return;
80
+ const inserted = inject(s, () => edits.length === 0 ? this.current : s.toString());
81
+ if (edits.length === 0 && !inserted) return;
57
82
  this.current = s.toString();
58
83
  this.maps.push(s.generateMap({
59
84
  source: this.source,
@@ -248,10 +273,7 @@ async function transformCodeWithMap(code, id, options) {
248
273
  failed: 0
249
274
  });
250
275
  const prefix = computeRuntimePrefix(staged.current, hoistHelpers, mode, options.runtimeId);
251
- if (prefix !== null) staged.apply([], {
252
- offset: 0,
253
- text: prefix
254
- });
276
+ if (prefix !== null) staged.applyThen([], () => prefix);
255
277
  }
256
278
  return {
257
279
  code: staged.current,
@@ -332,10 +354,7 @@ async function transformCodeWithMap(code, id, options) {
332
354
  const prefix = computeRuntimePrefix(rewritten, usedHelpers, mode, options.runtimeId);
333
355
  const needsShared = shared.code !== "" && !rewritten.includes("/* zod-compiler shared */");
334
356
  const head = (prefix ?? "") + (needsShared ? `${shared.code}\n` : "");
335
- return head === "" ? void 0 : {
336
- offset: 0,
337
- text: head
338
- };
357
+ return head === "" ? void 0 : head;
339
358
  });
340
359
  return {
341
360
  code: staged.current,
@@ -359,7 +378,7 @@ async function transformCodeWithMap(code, id, options) {
359
378
  function computeRuntimePrefix(code, usedHelpers, mode, runtimeId = VIRTUAL_RUNTIME_ID) {
360
379
  if (mode === "lean") {
361
380
  if (usedHelpers.size === 0) return null;
362
- if (code.includes(runtimeId)) return null;
381
+ if (code.includes(`from "${runtimeId}"`)) return null;
363
382
  return `import { ${[...usedHelpers].sort().join(", ")} } from "${runtimeId}";\n`;
364
383
  }
365
384
  if (!code.includes("__zcMkv")) return null;