zod-compiler 1.28.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -148
- package/dist/core/codegen/build-path.d.ts +12 -1
- package/dist/core/codegen/build-path.d.ts.map +1 -1
- package/dist/core/codegen/build-path.js +102 -21
- package/dist/core/codegen/build-path.js.map +1 -1
- package/dist/core/codegen/context.d.ts +31 -16
- package/dist/core/codegen/context.d.ts.map +1 -1
- package/dist/core/codegen/context.js +43 -18
- package/dist/core/codegen/context.js.map +1 -1
- package/dist/core/codegen/emit-issue.d.ts +17 -20
- package/dist/core/codegen/emit-issue.d.ts.map +1 -1
- package/dist/core/codegen/emit-issue.js +13 -13
- package/dist/core/codegen/emit-issue.js.map +1 -1
- package/dist/core/codegen/index.d.ts.map +1 -1
- package/dist/core/codegen/index.js +9 -7
- package/dist/core/codegen/index.js.map +1 -1
- package/dist/core/codegen/issue-decls.d.ts +83 -7
- package/dist/core/codegen/issue-decls.d.ts.map +1 -1
- package/dist/core/codegen/issue-decls.js +93 -10
- package/dist/core/codegen/issue-decls.js.map +1 -1
- package/dist/core/codegen/schemas/array.js +1 -1
- package/dist/core/codegen/schemas/array.js.map +1 -1
- package/dist/core/codegen/schemas/bigint.d.ts.map +1 -1
- package/dist/core/codegen/schemas/bigint.js +15 -4
- package/dist/core/codegen/schemas/bigint.js.map +1 -1
- package/dist/core/codegen/schemas/catch.d.ts.map +1 -1
- package/dist/core/codegen/schemas/catch.js +3 -2
- package/dist/core/codegen/schemas/catch.js.map +1 -1
- package/dist/core/codegen/schemas/discriminated-union.d.ts +6 -2
- package/dist/core/codegen/schemas/discriminated-union.d.ts.map +1 -1
- package/dist/core/codegen/schemas/discriminated-union.js +16 -56
- package/dist/core/codegen/schemas/discriminated-union.js.map +1 -1
- package/dist/core/codegen/schemas/effect.d.ts.map +1 -1
- package/dist/core/codegen/schemas/effect.js +4 -2
- package/dist/core/codegen/schemas/effect.js.map +1 -1
- package/dist/core/codegen/schemas/file.js +2 -8
- package/dist/core/codegen/schemas/file.js.map +1 -1
- package/dist/core/codegen/schemas/number.js +4 -3
- package/dist/core/codegen/schemas/number.js.map +1 -1
- package/dist/core/codegen/schemas/object.d.ts +11 -1
- package/dist/core/codegen/schemas/object.d.ts.map +1 -1
- package/dist/core/codegen/schemas/object.js +58 -14
- package/dist/core/codegen/schemas/object.js.map +1 -1
- package/dist/core/codegen/schemas/readonly.d.ts.map +1 -1
- package/dist/core/codegen/schemas/readonly.js.map +1 -1
- package/dist/core/codegen/schemas/record.d.ts.map +1 -1
- package/dist/core/codegen/schemas/record.js +8 -3
- package/dist/core/codegen/schemas/record.js.map +1 -1
- package/dist/core/codegen/schemas/sizeable.d.ts +49 -3
- package/dist/core/codegen/schemas/sizeable.d.ts.map +1 -1
- package/dist/core/codegen/schemas/sizeable.js +101 -8
- package/dist/core/codegen/schemas/sizeable.js.map +1 -1
- package/dist/core/codegen/schemas/string-bool.d.ts +12 -1
- package/dist/core/codegen/schemas/string-bool.d.ts.map +1 -1
- package/dist/core/codegen/schemas/string-bool.js +19 -4
- package/dist/core/codegen/schemas/string-bool.js.map +1 -1
- package/dist/core/codegen/schemas/string.d.ts.map +1 -1
- package/dist/core/codegen/schemas/string.js +60 -26
- package/dist/core/codegen/schemas/string.js.map +1 -1
- package/dist/core/codegen/schemas/tuple.d.ts +14 -11
- package/dist/core/codegen/schemas/tuple.d.ts.map +1 -1
- package/dist/core/codegen/schemas/tuple.js +99 -49
- package/dist/core/codegen/schemas/tuple.js.map +1 -1
- package/dist/core/codegen/well-known-regex.d.ts +26 -1
- package/dist/core/codegen/well-known-regex.d.ts.map +1 -1
- package/dist/core/codegen/well-known-regex.js +31 -4
- package/dist/core/codegen/well-known-regex.js.map +1 -1
- package/dist/core/extract/checks.d.ts.map +1 -1
- package/dist/core/extract/checks.js +1 -0
- package/dist/core/extract/checks.js.map +1 -1
- package/dist/core/extract/extractors/intersection.js +21 -6
- package/dist/core/extract/extractors/intersection.js.map +1 -1
- package/dist/core/extract/extractors/object.d.ts.map +1 -1
- package/dist/core/extract/extractors/object.js +25 -9
- package/dist/core/extract/extractors/object.js.map +1 -1
- package/dist/core/extract/extractors/optional.d.ts.map +1 -1
- package/dist/core/extract/extractors/optional.js +1 -28
- package/dist/core/extract/extractors/optional.js.map +1 -1
- package/dist/core/extract/extractors/record.js +9 -3
- package/dist/core/extract/extractors/record.js.map +1 -1
- package/dist/core/extract/extractors/tuple.d.ts.map +1 -1
- package/dist/core/extract/extractors/tuple.js +16 -20
- package/dist/core/extract/extractors/tuple.js.map +1 -1
- package/dist/core/extract/types.d.ts +16 -8
- package/dist/core/extract/types.d.ts.map +1 -1
- package/dist/core/iife.d.ts +2 -1
- package/dist/core/iife.d.ts.map +1 -1
- package/dist/core/iife.js +2 -1
- package/dist/core/iife.js.map +1 -1
- package/dist/core/types.d.ts +70 -21
- package/dist/core/types.d.ts.map +1 -1
- package/dist/jit.d.ts.map +1 -1
- package/dist/jit.js +47 -12
- package/dist/jit.js.map +1 -1
- package/dist/runtime.d.ts +4 -1
- package/dist/runtime.js +14 -11
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-issue.js","names":[],"sources":["../../../src/core/codegen/emit-issue.ts"],"sourcesContent":["/**\n * Issue object emit helpers.\n *\n * Each helper returns a string of the form `_e.push(...)` (or equivalent on a\n * caller-supplied issues variable). Two emit modes:\n *\n * - inline (CLI .compiled.ts): emits the literal `{code:\"too_small\",...}` object.\n * - lean (unplugin): emits a call like `__zcTS(min,origin,inclusive,input,path)`\n * and registers the helper in `ctx.usedHelpers` so the transform layer can\n * construct the corresponding `import` from `\"virtual:zod-compiler/runtime\"`.\n *\n * Centralizing all issue emission here means schema codegen files don't carry\n * the inline/lean branching; they just call `tooSmall(g, ...)` etc.\n *\n * Message resolution mirrors Zod, which consults the error map of the\n * INSTANCE that created the issue:\n * - check-created issues (min/max/format/refine): per-check message only\n * (options.message, extracted from `.min(3, \"msg\")`)\n * - schema-created issues (invalid_type, enum/literal invalid_value, tuple\n * length, invalid_union, invalid_key): schema-level message (g.typeMsg,\n * from `z.string({ error: \"msg\" })`)\n * Helpers default per the most common call-site kind; size-issue emitters\n * accept `useTypeMsg: true` for node-level uses (tuple), and invalidValue\n * accepts `useTypeMsg: false` for check-level uses (file mime).\n * When no message lands, the __zcFin finalizer applies the locale default.\n *\n * KEY ORDER MATTERS, and is reproduced from zod issue by issue. `ZodError`\n * builds its `message` as `JSON.stringify(issues, …, 2)`, so insertion order is\n * printed text in a property consumers log, snapshot and serialize — an issue\n * carrying the right fields in the wrong order still renders a different error.\n * zod's own orders are irregular (`too_small` leads with `origin` from a check\n * but with `code` from a tuple's length branch; `invalid_format` carries\n * `origin` for a pattern check and omits it for `z.url()`), so each emitter\n * below mirrors one `payload.issues.push({…})` rather than a house style.\n *\n * `message` is written LAST everywhere, after `path`: zod never puts it in the\n * literal — `finalizeIssue` assigns `full.message` afterwards — and that holds\n * for a baked custom message too, since the custom error map is consulted from\n * inside that same assignment.\n */\n\nimport type { CodeGenContext } from \"./context.js\";\nimport { escapeString } from \"./context.js\";\n\n/** Common slim slice of SlowGen + FastGen needed for issue emission. */\ninterface IssueGen {\n readonly issues: string;\n readonly input: string;\n readonly path: string;\n readonly ctx: CodeGenContext;\n readonly typeMsg?: string | undefined;\n}\n\nfunction pushIssue(g: IssueGen, body: string): string {\n return `${g.issues}.push(${body});`;\n}\n\n/** Resolve the effective static message for an issue site. */\nfunction resolveMessage(\n g: IssueGen,\n explicit: string | undefined,\n useTypeMsg: boolean,\n): string | undefined {\n return explicit ?? (useTypeMsg ? g.typeMsg : undefined);\n}\n\n/** `,message:\"...\"` fragment for inline object literals (\"\" when no message). */\n/**\n * `,continue:false` — the marker that makes an issue ABORT its union option.\n *\n * zod prunes union options with `util.aborted`, which asks whether any issue has\n * `continue !== true`. Compiled issues carry no `continue` at all, so the union\n * generator classifies by CODE instead — sound for every issue a schema node\n * raises (`invalid_type`, `unrecognized_keys`, …) but blind to the one\n * exception: `$ZodTuple`'s length branch pushes a `too_small`/`too_big` from the\n * NODE, with no `continue`, where the identically-coded issue from an\n * `.min()`/`.max()` CHECK carries `continue: true` and does not abort. Without\n * this, `z.union([z.tuple([a, b]), z.number()])` handed `[]` surfaced the\n * tuple's `too_small` directly instead of wrapping both options in an\n * `invalid_union`.\n *\n * Stripped during finalization exactly as zod strips its own (`delete\n * full.continue`), so it never reaches a reported issue — see FAIL_CLASS_DECL\n * and ZC_FZ_DECL.\n */\nfunction abortsProp(aborts: boolean | undefined): string {\n return aborts === true ? \",continue:false\" : \"\";\n}\n\nfunction messageProp(m: string | undefined): string {\n return m === undefined ? \"\" : `,message:${escapeString(m)}`;\n}\n\n/** `,\"...\"` trailing argument fragment for lean factory calls (\"\" when no message). */\nfunction messageArg(m: string | undefined): string {\n return m === undefined ? \"\" : `,${escapeString(m)}`;\n}\n\n/**\n * `origin` as source: a bare string is a literal (`\"string\"`), `{ expr }` is an\n * expression evaluated at runtime — what a `when`-gated length/size check needs,\n * since zod derives its origin from the INPUT (`getLengthableOrigin`).\n */\ntype Origin = string | { expr: string };\n\nfunction originExpr(origin: Origin): string {\n return typeof origin === \"string\" ? escapeString(origin) : origin.expr;\n}\n\nexport function tooSmall(\n g: IssueGen,\n minimum: string | number,\n origin: Origin,\n /**\n * `\"omit\"` leaves the key OFF the issue entirely — not the same as `false`.\n * $ZodTuple's under-length branch pushes a bare\n * `{ code: \"too_small\", minimum: items.length }` (its over-length sibling in\n * the very same ternary spells out `inclusive: true`), so a tuple issue\n * carrying `inclusive: false` has a field zod never wrote. Every check-created\n * size issue (array/string/set/number/bigint/date min) does carry it, `false`\n * included — that is what `.gt()`/`.lt()` report.\n */\n inclusive: boolean | \"omit\",\n options?: {\n exact?: boolean;\n input?: string;\n path?: string;\n message?: string | undefined;\n /** Set for node-level issues (tuple length) where schema error applies. */\n useTypeMsg?: boolean;\n /** Emit the union-abort marker; see {@link abortsProp}. */\n aborts?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const exact = options?.exact === true;\n const m = resolveMessage(g, options?.message, options?.useTypeMsg === true);\n if (g.ctx.mode === \"lean\") {\n if (exact) {\n g.ctx.usedHelpers.add(\"__zcTSx\");\n return pushIssue(\n g,\n `__zcTSx(${minimum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n if (inclusive === \"omit\") {\n g.ctx.usedHelpers.add(\"__zcTSn\");\n return pushIssue(\n g,\n `__zcTSn(${minimum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n g.ctx.usedHelpers.add(\"__zcTS\");\n return pushIssue(\n g,\n `__zcTS(${minimum},${originExpr(origin)},${inclusive},${input},${path}${messageArg(m)})`,\n );\n }\n if (exact) {\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_small\",minimum:${minimum},inclusive:true,exact:true,input:${input},path:${path}${messageProp(m)}}`,\n );\n }\n // The tuple's under-length branch is the only caller that omits `inclusive`,\n // and it also puts `origin` last — see __zcTSn.\n if (inclusive === \"omit\") {\n return pushIssue(\n g,\n `{code:\"too_small\",minimum:${minimum},origin:${originExpr(origin)},input:${input},path:${path}${messageProp(m)}${abortsProp(options?.aborts)}}`,\n );\n }\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_small\",minimum:${minimum},inclusive:${inclusive},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function tooBig(\n g: IssueGen,\n maximum: string | number,\n origin: Origin,\n inclusive: boolean,\n options?: {\n exact?: boolean;\n input?: string;\n path?: string;\n message?: string | undefined;\n /** Set for node-level issues (tuple length) where schema error applies. */\n useTypeMsg?: boolean;\n /**\n * `\"tuple\"` selects $ZodTuple's over-length key order — `code, maximum,\n * inclusive, origin` — where a check-created size issue leads with `origin`.\n * zod builds the tuple issue by spreading `{code, maximum, inclusive}` and\n * appending `origin` after `input`/`inst`, and that ordering is visible in\n * `ZodError.message`.\n */\n layout?: \"tuple\";\n /** Emit the union-abort marker; see {@link abortsProp}. */\n aborts?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const exact = options?.exact === true;\n const m = resolveMessage(g, options?.message, options?.useTypeMsg === true);\n if (g.ctx.mode === \"lean\") {\n if (exact) {\n g.ctx.usedHelpers.add(\"__zcTBx\");\n return pushIssue(\n g,\n `__zcTBx(${maximum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n if (options?.layout === \"tuple\") {\n g.ctx.usedHelpers.add(\"__zcTBt\");\n return pushIssue(\n g,\n `__zcTBt(${maximum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n g.ctx.usedHelpers.add(\"__zcTB\");\n return pushIssue(\n g,\n `__zcTB(${maximum},${originExpr(origin)},${inclusive},${input},${path}${messageArg(m)})`,\n );\n }\n if (exact) {\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_big\",maximum:${maximum},inclusive:true,exact:true,input:${input},path:${path}${messageProp(m)}}`,\n );\n }\n if (options?.layout === \"tuple\") {\n return pushIssue(\n g,\n `{code:\"too_big\",maximum:${maximum},inclusive:${inclusive},origin:${originExpr(origin)},input:${input},path:${path}${messageProp(m)}${abortsProp(options?.aborts)}}`,\n );\n }\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_big\",maximum:${maximum},inclusive:${inclusive},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function invalidType(\n g: IssueGen,\n expected: string,\n options?: {\n input?: string;\n path?: string;\n extra?: string;\n message?: string | undefined;\n /**\n * Put `extra` BEFORE `code` rather than after it. $ZodCheckNumberFormat's\n * non-integer issue is `{expected, format, code}` while the `received` a\n * number/date schema adds trails `code` — two orders for one issue code, both\n * printed verbatim in `ZodError.message`.\n */\n extraBeforeCode?: boolean;\n /**\n * Lead with `code` instead of `expected`. Only `$ZodDiscriminatedUnion`'s\n * non-object guard writes the issue that way; every other schema in zod puts\n * `expected` first.\n */\n codeFirst?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n // invalid_type is always created by the schema node — schema error applies.\n const m = resolveMessage(g, options?.message, true);\n if (g.ctx.mode === \"lean\" && !options?.extra) {\n const helper = options?.codeFirst ? \"__zcITc\" : \"__zcIT\";\n g.ctx.usedHelpers.add(helper);\n return pushIssue(g, `${helper}(${escapeString(expected)},${input},${path}${messageArg(m)})`);\n }\n const extra = options?.extra ?? \"\";\n const head = options?.codeFirst\n ? `code:\"invalid_type\",expected:${escapeString(expected)}${extra ? `,${extra}` : \"\"}`\n : options?.extraBeforeCode\n ? `expected:${escapeString(expected)}${extra ? `,${extra}` : \"\"},code:\"invalid_type\"`\n : `expected:${escapeString(expected)},code:\"invalid_type\"${extra ? `,${extra}` : \"\"}`;\n return pushIssue(g, `{${head},input:${input},path:${path}${messageProp(m)}}`);\n}\n\nexport function invalidFormat(\n g: IssueGen,\n format: string | { expr: string },\n options?: {\n input?: string;\n path?: string;\n /**\n * Leading `origin`, present only where zod's push carries one:\n * `$ZodCheckStringFormat`'s default pattern check and the regex / includes /\n * starts_with / ends_with checks lead with `origin: \"string\"`, while\n * `z.url()`'s own issues and every `$ZodCustomStringFormat` omit it.\n */\n origin?: string | undefined;\n /**\n * Extra issue properties as a source fragment (`'pattern:\"…\"'`), emitted\n * right after `format` where zod writes them. Explicitly `| undefined` so a\n * caller can compute it conditionally: zod's `invalid_format` carries\n * different fields per format, and the bare-issue formats carry none.\n */\n extra?: string | undefined;\n message?: string | undefined;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const formatExpr = typeof format === \"string\" ? escapeString(format) : format.expr;\n // Format issues are created by check instances — schema error never applies.\n const m = options?.message;\n if (g.ctx.mode === \"lean\") {\n g.ctx.usedHelpers.add(\"__zcIF\");\n const originArg = options?.origin === undefined ? \"undefined\" : escapeString(options.origin);\n const extraArg = options?.extra ? `,{${options.extra}}` : m !== undefined ? \",undefined\" : \"\";\n return pushIssue(\n g,\n `__zcIF(${originArg},${formatExpr},${input},${path}${extraArg}${messageArg(m)})`,\n );\n }\n const originProp = options?.origin === undefined ? \"\" : `origin:${escapeString(options.origin)},`;\n const extra = options?.extra ? `,${options.extra}` : \"\";\n return pushIssue(\n g,\n `{${originProp}code:\"invalid_format\",format:${formatExpr}${extra},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function unrecognizedKeys(\n g: IssueGen,\n keysExpr: string,\n options?: { input?: string; path?: string; message?: string | undefined },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n // unrecognized_keys is created by the object schema node — schema error applies.\n const m = resolveMessage(g, options?.message, true);\n if (g.ctx.mode === \"lean\") {\n g.ctx.usedHelpers.add(\"__zcUK\");\n return pushIssue(g, `__zcUK(${keysExpr},${input},${path}${messageArg(m)})`);\n }\n return pushIssue(\n g,\n `{code:\"unrecognized_keys\",keys:${keysExpr},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function invalidValue(\n g: IssueGen,\n valuesExpr: string,\n options?: {\n input?: string;\n path?: string;\n /**\n * Extra issue properties as a source fragment (`'expected:\"stringbool\"'`),\n * modelled on {@link invalidFormat}'s option of the same name. Explicitly\n * `| undefined` so a caller can compute it conditionally: the `invalid_value`\n * producers do NOT agree on fields — enum and literal push only `values`,\n * while z.stringbool()'s codec transform also pushes\n * `expected: \"stringbool\"`, which zod's locale reads to phrase the message.\n */\n extra?: string | undefined;\n message?: string | undefined;\n /** Set to false for check-level issues (file mime) where schema error does not apply. */\n useTypeMsg?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n // Default: enum/literal invalid_value is created by the schema node.\n const m = resolveMessage(g, options?.message, options?.useTypeMsg !== false);\n if (g.ctx.mode === \"lean\") {\n g.ctx.usedHelpers.add(\"__zcIV\");\n const extraArg = options?.extra ? `,{${options.extra}}` : m !== undefined ? \",undefined\" : \"\";\n return pushIssue(g, `__zcIV(${valuesExpr},${input},${path}${extraArg}${messageArg(m)})`);\n }\n // `expected` precedes `values` in z.stringbool()'s push, so extras go between\n // `code` and `values` rather than after them.\n const extra = options?.extra ? `,${options.extra}` : \"\";\n return pushIssue(\n g,\n `{code:\"invalid_value\"${extra},values:${valuesExpr},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"emit-issue.js","names":[],"sources":["../../../src/core/codegen/emit-issue.ts"],"sourcesContent":["/**\n * Issue object emit helpers.\n *\n * Each helper returns a string of the form `_e.push(...)` (or equivalent on a\n * caller-supplied issues variable). Two emit modes:\n *\n * - inline (CLI .compiled.ts): emits the literal `{code:\"too_small\",...}` object.\n * - lean (unplugin): emits a call like `__zcTS(min,origin,inclusive,input,path)`\n * and registers the helper in `ctx.usedHelpers` so the transform layer can\n * construct the corresponding `import` from `\"virtual:zod-compiler/runtime\"`.\n *\n * Centralizing all issue emission here means schema codegen files don't carry\n * the inline/lean branching; they just call `tooSmall(g, ...)` etc.\n *\n * Message resolution mirrors zod's `finalizeIssue`, which consults the error\n * map of the INSTANCE that created the issue first and then the map of the\n * SCHEMA that owns it: a check stamps its owner onto every issue it raises\n * (`attachSchema`), so `z.string({ error: \"msg\" }).min(3)` reports \"msg\" for the\n * `too_small` as well as for the `invalid_type`. Every emitter therefore takes\n * the per-check message (options.message, extracted from `.min(3, \"msg\")`) and\n * falls back to the node's schema-level message (g.typeMsg, from\n * `z.string({ error: \"msg\" })`), which is scoped to the node being generated and\n * never inherited by a child node's issues. When no message lands, the __zcFin\n * finalizer applies the locale default.\n *\n * KEY ORDER MATTERS, and is reproduced from zod issue by issue. `ZodError`\n * builds its `message` as `JSON.stringify(issues, …, 2)`, so insertion order is\n * printed text in a property consumers log, snapshot and serialize — an issue\n * carrying the right fields in the wrong order still renders a different error.\n * zod's own orders are irregular (`too_small` leads with `origin` from a check\n * but with `code` from a tuple's length branch; `invalid_format` carries\n * `origin` for a pattern check and omits it for `z.url()`), so each emitter\n * below mirrors one `payload.issues.push({…})` rather than a house style.\n *\n * `message` is written LAST everywhere, after `path`: zod never puts it in the\n * literal — `finalizeIssue` assigns `full.message` afterwards — and that holds\n * for a baked custom message too, since the custom error map is consulted from\n * inside that same assignment.\n */\n\nimport type { CodeGenContext } from \"./context.js\";\nimport { escapeString } from \"./context.js\";\n\n/** Common slim slice of SlowGen + FastGen needed for issue emission. */\ninterface IssueGen {\n readonly issues: string;\n readonly input: string;\n readonly path: string;\n readonly ctx: CodeGenContext;\n readonly typeMsg?: string | undefined;\n}\n\nfunction pushIssue(g: IssueGen, body: string): string {\n return `${g.issues}.push(${body});`;\n}\n\n/** Resolve the effective static message for an issue site: the check's own message, else the owning schema's. */\nfunction resolveMessage(g: IssueGen, explicit: string | undefined): string | undefined {\n return explicit ?? g.typeMsg;\n}\n\n/** `,message:\"...\"` fragment for inline object literals (\"\" when no message). */\n/**\n * `,continue:false` — the marker that makes an issue ABORT its union option.\n *\n * zod prunes union options with `util.aborted`, which asks whether any issue has\n * `continue !== true`. Compiled issues carry no `continue` at all, so the union\n * generator classifies by CODE instead — sound for every issue a schema node\n * raises (`invalid_type`, `unrecognized_keys`, …) but blind to the one\n * exception: `$ZodTuple`'s length branch pushes a `too_small`/`too_big` from the\n * NODE, with no `continue`, where the identically-coded issue from an\n * `.min()`/`.max()` CHECK carries `continue: true` and does not abort. Without\n * this, `z.union([z.tuple([a, b]), z.number()])` handed `[]` surfaced the\n * tuple's `too_small` directly instead of wrapping both options in an\n * `invalid_union`.\n *\n * Stripped during finalization exactly as zod strips its own (`delete\n * full.continue`), so it never reaches a reported issue — see FAIL_CLASS_DECL\n * and ZC_FZ_DECL.\n */\nfunction abortsProp(aborts: boolean | undefined): string {\n return aborts === true ? \",continue:false\" : \"\";\n}\n\nfunction messageProp(m: string | undefined): string {\n return m === undefined ? \"\" : `,message:${escapeString(m)}`;\n}\n\n/** `,\"...\"` trailing argument fragment for lean factory calls (\"\" when no message). */\nfunction messageArg(m: string | undefined): string {\n return m === undefined ? \"\" : `,${escapeString(m)}`;\n}\n\n/**\n * `origin` as source: a bare string is a literal (`\"string\"`), `{ expr }` is an\n * expression evaluated at runtime — what a `when`-gated length/size check needs,\n * since zod derives its origin from the INPUT (`getLengthableOrigin`).\n */\ntype Origin = string | { expr: string };\n\nfunction originExpr(origin: Origin): string {\n return typeof origin === \"string\" ? escapeString(origin) : origin.expr;\n}\n\nexport function tooSmall(\n g: IssueGen,\n minimum: string | number,\n origin: Origin,\n inclusive: boolean,\n options?: {\n exact?: boolean;\n input?: string;\n path?: string;\n message?: string | undefined;\n /**\n * `\"tuple\"` selects $ZodTuple's under-length key order — `code, minimum,\n * inclusive, origin` — where a check-created size issue leads with `origin`.\n * Same shape as its over-length sibling in {@link tooBig}.\n */\n layout?: \"tuple\";\n /** Emit the union-abort marker; see {@link abortsProp}. */\n aborts?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const exact = options?.exact === true;\n const m = resolveMessage(g, options?.message);\n if (g.ctx.mode === \"lean\") {\n if (exact) {\n g.ctx.usedHelpers.add(\"__zcTSx\");\n return pushIssue(\n g,\n `__zcTSx(${minimum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n if (options?.layout === \"tuple\") {\n g.ctx.usedHelpers.add(\"__zcTSt\");\n return pushIssue(\n g,\n `__zcTSt(${minimum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n g.ctx.usedHelpers.add(\"__zcTS\");\n return pushIssue(\n g,\n `__zcTS(${minimum},${originExpr(origin)},${inclusive},${input},${path}${messageArg(m)})`,\n );\n }\n if (exact) {\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_small\",minimum:${minimum},inclusive:true,exact:true,input:${input},path:${path}${messageProp(m)}}`,\n );\n }\n if (options?.layout === \"tuple\") {\n return pushIssue(\n g,\n `{code:\"too_small\",minimum:${minimum},inclusive:${inclusive},origin:${originExpr(origin)},input:${input},path:${path}${messageProp(m)}${abortsProp(options?.aborts)}}`,\n );\n }\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_small\",minimum:${minimum},inclusive:${inclusive},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function tooBig(\n g: IssueGen,\n maximum: string | number,\n origin: Origin,\n inclusive: boolean,\n options?: {\n exact?: boolean;\n input?: string;\n path?: string;\n message?: string | undefined;\n /**\n * `\"tuple\"` selects $ZodTuple's over-length key order — `code, maximum,\n * inclusive, origin` — where a check-created size issue leads with `origin`.\n * zod builds the tuple issue by spreading `{code, maximum, inclusive}` and\n * appending `origin` after `input`/`inst`, and that ordering is visible in\n * `ZodError.message`.\n */\n layout?: \"tuple\";\n /** Emit the union-abort marker; see {@link abortsProp}. */\n aborts?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const exact = options?.exact === true;\n const m = resolveMessage(g, options?.message);\n if (g.ctx.mode === \"lean\") {\n if (exact) {\n g.ctx.usedHelpers.add(\"__zcTBx\");\n return pushIssue(\n g,\n `__zcTBx(${maximum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n if (options?.layout === \"tuple\") {\n g.ctx.usedHelpers.add(\"__zcTBt\");\n return pushIssue(\n g,\n `__zcTBt(${maximum},${originExpr(origin)},${input},${path}${messageArg(m)})`,\n );\n }\n g.ctx.usedHelpers.add(\"__zcTB\");\n return pushIssue(\n g,\n `__zcTB(${maximum},${originExpr(origin)},${inclusive},${input},${path}${messageArg(m)})`,\n );\n }\n if (exact) {\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_big\",maximum:${maximum},inclusive:true,exact:true,input:${input},path:${path}${messageProp(m)}}`,\n );\n }\n if (options?.layout === \"tuple\") {\n return pushIssue(\n g,\n `{code:\"too_big\",maximum:${maximum},inclusive:${inclusive},origin:${originExpr(origin)},input:${input},path:${path}${messageProp(m)}${abortsProp(options?.aborts)}}`,\n );\n }\n return pushIssue(\n g,\n `{origin:${originExpr(origin)},code:\"too_big\",maximum:${maximum},inclusive:${inclusive},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function invalidType(\n g: IssueGen,\n expected: string,\n options?: {\n input?: string;\n path?: string;\n extra?: string;\n message?: string | undefined;\n /**\n * Put `extra` BEFORE `code` rather than after it. $ZodCheckNumberFormat's\n * non-integer issue is `{expected, format, code}` while the `received` a\n * number/date schema adds trails `code` — two orders for one issue code, both\n * printed verbatim in `ZodError.message`.\n */\n extraBeforeCode?: boolean;\n /**\n * Lead with `code` instead of `expected`. `$ZodDiscriminatedUnion`'s\n * non-object guard and `$ZodObject`'s absent-required-key issue\n * (`expected: \"nonoptional\"`) write the issue that way; every other schema\n * in zod puts `expected` first.\n */\n codeFirst?: boolean;\n /**\n * Set to false for the one `invalid_type` zod pushes WITHOUT an `inst`:\n * the object's `nonoptional` issue for an absent required key, which no\n * schema-level `error` reaches.\n */\n useTypeMsg?: boolean;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n // The schema's own message applies unless the issue is raised inst-less, as the nonoptional issue is.\n const m = options?.useTypeMsg === false ? options?.message : resolveMessage(g, options?.message);\n if (g.ctx.mode === \"lean\" && !options?.extra) {\n const helper = options?.codeFirst ? \"__zcITc\" : \"__zcIT\";\n g.ctx.usedHelpers.add(helper);\n return pushIssue(g, `${helper}(${escapeString(expected)},${input},${path}${messageArg(m)})`);\n }\n const extra = options?.extra ?? \"\";\n const head = options?.codeFirst\n ? `code:\"invalid_type\",expected:${escapeString(expected)}${extra ? `,${extra}` : \"\"}`\n : options?.extraBeforeCode\n ? `expected:${escapeString(expected)}${extra ? `,${extra}` : \"\"},code:\"invalid_type\"`\n : `expected:${escapeString(expected)},code:\"invalid_type\"${extra ? `,${extra}` : \"\"}`;\n return pushIssue(g, `{${head},input:${input},path:${path}${messageProp(m)}}`);\n}\n\nexport function invalidFormat(\n g: IssueGen,\n format: string | { expr: string },\n options?: {\n input?: string;\n path?: string;\n /**\n * Leading `origin`, present only where zod's push carries one:\n * `$ZodCheckStringFormat`'s default pattern check and the regex / includes /\n * starts_with / ends_with checks lead with `origin: \"string\"`, while\n * `z.url()`'s own issues and every `$ZodCustomStringFormat` omit it.\n */\n origin?: string | undefined;\n /**\n * Extra issue properties as a source fragment (`'pattern:\"…\"'`), emitted\n * right after `format` where zod writes them. Explicitly `| undefined` so a\n * caller can compute it conditionally: zod's `invalid_format` carries\n * different fields per format, and the bare-issue formats carry none.\n */\n extra?: string | undefined;\n message?: string | undefined;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const formatExpr = typeof format === \"string\" ? escapeString(format) : format.expr;\n const m = resolveMessage(g, options?.message);\n if (g.ctx.mode === \"lean\") {\n g.ctx.usedHelpers.add(\"__zcIF\");\n const originArg = options?.origin === undefined ? \"undefined\" : escapeString(options.origin);\n const extraArg = options?.extra ? `,{${options.extra}}` : m !== undefined ? \",undefined\" : \"\";\n return pushIssue(\n g,\n `__zcIF(${originArg},${formatExpr},${input},${path}${extraArg}${messageArg(m)})`,\n );\n }\n const originProp = options?.origin === undefined ? \"\" : `origin:${escapeString(options.origin)},`;\n const extra = options?.extra ? `,${options.extra}` : \"\";\n return pushIssue(\n g,\n `{${originProp}code:\"invalid_format\",format:${formatExpr}${extra},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function unrecognizedKeys(\n g: IssueGen,\n keysExpr: string,\n options?: { input?: string; path?: string; message?: string | undefined },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const m = resolveMessage(g, options?.message);\n if (g.ctx.mode === \"lean\") {\n g.ctx.usedHelpers.add(\"__zcUK\");\n return pushIssue(g, `__zcUK(${keysExpr},${input},${path}${messageArg(m)})`);\n }\n return pushIssue(\n g,\n `{code:\"unrecognized_keys\",keys:${keysExpr},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n\nexport function invalidValue(\n g: IssueGen,\n valuesExpr: string,\n options?: {\n input?: string;\n path?: string;\n /**\n * Extra issue properties as a source fragment (`'expected:\"stringbool\"'`),\n * modelled on {@link invalidFormat}'s option of the same name. Explicitly\n * `| undefined` so a caller can compute it conditionally: the `invalid_value`\n * producers do NOT agree on fields — enum and literal push only `values`,\n * while z.stringbool()'s codec transform also pushes\n * `expected: \"stringbool\"`, which zod's locale reads to phrase the message.\n */\n extra?: string | undefined;\n message?: string | undefined;\n },\n): string {\n const input = options?.input ?? g.input;\n const path = options?.path ?? g.path;\n const m = resolveMessage(g, options?.message);\n if (g.ctx.mode === \"lean\") {\n g.ctx.usedHelpers.add(\"__zcIV\");\n const extraArg = options?.extra ? `,{${options.extra}}` : m !== undefined ? \",undefined\" : \"\";\n return pushIssue(g, `__zcIV(${valuesExpr},${input},${path}${extraArg}${messageArg(m)})`);\n }\n // `expected` precedes `values` in z.stringbool()'s push, so extras go between\n // `code` and `values` rather than after them.\n const extra = options?.extra ? `,${options.extra}` : \"\";\n return pushIssue(\n g,\n `{code:\"invalid_value\"${extra},values:${valuesExpr},input:${input},path:${path}${messageProp(m)}}`,\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/core/codegen/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/core/codegen/index.ts"],"mappings":";;;;UA8BiB;EACf;;EAEA,OAAO;;;;;EAKP,gBAAgB;;;;;;;;;EAShB;;EAEA,eAAe,UAAU;;EAEzB,sBAAsB;;;;;;;;;;;iBAYR,kBACd,IAAI,UACJ,cACA,UAAU,2BACT"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { RETAINED_SCHEMA_VAR, declareFastTemps, emitRetainedMethod, emitRfDelegate, hasMutation } from "./context.js";
|
|
1
|
+
import { RETAINED_SCHEMA_VAR, declareFastTemps, emitRetainedMethod, emitRfDelegate, emitRuntimeHelper, hasMutation, needsProtoScrub } from "./context.js";
|
|
2
|
+
import { ZC_PROTO_SCRUB_DECL } from "./issue-decls.js";
|
|
2
3
|
import { createSlowGen, generateSlow } from "./slow-path.js";
|
|
3
4
|
import { createFastGen, generateFast } from "./fast-path.js";
|
|
4
|
-
import { fastResultIsInput, generateBuild, rebuildsOutput } from "./build-path.js";
|
|
5
|
+
import { fastResultIsInput, generateBuild, nestedNeedsProtoScrub, rebuildsOutput } from "./build-path.js";
|
|
5
6
|
//#region src/core/codegen/index.ts
|
|
6
7
|
/**
|
|
7
8
|
* Generate optimized validation code from SchemaIR.
|
|
@@ -101,7 +102,7 @@ function generateValidator(ir, name, options) {
|
|
|
101
102
|
}
|
|
102
103
|
const buildIsFnName = ctx.buildSubstitutesValue === true ? null : fastFnName;
|
|
103
104
|
const baseRefCount = options?.refCount ?? 0;
|
|
104
|
-
if (options?.compact === true && fastExpr !== null && fastExpr !== "true" && !hasMutation(ir) && !hasNonRootTargets) {
|
|
105
|
+
if (options?.compact === true && fastExpr !== null && fastExpr !== "true" && !hasMutation(ir) && !needsProtoScrub(ir) && !nestedNeedsProtoScrub(ir) && !hasNonRootTargets) {
|
|
105
106
|
const delegate = emitRetainedMethod(ctx);
|
|
106
107
|
ctx.usedHelpers.add("__zcFinZ");
|
|
107
108
|
return {
|
|
@@ -190,20 +191,21 @@ function generateValidator(ir, name, options) {
|
|
|
190
191
|
fastTotal: false
|
|
191
192
|
};
|
|
192
193
|
}
|
|
193
|
-
if (fastExpr !== null && !hasMutation(ir)) {
|
|
194
|
+
if (fastExpr !== null && !hasMutation(ir) && !nestedNeedsProtoScrub(ir)) {
|
|
195
|
+
const fastData = needsProtoScrub(ir) ? `${emitRuntimeHelper(ctx, "__zcPs", ZC_PROTO_SCRUB_DECL)}(input)` : "input";
|
|
194
196
|
ctx.usedHelpers.add("__zcFinD");
|
|
195
|
-
if (slowCode.includes(fnName)) functionDefParts.push(`if(${fastExpr}){return{success:true,data
|
|
197
|
+
if (slowCode.includes(fnName)) functionDefParts.push(`if(${fastExpr}){return{success:true,data:${fastData}};}`, `return __zcFinD(function(input){`, `var _e=[];`, `var _d=input;`, slowCode, `return _e;`, `},input);`, `}`);
|
|
196
198
|
else {
|
|
197
199
|
const walkName = `__sw_${ctx.counter++}`;
|
|
198
200
|
ctx.preamble.push(`function ${walkName}(input){var _e=[];\nvar _d=input;\n${slowCode}\nreturn _e;}`);
|
|
199
|
-
functionDefParts.push(`if(${fastExpr}){return{success:true,data
|
|
201
|
+
functionDefParts.push(`if(${fastExpr}){return{success:true,data:${fastData}};}`, `return __zcFinD(${walkName},input);`, `}`);
|
|
200
202
|
}
|
|
201
203
|
return {
|
|
202
204
|
code: buildCode(),
|
|
203
205
|
functionDef: functionDefParts.join("\n"),
|
|
204
206
|
refCount: options?.refCount ?? 0,
|
|
205
207
|
usedHelpers: ctx.usedHelpers,
|
|
206
|
-
fastFnName,
|
|
208
|
+
fastFnName: fastResultIsInput(ir) ? fastFnName : null,
|
|
207
209
|
fastTotal: true
|
|
208
210
|
};
|
|
209
211
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/codegen/index.ts"],"sourcesContent":["import type { SchemaIR } from \"../types.js\";\nimport type {\n CodeGenContext,\n CodeGenResult,\n CodegenMode,\n GeneratedConstant,\n RecTargetGen,\n} from \"./context.js\";\nimport { fastResultIsInput, generateBuild, rebuildsOutput } from \"./build-path.js\";\nimport {\n declareFastTemps,\n emitRetainedMethod,\n emitRfDelegate,\n hasMutation,\n RETAINED_SCHEMA_VAR,\n} from \"./context.js\";\nimport type { SharedSchemaPlan } from \"./dedupe.js\";\nimport { createFastGen, generateFast } from \"./fast-path.js\";\nimport { createSlowGen, generateSlow } from \"./slow-path.js\";\n\nexport type { CodeGenResult } from \"./context.js\";\n\nexport interface GenerateValidatorOptions {\n refCount?: number;\n /** Codegen output mode. Defaults to \"inline\". */\n mode?: CodegenMode;\n /**\n * File-level shared slow-walk plan (schema deduplication). Applied only to\n * mutation-free schemas, so shared walks stay on the deferred cold path.\n */\n sharedSchemas?: SharedSchemaPlan | undefined;\n /**\n * Compact mode (`output: \"compact\"`). Drop the compiled slow walk for\n * mutation-free schemas with a TOTAL fast path and delegate the cold error\n * path to the retained Zod schema (`__zcFinZ`). The fast (hot) path is\n * unchanged; only the bulky error-collecting walk — 64–77% of generated\n * bytes — is replaced by a few bytes of zod delegation. See\n * {@link CodeGenResult.usesRetainedSchema}.\n */\n compact?: boolean | undefined;\n /** Internal file-pipeline hook for pooling exact constant initializers across validators. */\n onConstant?: ((constant: GeneratedConstant) => void) | undefined;\n /** Internal exact-initializer plan used by the file pipeline's final generation pass. */\n sharedConstantNames?: ReadonlyMap<string, string> | undefined;\n}\n\n/**\n * Generate optimized validation code from SchemaIR.\n *\n * - `code`: preamble declarations (Sets, RegExps, etc.) — deterministic for the same IR\n * - `functionDef`: full function expression string referencing preamble vars via closure\n * - `usedHelpers`: helper names from \"virtual:zod-compiler/runtime\" referenced (lean mode only)\n *\n * Usage: `new Function(code + \"\\nreturn \" + functionDef + \";\")()`\n */\nexport function generateValidator(\n ir: SchemaIR,\n name: string,\n options?: GenerateValidatorOptions,\n): CodeGenResult {\n const fnName = `safeParse_${name}`;\n const mode: CodegenMode = options?.mode ?? \"inline\";\n const ctx: CodeGenContext = {\n preamble: [],\n counter: 0,\n fnName,\n regexCache: new Map(),\n mode,\n usedHelpers: new Set(),\n onConstant: options?.onConstant,\n sharedConstantNames: options?.sharedConstantNames,\n };\n\n // Slow-walk sharing. The plan already excludes any shape that would reach for\n // this export's `__rf[]`, and a shared walk returns its parsed value, so a\n // rewriting shape (a stripping object above all) delivers its result through\n // the call. Nothing left to gate on here.\n if (options?.sharedSchemas !== undefined) {\n ctx.sharedSchemas = options.sharedSchemas;\n }\n\n // Root-level fallback: the whole schema delegates to Zod, so zod's own\n // safeParse result IS the result. Returning it directly skips the issue\n // copy loop (which would force zod's eager ZodError construction), the\n // pointless [].concat(path) rewrites, and the __zcFin re-wrap. Delegation\n // goes through the pre-mutation capture (emitRfDelegate) — here __rf[0]\n // and the __zcMkv target are routinely the SAME object.\n if (ir.type === \"fallback\" && ir.refIndex !== undefined) {\n const delegate = emitRfDelegate(ctx, ir.refIndex);\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: `function ${fnName}(input){return ${delegate}(input);}`,\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n fastTotal: false,\n };\n }\n\n // Recursion-target table. The root (refId 0) reuses the schema's own\n // `safeParse_<name>` / hosted fast-check, so it needs no separate helper and\n // its fast name is allocated lazily during the walk (recFastName). Non-root\n // targets — recursive sub-schemas nested in a larger root, multiple distinct\n // recursive shapes, mutual recursion — are each hosted as a standalone\n // `__rsp_N` (slow) / `__fcr_N` (fast) validator the cycle calls by name.\n // Common directly-self-recursive schemas have no non-root targets, so this\n // leaves their generated output byte-identical.\n const nonRootTargets = collectRecursionTargets(ir);\n ctx.recTargets = new Map<number, RecTargetGen>([[0, { isRoot: true, slowName: fnName }]]);\n for (const [refId, inner] of nonRootTargets) {\n ctx.recTargets.set(refId, {\n isRoot: false,\n inner,\n slowName: `__rsp_${ctx.counter++}`,\n fastName: `__fcr_${ctx.counter++}`,\n });\n }\n const hasNonRootTargets = nonRootTargets.size > 0;\n\n // Fast Path: generate a boolean expression for eligible schemas.\n //\n // generateFast mutates ctx as it walks (extracted __fo_ helpers + regex/effect\n // decls pushed to the preamble, a recursive __fcr_ name reserved, dedup caches\n // populated). The walk is all-or-nothing: a later fast-ineligible node makes it\n // return null AFTER those side effects already landed. Without a rollback the\n // discarded fast path leaves dead __fo_ helpers in the output — and, when one\n // referenced the recursive __fcr_ host that the `fastExpr !== null` branch below\n // never emits, a dangling reference to an undefined identifier. Snapshot the\n // mutable state and restore it on abort so the slow path re-declares from clean.\n const fastPreambleLen = ctx.preamble.length;\n const fastRegexCache = new Map(ctx.regexCache);\n const fastEffectCache = ctx.effectFnCache && new Map(ctx.effectFnCache);\n const fastValueCache = ctx.valueCache && new Map(ctx.valueCache);\n const fastRecName = ctx.recFastName;\n const fg = createFastGen(\"input\", ctx);\n let fastExpr = generateFast(ir, fg);\n if (fastExpr !== null && hasNonRootTargets) {\n // Host each non-root recursion target as a boolean fast-check helper. A\n // single fast-ineligible target (e.g. one whose recursive shape contains a\n // fallback) disables the WHOLE fast path: the root expression already emits\n // calls to these names, so a missing body would dangle. The shared\n // rollback below then restores clean state for the slow-only path.\n for (const t of ctx.recTargets.values()) {\n if (t.isRoot) continue;\n const targetGen = createFastGen(\"input\", ctx, false);\n const body = generateFast(t.inner as SchemaIR, targetGen);\n if (body === null) {\n fastExpr = null;\n break;\n }\n ctx.preamble.push(\n `function ${t.fastName}(input){${declareFastTemps(targetGen.scope)}return ${body};}`,\n );\n }\n }\n if (fastExpr === null) {\n ctx.preamble.length = fastPreambleLen;\n ctx.regexCache = fastRegexCache;\n if (fastEffectCache === undefined) delete ctx.effectFnCache;\n else ctx.effectFnCache = fastEffectCache;\n // Value declarations the abandoned walk emitted are truncated above, so\n // their cache entries would name identifiers that no longer exist.\n if (fastValueCache === undefined) delete ctx.valueCache;\n else ctx.valueCache = fastValueCache;\n if (fastRecName === undefined) delete ctx.recFastName;\n else ctx.recFastName = fastRecName;\n }\n\n // Host the fast expression in a named boolean helper. Self-recursive\n // schemas need it so recursive refs can call it; every other eligible\n // schema benefits too: __zcMkv wires it into parse()/parseAsync(), whose\n // success paths then return the input directly — no intermediate\n // SafeParseResult allocation (the safeParse function body is far past\n // V8's inlining budget, so escape analysis never removes it).\n let fastFnName: string | null = null;\n if (fastExpr !== null && fastExpr !== \"true\") {\n fastFnName = ctx.recFastName ?? `__fc_${ctx.counter++}`;\n ctx.preamble.push(\n `function ${fastFnName}(input){${declareFastTemps(fg.scope)}return ${fastExpr};}`,\n );\n fastExpr = `${fastFnName}(input)`;\n }\n\n // Build Path: one pass that validates and assembles rewritten output, bailing\n // on the first failure (see build-path). Null unless every mutation in the\n // schema is modelled — so this emits nothing for the mutation-free schemas\n // the compact branch takes.\n const buildFnName = generateBuild(ir, ctx);\n\n // A zodDelegate with a rebuilding inner exists only to accelerate that\n // build. If an unmodelled descendant made the all-or-nothing build decline,\n // preserve the old root-fallback shape instead of wrapping the same pristine\n // Zod call in an issues array/copy/finalizer. This keeps unsupported object\n // intersections neutral rather than making compilation slower than Zod.\n if (ir.type === \"zodDelegate\" && rebuildsOutput(ir.inner) && buildFnName === null) {\n ctx.preamble.length = 0;\n ctx.usedHelpers.clear();\n ctx.regexCache.clear();\n ctx.effectFnCache?.clear();\n ctx.valueCache?.clear();\n const delegate = emitRfDelegate(ctx, ir.refIndex);\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: `function ${fnName}(input){return ${delegate}(input);}`,\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n fastTotal: false,\n };\n }\n\n // `.is()` for a build-path schema is the fast expression — stripping reshapes\n // the payload, never the verdict. A substituted `.default()` breaks that: the\n // fast check demands a present value where the schema accepts its absence, so\n // the predicate is partial and `.is()` falls back to safeParse().success\n // (which runs the build pass, so it is no slower than the eager walk was).\n const buildIsFnName = ctx.buildSubstitutesValue === true ? null : fastFnName;\n\n const baseRefCount = options?.refCount ?? 0;\n\n // Compact mode: a mutation-free schema with a TOTAL fast path needs no\n // compiled slow walk — its only purpose is reproducing zod's issues on\n // failure, and the original zod schema (retained in `output: \"compact\"`) does\n // that exactly. Emit the fast check and, on failure, delegate to a fresh root\n // RefEntry (the schema itself) via the pristine safeParse method capture, then\n // wrap it in the lazy `__zcFinZ` failure. Drops 64–77% of generated bytes\n // with zero hot-path cost (fc and `.is()` are unchanged) and zod-identical\n // errors. Excluded: schemas with non-root recursion targets (mutual/nested\n // recursion still hosts standalone slow validators) and any non-total fast\n // path (mutation/default/catch/fallback) — those keep the compiled path.\n if (\n options?.compact === true &&\n fastExpr !== null &&\n fastExpr !== \"true\" &&\n !hasMutation(ir) &&\n !hasNonRootTargets\n ) {\n const delegate = emitRetainedMethod(ctx);\n ctx.usedHelpers.add(\"__zcFinZ\");\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: [\n `function ${fnName}(input){`,\n `if(${fastExpr}){return{success:true,data:input};}`,\n `return __zcFinZ(${delegate},${RETAINED_SCHEMA_VAR},input);`,\n `}`,\n ].join(\"\\n\"),\n refCount: baseRefCount,\n usedHelpers: ctx.usedHelpers,\n fastFnName,\n // Mutation-free total fast path: fc(input) ⟺ accepts(input), so `.is()`\n // installs fc directly (compact never weakens the guard).\n fastTotal: true,\n usesRetainedSchema: true,\n };\n }\n\n // Compact + Build Path: same bargain for a schema with modelled rewrites. The\n // build pass still has to run (it produces the payload, which zod's schema\n // would only reproduce by parsing again), but the compiled issue walk is what\n // compact drops, and delegating that to the retained zod schema costs a few\n // bytes.\n if (\n options?.compact === true &&\n buildFnName !== null &&\n ctx.buildFailName !== undefined &&\n !hasNonRootTargets\n ) {\n const delegate = emitRetainedMethod(ctx);\n ctx.usedHelpers.add(\"__zcFinZ\");\n const built = `__bd_${ctx.counter++}`;\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: [\n `function ${fnName}(input){`,\n `var ${built}=${buildFnName}(input);`,\n `if(${built}!==${ctx.buildFailName}){return{success:true,data:${built}};}`,\n `return __zcFinZ(${delegate},${RETAINED_SCHEMA_VAR},input);`,\n `}`,\n ].join(\"\\n\"),\n refCount: baseRefCount,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n fastTotal: false,\n isFnName: buildIsFnName,\n usesRetainedSchema: true,\n };\n }\n\n // Host each non-root recursion target as a safeParse-shaped slow validator,\n // mirroring the root's eager body: collect issues, return success+data or a\n // deferred-error result. Always emitted (the slow path always exists); the\n // recursion call sites read `.success` / `.error.issues` / `.data`. Hoisted\n // function declarations, so their order relative to the root is irrelevant.\n if (hasNonRootTargets) {\n for (const t of ctx.recTargets.values()) {\n if (t.isRoot) continue;\n const body = generateSlow(t.inner as SchemaIR, createSlowGen(\"_d\", \"_d\", \"[]\", \"_e\", ctx));\n ctx.usedHelpers.add(\"__zcFin\");\n ctx.preamble.push(\n `function ${t.slowName}(input){var _e=[];\\nvar _d=input;\\n${body}\\n` +\n `if(_e.length===0){return{success:true,data:_d};}\\nreturn __zcFin(_e,_d);}`,\n );\n }\n }\n\n const sg = createSlowGen(\"_d\", \"_d\", \"[]\", \"_e\", ctx);\n // When the root schema's own shape is shared (it recurs as a sub-schema of\n // another export, or as a duplicate root), its slow walk delegates to the\n // shared function instead of emitting a second full copy. The fast path is\n // still generated inline above — only the cold walk is shared.\n const rootRef = ctx.sharedSchemas?.refFor(ir);\n const slowCode = rootRef !== undefined ? `_d=${rootRef.name}(_d,[],_e);` : generateSlow(ir, sg);\n\n const buildCode = (): string => [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\");\n\n const functionDefParts = [`function ${fnName}(input){`];\n\n // Build Path: every mutation is modelled, so one pass can validate and\n // assemble the output together and bail on the first failure, leaving the\n // issue-producing walk deferred behind `.error` (see build-path).\n // The fast check stays out of `safeParse` entirely — running it first would\n // read every property twice — but it is still an EXACT acceptance predicate\n // (stripping reshapes the output, never the verdict), so `.is()` installs it.\n if (buildFnName !== null && ctx.buildFailName !== undefined) {\n ctx.usedHelpers.add(\"__zcFinD\");\n const built = `__bd_${ctx.counter++}`;\n // A self-recursive walk calls this validator BY NAME (slowRecursiveRef),\n // and that binding exists only inside the named function expression — so\n // there the walk stays a per-call closure. Everything else hosts it in the\n // preamble, keeping safeParse to three statements. Mirrors the same split\n // in the mutation-free branch below.\n const recursive = slowCode.includes(fnName);\n let deferred: string;\n if (recursive) {\n deferred = `__zcFinD(function(input){var _e=[];\\nvar _d=input;\\n${slowCode}\\nreturn _e;},input)`;\n } else {\n const walkName = `__sw_${ctx.counter++}`;\n ctx.preamble.push(\n `function ${walkName}(input){var _e=[];\\nvar _d=input;\\n${slowCode}\\nreturn _e;}`,\n );\n deferred = `__zcFinD(${walkName},input)`;\n }\n return {\n code: buildCode(),\n functionDef: [\n `function ${fnName}(input){`,\n `var ${built}=${buildFnName}(input);`,\n `if(${built}!==${ctx.buildFailName}){return{success:true,data:${built}};}`,\n `return ${deferred};`,\n `}`,\n ].join(\"\\n\"),\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n // No by-reference shortcut: `data` is the freshly built object, so\n // parse() must go through safeParse rather than returning its input.\n fastFnName: null,\n // `fastTotal` qualifies `fastFnName`, which is null here; the predicate\n // travels in `isFnName` instead.\n fastTotal: false,\n isFnName: buildIsFnName,\n };\n }\n\n if (fastExpr === \"true\") {\n // Schema always succeeds (any/unknown) — skip slow path entirely\n functionDefParts.push(`return{success:true,data:input};`);\n functionDefParts.push(`}`);\n return {\n code: buildCode(),\n functionDef: functionDefParts.join(\"\\n\"),\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n // any/unknown always succeed; `.is()` derives `true` from the fn fallback.\n fastTotal: false,\n };\n }\n\n if (fastExpr !== null && !hasMutation(ir)) {\n // Mutation-free schemas with a fast path: a fast-check failure can never\n // become a slow-path success (both are generated from the same checks —\n // unlike default/catch schemas, whose partial fast path requires value\n // presence while the slow path SUCCEEDS by applying the fallback).\n // The slow path's only output is therefore the issues array, observable\n // solely through `.error` — defer the whole re-walk into the cached\n // accessor (__zcFinD): a failed safeParse whose `.error` is never read\n // costs the fast check alone.\n //\n // The walk is HOSTED as a named preamble function rather than a per-call\n // closure, for two measured reasons: (1) a failed safeParse no longer\n // allocates a closure environment + function object before the deferral\n // even starts; (2) the safeParse body shrinks to two statements, putting\n // it within V8's inlining budget — callers in hot loops get the\n // success-path result object escape-analyzed away entirely, which the\n // old shape (slow walk inlined into the body) made impossible.\n ctx.usedHelpers.add(\"__zcFinD\");\n if (slowCode.includes(fnName)) {\n // Self-recursive slow paths call the safeParse function by NAME\n // (slowRecursiveRef) — that binding exists only inside the named\n // function expression under the documented evaluation contract\n // (`new Function(code + \"return \" + functionDef)`), so the walk stays\n // a per-call closure for recursive schemas. Recursion is the rare\n // shape; everything else gets the hosted walk.\n functionDefParts.push(\n `if(${fastExpr}){return{success:true,data:input};}`,\n `return __zcFinD(function(input){`,\n `var _e=[];`,\n `var _d=input;`,\n slowCode,\n `return _e;`,\n `},input);`,\n `}`,\n );\n } else {\n const walkName = `__sw_${ctx.counter++}`;\n ctx.preamble.push(\n `function ${walkName}(input){var _e=[];\\nvar _d=input;\\n${slowCode}\\nreturn _e;}`,\n );\n functionDefParts.push(\n `if(${fastExpr}){return{success:true,data:input};}`,\n `return __zcFinD(${walkName},input);`,\n `}`,\n );\n }\n return {\n code: buildCode(),\n functionDef: functionDefParts.join(\"\\n\"),\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName,\n // Total predicate: mutation-free fast path, fc(input) ⟺ accepts(input).\n // generateIIFE installs fc directly as the zero-allocation `.is()`.\n fastTotal: true,\n };\n }\n\n if (fastExpr !== null && fastResultIsInput(ir)) {\n // Partial fast path (default/catch/... present-value shortcut): the slow\n // path must run eagerly — it can succeed where the fast check failed.\n //\n // Withheld when the schema rebuilds its output: there the fast check is a\n // sound VERDICT but says nothing about the payload, and `data:input` would\n // hand back the unstripped input. Such schemas reach here only when the\n // build path declined them, so the eager walk produces the output instead.\n functionDefParts.push(`if(${fastExpr}){return{success:true,data:input};}`);\n }\n\n // Success branch inlined at the call site instead of inside __zcFin: the\n // eager path (mutation schemas — coerce/default/trim/transform) returns\n // here on EVERY parse, and the inline literal keeps the hot exit free of a\n // cross-function call; __zcFin is reached only on failure.\n functionDefParts.push(\n `var _e=[];`,\n `var _d=input;`,\n slowCode,\n `if(_e.length===0){return{success:true,data:_d};}`,\n `return __zcFin(_e,_d);`,\n `}`,\n );\n\n const functionDef = functionDefParts.join(\"\\n\");\n\n return {\n code: buildCode(),\n functionDef,\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n // `fc` carries a stronger contract than \"accepts\": `__zcMkv` returns the\n // INPUT from `parse()`/`parseAsync()`/`~standard` whenever it holds, so it\n // may only be published when a passing check implies `data === input`. A\n // rebuilding schema breaks that even though its safeParse is correct, and so\n // does a union whose options can rewrite — see `fastResultIsInput` for both.\n // Same guard as the `data: input` shortcut above, which is the other reader\n // of the same contract.\n fastFnName: fastResultIsInput(ir) ? fastFnName : null,\n // Partial fast path (default/catch) or none (including coercion): a false fc\n // result does not imply rejection, so `.is()` derives from\n // safeParse(input).success.\n fastTotal: false,\n };\n}\n\n/**\n * Find every non-root recursion target (a `recursionTarget` node, refId ≥ 1)\n * reachable from `root`, mapping refId → the inner IR to host as a standalone\n * validator. The root target (refId 0) is the schema's own function and is\n * never wrapped, so it never appears here. The same target may be wrapped at\n * several sites (a recursive schema reached from sibling positions); the first\n * inner wins — they are structurally identical extractions of one schema.\n */\nfunction collectRecursionTargets(root: SchemaIR): Map<number, SchemaIR> {\n const out = new Map<number, SchemaIR>();\n const seen = new Set<SchemaIR>();\n const walk = (ir: SchemaIR): void => {\n if (seen.has(ir)) return;\n seen.add(ir);\n if (ir.type === \"recursionTarget\" && !out.has(ir.refId)) {\n out.set(ir.refId, ir.inner);\n }\n for (const child of childIRs(ir)) walk(child);\n };\n walk(root);\n return out;\n}\n\n/** Direct child SchemaIR nodes, covering every node type (including the new wrapper). */\nfunction childIRs(ir: SchemaIR): readonly SchemaIR[] {\n switch (ir.type) {\n case \"object\":\n return Object.values(ir.properties);\n case \"array\":\n return [ir.element];\n case \"tuple\":\n return ir.rest === null ? ir.items : [...ir.items, ir.rest];\n case \"record\":\n case \"map\":\n return [ir.keyType, ir.valueType];\n case \"set\":\n return [ir.valueType];\n case \"union\":\n case \"discriminatedUnion\":\n return ir.options;\n case \"intersection\":\n return [ir.left, ir.right];\n case \"optional\":\n case \"nullable\":\n case \"readonly\":\n case \"default\":\n case \"catch\":\n case \"effect\":\n case \"recursionTarget\":\n case \"zodDelegate\":\n return [ir.inner];\n case \"pipe\":\n return [ir.in, ir.out];\n default:\n return [];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/codegen/index.ts"],"sourcesContent":["import type { SchemaIR } from \"../types.js\";\nimport type {\n CodeGenContext,\n CodeGenResult,\n CodegenMode,\n GeneratedConstant,\n RecTargetGen,\n} from \"./context.js\";\nimport {\n fastResultIsInput,\n generateBuild,\n nestedNeedsProtoScrub,\n rebuildsOutput,\n} from \"./build-path.js\";\nimport {\n declareFastTemps,\n emitRetainedMethod,\n emitRfDelegate,\n emitRuntimeHelper,\n hasMutation,\n needsProtoScrub,\n RETAINED_SCHEMA_VAR,\n} from \"./context.js\";\nimport type { SharedSchemaPlan } from \"./dedupe.js\";\nimport { ZC_PROTO_SCRUB_DECL } from \"./issue-decls.js\";\nimport { createFastGen, generateFast } from \"./fast-path.js\";\nimport { createSlowGen, generateSlow } from \"./slow-path.js\";\n\nexport type { CodeGenResult } from \"./context.js\";\n\nexport interface GenerateValidatorOptions {\n refCount?: number;\n /** Codegen output mode. Defaults to \"inline\". */\n mode?: CodegenMode;\n /**\n * File-level shared slow-walk plan (schema deduplication). Applied only to\n * mutation-free schemas, so shared walks stay on the deferred cold path.\n */\n sharedSchemas?: SharedSchemaPlan | undefined;\n /**\n * Compact mode (`output: \"compact\"`). Drop the compiled slow walk for\n * mutation-free schemas with a TOTAL fast path and delegate the cold error\n * path to the retained Zod schema (`__zcFinZ`). The fast (hot) path is\n * unchanged; only the bulky error-collecting walk — 64–77% of generated\n * bytes — is replaced by a few bytes of zod delegation. See\n * {@link CodeGenResult.usesRetainedSchema}.\n */\n compact?: boolean | undefined;\n /** Internal file-pipeline hook for pooling exact constant initializers across validators. */\n onConstant?: ((constant: GeneratedConstant) => void) | undefined;\n /** Internal exact-initializer plan used by the file pipeline's final generation pass. */\n sharedConstantNames?: ReadonlyMap<string, string> | undefined;\n}\n\n/**\n * Generate optimized validation code from SchemaIR.\n *\n * - `code`: preamble declarations (Sets, RegExps, etc.) — deterministic for the same IR\n * - `functionDef`: full function expression string referencing preamble vars via closure\n * - `usedHelpers`: helper names from \"virtual:zod-compiler/runtime\" referenced (lean mode only)\n *\n * Usage: `new Function(code + \"\\nreturn \" + functionDef + \";\")()`\n */\nexport function generateValidator(\n ir: SchemaIR,\n name: string,\n options?: GenerateValidatorOptions,\n): CodeGenResult {\n const fnName = `safeParse_${name}`;\n const mode: CodegenMode = options?.mode ?? \"inline\";\n const ctx: CodeGenContext = {\n preamble: [],\n counter: 0,\n fnName,\n regexCache: new Map(),\n mode,\n usedHelpers: new Set(),\n onConstant: options?.onConstant,\n sharedConstantNames: options?.sharedConstantNames,\n };\n\n // Slow-walk sharing. The plan already excludes any shape that would reach for\n // this export's `__rf[]`, and a shared walk returns its parsed value, so a\n // rewriting shape (a stripping object above all) delivers its result through\n // the call. Nothing left to gate on here.\n if (options?.sharedSchemas !== undefined) {\n ctx.sharedSchemas = options.sharedSchemas;\n }\n\n // Root-level fallback: the whole schema delegates to Zod, so zod's own\n // safeParse result IS the result. Returning it directly skips the issue\n // copy loop (which would force zod's eager ZodError construction), the\n // pointless [].concat(path) rewrites, and the __zcFin re-wrap. Delegation\n // goes through the pre-mutation capture (emitRfDelegate) — here __rf[0]\n // and the __zcMkv target are routinely the SAME object.\n if (ir.type === \"fallback\" && ir.refIndex !== undefined) {\n const delegate = emitRfDelegate(ctx, ir.refIndex);\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: `function ${fnName}(input){return ${delegate}(input);}`,\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n fastTotal: false,\n };\n }\n\n // Recursion-target table. The root (refId 0) reuses the schema's own\n // `safeParse_<name>` / hosted fast-check, so it needs no separate helper and\n // its fast name is allocated lazily during the walk (recFastName). Non-root\n // targets — recursive sub-schemas nested in a larger root, multiple distinct\n // recursive shapes, mutual recursion — are each hosted as a standalone\n // `__rsp_N` (slow) / `__fcr_N` (fast) validator the cycle calls by name.\n // Common directly-self-recursive schemas have no non-root targets, so this\n // leaves their generated output byte-identical.\n const nonRootTargets = collectRecursionTargets(ir);\n ctx.recTargets = new Map<number, RecTargetGen>([[0, { isRoot: true, slowName: fnName }]]);\n for (const [refId, inner] of nonRootTargets) {\n ctx.recTargets.set(refId, {\n isRoot: false,\n inner,\n slowName: `__rsp_${ctx.counter++}`,\n fastName: `__fcr_${ctx.counter++}`,\n });\n }\n const hasNonRootTargets = nonRootTargets.size > 0;\n\n // Fast Path: generate a boolean expression for eligible schemas.\n //\n // generateFast mutates ctx as it walks (extracted __fo_ helpers + regex/effect\n // decls pushed to the preamble, a recursive __fcr_ name reserved, dedup caches\n // populated). The walk is all-or-nothing: a later fast-ineligible node makes it\n // return null AFTER those side effects already landed. Without a rollback the\n // discarded fast path leaves dead __fo_ helpers in the output — and, when one\n // referenced the recursive __fcr_ host that the `fastExpr !== null` branch below\n // never emits, a dangling reference to an undefined identifier. Snapshot the\n // mutable state and restore it on abort so the slow path re-declares from clean.\n const fastPreambleLen = ctx.preamble.length;\n const fastRegexCache = new Map(ctx.regexCache);\n const fastEffectCache = ctx.effectFnCache && new Map(ctx.effectFnCache);\n const fastValueCache = ctx.valueCache && new Map(ctx.valueCache);\n const fastRecName = ctx.recFastName;\n const fg = createFastGen(\"input\", ctx);\n let fastExpr = generateFast(ir, fg);\n if (fastExpr !== null && hasNonRootTargets) {\n // Host each non-root recursion target as a boolean fast-check helper. A\n // single fast-ineligible target (e.g. one whose recursive shape contains a\n // fallback) disables the WHOLE fast path: the root expression already emits\n // calls to these names, so a missing body would dangle. The shared\n // rollback below then restores clean state for the slow-only path.\n for (const t of ctx.recTargets.values()) {\n if (t.isRoot) continue;\n const targetGen = createFastGen(\"input\", ctx, false);\n const body = generateFast(t.inner as SchemaIR, targetGen);\n if (body === null) {\n fastExpr = null;\n break;\n }\n ctx.preamble.push(\n `function ${t.fastName}(input){${declareFastTemps(targetGen.scope)}return ${body};}`,\n );\n }\n }\n if (fastExpr === null) {\n ctx.preamble.length = fastPreambleLen;\n ctx.regexCache = fastRegexCache;\n if (fastEffectCache === undefined) delete ctx.effectFnCache;\n else ctx.effectFnCache = fastEffectCache;\n // Value declarations the abandoned walk emitted are truncated above, so\n // their cache entries would name identifiers that no longer exist.\n if (fastValueCache === undefined) delete ctx.valueCache;\n else ctx.valueCache = fastValueCache;\n if (fastRecName === undefined) delete ctx.recFastName;\n else ctx.recFastName = fastRecName;\n }\n\n // Host the fast expression in a named boolean helper. Self-recursive\n // schemas need it so recursive refs can call it; every other eligible\n // schema benefits too: __zcMkv wires it into parse()/parseAsync(), whose\n // success paths then return the input directly — no intermediate\n // SafeParseResult allocation (the safeParse function body is far past\n // V8's inlining budget, so escape analysis never removes it).\n let fastFnName: string | null = null;\n if (fastExpr !== null && fastExpr !== \"true\") {\n fastFnName = ctx.recFastName ?? `__fc_${ctx.counter++}`;\n ctx.preamble.push(\n `function ${fastFnName}(input){${declareFastTemps(fg.scope)}return ${fastExpr};}`,\n );\n fastExpr = `${fastFnName}(input)`;\n }\n\n // Build Path: one pass that validates and assembles rewritten output, bailing\n // on the first failure (see build-path). Null unless every mutation in the\n // schema is modelled — so this emits nothing for the mutation-free schemas\n // the compact branch takes.\n const buildFnName = generateBuild(ir, ctx);\n\n // A zodDelegate with a rebuilding inner exists only to accelerate that\n // build. If an unmodelled descendant made the all-or-nothing build decline,\n // preserve the old root-fallback shape instead of wrapping the same pristine\n // Zod call in an issues array/copy/finalizer. This keeps unsupported object\n // intersections neutral rather than making compilation slower than Zod.\n if (ir.type === \"zodDelegate\" && rebuildsOutput(ir.inner) && buildFnName === null) {\n ctx.preamble.length = 0;\n ctx.usedHelpers.clear();\n ctx.regexCache.clear();\n ctx.effectFnCache?.clear();\n ctx.valueCache?.clear();\n const delegate = emitRfDelegate(ctx, ir.refIndex);\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: `function ${fnName}(input){return ${delegate}(input);}`,\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n fastTotal: false,\n };\n }\n\n // `.is()` for a build-path schema is the fast expression — stripping reshapes\n // the payload, never the verdict. A substituted `.default()` breaks that: the\n // fast check demands a present value where the schema accepts its absence, so\n // the predicate is partial and `.is()` falls back to safeParse().success\n // (which runs the build pass, so it is no slower than the eager walk was).\n const buildIsFnName = ctx.buildSubstitutesValue === true ? null : fastFnName;\n\n const baseRefCount = options?.refCount ?? 0;\n\n // Compact mode: a mutation-free schema with a TOTAL fast path needs no\n // compiled slow walk — its only purpose is reproducing zod's issues on\n // failure, and the original zod schema (retained in `output: \"compact\"`) does\n // that exactly. Emit the fast check and, on failure, delegate to a fresh root\n // RefEntry (the schema itself) via the pristine safeParse method capture, then\n // wrap it in the lazy `__zcFinZ` failure. Drops 64–77% of generated bytes\n // with zero hot-path cost (fc and `.is()` are unchanged) and zod-identical\n // errors. Excluded: schemas with non-root recursion targets (mutual/nested\n // recursion still hosts standalone slow validators) and any non-total fast\n // path (mutation/default/catch/fallback) — those keep the compiled path.\n if (\n options?.compact === true &&\n fastExpr !== null &&\n fastExpr !== \"true\" &&\n !hasMutation(ir) &&\n // `data: input` verbatim, with no compiled walk to fall back on — so a\n // schema whose output needs an own `__proto__` removed cannot use it.\n !needsProtoScrub(ir) &&\n !nestedNeedsProtoScrub(ir) &&\n !hasNonRootTargets\n ) {\n const delegate = emitRetainedMethod(ctx);\n ctx.usedHelpers.add(\"__zcFinZ\");\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: [\n `function ${fnName}(input){`,\n `if(${fastExpr}){return{success:true,data:input};}`,\n `return __zcFinZ(${delegate},${RETAINED_SCHEMA_VAR},input);`,\n `}`,\n ].join(\"\\n\"),\n refCount: baseRefCount,\n usedHelpers: ctx.usedHelpers,\n fastFnName,\n // Mutation-free total fast path: fc(input) ⟺ accepts(input), so `.is()`\n // installs fc directly (compact never weakens the guard).\n fastTotal: true,\n usesRetainedSchema: true,\n };\n }\n\n // Compact + Build Path: same bargain for a schema with modelled rewrites. The\n // build pass still has to run (it produces the payload, which zod's schema\n // would only reproduce by parsing again), but the compiled issue walk is what\n // compact drops, and delegating that to the retained zod schema costs a few\n // bytes.\n if (\n options?.compact === true &&\n buildFnName !== null &&\n ctx.buildFailName !== undefined &&\n !hasNonRootTargets\n ) {\n const delegate = emitRetainedMethod(ctx);\n ctx.usedHelpers.add(\"__zcFinZ\");\n const built = `__bd_${ctx.counter++}`;\n return {\n code: [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\"),\n functionDef: [\n `function ${fnName}(input){`,\n `var ${built}=${buildFnName}(input);`,\n `if(${built}!==${ctx.buildFailName}){return{success:true,data:${built}};}`,\n `return __zcFinZ(${delegate},${RETAINED_SCHEMA_VAR},input);`,\n `}`,\n ].join(\"\\n\"),\n refCount: baseRefCount,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n fastTotal: false,\n isFnName: buildIsFnName,\n usesRetainedSchema: true,\n };\n }\n\n // Host each non-root recursion target as a safeParse-shaped slow validator,\n // mirroring the root's eager body: collect issues, return success+data or a\n // deferred-error result. Always emitted (the slow path always exists); the\n // recursion call sites read `.success` / `.error.issues` / `.data`. Hoisted\n // function declarations, so their order relative to the root is irrelevant.\n if (hasNonRootTargets) {\n for (const t of ctx.recTargets.values()) {\n if (t.isRoot) continue;\n const body = generateSlow(t.inner as SchemaIR, createSlowGen(\"_d\", \"_d\", \"[]\", \"_e\", ctx));\n ctx.usedHelpers.add(\"__zcFin\");\n ctx.preamble.push(\n `function ${t.slowName}(input){var _e=[];\\nvar _d=input;\\n${body}\\n` +\n `if(_e.length===0){return{success:true,data:_d};}\\nreturn __zcFin(_e,_d);}`,\n );\n }\n }\n\n const sg = createSlowGen(\"_d\", \"_d\", \"[]\", \"_e\", ctx);\n // When the root schema's own shape is shared (it recurs as a sub-schema of\n // another export, or as a duplicate root), its slow walk delegates to the\n // shared function instead of emitting a second full copy. The fast path is\n // still generated inline above — only the cold walk is shared.\n const rootRef = ctx.sharedSchemas?.refFor(ir);\n const slowCode = rootRef !== undefined ? `_d=${rootRef.name}(_d,[],_e);` : generateSlow(ir, sg);\n\n const buildCode = (): string => [\"/* zod-compiler */\", ...ctx.preamble].join(\"\\n\");\n\n const functionDefParts = [`function ${fnName}(input){`];\n\n // Build Path: every mutation is modelled, so one pass can validate and\n // assemble the output together and bail on the first failure, leaving the\n // issue-producing walk deferred behind `.error` (see build-path).\n // The fast check stays out of `safeParse` entirely — running it first would\n // read every property twice — but it is still an EXACT acceptance predicate\n // (stripping reshapes the output, never the verdict), so `.is()` installs it.\n if (buildFnName !== null && ctx.buildFailName !== undefined) {\n ctx.usedHelpers.add(\"__zcFinD\");\n const built = `__bd_${ctx.counter++}`;\n // A self-recursive walk calls this validator BY NAME (slowRecursiveRef),\n // and that binding exists only inside the named function expression — so\n // there the walk stays a per-call closure. Everything else hosts it in the\n // preamble, keeping safeParse to three statements. Mirrors the same split\n // in the mutation-free branch below.\n const recursive = slowCode.includes(fnName);\n let deferred: string;\n if (recursive) {\n deferred = `__zcFinD(function(input){var _e=[];\\nvar _d=input;\\n${slowCode}\\nreturn _e;},input)`;\n } else {\n const walkName = `__sw_${ctx.counter++}`;\n ctx.preamble.push(\n `function ${walkName}(input){var _e=[];\\nvar _d=input;\\n${slowCode}\\nreturn _e;}`,\n );\n deferred = `__zcFinD(${walkName},input)`;\n }\n return {\n code: buildCode(),\n functionDef: [\n `function ${fnName}(input){`,\n `var ${built}=${buildFnName}(input);`,\n `if(${built}!==${ctx.buildFailName}){return{success:true,data:${built}};}`,\n `return ${deferred};`,\n `}`,\n ].join(\"\\n\"),\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n // No by-reference shortcut: `data` is the freshly built object, so\n // parse() must go through safeParse rather than returning its input.\n fastFnName: null,\n // `fastTotal` qualifies `fastFnName`, which is null here; the predicate\n // travels in `isFnName` instead.\n fastTotal: false,\n isFnName: buildIsFnName,\n };\n }\n\n if (fastExpr === \"true\") {\n // Schema always succeeds (any/unknown) — skip slow path entirely\n functionDefParts.push(`return{success:true,data:input};`);\n functionDefParts.push(`}`);\n return {\n code: buildCode(),\n functionDef: functionDefParts.join(\"\\n\"),\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n fastFnName: null,\n // any/unknown always succeed; `.is()` derives `true` from the fn fallback.\n fastTotal: false,\n };\n }\n\n if (fastExpr !== null && !hasMutation(ir) && !nestedNeedsProtoScrub(ir)) {\n // The by-reference shortcut hands back the input verbatim, which a loose or\n // catchall object — or a record — must not do while it still carries an own\n // `__proto__` (see ZC_PROTO_SCRUB_DECL). The fast check itself stays a pure\n // predicate, so `fc(input) ⟺ zod accepts` still holds and the deferred error\n // path below is untouched; only the value handed back is filtered. The cost\n // is one `hasOwnProperty` per successful parse of those shapes.\n const fastData = needsProtoScrub(ir)\n ? `${emitRuntimeHelper(ctx, \"__zcPs\", ZC_PROTO_SCRUB_DECL)}(input)`\n : \"input\";\n // Mutation-free schemas with a fast path: a fast-check failure can never\n // become a slow-path success (both are generated from the same checks —\n // unlike default/catch schemas, whose partial fast path requires value\n // presence while the slow path SUCCEEDS by applying the fallback).\n // The slow path's only output is therefore the issues array, observable\n // solely through `.error` — defer the whole re-walk into the cached\n // accessor (__zcFinD): a failed safeParse whose `.error` is never read\n // costs the fast check alone.\n //\n // The walk is HOSTED as a named preamble function rather than a per-call\n // closure, for two measured reasons: (1) a failed safeParse no longer\n // allocates a closure environment + function object before the deferral\n // even starts; (2) the safeParse body shrinks to two statements, putting\n // it within V8's inlining budget — callers in hot loops get the\n // success-path result object escape-analyzed away entirely, which the\n // old shape (slow walk inlined into the body) made impossible.\n ctx.usedHelpers.add(\"__zcFinD\");\n if (slowCode.includes(fnName)) {\n // Self-recursive slow paths call the safeParse function by NAME\n // (slowRecursiveRef) — that binding exists only inside the named\n // function expression under the documented evaluation contract\n // (`new Function(code + \"return \" + functionDef)`), so the walk stays\n // a per-call closure for recursive schemas. Recursion is the rare\n // shape; everything else gets the hosted walk.\n functionDefParts.push(\n `if(${fastExpr}){return{success:true,data:${fastData}};}`,\n `return __zcFinD(function(input){`,\n `var _e=[];`,\n `var _d=input;`,\n slowCode,\n `return _e;`,\n `},input);`,\n `}`,\n );\n } else {\n const walkName = `__sw_${ctx.counter++}`;\n ctx.preamble.push(\n `function ${walkName}(input){var _e=[];\\nvar _d=input;\\n${slowCode}\\nreturn _e;}`,\n );\n functionDefParts.push(\n `if(${fastExpr}){return{success:true,data:${fastData}};}`,\n `return __zcFinD(${walkName},input);`,\n `}`,\n );\n }\n return {\n code: buildCode(),\n functionDef: functionDefParts.join(\"\\n\"),\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n // `fc` is a sound VERDICT here either way, but publishing it also promises\n // `parse()` may return the input — which a scrubbed output cannot (see\n // fastResultIsInput). `.is()` still gets the predicate through fastTotal.\n fastFnName: fastResultIsInput(ir) ? fastFnName : null,\n // Total predicate: mutation-free fast path, fc(input) ⟺ accepts(input).\n // generateIIFE installs fc directly as the zero-allocation `.is()`.\n fastTotal: true,\n };\n }\n\n if (fastExpr !== null && fastResultIsInput(ir)) {\n // Partial fast path (default/catch/... present-value shortcut): the slow\n // path must run eagerly — it can succeed where the fast check failed.\n //\n // Withheld when the schema rebuilds its output: there the fast check is a\n // sound VERDICT but says nothing about the payload, and `data:input` would\n // hand back the unstripped input. Such schemas reach here only when the\n // build path declined them, so the eager walk produces the output instead.\n functionDefParts.push(`if(${fastExpr}){return{success:true,data:input};}`);\n }\n\n // Success branch inlined at the call site instead of inside __zcFin: the\n // eager path (mutation schemas — coerce/default/trim/transform) returns\n // here on EVERY parse, and the inline literal keeps the hot exit free of a\n // cross-function call; __zcFin is reached only on failure.\n functionDefParts.push(\n `var _e=[];`,\n `var _d=input;`,\n slowCode,\n `if(_e.length===0){return{success:true,data:_d};}`,\n `return __zcFin(_e,_d);`,\n `}`,\n );\n\n const functionDef = functionDefParts.join(\"\\n\");\n\n return {\n code: buildCode(),\n functionDef,\n refCount: options?.refCount ?? 0,\n usedHelpers: ctx.usedHelpers,\n // `fc` carries a stronger contract than \"accepts\": `__zcMkv` returns the\n // INPUT from `parse()`/`parseAsync()`/`~standard` whenever it holds, so it\n // may only be published when a passing check implies `data === input`. A\n // rebuilding schema breaks that even though its safeParse is correct, and so\n // does a union whose options can rewrite — see `fastResultIsInput` for both.\n // Same guard as the `data: input` shortcut above, which is the other reader\n // of the same contract.\n fastFnName: fastResultIsInput(ir) ? fastFnName : null,\n // Partial fast path (default/catch) or none (including coercion): a false fc\n // result does not imply rejection, so `.is()` derives from\n // safeParse(input).success.\n fastTotal: false,\n };\n}\n\n/**\n * Find every non-root recursion target (a `recursionTarget` node, refId ≥ 1)\n * reachable from `root`, mapping refId → the inner IR to host as a standalone\n * validator. The root target (refId 0) is the schema's own function and is\n * never wrapped, so it never appears here. The same target may be wrapped at\n * several sites (a recursive schema reached from sibling positions); the first\n * inner wins — they are structurally identical extractions of one schema.\n */\nfunction collectRecursionTargets(root: SchemaIR): Map<number, SchemaIR> {\n const out = new Map<number, SchemaIR>();\n const seen = new Set<SchemaIR>();\n const walk = (ir: SchemaIR): void => {\n if (seen.has(ir)) return;\n seen.add(ir);\n if (ir.type === \"recursionTarget\" && !out.has(ir.refId)) {\n out.set(ir.refId, ir.inner);\n }\n for (const child of childIRs(ir)) walk(child);\n };\n walk(root);\n return out;\n}\n\n/** Direct child SchemaIR nodes, covering every node type (including the new wrapper). */\nfunction childIRs(ir: SchemaIR): readonly SchemaIR[] {\n switch (ir.type) {\n case \"object\":\n return Object.values(ir.properties);\n case \"array\":\n return [ir.element];\n case \"tuple\":\n return ir.rest === null ? ir.items : [...ir.items, ir.rest];\n case \"record\":\n case \"map\":\n return [ir.keyType, ir.valueType];\n case \"set\":\n return [ir.valueType];\n case \"union\":\n case \"discriminatedUnion\":\n return ir.options;\n case \"intersection\":\n return [ir.left, ir.right];\n case \"optional\":\n case \"nullable\":\n case \"readonly\":\n case \"default\":\n case \"catch\":\n case \"effect\":\n case \"recursionTarget\":\n case \"zodDelegate\":\n return [ir.inner];\n case \"pipe\":\n return [ir.in, ir.out];\n default:\n return [];\n }\n}\n"],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Argument convention (positional, kept short to minimize call-site bytes):
|
|
10
10
|
* __zcTS(minimum, origin, inclusive, input, path, msg?) — too_small
|
|
11
|
-
*
|
|
11
|
+
* __zcTSt(minimum, origin, input, path, msg?) — too_small, tuple key order
|
|
12
12
|
* __zcTBt(maximum, origin, input, path, msg?) — too_big, tuple key order
|
|
13
13
|
* __zcTB(maximum, origin, inclusive, input, path, msg?) — too_big
|
|
14
14
|
* __zcIT(expected, input, path, msg?) — invalid_type
|
|
@@ -34,10 +34,17 @@
|
|
|
34
34
|
declare const ISSUE_DECLS: Readonly<Record<string, string>>;
|
|
35
35
|
/**
|
|
36
36
|
* Float-safe remainder — byte-for-byte port of zod's util.floatSafeRemainder.
|
|
37
|
-
* Raw `%` mis-rejects valid multiples of decimal steps (0.3 % 0.1 !== 0)
|
|
38
|
-
*
|
|
37
|
+
* Raw `%` mis-rejects valid multiples of decimal steps (0.3 % 0.1 !== 0).
|
|
38
|
+
*
|
|
39
|
+
* zod 4.5 REPLACED the decimal-scaling implementation this once mirrored with a
|
|
40
|
+
* ratio-and-tolerance one, and the two disagree in both directions: the old form
|
|
41
|
+
* accepted `1e-7` as a multiple of 3 (its `toFixed` scaling collapsed the value
|
|
42
|
+
* to 0) and rejected `1e21` (where `toFixed` yields exponential notation and
|
|
43
|
+
* `parseInt` then reads 1). The tolerance is 4x epsilon because `val` and `step`
|
|
44
|
+
* each round to a double before the division rounds again, so a true decimal
|
|
45
|
+
* multiple's quotient can sit up to 1.5 scaled epsilons from the integer.
|
|
39
46
|
*/
|
|
40
|
-
declare const ZC_FSR_DECL
|
|
47
|
+
declare const ZC_FSR_DECL: string;
|
|
41
48
|
/**
|
|
42
49
|
* Hoisted `Object.prototype.hasOwnProperty` reference. Record fast/slow paths
|
|
43
50
|
* iterate keys with `for(k in o)` (no `Object.keys` array allocation) and guard
|
|
@@ -71,12 +78,54 @@ declare const ZC_HOP_DECL = "const __zcHop=Object.prototype.hasOwnProperty;";
|
|
|
71
78
|
* than `Object.getPrototypeOf(o) === Object.prototype` is what lets a plain
|
|
72
79
|
* object from another realm (a vm context, an iframe) still count as plain.
|
|
73
80
|
*
|
|
81
|
+
* `c===Object` is a short-cut, not a fourth rule: it is exactly the case where
|
|
82
|
+
* zod's remaining steps are foregone — `Object.prototype` is an object and has
|
|
83
|
+
* its own `isPrototypeOf` — so the answer is `true` either way. It is also the
|
|
84
|
+
* case every ordinary record takes (an object literal, `JSON.parse` output, a
|
|
85
|
+
* `Map`-free DTO), and taking it saves the `prototype` load and the
|
|
86
|
+
* `hasOwnProperty` call: measured 9.6 → 5.7 ns on a monomorphic record and
|
|
87
|
+
* 15.7 → 9.2 ns across 16 shapes, i.e. 22% of a five-key record's whole parse.
|
|
88
|
+
* A plain object from another realm has a different `Object` and simply takes
|
|
89
|
+
* the long road to the same verdict, as before.
|
|
90
|
+
*
|
|
74
91
|
* Self-contained (`Object.prototype.hasOwnProperty` spelled out rather than
|
|
75
92
|
* reusing `__zcHop`) so inline mode can emit this decl alone: `emitRuntimeHelper`
|
|
76
93
|
* pushes only the decl it is asked for, and a helper that closed over another
|
|
77
94
|
* name would dangle wherever that one was not also emitted.
|
|
78
95
|
*/
|
|
79
96
|
declare const ZC_PLAIN_DECL: string;
|
|
97
|
+
/**
|
|
98
|
+
* `z.email()`'s default validator, `regexes.email`, as a single linear scan.
|
|
99
|
+
*
|
|
100
|
+
* Zod's pattern is
|
|
101
|
+
* `^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$`,
|
|
102
|
+
* and even its lookahead-free rewrite (EMAIL_FAST_REGEX_SOURCE) backtracks at
|
|
103
|
+
* every dot it fails to find: `(?:[X]+\.)*` re-tries the run one character
|
|
104
|
+
* shorter each time, and the domain's `(?:label\.)+` does the same over the
|
|
105
|
+
* TLD. Written as a scanner the language is:
|
|
106
|
+
*
|
|
107
|
+
* local — `[A-Za-z0-9_'+.-]+`, no leading `.`, no `..`, and the character
|
|
108
|
+
* before `@` is neither `.` nor `'` (that last is the `[A-Za-z0-9_+-]`
|
|
109
|
+
* the pattern demands there);
|
|
110
|
+
* domain — one or more labels `[A-Za-z0-9][A-Za-z0-9-]*` each ending in `.`,
|
|
111
|
+
* then a TLD of two or more letters running to the end.
|
|
112
|
+
*
|
|
113
|
+
* A trailing `\n` is not accepted: the pattern has no `m` flag, so its `$`
|
|
114
|
+
* matches only at the end of input, and the scan reads to `length`.
|
|
115
|
+
*
|
|
116
|
+
* Measured against the fast regex on V8: 32 → 16 ns for `alice@example.com`,
|
|
117
|
+
* 48 → 40 for `bob_smith-99@mail-server.io`, 39 → 20 for a non-address, and a
|
|
118
|
+
* tie from ~35 characters up (the regex's per-character work is cheaper than a
|
|
119
|
+
* `charCodeAt` loop's; its fixed dispatch cost is what the scanner avoids). A
|
|
120
|
+
* lookbehind rewrite runs about as fast but needs ES2018 regex support, which
|
|
121
|
+
* the CLI's React Native / Hermes and older-Safari consumers cannot assume.
|
|
122
|
+
*
|
|
123
|
+
* Equivalence to zod's regex — every string, both verdicts — is pinned by
|
|
124
|
+
* tests/core/codegen/email-scanner.test.ts. Reached only behind a `typeof`
|
|
125
|
+
* string guard, like the `.test()` it replaces; issue sites keep reporting
|
|
126
|
+
* zod's own pattern string (see `emitRegexSourceString`).
|
|
127
|
+
*/
|
|
128
|
+
declare const ZC_EMAIL_DECL: string;
|
|
80
129
|
/**
|
|
81
130
|
* Ports of `util.getLengthableOrigin` / `util.getSizableOrigin` — the `origin` a
|
|
82
131
|
* length/size check puts on its issue, computed from the RUNTIME INPUT rather
|
|
@@ -95,6 +144,31 @@ declare const ZC_PLAIN_DECL: string;
|
|
|
95
144
|
* not run in, and not one worth reproducing a crash for.
|
|
96
145
|
*/
|
|
97
146
|
declare const ZC_LENGTH_ORIGIN_DECL = "function __zcLo(v){return Array.isArray(v)?\"array\":typeof v===\"string\"?\"string\":\"unknown\";}";
|
|
147
|
+
/**
|
|
148
|
+
* Drop an own `__proto__` from a container the parse hands back BY REFERENCE.
|
|
149
|
+
*
|
|
150
|
+
* zod never lets the key into an output: `$ZodObject`'s shape loop strips a
|
|
151
|
+
* declared one, `handleCatchall` skips an undeclared one, and `$ZodRecord` skips
|
|
152
|
+
* it while copying — all so the assignment into their fresh `{}` cannot replace
|
|
153
|
+
* the result's prototype. A compiled loose/catchall object or record IS its
|
|
154
|
+
* input, so the key has to be removed here instead; leaving it made
|
|
155
|
+
* `Object.assign({}, parsed)` a prototype-pollution sink, since [[Set]] runs the
|
|
156
|
+
* inherited setter the spread that built the value did not.
|
|
157
|
+
*
|
|
158
|
+
* Copies rather than editing in place: the divergence note promises the caller
|
|
159
|
+
* its own container back, not one with a key silently deleted from it. The
|
|
160
|
+
* common object has no such key and is returned untouched, so the cost is one
|
|
161
|
+
* `hasOwnProperty` call.
|
|
162
|
+
*/
|
|
163
|
+
declare const ZC_PROTO_SCRUB_DECL: string;
|
|
164
|
+
/**
|
|
165
|
+
* Code points in a string — zod's `util.codePointLength`, verbatim. A surrogate
|
|
166
|
+
* pair counts once and a lone surrogate as itself. The regex probe is the fast
|
|
167
|
+
* exit for a string with no astral characters, and the hand-rolled loop avoids
|
|
168
|
+
* the allocating string iterator. Only reached from a length check whose
|
|
169
|
+
* UTF-16 count leaves the verdict in doubt (see stringLengthTests).
|
|
170
|
+
*/
|
|
171
|
+
declare const ZC_CPL_DECL = "function __zcCpl(s){var n=s.length;if(!/[\\uD800-\\uDBFF]/.test(s))return n;var c=n;for(var i=0;i<n-1;i++){if((s.charCodeAt(i)&0xfc00)===0xd800&&(s.charCodeAt(i+1)&0xfc00)===0xdc00){c--;i++;}}return c;}";
|
|
98
172
|
declare const ZC_SIZE_ORIGIN_DECL: string;
|
|
99
173
|
/** `c==="invalid_type"||c==="invalid_value"||…` over the code held in `codeExpr`. */
|
|
100
174
|
declare function abortingCodeTest(codeExpr: string): string;
|
|
@@ -179,8 +253,10 @@ declare const ZC_CUSTOM_OK_DECL: string;
|
|
|
179
253
|
/**
|
|
180
254
|
* superRefine slow-path merge: run the callback, then move its issues onto the
|
|
181
255
|
* validator's list the way zod's finalizeIssue does — the node's path prefixed
|
|
182
|
-
* onto any path the user supplied,
|
|
183
|
-
* dropped (they are zod bookkeeping, deleted before the issue is user-visible)
|
|
256
|
+
* onto any path the user supplied, the internal `inst`/`continue` fields
|
|
257
|
+
* dropped (they are zod bookkeeping, deleted before the issue is user-visible),
|
|
258
|
+
* and the owning schema's static message `m` applied to an issue that carries
|
|
259
|
+
* none of its own, since zod stamps the owner onto every issue a check raises.
|
|
184
260
|
*
|
|
185
261
|
* Returns the payload, so the caller can write `.value` back (the callback may
|
|
186
262
|
* have rewritten it) and read `.aborted`. Aborted is set when any issue aborts
|
|
@@ -195,5 +271,5 @@ declare const ZC_SR_DECL: string;
|
|
|
195
271
|
/** Non-issue runtime helper declarations hosted in the virtual module. */
|
|
196
272
|
declare const RUNTIME_HELPER_DECLS: Readonly<Record<string, string>>;
|
|
197
273
|
//#endregion
|
|
198
|
-
export { ISSUE_DECLS, RUNTIME_HELPER_DECLS, ZC_AB_DECL, ZC_CUSTOM_OK_DECL, ZC_FSR_DECL, ZC_FZ_DECL, ZC_HOP_DECL, ZC_LENGTH_ORIGIN_DECL, ZC_PFX_DECL, ZC_PLAIN_DECL, ZC_SIZE_ORIGIN_DECL, ZC_SR_DECL, ZC_SR_OK_DECL, ZC_SR_RUN_DECL, abortingCodeTest, propertyKeyTest };
|
|
274
|
+
export { ISSUE_DECLS, RUNTIME_HELPER_DECLS, ZC_AB_DECL, ZC_CPL_DECL, ZC_CUSTOM_OK_DECL, ZC_EMAIL_DECL, ZC_FSR_DECL, ZC_FZ_DECL, ZC_HOP_DECL, ZC_LENGTH_ORIGIN_DECL, ZC_PFX_DECL, ZC_PLAIN_DECL, ZC_PROTO_SCRUB_DECL, ZC_SIZE_ORIGIN_DECL, ZC_SR_DECL, ZC_SR_OK_DECL, ZC_SR_RUN_DECL, abortingCodeTest, propertyKeyTest };
|
|
199
275
|
//# sourceMappingURL=issue-decls.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-decls.d.ts","names":[],"sources":["../../../src/core/codegen/issue-decls.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"issue-decls.d.ts","names":[],"sources":["../../../src/core/codegen/issue-decls.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkGa,aAAa,SAAS;;;;;;;;;;;;;cA0BtB;;;;;;;;;;cAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAwCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqCA;;;;;;;;;;;;;;;;;;cAkCA;;;;;;;;;;;;;;;;;cAmBA;;;;;;;;cAWA;cAGA;;iBA+BG,iBAAiB;;;;;;;;;;;;;;;cAkBpB;;;;;;;;;;;;;;;;;cAkBA;;;;;;;;;cAaA;;iBAIG,gBAAgB;;;;;;;;;;;;;;;;cAmBnB;;;;;;;;;;;;;cAgBA;;;;;;cASA;;;;;;;;;;;;;;;;;;cAqBA;;cASA,sBAAsB,SAAS"}
|