zod-compiler 1.0.2 → 1.0.3
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 +12 -5
- package/dist/core/codegen/context.d.ts +27 -8
- package/dist/core/codegen/context.d.ts.map +1 -1
- package/dist/core/codegen/context.js +29 -14
- package/dist/core/codegen/context.js.map +1 -1
- package/dist/core/codegen/index.d.ts.map +1 -1
- package/dist/core/codegen/index.js +19 -1
- package/dist/core/codegen/index.js.map +1 -1
- package/dist/core/codegen/schemas/array.js +2 -2
- package/dist/core/codegen/schemas/array.js.map +1 -1
- package/dist/core/codegen/schemas/discriminated-union.js +2 -2
- package/dist/core/codegen/schemas/discriminated-union.js.map +1 -1
- package/dist/core/codegen/schemas/map.js +3 -3
- package/dist/core/codegen/schemas/map.js.map +1 -1
- package/dist/core/codegen/schemas/number.d.ts.map +1 -1
- package/dist/core/codegen/schemas/number.js +15 -8
- package/dist/core/codegen/schemas/number.js.map +1 -1
- package/dist/core/codegen/schemas/record.d.ts.map +1 -1
- package/dist/core/codegen/schemas/record.js +13 -5
- package/dist/core/codegen/schemas/record.js.map +1 -1
- package/dist/core/codegen/schemas/recursive-ref.d.ts +1 -1
- package/dist/core/codegen/schemas/recursive-ref.d.ts.map +1 -1
- package/dist/core/codegen/schemas/recursive-ref.js +9 -3
- package/dist/core/codegen/schemas/recursive-ref.js.map +1 -1
- package/dist/core/codegen/schemas/set.js +2 -2
- package/dist/core/codegen/schemas/set.js.map +1 -1
- package/dist/core/codegen/schemas/tuple.js +2 -2
- package/dist/core/codegen/schemas/tuple.js.map +1 -1
- package/dist/core/diagnostic.js +1 -1
- package/dist/core/diagnostic.js.map +1 -1
- package/dist/core/iife.d.ts +9 -1
- package/dist/core/iife.d.ts.map +1 -1
- package/dist/core/iife.js +9 -1
- package/dist/core/iife.js.map +1 -1
- package/dist/unplugin/hoist.d.ts +10 -1
- package/dist/unplugin/hoist.d.ts.map +1 -1
- package/dist/unplugin/hoist.js +222 -55
- package/dist/unplugin/hoist.js.map +1 -1
- package/dist/unplugin/transform.d.ts.map +1 -1
- package/dist/unplugin/transform.js +4 -4
- package/dist/unplugin/transform.js.map +1 -1
- package/dist/unplugin/types.d.ts +13 -3
- package/dist/unplugin/types.d.ts.map +1 -1
- package/dist/unplugin/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tuple.js","sourceRoot":"","sources":["../../../../src/core/codegen/schemas/tuple.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"tuple.js","sourceRoot":"","sources":["../../../../src/core/codegen/schemas/tuple.ts"],"names":[],"mappings":"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"}
|
package/dist/core/diagnostic.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
// ─── Fast Path Eligibility ──────────────────────────────────────────────────
|
|
6
6
|
/** Schema types that block Fast Path eligibility. */
|
|
7
|
-
const FAST_PATH_BLOCKERS = new Set(["fallback", "effect", "
|
|
7
|
+
const FAST_PATH_BLOCKERS = new Set(["fallback", "effect", "stringBool"]);
|
|
8
8
|
/** Check if a single node blocks Fast Path (without recursing). */
|
|
9
9
|
function detectFastPathBlocker(ir) {
|
|
10
10
|
if (FAST_PATH_BLOCKERS.has(ir.type)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../../src/core/diagnostic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwCH,+EAA+E;AAE/E,qDAAqD;AACrD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../../src/core/diagnostic.ts"],"names":[],"mappings":"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"}
|
package/dist/core/iife.d.ts
CHANGED
|
@@ -16,8 +16,16 @@ export declare const ZOD_MSG_DECLARATION = "var __msg=__zodCompilerConfig().loca
|
|
|
16
16
|
* mirroring Zod's precedence: check/schema-level custom messages baked into
|
|
17
17
|
* generated issues — and messages on issues copied from fallback sub-schemas —
|
|
18
18
|
* must never be overwritten by the locale map.
|
|
19
|
+
*
|
|
20
|
+
* The whole finalization (message fill, input strip, ZodError construction)
|
|
21
|
+
* runs lazily inside a cached accessor (zod v3's safeParse trick): zod v4's
|
|
22
|
+
* $ZodError initializer JSON.stringifies all issues into `message` and
|
|
23
|
+
* $ZodRealError's Error parent captures a stack trace — paying that (plus a
|
|
24
|
+
* locale __msg call per issue) on every failed safeParse dominates
|
|
25
|
+
* invalid-input cost when callers never read `.error`. The issues array is
|
|
26
|
+
* only observable through `.error`, so deferring is safe.
|
|
19
27
|
*/
|
|
20
|
-
export declare const FIN_DECL = "function __fin(e,d){for(var i=0;i<e.length;i++){if(e[i].message===undefined&&typeof __msg===\"function\")e[i].message=__msg(e[i]);e[i].input=undefined;}return
|
|
28
|
+
export declare const FIN_DECL = "function __fin(e,d){if(!e.length)return{success:true,data:d};var c;return{success:false,get error(){if(c)return c;for(var i=0;i<e.length;i++){if(e[i].message===undefined&&typeof __msg===\"function\")e[i].message=__msg(e[i]);e[i].input=undefined;}return c=new __ZodError(e);}};}";
|
|
21
29
|
/**
|
|
22
30
|
* File-level validator factory (must appear once per compiled file).
|
|
23
31
|
* Wraps a safeParse function into the CompiledSchema interface.
|
package/dist/core/iife.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iife.d.ts","sourceRoot":"","sources":["../../src/core/iife.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,uFACsD,CAAC;AAErF,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,iDAAiD,CAAC;AAElF
|
|
1
|
+
{"version":3,"file":"iife.d.ts","sourceRoot":"","sources":["../../src/core/iife.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,uFACsD,CAAC;AAErF,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,iDAAiD,CAAC;AAElF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,QAAQ,0RACkQ,CAAC;AAExR;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,gXACiV,CAAC;AAUhX;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAC5C,MAAM,CAkBR"}
|
package/dist/core/iife.js
CHANGED
|
@@ -15,8 +15,16 @@ export const ZOD_MSG_DECLARATION = "var __msg=__zodCompilerConfig().localeError;
|
|
|
15
15
|
* mirroring Zod's precedence: check/schema-level custom messages baked into
|
|
16
16
|
* generated issues — and messages on issues copied from fallback sub-schemas —
|
|
17
17
|
* must never be overwritten by the locale map.
|
|
18
|
+
*
|
|
19
|
+
* The whole finalization (message fill, input strip, ZodError construction)
|
|
20
|
+
* runs lazily inside a cached accessor (zod v3's safeParse trick): zod v4's
|
|
21
|
+
* $ZodError initializer JSON.stringifies all issues into `message` and
|
|
22
|
+
* $ZodRealError's Error parent captures a stack trace — paying that (plus a
|
|
23
|
+
* locale __msg call per issue) on every failed safeParse dominates
|
|
24
|
+
* invalid-input cost when callers never read `.error`. The issues array is
|
|
25
|
+
* only observable through `.error`, so deferring is safe.
|
|
18
26
|
*/
|
|
19
|
-
export const FIN_DECL = 'function __fin(e,d){for(var i=0;i<e.length;i++){if(e[i].message===undefined&&typeof __msg==="function")e[i].message=__msg(e[i]);e[i].input=undefined;}return
|
|
27
|
+
export const FIN_DECL = 'function __fin(e,d){if(!e.length)return{success:true,data:d};var c;return{success:false,get error(){if(c)return c;for(var i=0;i<e.length;i++){if(e[i].message===undefined&&typeof __msg==="function")e[i].message=__msg(e[i]);e[i].input=undefined;}return c=new __ZodError(e);}};}';
|
|
20
28
|
/**
|
|
21
29
|
* File-level validator factory (must appear once per compiled file).
|
|
22
30
|
* Wraps a safeParse function into the CompiledSchema interface.
|
package/dist/core/iife.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iife.js","sourceRoot":"","sources":["../../src/core/iife.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,yFAAyF;AACzF,MAAM,CAAC,MAAM,iBAAiB,GAC5B,kFAAkF,CAAC;AAErF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAElF
|
|
1
|
+
{"version":3,"file":"iife.js","sourceRoot":"","sources":["../../src/core/iife.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,yFAAyF;AACzF,MAAM,CAAC,MAAM,iBAAiB,GAC5B,kFAAkF,CAAC;AAErF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAElF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,QAAQ,GACnB,qRAAqR,CAAC;AAExR;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC5B,6WAA6W,CAAC;AAEhX,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,UAAkB,EAClB,MAA0B,EAC1B,OAA6C;IAE7C,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,MAAM,GAAG,mBAAmB,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,KAAK,KAAK,CAAC;IAC/C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IAElD,OAAO;QACL,0BAA0B;QAC1B,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;YACvB,CAAC,CAAC,CAAC,aAAa,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACtF,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,aAAa,CAAC,IAAI;aAClB,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,oBAAoB,CAAC;QACtE,aAAa,CAAC,WAAW;QACzB,gBAAgB,MAAM,IAAI,SAAS,IAAI;QACvC,MAAM;KACP,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
package/dist/unplugin/hoist.d.ts
CHANGED
|
@@ -10,10 +10,19 @@ interface ImportBindings {
|
|
|
10
10
|
* referenced at runtime, so excluding them keeps the capture rule sound.
|
|
11
11
|
*/
|
|
12
12
|
export declare function collectImportBindings(code: string): ImportBindings;
|
|
13
|
+
export interface HoistOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Imported identifiers matching this pattern are treated as schema chain
|
|
16
|
+
* roots even without an inline z.* reference. A string is compiled as a
|
|
17
|
+
* RegExp source; null disables name-based matching.
|
|
18
|
+
* @default /ZodSchema$/
|
|
19
|
+
*/
|
|
20
|
+
schemaNamePattern?: RegExp | string | null | undefined;
|
|
21
|
+
}
|
|
13
22
|
/**
|
|
14
23
|
* Hoist eligible Zod schema expressions to module scope.
|
|
15
24
|
* Returns the rewritten source, or null when nothing was hoisted.
|
|
16
25
|
*/
|
|
17
|
-
export declare function hoistZodSchemas(code: string): string | null;
|
|
26
|
+
export declare function hoistZodSchemas(code: string, options?: HoistOptions): string | null;
|
|
18
27
|
export {};
|
|
19
28
|
//# sourceMappingURL=hoist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hoist.d.ts","sourceRoot":"","sources":["../../src/unplugin/hoist.ts"],"names":[],"mappings":"AA8CA,UAAU,cAAc;IACtB,sDAAsD;IACtD,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,8DAA8D;IAC9D,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAelE;
|
|
1
|
+
{"version":3,"file":"hoist.d.ts","sourceRoot":"","sources":["../../src/unplugin/hoist.ts"],"names":[],"mappings":"AA8CA,UAAU,cAAc;IACtB,sDAAsD;IACtD,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,8DAA8D;IAC9D,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAelE;AA8mBD,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACxD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CA0KnF"}
|
package/dist/unplugin/hoist.js
CHANGED
|
@@ -139,8 +139,15 @@ function isDivisionContext(lastToken) {
|
|
|
139
139
|
* depth. Depth 0 candidates are top-level initializers — already evaluated
|
|
140
140
|
* once — and are recorded only so their extents mask nested candidates.
|
|
141
141
|
*/
|
|
142
|
-
function
|
|
142
|
+
function scanSource(code, roots) {
|
|
143
143
|
const candidates = [];
|
|
144
|
+
const out = code.split("");
|
|
145
|
+
const mask = (from, to) => {
|
|
146
|
+
for (let p = from; p < to; p++) {
|
|
147
|
+
if (out[p] !== "\n")
|
|
148
|
+
out[p] = " ";
|
|
149
|
+
}
|
|
150
|
+
};
|
|
144
151
|
let depth = 0;
|
|
145
152
|
// Template literals interleave string and expression states; the stack
|
|
146
153
|
// records the brace depth at which each `${` opened so the matching `}`
|
|
@@ -154,17 +161,23 @@ function scanCandidates(code, roots) {
|
|
|
154
161
|
// Comments
|
|
155
162
|
if (ch === "/" && next === "/") {
|
|
156
163
|
const nl = code.indexOf("\n", i);
|
|
157
|
-
|
|
164
|
+
const end = nl === -1 ? code.length : nl + 1;
|
|
165
|
+
mask(i, end);
|
|
166
|
+
i = end;
|
|
158
167
|
continue;
|
|
159
168
|
}
|
|
160
169
|
if (ch === "/" && next === "*") {
|
|
161
|
-
const
|
|
162
|
-
|
|
170
|
+
const close = code.indexOf("*/", i + 2);
|
|
171
|
+
const end = close === -1 ? code.length : close + 2;
|
|
172
|
+
mask(i, end);
|
|
173
|
+
i = end;
|
|
163
174
|
continue;
|
|
164
175
|
}
|
|
165
176
|
if (ch === "/") {
|
|
166
177
|
if (!isDivisionContext(lastToken)) {
|
|
167
|
-
|
|
178
|
+
const end = skipRegexLiteral(code, i);
|
|
179
|
+
mask(i, end);
|
|
180
|
+
i = end;
|
|
168
181
|
lastToken = ")"; // a regex literal is an operand
|
|
169
182
|
continue;
|
|
170
183
|
}
|
|
@@ -174,13 +187,17 @@ function scanCandidates(code, roots) {
|
|
|
174
187
|
}
|
|
175
188
|
// Strings
|
|
176
189
|
if (ch === '"' || ch === "'") {
|
|
177
|
-
|
|
190
|
+
const end = skipString(code, i, ch);
|
|
191
|
+
mask(i, end);
|
|
192
|
+
i = end;
|
|
178
193
|
lastToken = ch;
|
|
179
194
|
continue;
|
|
180
195
|
}
|
|
181
196
|
// Template literals
|
|
182
197
|
if (ch === "`") {
|
|
183
|
-
|
|
198
|
+
const end = skipTemplateChunk(code, i + 1, templateStack, depth);
|
|
199
|
+
mask(i, end);
|
|
200
|
+
i = end;
|
|
184
201
|
lastToken = "`";
|
|
185
202
|
continue;
|
|
186
203
|
}
|
|
@@ -189,7 +206,9 @@ function scanCandidates(code, roots) {
|
|
|
189
206
|
depth === templateStack[templateStack.length - 1]) {
|
|
190
207
|
// End of a ${ } expression — back into template string state
|
|
191
208
|
templateStack.pop();
|
|
192
|
-
|
|
209
|
+
const end = skipTemplateChunk(code, i + 1, templateStack, depth);
|
|
210
|
+
mask(i, end);
|
|
211
|
+
i = end;
|
|
193
212
|
lastToken = "`";
|
|
194
213
|
continue;
|
|
195
214
|
}
|
|
@@ -215,17 +234,18 @@ function scanCandidates(code, roots) {
|
|
|
215
234
|
while (k < code.length && /\s/.test(code[k]))
|
|
216
235
|
k++;
|
|
217
236
|
if (roots.has(word) && code[k] === "." && lastToken !== ".") {
|
|
218
|
-
candidates.push({ index: i, depth, name: word });
|
|
237
|
+
candidates.push({ index: i, depth, name: word, afterArrow: lastToken === "=>" });
|
|
219
238
|
}
|
|
220
239
|
lastToken = word;
|
|
221
240
|
i = j;
|
|
222
241
|
continue;
|
|
223
242
|
}
|
|
224
|
-
if (!/\s/.test(ch))
|
|
225
|
-
lastToken = ch;
|
|
243
|
+
if (!/\s/.test(ch)) {
|
|
244
|
+
lastToken = ch === ">" && lastToken === "=" ? "=>" : ch;
|
|
245
|
+
}
|
|
226
246
|
i++;
|
|
227
247
|
}
|
|
228
|
-
return candidates;
|
|
248
|
+
return { candidates, stripped: out.join("") };
|
|
229
249
|
}
|
|
230
250
|
function skipString(code, start, quote) {
|
|
231
251
|
for (let i = start + 1; i < code.length; i++) {
|
|
@@ -358,13 +378,53 @@ const PARSE_METHODS = new Set([
|
|
|
358
378
|
"decodeAsync",
|
|
359
379
|
"encodeAsync",
|
|
360
380
|
]);
|
|
381
|
+
/**
|
|
382
|
+
* Globals that are safe to reference from a DEFERRED position (inside a
|
|
383
|
+
* callback): the callback still runs per parse, so hoisting cannot change
|
|
384
|
+
* when these evaluate. Eager positions stay imports-only — an eager
|
|
385
|
+
* `Math.random()` / `Date.now()` would freeze at module load.
|
|
386
|
+
*/
|
|
387
|
+
const SAFE_DEFERRED_GLOBALS = new Set([
|
|
388
|
+
"NaN",
|
|
389
|
+
"Infinity",
|
|
390
|
+
"Math",
|
|
391
|
+
"Number",
|
|
392
|
+
"String",
|
|
393
|
+
"Boolean",
|
|
394
|
+
"Array",
|
|
395
|
+
"Object",
|
|
396
|
+
"JSON",
|
|
397
|
+
"Date",
|
|
398
|
+
"RegExp",
|
|
399
|
+
"BigInt",
|
|
400
|
+
"Symbol",
|
|
401
|
+
"Map",
|
|
402
|
+
"Set",
|
|
403
|
+
"Promise",
|
|
404
|
+
"Error",
|
|
405
|
+
"TypeError",
|
|
406
|
+
"RangeError",
|
|
407
|
+
"SyntaxError",
|
|
408
|
+
"parseInt",
|
|
409
|
+
"parseFloat",
|
|
410
|
+
"isNaN",
|
|
411
|
+
"isFinite",
|
|
412
|
+
"encodeURI",
|
|
413
|
+
"decodeURI",
|
|
414
|
+
"encodeURIComponent",
|
|
415
|
+
"decodeURIComponent",
|
|
416
|
+
"structuredClone",
|
|
417
|
+
]);
|
|
361
418
|
/**
|
|
362
419
|
* Scope-aware free-variable analysis of an expression. Nested function
|
|
363
420
|
* params and local declarations are bound names, not captures — so
|
|
364
421
|
* `z.string().refine((v) => v.length > 0)` has no free variables beyond `z`.
|
|
422
|
+
* References inside nested function bodies are tracked separately: they
|
|
423
|
+
* evaluate per call even after hoisting, so safe globals are allowed there.
|
|
365
424
|
*/
|
|
366
425
|
function analyzeCaptures(expr) {
|
|
367
|
-
const
|
|
426
|
+
const eagerFree = new Set();
|
|
427
|
+
const deferredFree = new Set();
|
|
368
428
|
let impure = false;
|
|
369
429
|
function patternNames(node, into) {
|
|
370
430
|
switch (node.type) {
|
|
@@ -430,32 +490,42 @@ function analyzeCaptures(expr) {
|
|
|
430
490
|
}
|
|
431
491
|
}
|
|
432
492
|
}
|
|
433
|
-
function visit(node, scopes) {
|
|
493
|
+
function visit(node, scopes, deferred) {
|
|
434
494
|
switch (node.type) {
|
|
435
495
|
case "Identifier": {
|
|
436
496
|
const name = node.name;
|
|
437
|
-
if (name !== "undefined" && !scopes.some((s) => s.has(name)))
|
|
438
|
-
|
|
497
|
+
if (name !== "undefined" && !scopes.some((s) => s.has(name))) {
|
|
498
|
+
(deferred ? deferredFree : eagerFree).add(name);
|
|
499
|
+
}
|
|
439
500
|
return;
|
|
440
501
|
}
|
|
441
502
|
case "ThisExpression":
|
|
442
503
|
case "Super":
|
|
504
|
+
// Arrows bind `this` lexically — hoisting changes it even when the
|
|
505
|
+
// reference sits inside a callback. Always disqualifying.
|
|
506
|
+
impure = true;
|
|
507
|
+
return;
|
|
443
508
|
case "AwaitExpression":
|
|
444
509
|
case "YieldExpression":
|
|
445
510
|
case "NewExpression":
|
|
446
511
|
case "TaggedTemplateExpression":
|
|
447
512
|
case "MetaProperty":
|
|
448
|
-
|
|
449
|
-
|
|
513
|
+
// Deferred occurrences run per call (`refine(d => d < new Date())`)
|
|
514
|
+
// — hoisting does not change when they evaluate.
|
|
515
|
+
if (!deferred) {
|
|
516
|
+
impure = true;
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
break;
|
|
450
520
|
case "MemberExpression":
|
|
451
|
-
visit(node.object, scopes);
|
|
521
|
+
visit(node.object, scopes, deferred);
|
|
452
522
|
if (node.computed)
|
|
453
|
-
visit(node.property, scopes);
|
|
523
|
+
visit(node.property, scopes, deferred);
|
|
454
524
|
return;
|
|
455
525
|
case "Property":
|
|
456
526
|
if (node.computed)
|
|
457
|
-
visit(node.key, scopes);
|
|
458
|
-
visit(node.value, scopes);
|
|
527
|
+
visit(node.key, scopes, deferred);
|
|
528
|
+
visit(node.value, scopes, deferred);
|
|
459
529
|
return;
|
|
460
530
|
case "FunctionExpression":
|
|
461
531
|
case "ArrowFunctionExpression": {
|
|
@@ -465,27 +535,27 @@ function analyzeCaptures(expr) {
|
|
|
465
535
|
if (node.type === "FunctionExpression" && node.id)
|
|
466
536
|
scope.add(node.id.name);
|
|
467
537
|
collectFunctionScope(node.body, scope);
|
|
468
|
-
visit(node.body, [...scopes, scope]);
|
|
538
|
+
visit(node.body, [...scopes, scope], true);
|
|
469
539
|
return;
|
|
470
540
|
}
|
|
471
|
-
default:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
else if (typeof value === "object" && value !== null && "type" in value) {
|
|
481
|
-
visit(value, scopes);
|
|
541
|
+
default:
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
for (const value of Object.values(node)) {
|
|
545
|
+
if (Array.isArray(value)) {
|
|
546
|
+
for (const item of value) {
|
|
547
|
+
if (typeof item === "object" && item !== null && "type" in item) {
|
|
548
|
+
visit(item, scopes, deferred);
|
|
482
549
|
}
|
|
483
550
|
}
|
|
484
551
|
}
|
|
552
|
+
else if (typeof value === "object" && value !== null && "type" in value) {
|
|
553
|
+
visit(value, scopes, deferred);
|
|
554
|
+
}
|
|
485
555
|
}
|
|
486
556
|
}
|
|
487
|
-
visit(expr, []);
|
|
488
|
-
return {
|
|
557
|
+
visit(expr, [], false);
|
|
558
|
+
return { eagerFree, deferredFree, impure };
|
|
489
559
|
}
|
|
490
560
|
/** Offset after the shebang and directive prologue ("use client", ...). */
|
|
491
561
|
function insertionOffset(code) {
|
|
@@ -519,18 +589,86 @@ function insertionOffset(code) {
|
|
|
519
589
|
i += directive[0].length;
|
|
520
590
|
}
|
|
521
591
|
}
|
|
592
|
+
/** Keywords that precede `( ... ) {` without binding anything. */
|
|
593
|
+
const NON_BINDING_KEYWORDS = "if|for|while|switch|return|typeof|await|yield|new|do|else|case|in|of|delete|void";
|
|
594
|
+
/**
|
|
595
|
+
* Conservative shadow detection: collect every identifier appearing in a
|
|
596
|
+
* binding-like position — function/method/arrow parameter lists, catch
|
|
597
|
+
* clauses, const/let/var declarator names. The scanner has no scope
|
|
598
|
+
* information, so an import referenced from a hoisted expression must
|
|
599
|
+
* resolve to that import everywhere; a name that is ever re-bound cannot be
|
|
600
|
+
* trusted and disqualifies hoists referencing it. Over-collection only
|
|
601
|
+
* costs missed hoists; the identifiers extracted from each binding segment
|
|
602
|
+
* are cut at `:` and `=` so TypeScript annotations and initializers
|
|
603
|
+
* (`schema: z.ZodType`, `x = z.object()`) never poison the set.
|
|
604
|
+
*/
|
|
605
|
+
function collectBoundNames(code) {
|
|
606
|
+
const bound = new Set();
|
|
607
|
+
// Per comma-separated piece, keep only the binding side: names before any
|
|
608
|
+
// type annotation (`a: T`) or default/initializer (`a = v`).
|
|
609
|
+
const addBindingSegment = (segment) => {
|
|
610
|
+
for (const piece of segment.split(",")) {
|
|
611
|
+
let cut = piece;
|
|
612
|
+
const colon = cut.indexOf(":");
|
|
613
|
+
if (colon !== -1)
|
|
614
|
+
cut = cut.slice(0, colon);
|
|
615
|
+
const eq = cut.indexOf("=");
|
|
616
|
+
if (eq !== -1)
|
|
617
|
+
cut = cut.slice(0, eq);
|
|
618
|
+
for (const id of cut.matchAll(/[A-Za-z_$][\w$]*/g)) {
|
|
619
|
+
bound.add(id[0]);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
// function f(a, b) / function (a, b)
|
|
624
|
+
for (const m of code.matchAll(/\bfunction\b[^(]*\(([^()]*)\)/g)) {
|
|
625
|
+
addBindingSegment(m[1] ?? "");
|
|
626
|
+
}
|
|
627
|
+
// (a, b) => / (a, b): Ret =>
|
|
628
|
+
for (const m of code.matchAll(/\(([^()]*)\)\s*(?::[^=>{};()]*)?=>/g)) {
|
|
629
|
+
addBindingSegment(m[1] ?? "");
|
|
630
|
+
}
|
|
631
|
+
// bare arrow param: a =>
|
|
632
|
+
for (const m of code.matchAll(/([A-Za-z_$][\w$]*)\s*=>/g)) {
|
|
633
|
+
bound.add(m[1] ?? "");
|
|
634
|
+
}
|
|
635
|
+
// method(a, b) { / method(a): Ret { — excluding control flow (`if (x) {`)
|
|
636
|
+
const methodPattern = new RegExp(String.raw `(?<![.\w$])(?!(?:${NON_BINDING_KEYWORDS})\b)[A-Za-z_$][\w$]*\s*\(([^()]*)\)\s*(?::[^{};()]*)?\{`, "g");
|
|
637
|
+
for (const m of code.matchAll(methodPattern)) {
|
|
638
|
+
addBindingSegment(m[1] ?? "");
|
|
639
|
+
}
|
|
640
|
+
// catch (e)
|
|
641
|
+
for (const m of code.matchAll(/\bcatch\s*\(([^()]*)\)/g)) {
|
|
642
|
+
addBindingSegment(m[1] ?? "");
|
|
643
|
+
}
|
|
644
|
+
// const/let/var declarator names (cut per comma at `:` / `=`)
|
|
645
|
+
for (const m of code.matchAll(/\b(?:const|let|var)\s+([^;\n]*)/g)) {
|
|
646
|
+
addBindingSegment(m[1] ?? "");
|
|
647
|
+
}
|
|
648
|
+
return bound;
|
|
649
|
+
}
|
|
522
650
|
/**
|
|
523
651
|
* Hoist eligible Zod schema expressions to module scope.
|
|
524
652
|
* Returns the rewritten source, or null when nothing was hoisted.
|
|
525
653
|
*/
|
|
526
|
-
export function hoistZodSchemas(code) {
|
|
654
|
+
export function hoistZodSchemas(code, options) {
|
|
527
655
|
const imports = collectImportBindings(code);
|
|
528
656
|
if (imports.all.size === 0)
|
|
529
657
|
return null;
|
|
658
|
+
const rawPattern = options?.schemaNamePattern;
|
|
659
|
+
const namePattern = rawPattern === null
|
|
660
|
+
? null
|
|
661
|
+
: rawPattern === undefined
|
|
662
|
+
? SCHEMA_NAME_PATTERN
|
|
663
|
+
: typeof rawPattern === "string"
|
|
664
|
+
? new RegExp(rawPattern)
|
|
665
|
+
: rawPattern;
|
|
530
666
|
const roots = new Set(imports.zod);
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
667
|
+
if (namePattern) {
|
|
668
|
+
for (const name of imports.all) {
|
|
669
|
+
if (namePattern.test(name))
|
|
670
|
+
roots.add(name);
|
|
671
|
+
}
|
|
534
672
|
}
|
|
535
673
|
// Imported roots that only qualify via an inline z.* reference in the
|
|
536
674
|
// chain are validated per-expression below; scan them as candidates too.
|
|
@@ -540,9 +678,14 @@ export function hoistZodSchemas(code) {
|
|
|
540
678
|
}
|
|
541
679
|
if (roots.size === 0)
|
|
542
680
|
return null;
|
|
543
|
-
const candidates =
|
|
681
|
+
const { candidates, stripped } = scanSource(code, roots);
|
|
544
682
|
if (candidates.length === 0)
|
|
545
683
|
return null;
|
|
684
|
+
let boundNames;
|
|
685
|
+
function isShadowed(name) {
|
|
686
|
+
boundNames ??= collectBoundNames(stripped);
|
|
687
|
+
return boundNames.has(name);
|
|
688
|
+
}
|
|
546
689
|
const hoists = [];
|
|
547
690
|
const declByText = new Map();
|
|
548
691
|
let consumedUntil = 0;
|
|
@@ -566,8 +709,9 @@ export function hoistZodSchemas(code) {
|
|
|
566
709
|
// an inner z.string() of a top-level schema must not hoist on its own.
|
|
567
710
|
consumedUntil = chain.end;
|
|
568
711
|
// Depth 0 expressions are top-level statements/initializers: already
|
|
569
|
-
// evaluated once per module load, nothing to gain.
|
|
570
|
-
|
|
712
|
+
// evaluated once per module load, nothing to gain. Exception: concise
|
|
713
|
+
// arrow bodies (`const make = () => z.object(...)`) re-run per call.
|
|
714
|
+
if (candidate.depth === 0 && !candidate.afterArrow)
|
|
571
715
|
continue;
|
|
572
716
|
// Peel trailing parse calls: for `z.object({...}).safeParse(input)`,
|
|
573
717
|
// hoist the construction and leave `.safeParse(input)` — with its
|
|
@@ -589,32 +733,55 @@ export function hoistZodSchemas(code) {
|
|
|
589
733
|
if (described.methods.some((m) => PARSE_METHODS.has(m)))
|
|
590
734
|
continue;
|
|
591
735
|
const rootIsZod = imports.zod.has(candidate.name);
|
|
592
|
-
const rootMatchesPattern =
|
|
593
|
-
// Non-z bases must look like schema derivation:
|
|
594
|
-
//
|
|
595
|
-
// arbitrary imported object with a z-mentioning argument
|
|
596
|
-
|
|
736
|
+
const rootMatchesPattern = namePattern?.test(candidate.name) === true;
|
|
737
|
+
// Non-z bases must look like schema derivation: the chain must START
|
|
738
|
+
// with a combinator (`Base.extend({...}).optional()` qualifies via
|
|
739
|
+
// extend), so an arbitrary imported object with a z-mentioning argument
|
|
740
|
+
// (`api.get(z.string())`) is never hoisted. describeChain records
|
|
741
|
+
// methods outermost-first — the deepest method is last.
|
|
742
|
+
const deepestMethod = described.methods[described.methods.length - 1];
|
|
743
|
+
if (!rootIsZod && (deepestMethod === undefined || !COMBINATOR_METHODS.has(deepestMethod))) {
|
|
597
744
|
continue;
|
|
598
|
-
|
|
745
|
+
}
|
|
746
|
+
const { eagerFree, deferredFree, impure } = analyzeCaptures(chain);
|
|
599
747
|
if (impure)
|
|
600
748
|
continue;
|
|
601
|
-
// Imports-and-literals
|
|
602
|
-
//
|
|
603
|
-
//
|
|
749
|
+
// Imports-and-literals rule (babel-plugin-zod-hoist): eager positions
|
|
750
|
+
// may reference only imports — locals, module-level bindings, and
|
|
751
|
+
// globals all disqualify. Deferred positions (callback bodies) run per
|
|
752
|
+
// call regardless, so safe globals are additionally allowed there.
|
|
753
|
+
// Every referenced import must also be shadow-free: without scope
|
|
754
|
+
// information, a name that is ever re-bound (function parameter, local)
|
|
755
|
+
// cannot be trusted to mean the import.
|
|
604
756
|
let eligible = true;
|
|
605
|
-
for (const name of
|
|
606
|
-
if (!imports.all.has(name)) {
|
|
757
|
+
for (const name of eagerFree) {
|
|
758
|
+
if (!imports.all.has(name) || isShadowed(name)) {
|
|
607
759
|
eligible = false;
|
|
608
760
|
break;
|
|
609
761
|
}
|
|
610
762
|
}
|
|
763
|
+
if (eligible) {
|
|
764
|
+
for (const name of deferredFree) {
|
|
765
|
+
const allowed = imports.all.has(name) || SAFE_DEFERRED_GLOBALS.has(name);
|
|
766
|
+
if (!allowed || isShadowed(name)) {
|
|
767
|
+
eligible = false;
|
|
768
|
+
break;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
611
772
|
if (!eligible)
|
|
612
773
|
continue;
|
|
613
774
|
// Non-zod, non-pattern roots qualify only when the chain itself
|
|
614
775
|
// references a zod binding (`Base.extend({ a: z.string() })`).
|
|
615
776
|
if (!rootIsZod && !rootMatchesPattern) {
|
|
616
777
|
let referencesZod = false;
|
|
617
|
-
for (const name of
|
|
778
|
+
for (const name of eagerFree) {
|
|
779
|
+
if (imports.zod.has(name)) {
|
|
780
|
+
referencesZod = true;
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
for (const name of deferredFree) {
|
|
618
785
|
if (imports.zod.has(name)) {
|
|
619
786
|
referencesZod = true;
|
|
620
787
|
break;
|