zod-compiler 1.23.0 → 1.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/README.md +9 -6
  2. package/dist/cli/commands/check.d.ts +10 -7
  3. package/dist/cli/commands/check.d.ts.map +1 -1
  4. package/dist/cli/commands/check.js +125 -148
  5. package/dist/cli/commands/check.js.map +1 -1
  6. package/dist/cli/commands/generate.d.ts +22 -19
  7. package/dist/cli/commands/generate.d.ts.map +1 -1
  8. package/dist/cli/commands/generate.js +102 -133
  9. package/dist/cli/commands/generate.js.map +1 -1
  10. package/dist/cli/commands/watch.d.ts +17 -15
  11. package/dist/cli/commands/watch.d.ts.map +1 -1
  12. package/dist/cli/commands/watch.js +126 -154
  13. package/dist/cli/commands/watch.js.map +1 -1
  14. package/dist/cli/emitter.d.ts +19 -16
  15. package/dist/cli/emitter.d.ts.map +1 -1
  16. package/dist/cli/emitter.js +55 -71
  17. package/dist/cli/emitter.js.map +1 -1
  18. package/dist/cli/errors.d.ts +4 -1
  19. package/dist/cli/errors.d.ts.map +1 -1
  20. package/dist/cli/errors.js +6 -2
  21. package/dist/cli/errors.js.map +1 -1
  22. package/dist/cli/index.d.ts +1 -3
  23. package/dist/cli/index.js +147 -160
  24. package/dist/cli/index.js.map +1 -1
  25. package/dist/cli/logger.d.ts +18 -15
  26. package/dist/cli/logger.d.ts.map +1 -1
  27. package/dist/cli/logger.js +38 -37
  28. package/dist/cli/logger.js.map +1 -1
  29. package/dist/core/codegen/build-path.d.ts +7 -41
  30. package/dist/core/codegen/build-path.d.ts.map +1 -1
  31. package/dist/core/codegen/build-path.js +481 -570
  32. package/dist/core/codegen/build-path.js.map +1 -1
  33. package/dist/core/codegen/context.d.ts +256 -253
  34. package/dist/core/codegen/context.d.ts.map +1 -1
  35. package/dist/core/codegen/context.js +363 -437
  36. package/dist/core/codegen/context.js.map +1 -1
  37. package/dist/core/codegen/dedupe.d.ts +22 -56
  38. package/dist/core/codegen/dedupe.d.ts.map +1 -1
  39. package/dist/core/codegen/dedupe.js +150 -242
  40. package/dist/core/codegen/dedupe.js.map +1 -1
  41. package/dist/core/codegen/emit-issue.d.ts +44 -68
  42. package/dist/core/codegen/emit-issue.d.ts.map +1 -1
  43. package/dist/core/codegen/emit-issue.js +76 -108
  44. package/dist/core/codegen/emit-issue.js.map +1 -1
  45. package/dist/core/codegen/emit.d.ts +4 -1
  46. package/dist/core/codegen/emit.d.ts.map +1 -1
  47. package/dist/core/codegen/emit.js +16 -13
  48. package/dist/core/codegen/emit.js.map +1 -1
  49. package/dist/core/codegen/fast-path.d.ts +7 -12
  50. package/dist/core/codegen/fast-path.d.ts.map +1 -1
  51. package/dist/core/codegen/fast-path.js +116 -145
  52. package/dist/core/codegen/fast-path.js.map +1 -1
  53. package/dist/core/codegen/fast-size.d.ts +12 -26
  54. package/dist/core/codegen/fast-size.d.ts.map +1 -1
  55. package/dist/core/codegen/fast-size.js +169 -244
  56. package/dist/core/codegen/fast-size.js.map +1 -1
  57. package/dist/core/codegen/index.d.ts +25 -23
  58. package/dist/core/codegen/index.d.ts.map +1 -1
  59. package/dist/core/codegen/index.js +239 -405
  60. package/dist/core/codegen/index.js.map +1 -1
  61. package/dist/core/codegen/issue-decls.d.ts +15 -12
  62. package/dist/core/codegen/issue-decls.d.ts.map +1 -1
  63. package/dist/core/codegen/issue-decls.js +131 -162
  64. package/dist/core/codegen/issue-decls.js.map +1 -1
  65. package/dist/core/codegen/regex-unroll.d.ts +4 -1
  66. package/dist/core/codegen/regex-unroll.d.ts.map +1 -1
  67. package/dist/core/codegen/regex-unroll.js +173 -197
  68. package/dist/core/codegen/regex-unroll.js.map +1 -1
  69. package/dist/core/codegen/schemas/any.d.ts +7 -4
  70. package/dist/core/codegen/schemas/any.d.ts.map +1 -1
  71. package/dist/core/codegen/schemas/any.js +8 -4
  72. package/dist/core/codegen/schemas/any.js.map +1 -1
  73. package/dist/core/codegen/schemas/array.d.ts +8 -5
  74. package/dist/core/codegen/schemas/array.d.ts.map +1 -1
  75. package/dist/core/codegen/schemas/array.js +77 -95
  76. package/dist/core/codegen/schemas/array.js.map +1 -1
  77. package/dist/core/codegen/schemas/bigint.d.ts +7 -4
  78. package/dist/core/codegen/schemas/bigint.d.ts.map +1 -1
  79. package/dist/core/codegen/schemas/bigint.js +44 -56
  80. package/dist/core/codegen/schemas/bigint.js.map +1 -1
  81. package/dist/core/codegen/schemas/boolean.d.ts +7 -4
  82. package/dist/core/codegen/schemas/boolean.d.ts.map +1 -1
  83. package/dist/core/codegen/schemas/boolean.js +12 -11
  84. package/dist/core/codegen/schemas/boolean.js.map +1 -1
  85. package/dist/core/codegen/schemas/catch.d.ts +8 -5
  86. package/dist/core/codegen/schemas/catch.d.ts.map +1 -1
  87. package/dist/core/codegen/schemas/catch.js +23 -23
  88. package/dist/core/codegen/schemas/catch.js.map +1 -1
  89. package/dist/core/codegen/schemas/date.d.ts +7 -4
  90. package/dist/core/codegen/schemas/date.d.ts.map +1 -1
  91. package/dist/core/codegen/schemas/date.js +49 -68
  92. package/dist/core/codegen/schemas/date.js.map +1 -1
  93. package/dist/core/codegen/schemas/default.d.ts +9 -6
  94. package/dist/core/codegen/schemas/default.d.ts.map +1 -1
  95. package/dist/core/codegen/schemas/default.js +29 -27
  96. package/dist/core/codegen/schemas/default.js.map +1 -1
  97. package/dist/core/codegen/schemas/discriminated-union.d.ts +12 -10
  98. package/dist/core/codegen/schemas/discriminated-union.d.ts.map +1 -1
  99. package/dist/core/codegen/schemas/discriminated-union.js +153 -178
  100. package/dist/core/codegen/schemas/discriminated-union.js.map +1 -1
  101. package/dist/core/codegen/schemas/effect.d.ts +9 -6
  102. package/dist/core/codegen/schemas/effect.d.ts.map +1 -1
  103. package/dist/core/codegen/schemas/effect.js +54 -67
  104. package/dist/core/codegen/schemas/effect.js.map +1 -1
  105. package/dist/core/codegen/schemas/enum.d.ts +7 -4
  106. package/dist/core/codegen/schemas/enum.d.ts.map +1 -1
  107. package/dist/core/codegen/schemas/enum.js +15 -21
  108. package/dist/core/codegen/schemas/enum.js.map +1 -1
  109. package/dist/core/codegen/schemas/fallback.d.ts +6 -3
  110. package/dist/core/codegen/schemas/fallback.d.ts.map +1 -1
  111. package/dist/core/codegen/schemas/fallback.js +14 -13
  112. package/dist/core/codegen/schemas/fallback.js.map +1 -1
  113. package/dist/core/codegen/schemas/file.d.ts +7 -4
  114. package/dist/core/codegen/schemas/file.d.ts.map +1 -1
  115. package/dist/core/codegen/schemas/file.js +51 -57
  116. package/dist/core/codegen/schemas/file.js.map +1 -1
  117. package/dist/core/codegen/schemas/intersection.d.ts +8 -5
  118. package/dist/core/codegen/schemas/intersection.d.ts.map +1 -1
  119. package/dist/core/codegen/schemas/intersection.js +16 -13
  120. package/dist/core/codegen/schemas/intersection.js.map +1 -1
  121. package/dist/core/codegen/schemas/literal.d.ts +7 -4
  122. package/dist/core/codegen/schemas/literal.d.ts.map +1 -1
  123. package/dist/core/codegen/schemas/literal.js +20 -23
  124. package/dist/core/codegen/schemas/literal.js.map +1 -1
  125. package/dist/core/codegen/schemas/map.d.ts +8 -5
  126. package/dist/core/codegen/schemas/map.d.ts.map +1 -1
  127. package/dist/core/codegen/schemas/map.js +61 -67
  128. package/dist/core/codegen/schemas/map.js.map +1 -1
  129. package/dist/core/codegen/schemas/nan.d.ts +7 -4
  130. package/dist/core/codegen/schemas/nan.d.ts.map +1 -1
  131. package/dist/core/codegen/schemas/nan.js +8 -4
  132. package/dist/core/codegen/schemas/nan.js.map +1 -1
  133. package/dist/core/codegen/schemas/never.d.ts +7 -4
  134. package/dist/core/codegen/schemas/never.d.ts.map +1 -1
  135. package/dist/core/codegen/schemas/never.js +8 -4
  136. package/dist/core/codegen/schemas/never.js.map +1 -1
  137. package/dist/core/codegen/schemas/null.d.ts +7 -4
  138. package/dist/core/codegen/schemas/null.d.ts.map +1 -1
  139. package/dist/core/codegen/schemas/null.js +8 -4
  140. package/dist/core/codegen/schemas/null.js.map +1 -1
  141. package/dist/core/codegen/schemas/nullable.d.ts +8 -5
  142. package/dist/core/codegen/schemas/nullable.d.ts.map +1 -1
  143. package/dist/core/codegen/schemas/nullable.js +8 -5
  144. package/dist/core/codegen/schemas/nullable.js.map +1 -1
  145. package/dist/core/codegen/schemas/number.d.ts +7 -4
  146. package/dist/core/codegen/schemas/number.d.ts.map +1 -1
  147. package/dist/core/codegen/schemas/number.js +120 -176
  148. package/dist/core/codegen/schemas/number.js.map +1 -1
  149. package/dist/core/codegen/schemas/object.d.ts +8 -5
  150. package/dist/core/codegen/schemas/object.d.ts.map +1 -1
  151. package/dist/core/codegen/schemas/object.js +144 -231
  152. package/dist/core/codegen/schemas/object.js.map +1 -1
  153. package/dist/core/codegen/schemas/optional.d.ts +9 -6
  154. package/dist/core/codegen/schemas/optional.d.ts.map +1 -1
  155. package/dist/core/codegen/schemas/optional.js +23 -31
  156. package/dist/core/codegen/schemas/optional.js.map +1 -1
  157. package/dist/core/codegen/schemas/pipe.d.ts +8 -5
  158. package/dist/core/codegen/schemas/pipe.d.ts.map +1 -1
  159. package/dist/core/codegen/schemas/pipe.js +20 -27
  160. package/dist/core/codegen/schemas/pipe.js.map +1 -1
  161. package/dist/core/codegen/schemas/readonly.d.ts +8 -5
  162. package/dist/core/codegen/schemas/readonly.d.ts.map +1 -1
  163. package/dist/core/codegen/schemas/readonly.js +8 -5
  164. package/dist/core/codegen/schemas/readonly.js.map +1 -1
  165. package/dist/core/codegen/schemas/record.d.ts +8 -5
  166. package/dist/core/codegen/schemas/record.d.ts.map +1 -1
  167. package/dist/core/codegen/schemas/record.js +52 -65
  168. package/dist/core/codegen/schemas/record.js.map +1 -1
  169. package/dist/core/codegen/schemas/recursive-ref.d.ts +9 -6
  170. package/dist/core/codegen/schemas/recursive-ref.d.ts.map +1 -1
  171. package/dist/core/codegen/schemas/recursive-ref.js +44 -44
  172. package/dist/core/codegen/schemas/recursive-ref.js.map +1 -1
  173. package/dist/core/codegen/schemas/set.d.ts +8 -5
  174. package/dist/core/codegen/schemas/set.d.ts.map +1 -1
  175. package/dist/core/codegen/schemas/set.js +61 -73
  176. package/dist/core/codegen/schemas/set.js.map +1 -1
  177. package/dist/core/codegen/schemas/string-bool.d.ts +6 -3
  178. package/dist/core/codegen/schemas/string-bool.d.ts.map +1 -1
  179. package/dist/core/codegen/schemas/string-bool.js +22 -23
  180. package/dist/core/codegen/schemas/string-bool.js.map +1 -1
  181. package/dist/core/codegen/schemas/string.d.ts +8 -5
  182. package/dist/core/codegen/schemas/string.d.ts.map +1 -1
  183. package/dist/core/codegen/schemas/string.js +168 -207
  184. package/dist/core/codegen/schemas/string.js.map +1 -1
  185. package/dist/core/codegen/schemas/symbol.d.ts +7 -4
  186. package/dist/core/codegen/schemas/symbol.d.ts.map +1 -1
  187. package/dist/core/codegen/schemas/symbol.js +8 -4
  188. package/dist/core/codegen/schemas/symbol.js.map +1 -1
  189. package/dist/core/codegen/schemas/template-literal.d.ts +7 -4
  190. package/dist/core/codegen/schemas/template-literal.d.ts.map +1 -1
  191. package/dist/core/codegen/schemas/template-literal.js +12 -13
  192. package/dist/core/codegen/schemas/template-literal.js.map +1 -1
  193. package/dist/core/codegen/schemas/tuple.d.ts +8 -5
  194. package/dist/core/codegen/schemas/tuple.d.ts.map +1 -1
  195. package/dist/core/codegen/schemas/tuple.js +84 -94
  196. package/dist/core/codegen/schemas/tuple.js.map +1 -1
  197. package/dist/core/codegen/schemas/undefined.d.ts +7 -4
  198. package/dist/core/codegen/schemas/undefined.d.ts.map +1 -1
  199. package/dist/core/codegen/schemas/undefined.js +8 -4
  200. package/dist/core/codegen/schemas/undefined.js.map +1 -1
  201. package/dist/core/codegen/schemas/union.d.ts +8 -5
  202. package/dist/core/codegen/schemas/union.d.ts.map +1 -1
  203. package/dist/core/codegen/schemas/union.js +49 -69
  204. package/dist/core/codegen/schemas/union.js.map +1 -1
  205. package/dist/core/codegen/schemas/unknown.d.ts +7 -4
  206. package/dist/core/codegen/schemas/unknown.d.ts.map +1 -1
  207. package/dist/core/codegen/schemas/unknown.js +8 -4
  208. package/dist/core/codegen/schemas/unknown.js.map +1 -1
  209. package/dist/core/codegen/schemas/void.d.ts +7 -4
  210. package/dist/core/codegen/schemas/void.d.ts.map +1 -1
  211. package/dist/core/codegen/schemas/void.js +8 -4
  212. package/dist/core/codegen/schemas/void.js.map +1 -1
  213. package/dist/core/codegen/slow-path.d.ts +7 -4
  214. package/dist/core/codegen/slow-path.d.ts.map +1 -1
  215. package/dist/core/codegen/slow-path.js +71 -96
  216. package/dist/core/codegen/slow-path.js.map +1 -1
  217. package/dist/core/codegen/well-known-regex.d.ts +22 -19
  218. package/dist/core/codegen/well-known-regex.d.ts.map +1 -1
  219. package/dist/core/codegen/well-known-regex.js +127 -96
  220. package/dist/core/codegen/well-known-regex.js.map +1 -1
  221. package/dist/core/compile.d.ts +7 -4
  222. package/dist/core/compile.d.ts.map +1 -1
  223. package/dist/core/compile.js +48 -48
  224. package/dist/core/compile.js.map +1 -1
  225. package/dist/core/diagnostic.d.ts +38 -39
  226. package/dist/core/diagnostic.d.ts.map +1 -1
  227. package/dist/core/diagnostic.js +140 -164
  228. package/dist/core/diagnostic.js.map +1 -1
  229. package/dist/core/extract/checks.d.ts +18 -15
  230. package/dist/core/extract/checks.d.ts.map +1 -1
  231. package/dist/core/extract/checks.js +318 -311
  232. package/dist/core/extract/checks.js.map +1 -1
  233. package/dist/core/extract/effects.d.ts +13 -10
  234. package/dist/core/extract/effects.d.ts.map +1 -1
  235. package/dist/core/extract/effects.js +153 -222
  236. package/dist/core/extract/effects.js.map +1 -1
  237. package/dist/core/extract/extractors/any.d.ts +5 -2
  238. package/dist/core/extract/extractors/any.d.ts.map +1 -1
  239. package/dist/core/extract/extractors/any.js +5 -1
  240. package/dist/core/extract/extractors/any.js.map +1 -1
  241. package/dist/core/extract/extractors/array.d.ts +6 -3
  242. package/dist/core/extract/extractors/array.d.ts.map +1 -1
  243. package/dist/core/extract/extractors/array.js +25 -20
  244. package/dist/core/extract/extractors/array.js.map +1 -1
  245. package/dist/core/extract/extractors/bigint.d.ts +6 -3
  246. package/dist/core/extract/extractors/bigint.d.ts.map +1 -1
  247. package/dist/core/extract/extractors/bigint.js +66 -64
  248. package/dist/core/extract/extractors/bigint.js.map +1 -1
  249. package/dist/core/extract/extractors/boolean.d.ts +5 -2
  250. package/dist/core/extract/extractors/boolean.d.ts.map +1 -1
  251. package/dist/core/extract/extractors/boolean.js +7 -3
  252. package/dist/core/extract/extractors/boolean.js.map +1 -1
  253. package/dist/core/extract/extractors/catch.d.ts +6 -3
  254. package/dist/core/extract/extractors/catch.d.ts.map +1 -1
  255. package/dist/core/extract/extractors/catch.js +26 -17
  256. package/dist/core/extract/extractors/catch.js.map +1 -1
  257. package/dist/core/extract/extractors/date.d.ts +6 -3
  258. package/dist/core/extract/extractors/date.d.ts.map +1 -1
  259. package/dist/core/extract/extractors/date.js +42 -46
  260. package/dist/core/extract/extractors/date.js.map +1 -1
  261. package/dist/core/extract/extractors/default.d.ts +6 -3
  262. package/dist/core/extract/extractors/default.d.ts.map +1 -1
  263. package/dist/core/extract/extractors/default.js +20 -14
  264. package/dist/core/extract/extractors/default.js.map +1 -1
  265. package/dist/core/extract/extractors/enum.d.ts +5 -2
  266. package/dist/core/extract/extractors/enum.d.ts.map +1 -1
  267. package/dist/core/extract/extractors/enum.js +12 -13
  268. package/dist/core/extract/extractors/enum.js.map +1 -1
  269. package/dist/core/extract/extractors/file.d.ts +6 -3
  270. package/dist/core/extract/extractors/file.d.ts.map +1 -1
  271. package/dist/core/extract/extractors/file.js +34 -28
  272. package/dist/core/extract/extractors/file.js.map +1 -1
  273. package/dist/core/extract/extractors/intersection.d.ts +5 -2
  274. package/dist/core/extract/extractors/intersection.d.ts.map +1 -1
  275. package/dist/core/extract/extractors/intersection.js +13 -11
  276. package/dist/core/extract/extractors/intersection.js.map +1 -1
  277. package/dist/core/extract/extractors/lazy.d.ts +6 -3
  278. package/dist/core/extract/extractors/lazy.d.ts.map +1 -1
  279. package/dist/core/extract/extractors/lazy.js +21 -30
  280. package/dist/core/extract/extractors/lazy.js.map +1 -1
  281. package/dist/core/extract/extractors/literal.d.ts +5 -2
  282. package/dist/core/extract/extractors/literal.d.ts.map +1 -1
  283. package/dist/core/extract/extractors/literal.js +8 -1
  284. package/dist/core/extract/extractors/literal.js.map +1 -1
  285. package/dist/core/extract/extractors/map.d.ts +6 -3
  286. package/dist/core/extract/extractors/map.d.ts.map +1 -1
  287. package/dist/core/extract/extractors/map.js +10 -4
  288. package/dist/core/extract/extractors/map.js.map +1 -1
  289. package/dist/core/extract/extractors/nan.d.ts +5 -2
  290. package/dist/core/extract/extractors/nan.d.ts.map +1 -1
  291. package/dist/core/extract/extractors/nan.js +5 -1
  292. package/dist/core/extract/extractors/nan.js.map +1 -1
  293. package/dist/core/extract/extractors/never.d.ts +5 -2
  294. package/dist/core/extract/extractors/never.d.ts.map +1 -1
  295. package/dist/core/extract/extractors/never.js +5 -1
  296. package/dist/core/extract/extractors/never.js.map +1 -1
  297. package/dist/core/extract/extractors/null.d.ts +5 -2
  298. package/dist/core/extract/extractors/null.d.ts.map +1 -1
  299. package/dist/core/extract/extractors/null.js +5 -1
  300. package/dist/core/extract/extractors/null.js.map +1 -1
  301. package/dist/core/extract/extractors/nullable.d.ts +5 -2
  302. package/dist/core/extract/extractors/nullable.d.ts.map +1 -1
  303. package/dist/core/extract/extractors/nullable.js +7 -3
  304. package/dist/core/extract/extractors/nullable.js.map +1 -1
  305. package/dist/core/extract/extractors/number.d.ts +6 -3
  306. package/dist/core/extract/extractors/number.d.ts.map +1 -1
  307. package/dist/core/extract/extractors/number.js +35 -35
  308. package/dist/core/extract/extractors/number.js.map +1 -1
  309. package/dist/core/extract/extractors/object.d.ts +6 -3
  310. package/dist/core/extract/extractors/object.d.ts.map +1 -1
  311. package/dist/core/extract/extractors/object.js +49 -76
  312. package/dist/core/extract/extractors/object.js.map +1 -1
  313. package/dist/core/extract/extractors/optional.d.ts +5 -2
  314. package/dist/core/extract/extractors/optional.d.ts.map +1 -1
  315. package/dist/core/extract/extractors/optional.js +10 -12
  316. package/dist/core/extract/extractors/optional.js.map +1 -1
  317. package/dist/core/extract/extractors/pipe.d.ts +6 -3
  318. package/dist/core/extract/extractors/pipe.d.ts.map +1 -1
  319. package/dist/core/extract/extractors/pipe.js +40 -41
  320. package/dist/core/extract/extractors/pipe.js.map +1 -1
  321. package/dist/core/extract/extractors/readonly.d.ts +5 -2
  322. package/dist/core/extract/extractors/readonly.d.ts.map +1 -1
  323. package/dist/core/extract/extractors/readonly.js +10 -6
  324. package/dist/core/extract/extractors/readonly.js.map +1 -1
  325. package/dist/core/extract/extractors/record.d.ts +6 -3
  326. package/dist/core/extract/extractors/record.d.ts.map +1 -1
  327. package/dist/core/extract/extractors/record.js +24 -35
  328. package/dist/core/extract/extractors/record.js.map +1 -1
  329. package/dist/core/extract/extractors/set.d.ts +6 -3
  330. package/dist/core/extract/extractors/set.d.ts.map +1 -1
  331. package/dist/core/extract/extractors/set.js +36 -30
  332. package/dist/core/extract/extractors/set.js.map +1 -1
  333. package/dist/core/extract/extractors/string-bool.d.ts +7 -4
  334. package/dist/core/extract/extractors/string-bool.d.ts.map +1 -1
  335. package/dist/core/extract/extractors/string-bool.js +66 -84
  336. package/dist/core/extract/extractors/string-bool.js.map +1 -1
  337. package/dist/core/extract/extractors/string.d.ts +6 -3
  338. package/dist/core/extract/extractors/string.d.ts.map +1 -1
  339. package/dist/core/extract/extractors/string.js +34 -37
  340. package/dist/core/extract/extractors/string.js.map +1 -1
  341. package/dist/core/extract/extractors/symbol.d.ts +5 -2
  342. package/dist/core/extract/extractors/symbol.d.ts.map +1 -1
  343. package/dist/core/extract/extractors/symbol.js +5 -1
  344. package/dist/core/extract/extractors/symbol.js.map +1 -1
  345. package/dist/core/extract/extractors/template-literal.d.ts +6 -3
  346. package/dist/core/extract/extractors/template-literal.d.ts.map +1 -1
  347. package/dist/core/extract/extractors/template-literal.js +11 -6
  348. package/dist/core/extract/extractors/template-literal.js.map +1 -1
  349. package/dist/core/extract/extractors/tuple.d.ts +6 -3
  350. package/dist/core/extract/extractors/tuple.d.ts.map +1 -1
  351. package/dist/core/extract/extractors/tuple.js +10 -4
  352. package/dist/core/extract/extractors/tuple.js.map +1 -1
  353. package/dist/core/extract/extractors/undefined.d.ts +5 -2
  354. package/dist/core/extract/extractors/undefined.d.ts.map +1 -1
  355. package/dist/core/extract/extractors/undefined.js +5 -1
  356. package/dist/core/extract/extractors/undefined.js.map +1 -1
  357. package/dist/core/extract/extractors/union.d.ts +6 -3
  358. package/dist/core/extract/extractors/union.d.ts.map +1 -1
  359. package/dist/core/extract/extractors/union.js +38 -64
  360. package/dist/core/extract/extractors/union.js.map +1 -1
  361. package/dist/core/extract/extractors/unknown.d.ts +5 -2
  362. package/dist/core/extract/extractors/unknown.d.ts.map +1 -1
  363. package/dist/core/extract/extractors/unknown.js +5 -1
  364. package/dist/core/extract/extractors/unknown.js.map +1 -1
  365. package/dist/core/extract/extractors/void.d.ts +5 -2
  366. package/dist/core/extract/extractors/void.d.ts.map +1 -1
  367. package/dist/core/extract/extractors/void.js +5 -1
  368. package/dist/core/extract/extractors/void.js.map +1 -1
  369. package/dist/core/extract/fallback.d.ts +6 -3
  370. package/dist/core/extract/fallback.d.ts.map +1 -1
  371. package/dist/core/extract/fallback.js +21 -7
  372. package/dist/core/extract/fallback.js.map +1 -1
  373. package/dist/core/extract/index.d.ts +6 -4
  374. package/dist/core/extract/index.d.ts.map +1 -1
  375. package/dist/core/extract/index.js +15 -15
  376. package/dist/core/extract/index.js.map +1 -1
  377. package/dist/core/extract/registry.d.ts +39 -36
  378. package/dist/core/extract/registry.d.ts.map +1 -1
  379. package/dist/core/extract/registry.js +96 -123
  380. package/dist/core/extract/registry.js.map +1 -1
  381. package/dist/core/extract/types.d.ts +124 -120
  382. package/dist/core/extract/types.d.ts.map +1 -1
  383. package/dist/core/extract/types.js +0 -1
  384. package/dist/core/iife.d.ts +14 -15
  385. package/dist/core/iife.d.ts.map +1 -1
  386. package/dist/core/iife.js +182 -206
  387. package/dist/core/iife.js.map +1 -1
  388. package/dist/core/pipeline.d.ts +33 -30
  389. package/dist/core/pipeline.d.ts.map +1 -1
  390. package/dist/core/pipeline.js +67 -74
  391. package/dist/core/pipeline.js.map +1 -1
  392. package/dist/core/types.d.ts +430 -427
  393. package/dist/core/types.d.ts.map +1 -1
  394. package/dist/core/types.js +0 -5
  395. package/dist/discovery.d.ts +8 -5
  396. package/dist/discovery.d.ts.map +1 -1
  397. package/dist/discovery.js +31 -32
  398. package/dist/discovery.js.map +1 -1
  399. package/dist/index.d.ts +4 -4
  400. package/dist/index.js +2 -2
  401. package/dist/jit.d.ts +15 -42
  402. package/dist/jit.d.ts.map +1 -1
  403. package/dist/jit.js +187 -216
  404. package/dist/jit.js.map +1 -1
  405. package/dist/loader.d.ts +14 -11
  406. package/dist/loader.d.ts.map +1 -1
  407. package/dist/loader.js +226 -258
  408. package/dist/loader.js.map +1 -1
  409. package/dist/static-filter.d.ts +4 -1
  410. package/dist/static-filter.d.ts.map +1 -1
  411. package/dist/static-filter.js +240 -367
  412. package/dist/static-filter.js.map +1 -1
  413. package/dist/swc.d.ts +38 -35
  414. package/dist/swc.d.ts.map +1 -1
  415. package/dist/swc.js +83 -76
  416. package/dist/swc.js.map +1 -1
  417. package/dist/unplugin/bun.d.ts +5 -2
  418. package/dist/unplugin/bun.d.ts.map +1 -1
  419. package/dist/unplugin/bun.js +5 -1
  420. package/dist/unplugin/bun.js.map +1 -1
  421. package/dist/unplugin/dep-graph.d.ts +10 -7
  422. package/dist/unplugin/dep-graph.d.ts.map +1 -1
  423. package/dist/unplugin/dep-graph.js +216 -252
  424. package/dist/unplugin/dep-graph.js.map +1 -1
  425. package/dist/unplugin/disk-cache.d.ts +121 -92
  426. package/dist/unplugin/disk-cache.d.ts.map +1 -1
  427. package/dist/unplugin/disk-cache.js +425 -444
  428. package/dist/unplugin/disk-cache.js.map +1 -1
  429. package/dist/unplugin/edits.d.ts +15 -12
  430. package/dist/unplugin/edits.d.ts.map +1 -1
  431. package/dist/unplugin/edits.js +24 -37
  432. package/dist/unplugin/edits.js.map +1 -1
  433. package/dist/unplugin/esbuild.d.ts +5 -2
  434. package/dist/unplugin/esbuild.d.ts.map +1 -1
  435. package/dist/unplugin/esbuild.js +5 -1
  436. package/dist/unplugin/esbuild.js.map +1 -1
  437. package/dist/unplugin/farm.d.ts +5 -2
  438. package/dist/unplugin/farm.d.ts.map +1 -1
  439. package/dist/unplugin/farm.js +5 -1
  440. package/dist/unplugin/farm.js.map +1 -1
  441. package/dist/unplugin/hoist-compile.d.ts +14 -42
  442. package/dist/unplugin/hoist-compile.d.ts.map +1 -1
  443. package/dist/unplugin/hoist-compile.js +67 -112
  444. package/dist/unplugin/hoist-compile.js.map +1 -1
  445. package/dist/unplugin/hoist.d.ts +56 -54
  446. package/dist/unplugin/hoist.d.ts.map +1 -1
  447. package/dist/unplugin/hoist.js +945 -1170
  448. package/dist/unplugin/hoist.js.map +1 -1
  449. package/dist/unplugin/index.d.ts +5 -3
  450. package/dist/unplugin/index.d.ts.map +1 -1
  451. package/dist/unplugin/index.js +175 -250
  452. package/dist/unplugin/index.js.map +1 -1
  453. package/dist/unplugin/rolldown.d.ts +5 -2
  454. package/dist/unplugin/rolldown.d.ts.map +1 -1
  455. package/dist/unplugin/rolldown.js +5 -1
  456. package/dist/unplugin/rolldown.js.map +1 -1
  457. package/dist/unplugin/rollup.d.ts +5 -2
  458. package/dist/unplugin/rollup.d.ts.map +1 -1
  459. package/dist/unplugin/rollup.js +5 -1
  460. package/dist/unplugin/rollup.js.map +1 -1
  461. package/dist/unplugin/rsbuild.d.ts +6 -3
  462. package/dist/unplugin/rsbuild.d.ts.map +1 -1
  463. package/dist/unplugin/rsbuild.js +15 -11
  464. package/dist/unplugin/rsbuild.js.map +1 -1
  465. package/dist/unplugin/rspack.d.ts +5 -2
  466. package/dist/unplugin/rspack.d.ts.map +1 -1
  467. package/dist/unplugin/rspack.js +5 -1
  468. package/dist/unplugin/rspack.js.map +1 -1
  469. package/dist/unplugin/transform.d.ts +30 -27
  470. package/dist/unplugin/transform.d.ts.map +1 -1
  471. package/dist/unplugin/transform.js +433 -620
  472. package/dist/unplugin/transform.js.map +1 -1
  473. package/dist/unplugin/types.d.ts +189 -184
  474. package/dist/unplugin/types.d.ts.map +1 -1
  475. package/dist/unplugin/types.js +22 -18
  476. package/dist/unplugin/types.js.map +1 -1
  477. package/dist/unplugin/virtual.d.ts +11 -8
  478. package/dist/unplugin/virtual.d.ts.map +1 -1
  479. package/dist/unplugin/virtual.js +65 -83
  480. package/dist/unplugin/virtual.js.map +1 -1
  481. package/dist/unplugin/vite.d.ts +5 -2
  482. package/dist/unplugin/vite.d.ts.map +1 -1
  483. package/dist/unplugin/vite.js +5 -1
  484. package/dist/unplugin/vite.js.map +1 -1
  485. package/dist/unplugin/webpack.d.ts +5 -2
  486. package/dist/unplugin/webpack.d.ts.map +1 -1
  487. package/dist/unplugin/webpack.js +5 -1
  488. package/dist/unplugin/webpack.js.map +1 -1
  489. package/package.json +23 -14
  490. package/dist/cli/index.d.ts.map +0 -1
  491. package/dist/core/extract/types.js.map +0 -1
  492. package/dist/core/types.js.map +0 -1
  493. package/dist/index.d.ts.map +0 -1
  494. package/dist/index.js.map +0 -1
@@ -1,676 +1,489 @@
1
- import remapping from "@jridgewell/remapping";
2
- import { parseExpressionAt } from "acorn";
3
- import MagicString from "magic-string";
4
- import picomatch from "picomatch";
5
- import { SHARED_BLOCK_MARKER } from "../core/codegen/dedupe.js";
6
- import { FAIL_CLASS_DECL, FAILZ_CLASS_DECL, FIN_DECL, FIN_DEFERRED_DECL, FINZ_DECL, generateIIFE, MK_VALIDATOR_DECL, ZOD_CONFIG_IMPORT, ZOD_MSG_DECLARATION, } from "../core/iife.js";
7
- import { aggregateUsedHelpers, compileSchemas } from "../core/pipeline.js";
8
- import { discoverSchemas } from "../discovery.js";
9
1
  import { ProcessExitDuringLoadError } from "../loader.js";
2
+ import { discoverSchemas } from "../discovery.js";
3
+ import { FAILZ_CLASS_DECL, FAIL_CLASS_DECL, FINZ_DECL, FIN_DECL, FIN_DEFERRED_DECL, MK_VALIDATOR_DECL, ZOD_CONFIG_IMPORT, ZOD_MSG_DECLARATION, generateIIFE } from "../core/iife.js";
4
+ import "../core/codegen/dedupe.js";
5
+ import { aggregateUsedHelpers, compileSchemas } from "../core/pipeline.js";
10
6
  import { mayExportSchemas } from "../static-filter.js";
11
7
  import { applyEdits } from "./edits.js";
12
8
  import { hoistZodSchemasMeta } from "./hoist.js";
13
9
  import { compileHoistedSchemas } from "./hoist-compile.js";
14
10
  import { VIRTUAL_RUNTIME_ID } from "./virtual.js";
11
+ import { parseExpressionAt } from "acorn";
12
+ import remapping from "@jridgewell/remapping";
13
+ import MagicString from "magic-string";
14
+ import picomatch from "picomatch";
15
+ //#region src/unplugin/transform.ts
15
16
  /**
16
- * The transform pipeline as a chain of edit batches. Each batch is applied
17
- * to the CURRENT text through a MagicString (one stage map per batch); the
18
- * final original→output map is the remapping-composed chain. Deriving the
19
- * output string and the map from the same edit list makes divergence
20
- * impossible.
21
- */
22
- class StagedTransform {
23
- current;
24
- source;
25
- maps = [];
26
- constructor(original, source) {
27
- this.current = original;
28
- this.source = source;
29
- }
30
- apply(edits, insert) {
31
- this.applyThen(edits, insert === undefined ? undefined : () => insert);
32
- }
33
- /**
34
- * Apply `edits`, then let `deferred` derive one more insertion from the
35
- * resulting text — both inside ONE stage.
36
- *
37
- * The head injection (runtime import + shared dedup block) has to be decided
38
- * from the REWRITTEN source, because `computeRuntimePrefix` probes it for
39
- * already-present markers. Staging it separately made a whole second
40
- * `generateMap` over the full generated output — for what is only a prepend at
41
- * offset 0 — and then forced `remapping` to compose the two. Together those
42
- * were the dominant cost of a transform: on a 320-schema project they ran to
43
- * 64% of total wall time, more than discovery and codegen combined. Deferring
44
- * the insertion into the same MagicString buys byte-identical output and an
45
- * equivalent map for one generation and no composition — 1.6x (small schemas)
46
- * to 3.4x (large ones) on the transform, scaling with how much code a file
47
- * emits, since that is what both costs are proportional to.
48
- */
49
- applyThen(edits, deferred) {
50
- const s = new MagicString(this.current);
51
- for (const e of edits) {
52
- if (e.start === e.end) {
53
- s.appendLeft(e.start, e.text);
54
- }
55
- else {
56
- s.overwrite(e.start, e.end, e.text);
57
- }
58
- }
59
- // `toString()` is the only way to show the deferred step what the rewrite
60
- // produced; it measured well under 1% of a transform.
61
- const insert = deferred?.(edits.length === 0 ? this.current : s.toString());
62
- if (insert !== undefined) {
63
- s.appendLeft(insert.offset, insert.text);
64
- }
65
- if (edits.length === 0 && insert === undefined)
66
- return;
67
- this.current = s.toString();
68
- // `hires: "boundary"` is load-bearing, not a tuning knob: without it every
69
- // mapping collapses to column 0, so a stack frame or debugger breakpoint in
70
- // untouched user code below a compiled schema lands at the start of its line
71
- // instead of the right column (tests/unplugin/sourcemap.test.ts pins it). It
72
- // is also the most expensive thing here, which is why the stage COUNT is
73
- // what to economize on.
74
- this.maps.push(s.generateMap({ source: this.source, hires: "boundary", includeContent: true }));
75
- }
76
- /** Composed original→current map, or null when nothing was applied. */
77
- map() {
78
- if (this.maps.length === 0)
79
- return null;
80
- // A single stage needs no composition: `remapping` over a one-map chain
81
- // reproduces that map, and it is expensive on generated-code-sized input.
82
- const [only] = this.maps;
83
- if (this.maps.length === 1)
84
- return only;
85
- const chain = [...this.maps].reverse();
86
- return remapping(chain, () => null);
87
- }
88
- }
17
+ * The transform pipeline as a chain of edit batches. Each batch is applied
18
+ * to the CURRENT text through a MagicString (one stage map per batch); the
19
+ * final original→output map is the remapping-composed chain. Deriving the
20
+ * output string and the map from the same edit list makes divergence
21
+ * impossible.
22
+ */
23
+ var StagedTransform = class {
24
+ current;
25
+ source;
26
+ maps = [];
27
+ constructor(original, source) {
28
+ this.current = original;
29
+ this.source = source;
30
+ }
31
+ apply(edits, insert) {
32
+ this.applyThen(edits, insert === void 0 ? void 0 : () => insert);
33
+ }
34
+ /**
35
+ * Apply `edits`, then let `deferred` derive one more insertion from the
36
+ * resulting text — both inside ONE stage.
37
+ *
38
+ * The head injection (runtime import + shared dedup block) has to be decided
39
+ * from the REWRITTEN source, because `computeRuntimePrefix` probes it for
40
+ * already-present markers. Staging it separately made a whole second
41
+ * `generateMap` over the full generated output — for what is only a prepend at
42
+ * offset 0 — and then forced `remapping` to compose the two. Together those
43
+ * were the dominant cost of a transform: on a 320-schema project they ran to
44
+ * 64% of total wall time, more than discovery and codegen combined. Deferring
45
+ * the insertion into the same MagicString buys byte-identical output and an
46
+ * equivalent map for one generation and no composition — 1.6x (small schemas)
47
+ * to 3.4x (large ones) on the transform, scaling with how much code a file
48
+ * emits, since that is what both costs are proportional to.
49
+ */
50
+ applyThen(edits, deferred) {
51
+ const s = new MagicString(this.current);
52
+ for (const e of edits) if (e.start === e.end) s.appendLeft(e.start, e.text);
53
+ else s.overwrite(e.start, e.end, e.text);
54
+ const insert = deferred?.(edits.length === 0 ? this.current : s.toString());
55
+ if (insert !== void 0) s.appendLeft(insert.offset, insert.text);
56
+ if (edits.length === 0 && insert === void 0) return;
57
+ this.current = s.toString();
58
+ this.maps.push(s.generateMap({
59
+ source: this.source,
60
+ hires: "boundary",
61
+ includeContent: true
62
+ }));
63
+ }
64
+ /** Composed original→current map, or null when nothing was applied. */
65
+ map() {
66
+ if (this.maps.length === 0) return null;
67
+ const [only] = this.maps;
68
+ if (this.maps.length === 1) return only;
69
+ return remapping([...this.maps].reverse(), () => null);
70
+ }
71
+ };
89
72
  /**
90
- * Matches a runtime (non-type-only) import from "zod".
91
- *
92
- * One of the three triggers ZOD_MENTION (the transform hook's `code` filter)
93
- * must remain a superset of — widening this to a specifier that does not
94
- * contain "zod" silently strips those files from every bundler with native
95
- * hook filters. `describe("code filter soundness")` fails if it drifts.
96
- */
97
- export const HAS_RUNTIME_ZOD_IMPORT = /import\s+(?!type\s)[^;]*from\s+["']zod(?:\/v\d+)?["']/;
73
+ * Matches a runtime (non-type-only) import from "zod".
74
+ *
75
+ * One of the three triggers ZOD_MENTION (the transform hook's `code` filter)
76
+ * must remain a superset of — widening this to a specifier that does not
77
+ * contain "zod" silently strips those files from every bundler with native
78
+ * hook filters. `describe("code filter soundness")` fails if it drifts.
79
+ */
80
+ const HAS_RUNTIME_ZOD_IMPORT = /import\s+(?!type\s)[^;]*from\s+["']zod(?:\/v\d+)?["']/;
98
81
  /**
99
- * Opt-in phase timing (ZOD_COMPILER_TIMING=1): accumulates per-phase wall time
100
- * across all transform calls and prints a summary on process exit. Used to
101
- * attribute plugin overhead in real builds/test runs.
102
- */
82
+ * Opt-in phase timing (ZOD_COMPILER_TIMING=1): accumulates per-phase wall time
83
+ * across all transform calls and prints a summary on process exit. Used to
84
+ * attribute plugin overhead in real builds/test runs.
85
+ */
103
86
  const TIMING = process.env["ZOD_COMPILER_TIMING"] === "1";
104
87
  /** A single file's discovery exceeding this is worth an actionable warning. */
105
- const SLOW_DISCOVERY_WARN_MS = 5_000;
106
- const phaseTotals = new Map();
88
+ const SLOW_DISCOVERY_WARN_MS = 5e3;
89
+ const phaseTotals = /* @__PURE__ */ new Map();
107
90
  let timingHookInstalled = false;
108
91
  /** Dedupes the process.exit-during-discovery warning to one per process. */
109
92
  let warnedProcessExit = false;
110
93
  function timePhase(phase, fn) {
111
- if (!TIMING)
112
- return fn();
113
- const t0 = performance.now();
114
- const done = () => {
115
- const dt = performance.now() - t0;
116
- const agg = phaseTotals.get(phase) ?? { ms: 0, calls: 0 };
117
- agg.ms += dt;
118
- agg.calls++;
119
- phaseTotals.set(phase, agg);
120
- };
121
- if (!timingHookInstalled) {
122
- timingHookInstalled = true;
123
- process.on("exit", () => {
124
- const rows = [...phaseTotals.entries()].sort((a, b) => b[1].ms - a[1].ms);
125
- for (const [name, { ms, calls }] of rows) {
126
- log(`timing ${name}: ${ms.toFixed(1)}ms over ${calls} call(s)`);
127
- }
128
- });
129
- }
130
- const r = fn();
131
- if (r instanceof Promise) {
132
- return r.finally(done);
133
- }
134
- done();
135
- return r;
94
+ if (!TIMING) return fn();
95
+ const t0 = performance.now();
96
+ const done = () => {
97
+ const dt = performance.now() - t0;
98
+ const agg = phaseTotals.get(phase) ?? {
99
+ ms: 0,
100
+ calls: 0
101
+ };
102
+ agg.ms += dt;
103
+ agg.calls++;
104
+ phaseTotals.set(phase, agg);
105
+ };
106
+ if (!timingHookInstalled) {
107
+ timingHookInstalled = true;
108
+ process.on("exit", () => {
109
+ const rows = [...phaseTotals.entries()].sort((a, b) => b[1].ms - a[1].ms);
110
+ for (const [name, { ms, calls }] of rows) log(`timing ${name}: ${ms.toFixed(1)}ms over ${calls} call(s)`);
111
+ });
112
+ }
113
+ const r = fn();
114
+ if (r instanceof Promise) return r.finally(done);
115
+ done();
116
+ return r;
136
117
  }
137
118
  /**
138
- * Check if a file should be transformed by the plugin.
139
- */
140
- export function shouldTransform(id, options) {
141
- if (!/\.[cm]?[jt]sx?$/.test(id))
142
- return false;
143
- if (id.includes("node_modules"))
144
- return false;
145
- if (id.endsWith(".d.ts"))
146
- return false;
147
- if (id.endsWith(".compiled.ts") || id.endsWith(".compiled.js"))
148
- return false;
149
- if (options?.exclude?.some((pattern) => picomatch.isMatch(id, pattern, { contains: true })))
150
- return false;
151
- if (options?.include &&
152
- !options.include.some((pattern) => picomatch.isMatch(id, pattern, { contains: true })))
153
- return false;
154
- return true;
119
+ * Check if a file should be transformed by the plugin.
120
+ */
121
+ function shouldTransform(id, options) {
122
+ if (!/\.[cm]?[jt]sx?$/.test(id)) return false;
123
+ if (id.includes("node_modules")) return false;
124
+ if (id.endsWith(".d.ts")) return false;
125
+ if (id.endsWith(".compiled.ts") || id.endsWith(".compiled.js")) return false;
126
+ if (options?.exclude?.some((pattern) => picomatch.isMatch(id, pattern, { contains: true }))) return false;
127
+ if (options?.include && !options.include.some((pattern) => picomatch.isMatch(id, pattern, { contains: true }))) return false;
128
+ return true;
155
129
  }
156
130
  /**
157
- * `id` half of the transform hook filter: the option-independent checks of
158
- * shouldTransform(), restated as patterns the bundler can evaluate itself.
159
- * Rolldown, Vite and Rollup 4.40+ apply hook filters natively, so a rejected
160
- * module never crosses into JS; unplugin applies the same patterns in JS for
161
- * the rest (webpack/rspack skip installing the transform loader entirely).
162
- *
163
- * The `include`/`exclude` options stay out of the filter on purpose: they are
164
- * matched with picomatch's `contains: true` semantics, which the native glob
165
- * support (patterns resolved against cwd, matched whole) would silently
166
- * narrow — shouldTransform() keeps applying them inside the handler.
167
- */
168
- export const TRANSFORM_ID_FILTER = {
169
- exclude: [/node_modules/, /\.d\.ts$/, /\.compiled\.[jt]s$/],
170
- include: [/\.[cm]?[jt]sx?$/],
131
+ * `id` half of the transform hook filter: the option-independent checks of
132
+ * shouldTransform(), restated as patterns the bundler can evaluate itself.
133
+ * Rolldown, Vite and Rollup 4.40+ apply hook filters natively, so a rejected
134
+ * module never crosses into JS; unplugin applies the same patterns in JS for
135
+ * the rest (webpack/rspack skip installing the transform loader entirely).
136
+ *
137
+ * The `include`/`exclude` options stay out of the filter on purpose: they are
138
+ * matched with picomatch's `contains: true` semantics, which the native glob
139
+ * support (patterns resolved against cwd, matched whole) would silently
140
+ * narrow — shouldTransform() keeps applying them inside the handler.
141
+ */
142
+ const TRANSFORM_ID_FILTER = {
143
+ exclude: [
144
+ /node_modules/,
145
+ /\.d\.ts$/,
146
+ /\.compiled\.[jt]s$/
147
+ ],
148
+ include: [/\.[cm]?[jt]sx?$/]
171
149
  };
172
150
  /**
173
- * Every transform path that can change a file needs the substring "zod" (or
174
- * "Zod") somewhere in the source. There are exactly three triggers, and each
175
- * one is pinned by `describe("code filter soundness")` in the transform tests:
176
- *
177
- * 1. auto-discovery — HAS_RUNTIME_ZOD_IMPORT (above), which only matches
178
- * specifiers spelled "zod…";
179
- * 2. `schemas: "explicit"` — an import from "zod-compiler" (the package name);
180
- * 3. hoisting — a root imported from ZOD_MODULES or an identifier matching
181
- * SCHEMA_NAME_PATTERN (both in hoist.ts; a *custom* pattern drops this
182
- * filter entirely, see transformCodeFilter).
183
- *
184
- * Adding a fourth trigger that can fire without a "zod" mention MUST widen
185
- * this pattern, or those files are silently skipped on every bundler with
186
- * native hook filters — no error, schemas just quietly stay uncompiled.
187
- *
188
- * Spelled as a character class rather than an `i` flag: native filters
189
- * recompile these patterns outside JS, where flag support is narrower.
190
- */
151
+ * Every transform path that can change a file needs the substring "zod" (or
152
+ * "Zod") somewhere in the source. There are exactly three triggers, and each
153
+ * one is pinned by `describe("code filter soundness")` in the transform tests:
154
+ *
155
+ * 1. auto-discovery — HAS_RUNTIME_ZOD_IMPORT (above), which only matches
156
+ * specifiers spelled "zod…";
157
+ * 2. `schemas: "explicit"` — an import from "zod-compiler" (the package name);
158
+ * 3. hoisting — a root imported from ZOD_MODULES or an identifier matching
159
+ * SCHEMA_NAME_PATTERN (both in hoist.ts; a *custom* pattern drops this
160
+ * filter entirely, see transformCodeFilter).
161
+ *
162
+ * Adding a fourth trigger that can fire without a "zod" mention MUST widen
163
+ * this pattern, or those files are silently skipped on every bundler with
164
+ * native hook filters — no error, schemas just quietly stay uncompiled.
165
+ *
166
+ * Spelled as a character class rather than an `i` flag: native filters
167
+ * recompile these patterns outside JS, where flag support is narrower.
168
+ */
191
169
  const ZOD_MENTION = /[Zz]od/;
192
170
  /**
193
- * `code` half of the transform hook filter, or undefined when no sound filter
194
- * exists. A custom `hoist.schemaNamePattern` promotes arbitrary imported
195
- * identifiers to schema roots (`UserModel`), so nothing in such a file is
196
- * guaranteed to mention zod — those setups keep the unfiltered behavior.
197
- */
198
- export function transformCodeFilter(options) {
199
- const namePattern = typeof options?.hoist === "object" ? options.hoist.schemaNamePattern : null;
200
- // `null` disables name matching and `undefined` keeps the default
201
- // /ZodSchema$/ — both leave a "zod" mention as the only way in.
202
- return namePattern === null || namePattern === undefined ? ZOD_MENTION : undefined;
171
+ * `code` half of the transform hook filter, or undefined when no sound filter
172
+ * exists. A custom `hoist.schemaNamePattern` promotes arbitrary imported
173
+ * identifiers to schema roots (`UserModel`), so nothing in such a file is
174
+ * guaranteed to mention zod — those setups keep the unfiltered behavior.
175
+ */
176
+ function transformCodeFilter(options) {
177
+ const namePattern = typeof options?.hoist === "object" ? options.hoist.schemaNamePattern : null;
178
+ return namePattern === null || namePattern === void 0 ? ZOD_MENTION : void 0;
203
179
  }
204
- export function log(msg) {
205
- // oxlint-disable-next-line no-console -- build output
206
- console.log(`[zod-compiler] ${msg}`);
180
+ function log(msg) {
181
+ console.log(`[zod-compiler] ${msg}`);
207
182
  }
208
183
  function warn(msg) {
209
- // oxlint-disable-next-line no-console -- build output
210
- console.warn(`[zod-compiler] ${msg}`);
184
+ console.warn(`[zod-compiler] ${msg}`);
211
185
  }
212
186
  /**
213
- * Transform source code by replacing compile() calls with optimized validators.
214
- * Returns the transformed code or null if no transformation was needed.
215
- * Compatibility wrapper over transformCodeWithMap() — discards the map.
216
- */
217
- export async function transformCode(code, id, options) {
218
- const result = await transformCodeWithMap(code, id, options);
219
- return result === null ? null : result.code;
187
+ * Transform source code by replacing compile() calls with optimized validators.
188
+ * Returns the transformed code or null if no transformation was needed.
189
+ * Compatibility wrapper over transformCodeWithMap() — discards the map.
190
+ */
191
+ async function transformCode(code, id, options) {
192
+ const result = await transformCodeWithMap(code, id, options);
193
+ return result === null ? null : result.code;
220
194
  }
221
195
  /**
222
- * transformCode + a composed sourcemap (original → output). Stack traces in
223
- * transformed files shift by prepended declarations and expanded IIFEs
224
- * without it — a vitest assertion can be reported dozens of lines off.
225
- */
226
- export async function transformCodeWithMap(code, id, options) {
227
- const verbose = options.verbose === true;
228
- const autoDiscover = options.autoDiscover === true;
229
- const mode = options.mode;
230
- const staged = new StagedTransform(code, id);
231
- // Hoist Zod schema construction out of function bodies to module scope
232
- // (babel-plugin-zod-hoist equivalent). Mode-independent: inline schemas
233
- // live exactly in the files that export none. hoistZodSchemasMeta() bails
234
- // in microseconds when no eligible imports exist.
235
- let hoistedSchemas = null;
236
- if (options.hoist !== false && code.includes("import")) {
237
- hoistedSchemas = timePhase("hoist", () => hoistZodSchemasMeta(code, {
238
- ...(typeof options.hoist === "object" ? options.hoist : undefined),
239
- onScan: options.onSubstantialWork,
240
- }));
241
- if (hoistedSchemas !== null) {
242
- staged.apply(hoistedSchemas.edits, hoistedSchemas.insert);
243
- if (verbose) {
244
- log(`Hoisted inline Zod schemas in ${id}`);
245
- }
246
- }
247
- }
248
- // Compile the hoisted schemas (autoDiscover only — compiling anonymous
249
- // schemas is auto-discovery of unexported module-scope schemas). Each
250
- // hoisted `const _zh_x = z.object({...});` whose construction is
251
- // deterministic (eager refs are zod bindings only) is evaluated at build
252
- // time and its initializer replaced with the compiled validator IIFE;
253
- // anything ineligible stays a plain hoist.
254
- const hoistHelpers = new Set();
255
- let hoistCompiledCount = 0;
256
- if (autoDiscover && hoistedSchemas !== null && hoistedSchemas.schemas.length > 0) {
257
- const hoistCompiled = await timePhase("hoist-compile", () => compileHoistedSchemas(hoistedSchemas.schemas, code, id, mode));
258
- const spliceEdits = [];
259
- for (const h of hoistCompiled) {
260
- const decl = `const ${h.name} = ${h.text};`;
261
- const at = staged.current.indexOf(decl);
262
- if (at === -1)
263
- continue;
264
- const iife = generateIIFE(h.text, h.info, { zodCompat: options.zodCompat });
265
- spliceEdits.push({ start: at, end: at + decl.length, text: `const ${h.name} = ${iife};` });
266
- hoistCompiledCount++;
267
- for (const helper of h.info.codegenResult.usedHelpers) {
268
- hoistHelpers.add(helper);
269
- }
270
- if (verbose) {
271
- log(` ✓ ${h.name} (hoisted schema compiled)`);
272
- }
273
- }
274
- staged.apply(spliceEdits);
275
- if (hoistCompiledCount > 0) {
276
- hoistHelpers.add("__zcMkv");
277
- hoistHelpers.add("__zcFin");
278
- }
279
- }
280
- // When only hoisting (± hoisted-schema compilation) changed the file, that
281
- // is still a transform result — with runtime helpers injected if any
282
- // hoisted schema compiled.
283
- const finishHoistOnly = () => {
284
- if (staged.current === code)
285
- return null;
286
- if (hoistCompiledCount > 0) {
287
- options.onBuildStats?.({
288
- files: 1,
289
- schemas: hoistedSchemas?.schemas.length ?? 0,
290
- optimized: hoistCompiledCount,
291
- failed: 0,
292
- });
293
- const prefix = computeRuntimePrefix(staged.current, hoistHelpers, mode, options.runtimeId);
294
- if (prefix !== null) {
295
- staged.apply([], { offset: 0, text: prefix });
296
- }
297
- }
298
- return { code: staged.current, map: staged.map() };
299
- };
300
- // Quick bail-out check. Both gates are also encoded in the transform hook's
301
- // `code` filter (ZOD_MENTION) so bundlers can skip the hook call entirely —
302
- // relaxing either one here without widening that pattern makes the bundler
303
- // drop those files before this code ever runs.
304
- if (autoDiscover) {
305
- // autoDiscover: any file with a runtime Zod import is a candidate.
306
- // Skip `import type` — these files have no runtime schemas.
307
- if (!HAS_RUNTIME_ZOD_IMPORT.test(staged.current))
308
- return finishHoistOnly();
309
- }
310
- else {
311
- // Legacy mode: require compile() from zod-compiler. The word-boundary
312
- // check matters: the package name itself contains the substring
313
- // "compile", so a plain includes("compile") would match every import of
314
- // "zod-compiler" — \bcompile\b does not match inside "zod-compiler"
315
- // (no boundary between "e" and "r") but matches compile( / { compile }.
316
- if (!staged.current.includes("zod-compiler") || !/\bcompile\b/.test(staged.current))
317
- return finishHoistOnly();
318
- }
319
- // Static pre-filter: skip files whose exports provably cannot be schemas
320
- // (functions, components, constants, type-only modules) without executing
321
- // them. Conservative — anything ambiguous stays a candidate. The filter
322
- // transpiles + parses the file, so its outcome is worth persisting even
323
- // when the eventual result is null.
324
- options.onSubstantialWork?.();
325
- if (!(await timePhase("static-filter", () => mayExportSchemas(staged.current, id))))
326
- return finishHoistOnly();
327
- // Discover schemas by executing the file. Module executions are cached in
328
- // the shared loader; watch/HMR changes invalidate via invalidateModuleCache().
329
- options.onDiscovery?.();
330
- let schemas;
331
- const discoverStart = performance.now();
332
- try {
333
- schemas = await timePhase("discover", () => discoverSchemas(id, { autoDiscover }));
334
- }
335
- catch (e) {
336
- const msg = e instanceof Error ? e.message : String(e);
337
- // A module in the import graph called process.exit() during discovery —
338
- // typically an env-validation guard in a CI build where secrets are
339
- // intentionally absent. The loader converts that exit into a catchable
340
- // error so the build survives; the affected files just fall back to
341
- // runtime Zod. Handle it in both modes (never crash on a build-time exit)
342
- // and surface the cooperative remedy once.
343
- if (e instanceof ProcessExitDuringLoadError) {
344
- // The result reflects missing secrets, not file content — never persist
345
- // it to the content-hashed disk cache (a later secret-ful build would be
346
- // served this stale "nothing compiled" entry).
347
- options.onUncacheableResult?.();
348
- if (!warnedProcessExit) {
349
- warnedProcessExit = true;
350
- warn(`${id} (or a module it imports) called process.exit during build-time schema ` +
351
- `discovery — those files fall back to runtime Zod instead of crashing the build. ` +
352
- `This is usually an env-validation guard; wrap it in ` +
353
- `\`if (!process.env.ZOD_COMPILER) { ... }\` to keep these schemas compiled, or set ` +
354
- `schemas:"explicit" / use include to scope discovery.`);
355
- }
356
- return finishHoistOnly();
357
- }
358
- // In autoDiscover mode, files that can't be loaded (JSX components,
359
- // unresolved path aliases, etc.) are expected — warn and skip.
360
- if (autoDiscover) {
361
- if (verbose) {
362
- warn(`Skipping ${id}: ${msg}`);
363
- }
364
- return finishHoistOnly();
365
- }
366
- throw new Error(`[zod-compiler] Failed to load schemas from ${id}: ${msg}`);
367
- }
368
- const discoverMs = performance.now() - discoverStart;
369
- if (discoverMs >= SLOW_DISCOVERY_WARN_MS) {
370
- // Discovery executes the file's whole first-party import graph inside
371
- // the bundler's single-threaded process — on saturated CI hosts a large
372
- // graph can stall the event loop long enough to trip test timeouts.
373
- // Surface the cost with the two effective remedies.
374
- warn(`Discovery of ${id} took ${(discoverMs / 1000).toFixed(1)}s executing its import graph ` +
375
- `in the bundler process. Persist node_modules/.cache/zod-compiler across CI runs to pay ` +
376
- `this once, or narrow autoDiscover/include for test runs (see README "Large projects ` +
377
- `and CI"). ZOD_COMPILER_TIMING=1 prints a per-phase breakdown.`);
378
- }
379
- if (schemas.length === 0)
380
- return finishHoistOnly();
381
- // Lean mode (every bundler in VIRTUAL_MODULE_FRAMEWORKS — Vite/Rollup/webpack/rspack/etc.)
382
- // imports shared helpers from a runtime module for cross-file dedup: virtual:zod-compiler/runtime
383
- // on virtual-friendly bundlers, the __zod-compiler-runtime__ bare specifier on webpack/rspack.
384
- // Inline mode (CLI emitter, and any bundler not in VIRTUAL_MODULE_FRAMEWORKS) emits self-contained
385
- // file-level helpers.
386
- let failedCount = 0;
387
- const { schemas: compiled, shared } = timePhase("compile", () => compileSchemas(schemas, {
388
- mode,
389
- compact: options.compact,
390
- onError(exportName, error) {
391
- failedCount++;
392
- warn(`Failed to compile "${exportName}" in ${id}: ${error.message}. Keeping original${autoDiscover ? "" : " compile()"} call.`);
393
- },
394
- }));
395
- if (verbose) {
396
- if (autoDiscover) {
397
- log(`Auto-discovering: ${id} (${schemas.length} Zod export${schemas.length > 1 ? "s" : ""} found)`);
398
- }
399
- for (const s of compiled) {
400
- const rfCount = s.refEntries.length;
401
- const rfSuffix = rfCount > 0 ? ` (${rfCount} ref${rfCount > 1 ? "s" : ""})` : "";
402
- log(` ✓ ${s.exportName}${rfSuffix}`);
403
- }
404
- if (failedCount > 0) {
405
- log(` ✗ ${failedCount} schema(s) failed`);
406
- }
407
- }
408
- if (compiled.length === 0)
409
- return finishHoistOnly();
410
- // Report build stats only when at least one schema was compiled
411
- // (hoisted-schema compiles count alongside export schemas).
412
- options.onBuildStats?.({
413
- files: 1,
414
- schemas: schemas.length + (hoistedSchemas?.schemas.length ?? 0),
415
- optimized: compiled.length + hoistCompiledCount,
416
- failed: failedCount,
417
- });
418
- // __zcMkv and __zcFin are always needed (they wrap every IIFE). Helpers used
419
- // by compiled hoisted schemas ride along in the same injection.
420
- const usedHelpers = aggregateUsedHelpers(compiled);
421
- usedHelpers.add("__zcMkv");
422
- usedHelpers.add("__zcFin");
423
- for (const helper of hoistHelpers) {
424
- usedHelpers.add(helper);
425
- }
426
- // Shared dedup validators ride the same runtime import.
427
- for (const helper of shared.usedHelpers) {
428
- usedHelpers.add(helper);
429
- }
430
- // Two-pass rewrite: separate compile() schemas from autoDiscover schemas.
431
- // Both passes collect edits against the same pristine stage input — their
432
- // target regions are disjoint (compile() assignments vs plain exported
433
- // declarations of OTHER names), so one batched application is equivalent
434
- // to the historical sequential rewrites.
435
- let rewriteEdits;
436
- if (autoDiscover) {
437
- // Detect compile() schemas by checking source code patterns
438
- const compileExportNames = new Set();
439
- for (const s of compiled) {
440
- const pattern = new RegExp(`\\b${s.exportName}\\s*=\\s*compile[\\s<(]`);
441
- if (pattern.test(staged.current)) {
442
- compileExportNames.add(s.exportName);
443
- }
444
- }
445
- const compileSchemaInfos = compiled.filter((s) => compileExportNames.has(s.exportName));
446
- const autoDiscoverSchemaInfos = compiled.filter((s) => !compileExportNames.has(s.exportName));
447
- const edits = [];
448
- // Pass 1: compile() schemas (includes compile-import removal — only when
449
- // compile() schemas were actually rewritten, mirroring the historical
450
- // conditional rewriteSource call)
451
- if (compileSchemaInfos.length > 0) {
452
- edits.push(...collectCompileRewriteEdits(staged.current, compileSchemaInfos, {
453
- zodCompat: options.zodCompat,
454
- }));
455
- }
456
- // Pass 2: plain exported schemas
457
- if (autoDiscoverSchemaInfos.length > 0) {
458
- edits.push(...collectAutoDiscoverEdits(staged.current, autoDiscoverSchemaInfos, {
459
- zodCompat: options.zodCompat,
460
- }));
461
- }
462
- rewriteEdits = edits;
463
- }
464
- else {
465
- rewriteEdits = collectCompileRewriteEdits(staged.current, compiled, {
466
- zodCompat: options.zodCompat,
467
- });
468
- }
469
- // Head = runtime helpers/import, then the file-level shared dedup block, then
470
- // the rewritten source. The shared `__zcSw_N` functions live at module scope
471
- // so every IIFE closes over them; they must follow the runtime import (lean)
472
- // and the helper decls (inline) that they reference. Guard against
473
- // double-injection on watch/HMR re-runs the same way computeRuntimePrefix
474
- // does — a second copy would redeclare every `__zcSw_N`.
475
- //
476
- // Deferred into the rewrite's own stage rather than staged after it: both
477
- // decisions read the REWRITTEN text, and giving a bare prepend its own stage
478
- // doubled the sourcemap work and added a composition pass (see applyThen).
479
- staged.applyThen(rewriteEdits, (rewritten) => {
480
- const prefix = computeRuntimePrefix(rewritten, usedHelpers, mode, options.runtimeId);
481
- const needsShared = shared.code !== "" && !rewritten.includes(SHARED_BLOCK_MARKER);
482
- const head = (prefix ?? "") + (needsShared ? `${shared.code}\n` : "");
483
- return head === "" ? undefined : { offset: 0, text: head };
484
- });
485
- return { code: staged.current, map: staged.map() };
196
+ * transformCode + a composed sourcemap (original → output). Stack traces in
197
+ * transformed files shift by prepended declarations and expanded IIFEs
198
+ * without it — a vitest assertion can be reported dozens of lines off.
199
+ */
200
+ async function transformCodeWithMap(code, id, options) {
201
+ const verbose = options.verbose === true;
202
+ const autoDiscover = options.autoDiscover === true;
203
+ const mode = options.mode;
204
+ const staged = new StagedTransform(code, id);
205
+ let hoistedSchemas = null;
206
+ if (options.hoist !== false && code.includes("import")) {
207
+ hoistedSchemas = timePhase("hoist", () => hoistZodSchemasMeta(code, {
208
+ ...typeof options.hoist === "object" ? options.hoist : void 0,
209
+ onScan: options.onSubstantialWork
210
+ }));
211
+ if (hoistedSchemas !== null) {
212
+ staged.apply(hoistedSchemas.edits, hoistedSchemas.insert);
213
+ if (verbose) log(`Hoisted inline Zod schemas in ${id}`);
214
+ }
215
+ }
216
+ const hoistHelpers = /* @__PURE__ */ new Set();
217
+ let hoistCompiledCount = 0;
218
+ if (autoDiscover && hoistedSchemas !== null && hoistedSchemas.schemas.length > 0) {
219
+ const hoistCompiled = await timePhase("hoist-compile", () => compileHoistedSchemas(hoistedSchemas.schemas, code, id, mode));
220
+ const spliceEdits = [];
221
+ for (const h of hoistCompiled) {
222
+ const decl = `const ${h.name} = ${h.text};`;
223
+ const at = staged.current.indexOf(decl);
224
+ if (at === -1) continue;
225
+ const iife = generateIIFE(h.text, h.info, { zodCompat: options.zodCompat });
226
+ spliceEdits.push({
227
+ start: at,
228
+ end: at + decl.length,
229
+ text: `const ${h.name} = ${iife};`
230
+ });
231
+ hoistCompiledCount++;
232
+ for (const helper of h.info.codegenResult.usedHelpers) hoistHelpers.add(helper);
233
+ if (verbose) log(` ✓ ${h.name} (hoisted schema compiled)`);
234
+ }
235
+ staged.apply(spliceEdits);
236
+ if (hoistCompiledCount > 0) {
237
+ hoistHelpers.add("__zcMkv");
238
+ hoistHelpers.add("__zcFin");
239
+ }
240
+ }
241
+ const finishHoistOnly = () => {
242
+ if (staged.current === code) return null;
243
+ if (hoistCompiledCount > 0) {
244
+ options.onBuildStats?.({
245
+ files: 1,
246
+ schemas: hoistedSchemas?.schemas.length ?? 0,
247
+ optimized: hoistCompiledCount,
248
+ failed: 0
249
+ });
250
+ const prefix = computeRuntimePrefix(staged.current, hoistHelpers, mode, options.runtimeId);
251
+ if (prefix !== null) staged.apply([], {
252
+ offset: 0,
253
+ text: prefix
254
+ });
255
+ }
256
+ return {
257
+ code: staged.current,
258
+ map: staged.map()
259
+ };
260
+ };
261
+ if (autoDiscover) {
262
+ if (!HAS_RUNTIME_ZOD_IMPORT.test(staged.current)) return finishHoistOnly();
263
+ } else if (!staged.current.includes("zod-compiler") || !/\bcompile\b/.test(staged.current)) return finishHoistOnly();
264
+ options.onSubstantialWork?.();
265
+ if (!await timePhase("static-filter", () => mayExportSchemas(staged.current, id))) return finishHoistOnly();
266
+ options.onDiscovery?.();
267
+ let schemas;
268
+ const discoverStart = performance.now();
269
+ try {
270
+ schemas = await timePhase("discover", () => discoverSchemas(id, { autoDiscover }));
271
+ } catch (e) {
272
+ const msg = e instanceof Error ? e.message : String(e);
273
+ if (e instanceof ProcessExitDuringLoadError) {
274
+ options.onUncacheableResult?.();
275
+ if (!warnedProcessExit) {
276
+ warnedProcessExit = true;
277
+ warn(`${id} (or a module it imports) called process.exit during build-time schema discovery — those files fall back to runtime Zod instead of crashing the build. This is usually an env-validation guard; wrap it in \`if (!process.env.ZOD_COMPILER) { ... }\` to keep these schemas compiled, or set schemas:"explicit" / use include to scope discovery.`);
278
+ }
279
+ return finishHoistOnly();
280
+ }
281
+ if (autoDiscover) {
282
+ if (verbose) warn(`Skipping ${id}: ${msg}`);
283
+ return finishHoistOnly();
284
+ }
285
+ throw new Error(`[zod-compiler] Failed to load schemas from ${id}: ${msg}`);
286
+ }
287
+ const discoverMs = performance.now() - discoverStart;
288
+ if (discoverMs >= SLOW_DISCOVERY_WARN_MS) warn(`Discovery of ${id} took ${(discoverMs / 1e3).toFixed(1)}s executing its import graph in the bundler process. Persist node_modules/.cache/zod-compiler across CI runs to pay this once, or narrow autoDiscover/include for test runs (see README "Large projects and CI"). ZOD_COMPILER_TIMING=1 prints a per-phase breakdown.`);
289
+ if (schemas.length === 0) return finishHoistOnly();
290
+ let failedCount = 0;
291
+ const { schemas: compiled, shared } = timePhase("compile", () => compileSchemas(schemas, {
292
+ mode,
293
+ compact: options.compact,
294
+ onError(exportName, error) {
295
+ failedCount++;
296
+ warn(`Failed to compile "${exportName}" in ${id}: ${error.message}. Keeping original${autoDiscover ? "" : " compile()"} call.`);
297
+ }
298
+ }));
299
+ if (verbose) {
300
+ if (autoDiscover) log(`Auto-discovering: ${id} (${schemas.length} Zod export${schemas.length > 1 ? "s" : ""} found)`);
301
+ for (const s of compiled) {
302
+ const rfCount = s.refEntries.length;
303
+ const rfSuffix = rfCount > 0 ? ` (${rfCount} ref${rfCount > 1 ? "s" : ""})` : "";
304
+ log(` ✓ ${s.exportName}${rfSuffix}`);
305
+ }
306
+ if (failedCount > 0) log(` ✗ ${failedCount} schema(s) failed`);
307
+ }
308
+ if (compiled.length === 0) return finishHoistOnly();
309
+ options.onBuildStats?.({
310
+ files: 1,
311
+ schemas: schemas.length + (hoistedSchemas?.schemas.length ?? 0),
312
+ optimized: compiled.length + hoistCompiledCount,
313
+ failed: failedCount
314
+ });
315
+ const usedHelpers = aggregateUsedHelpers(compiled);
316
+ usedHelpers.add("__zcMkv");
317
+ usedHelpers.add("__zcFin");
318
+ for (const helper of hoistHelpers) usedHelpers.add(helper);
319
+ for (const helper of shared.usedHelpers) usedHelpers.add(helper);
320
+ let rewriteEdits;
321
+ if (autoDiscover) {
322
+ const compileExportNames = /* @__PURE__ */ new Set();
323
+ for (const s of compiled) if (new RegExp(`\\b${s.exportName}\\s*=\\s*compile[\\s<(]`).test(staged.current)) compileExportNames.add(s.exportName);
324
+ const compileSchemaInfos = compiled.filter((s) => compileExportNames.has(s.exportName));
325
+ const autoDiscoverSchemaInfos = compiled.filter((s) => !compileExportNames.has(s.exportName));
326
+ const edits = [];
327
+ if (compileSchemaInfos.length > 0) edits.push(...collectCompileRewriteEdits(staged.current, compileSchemaInfos, { zodCompat: options.zodCompat }));
328
+ if (autoDiscoverSchemaInfos.length > 0) edits.push(...collectAutoDiscoverEdits(staged.current, autoDiscoverSchemaInfos, { zodCompat: options.zodCompat }));
329
+ rewriteEdits = edits;
330
+ } else rewriteEdits = collectCompileRewriteEdits(staged.current, compiled, { zodCompat: options.zodCompat });
331
+ staged.applyThen(rewriteEdits, (rewritten) => {
332
+ const prefix = computeRuntimePrefix(rewritten, usedHelpers, mode, options.runtimeId);
333
+ const needsShared = shared.code !== "" && !rewritten.includes("/* zod-compiler shared */");
334
+ const head = (prefix ?? "") + (needsShared ? `${shared.code}\n` : "");
335
+ return head === "" ? void 0 : {
336
+ offset: 0,
337
+ text: head
338
+ };
339
+ });
340
+ return {
341
+ code: staged.current,
342
+ map: staged.map()
343
+ };
486
344
  }
487
345
  /**
488
- * Prepend the runtime helpers required by the rewritten source.
489
- *
490
- * Lean mode emits a single `import { ... } from "<runtimeId>";` line —
491
- * bundlers whose resolveId hook intercepts the specifier dedup helpers across
492
- * every transformed file into one shared virtual module.
493
- *
494
- * Inline mode prepends file-level `function __zcMkv` / `function __zcFin`
495
- * declarations directly so the file is self-contained.
496
- *
497
- * Idempotent: if the file already contains the relevant marker (re-run during
498
- * watch/HMR), we skip re-injection.
499
- */
346
+ * Prepend the runtime helpers required by the rewritten source.
347
+ *
348
+ * Lean mode emits a single `import { ... } from "<runtimeId>";` line —
349
+ * bundlers whose resolveId hook intercepts the specifier dedup helpers across
350
+ * every transformed file into one shared virtual module.
351
+ *
352
+ * Inline mode prepends file-level `function __zcMkv` / `function __zcFin`
353
+ * declarations directly so the file is self-contained.
354
+ *
355
+ * Idempotent: if the file already contains the relevant marker (re-run during
356
+ * watch/HMR), we skip re-injection.
357
+ */
500
358
  /** The runtime-helper text to prepend, or null when nothing is needed. */
501
359
  function computeRuntimePrefix(code, usedHelpers, mode, runtimeId = VIRTUAL_RUNTIME_ID) {
502
- if (mode === "lean") {
503
- if (usedHelpers.size === 0)
504
- return null;
505
- if (code.includes(runtimeId))
506
- return null;
507
- const names = [...usedHelpers].sort().join(", ");
508
- return `import { ${names} } from "${runtimeId}";\n`;
509
- }
510
- // Inline mode (CLI emitter, and any bundler not in VIRTUAL_MODULE_FRAMEWORKS):
511
- // ship file-level helper declarations instead of a virtual import.
512
- // Codegen emits per-IIFE issue literals + per-IIFE `__re_*` decls,
513
- // so we only need __zcMkv / __zcFin (plus __zcMsg via the zod config import).
514
- if (!code.includes("__zcMkv"))
515
- return null;
516
- const prefix = [];
517
- if (!code.includes("__zodCompilerConfig")) {
518
- prefix.push(ZOD_CONFIG_IMPORT, ZOD_MSG_DECLARATION);
519
- }
520
- if (!code.includes("function __zcMkv(")) {
521
- prefix.push(MK_VALIDATOR_DECL);
522
- }
523
- // __zcFin and __zcFinD both construct __ZcFail; declare it once before either,
524
- // guarding against a header already shipped earlier in the same module.
525
- const needsFin = !code.includes("function __zcFin(");
526
- const needsFinD = code.includes("__zcFinD(") && !code.includes("function __zcFinD(");
527
- if ((needsFin || needsFinD) && !code.includes("function __ZcFail(")) {
528
- prefix.push(FAIL_CLASS_DECL);
529
- }
530
- if (needsFin) {
531
- prefix.push(FIN_DECL);
532
- }
533
- if (needsFinD) {
534
- prefix.push(FIN_DEFERRED_DECL);
535
- }
536
- // Compact mode (output: "compact") delegates cold errors to zod via __zcFinZ,
537
- // which constructs its own __ZcFailZ (distinct from __ZcFail).
538
- const needsFinZ = code.includes("__zcFinZ(") && !code.includes("function __zcFinZ(");
539
- if (needsFinZ && !code.includes("function __ZcFailZ(")) {
540
- prefix.push(FAILZ_CLASS_DECL);
541
- }
542
- if (needsFinZ) {
543
- prefix.push(FINZ_DECL);
544
- }
545
- return prefix.length > 0 ? `${prefix.join("\n")}\n` : null;
360
+ if (mode === "lean") {
361
+ if (usedHelpers.size === 0) return null;
362
+ if (code.includes(runtimeId)) return null;
363
+ return `import { ${[...usedHelpers].sort().join(", ")} } from "${runtimeId}";\n`;
364
+ }
365
+ if (!code.includes("__zcMkv")) return null;
366
+ const prefix = [];
367
+ if (!code.includes("__zodCompilerConfig")) prefix.push(ZOD_CONFIG_IMPORT, ZOD_MSG_DECLARATION);
368
+ if (!code.includes("function __zcMkv(")) prefix.push(MK_VALIDATOR_DECL);
369
+ const needsFin = !code.includes("function __zcFin(");
370
+ const needsFinD = code.includes("__zcFinD(") && !code.includes("function __zcFinD(");
371
+ if ((needsFin || needsFinD) && !code.includes("function __ZcFail(")) prefix.push(FAIL_CLASS_DECL);
372
+ if (needsFin) prefix.push(FIN_DECL);
373
+ if (needsFinD) prefix.push(FIN_DEFERRED_DECL);
374
+ const needsFinZ = code.includes("__zcFinZ(") && !code.includes("function __zcFinZ(");
375
+ if (needsFinZ && !code.includes("function __ZcFailZ(")) prefix.push(FAILZ_CLASS_DECL);
376
+ if (needsFinZ) prefix.push(FINZ_DECL);
377
+ return prefix.length > 0 ? `${prefix.join("\n")}\n` : null;
546
378
  }
547
379
  /**
548
- * Find the matching closing parenthesis for a compile() call,
549
- * handling nested parentheses like compile(z.object({...})).
550
- * Returns the index of the closing ')' or -1 if not found.
551
- */
380
+ * Find the matching closing parenthesis for a compile() call,
381
+ * handling nested parentheses like compile(z.object({...})).
382
+ * Returns the index of the closing ')' or -1 if not found.
383
+ */
552
384
  function findMatchingParen(code, openIndex) {
553
- let depth = 1;
554
- for (let i = openIndex + 1; i < code.length; i++) {
555
- if (code[i] === "(")
556
- depth++;
557
- else if (code[i] === ")") {
558
- depth--;
559
- if (depth === 0)
560
- return i;
561
- }
562
- }
563
- return -1;
385
+ let depth = 1;
386
+ for (let i = openIndex + 1; i < code.length; i++) if (code[i] === "(") depth++;
387
+ else if (code[i] === ")") {
388
+ depth--;
389
+ if (depth === 0) return i;
390
+ }
391
+ return -1;
564
392
  }
565
393
  /**
566
- * Rewrite source code by replacing compile() calls with IIFE-wrapped optimized validators.
567
- */
568
- export function rewriteSource(code, schemas, options) {
569
- return applyEdits(code, collectCompileRewriteEdits(code, schemas, options));
394
+ * Rewrite source code by replacing compile() calls with IIFE-wrapped optimized validators.
395
+ */
396
+ function rewriteSource(code, schemas, options) {
397
+ return applyEdits(code, collectCompileRewriteEdits(code, schemas, options));
570
398
  }
571
399
  /**
572
- * Edits for rewriteSource (compile() call replacements + compile-import
573
- * removal), collected against pristine `code`. Each schema's declaration is
574
- * a distinct region and the import statement is distinct from all of them,
575
- * so the batch is non-overlapping and order-independent.
576
- */
400
+ * Edits for rewriteSource (compile() call replacements + compile-import
401
+ * removal), collected against pristine `code`. Each schema's declaration is
402
+ * a distinct region and the import statement is distinct from all of them,
403
+ * so the batch is non-overlapping and order-independent.
404
+ */
577
405
  function collectCompileRewriteEdits(code, schemas, options) {
578
- const edits = [];
579
- for (const schema of schemas) {
580
- // Match: <exportName> = compile<...>( with word boundary to prevent substring matches
581
- const prefixPattern = new RegExp(`(\\b${schema.exportName}\\s*=\\s*)compile\\s*(?:<[^>]*(?:<[^>]*>[^>]*)?>)?\\s*\\(`);
582
- const match = prefixPattern.exec(code);
583
- if (!match)
584
- continue;
585
- // Find the matching closing paren (handles nested parens)
586
- const openParenIndex = match.index + match[0].length - 1;
587
- const closeParenIndex = findMatchingParen(code, openParenIndex);
588
- if (closeParenIndex === -1)
589
- continue;
590
- const schemaArgName = code
591
- .slice(openParenIndex + 1, closeParenIndex)
592
- .trim()
593
- .replace(/,\s*$/, "");
594
- const prefix = match[1] ?? "";
595
- edits.push({
596
- start: match.index,
597
- end: closeParenIndex + 1,
598
- text: prefix + generateIIFE(schemaArgName, schema, options),
599
- });
600
- }
601
- edits.push(...collectRemoveCompileImportEdits(code));
602
- return edits;
406
+ const edits = [];
407
+ for (const schema of schemas) {
408
+ const match = new RegExp(`(\\b${schema.exportName}\\s*=\\s*)compile\\s*(?:<[^>]*(?:<[^>]*>[^>]*)?>)?\\s*\\(`).exec(code);
409
+ if (!match) continue;
410
+ const openParenIndex = match.index + match[0].length - 1;
411
+ const closeParenIndex = findMatchingParen(code, openParenIndex);
412
+ if (closeParenIndex === -1) continue;
413
+ const schemaArgName = code.slice(openParenIndex + 1, closeParenIndex).trim().replace(/,\s*$/, "");
414
+ const prefix = match[1] ?? "";
415
+ edits.push({
416
+ start: match.index,
417
+ end: closeParenIndex + 1,
418
+ text: prefix + generateIIFE(schemaArgName, schema, options)
419
+ });
420
+ }
421
+ edits.push(...collectRemoveCompileImportEdits(code));
422
+ return edits;
603
423
  }
604
424
  /**
605
- * Find the end position of a JavaScript expression starting at `start` using acorn.
606
- * Returns the end offset, or -1 if the expression cannot be parsed.
607
- */
608
- export function findExpressionEnd(code, start) {
609
- try {
610
- const node = parseExpressionAt(code, start, {
611
- ecmaVersion: "latest",
612
- sourceType: "module",
613
- });
614
- return node.end;
615
- }
616
- catch {
617
- return -1;
618
- }
425
+ * Find the end position of a JavaScript expression starting at `start` using acorn.
426
+ * Returns the end offset, or -1 if the expression cannot be parsed.
427
+ */
428
+ function findExpressionEnd(code, start) {
429
+ try {
430
+ return parseExpressionAt(code, start, {
431
+ ecmaVersion: "latest",
432
+ sourceType: "module"
433
+ }).end;
434
+ } catch {
435
+ return -1;
436
+ }
619
437
  }
620
438
  /**
621
- * Rewrite source code by replacing plain Zod schema exports with IIFE-wrapped optimized validators.
622
- * Used by autoDiscover mode (no compile() wrappers needed).
623
- */
624
- export function rewriteSourceAutoDiscover(code, schemas, options) {
625
- return applyEdits(code, collectAutoDiscoverEdits(code, schemas, options));
439
+ * Rewrite source code by replacing plain Zod schema exports with IIFE-wrapped optimized validators.
440
+ * Used by autoDiscover mode (no compile() wrappers needed).
441
+ */
442
+ function rewriteSourceAutoDiscover(code, schemas, options) {
443
+ return applyEdits(code, collectAutoDiscoverEdits(code, schemas, options));
626
444
  }
627
445
  /** Edits for rewriteSourceAutoDiscover, collected against pristine `code`. */
628
446
  function collectAutoDiscoverEdits(code, schemas, options) {
629
- const edits = [];
630
- for (const schema of schemas) {
631
- const escapedName = schema.exportName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
632
- // Match: export? (const|let|var) ExportName[: TypeAnnotation] = <expr>
633
- const assignPattern = new RegExp(`((?:export\\s+)?(?:const|let|var)\\s+${escapedName}(?:\\s*:[^=]*)?\\s*=\\s*)`);
634
- const match = assignPattern.exec(code);
635
- if (!match)
636
- continue;
637
- const rhsStart = match.index + match[0].length;
638
- const rhsEnd = findExpressionEnd(code, rhsStart);
639
- if (rhsEnd === -1)
640
- continue;
641
- const originalExpr = code.slice(rhsStart, rhsEnd).trim();
642
- edits.push({
643
- start: rhsStart,
644
- end: rhsEnd,
645
- text: generateIIFE(originalExpr, schema, options),
646
- });
647
- }
648
- return edits;
447
+ const edits = [];
448
+ for (const schema of schemas) {
449
+ const escapedName = schema.exportName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
450
+ const match = new RegExp(`((?:export\\s+)?(?:const|let|var)\\s+${escapedName}(?:\\s*:[^=]*)?\\s*=\\s*)`).exec(code);
451
+ if (!match) continue;
452
+ const rhsStart = match.index + match[0].length;
453
+ const rhsEnd = findExpressionEnd(code, rhsStart);
454
+ if (rhsEnd === -1) continue;
455
+ const originalExpr = code.slice(rhsStart, rhsEnd).trim();
456
+ edits.push({
457
+ start: rhsStart,
458
+ end: rhsEnd,
459
+ text: generateIIFE(originalExpr, schema, options)
460
+ });
461
+ }
462
+ return edits;
649
463
  }
650
464
  /**
651
- * Remove the `compile` binding from `import { compile, ... } from "zod-compiler"` statements.
652
- * If `compile` is the only import, the entire import line is removed.
653
- */
654
- export function removeCompileImport(code) {
655
- return applyEdits(code, collectRemoveCompileImportEdits(code));
465
+ * Remove the `compile` binding from `import { compile, ... } from "zod-compiler"` statements.
466
+ * If `compile` is the only import, the entire import line is removed.
467
+ */
468
+ function removeCompileImport(code) {
469
+ return applyEdits(code, collectRemoveCompileImportEdits(code));
656
470
  }
657
471
  /** Edits stripping the `compile` binding from zod-compiler import statements. */
658
472
  function collectRemoveCompileImportEdits(code) {
659
- // Match: import { ... } from "zod-compiler" or 'zod-compiler'
660
- const importPattern = /import\s*\{([^}]*)\}\s*from\s*["']zod-compiler["'];?/g;
661
- const edits = [];
662
- for (const match of code.matchAll(importPattern)) {
663
- const imports = match[1] ?? "";
664
- const names = imports
665
- .split(",")
666
- .map((n) => n.trim())
667
- .filter(Boolean);
668
- const remaining = names.filter((n) => n !== "compile");
669
- const text = remaining.length === 0 ? "" : `import { ${remaining.join(", ")} } from "zod-compiler";`;
670
- if (text !== match[0]) {
671
- edits.push({ start: match.index, end: match.index + match[0].length, text });
672
- }
673
- }
674
- return edits;
473
+ const importPattern = /import\s*\{([^}]*)\}\s*from\s*["']zod-compiler["'];?/g;
474
+ const edits = [];
475
+ for (const match of code.matchAll(importPattern)) {
476
+ const remaining = (match[1] ?? "").split(",").map((n) => n.trim()).filter(Boolean).filter((n) => n !== "compile");
477
+ const text = remaining.length === 0 ? "" : `import { ${remaining.join(", ")} } from "zod-compiler";`;
478
+ if (text !== match[0]) edits.push({
479
+ start: match.index,
480
+ end: match.index + match[0].length,
481
+ text
482
+ });
483
+ }
484
+ return edits;
675
485
  }
486
+ //#endregion
487
+ export { HAS_RUNTIME_ZOD_IMPORT, TRANSFORM_ID_FILTER, findExpressionEnd, log, removeCompileImport, rewriteSource, rewriteSourceAutoDiscover, shouldTransform, transformCode, transformCodeFilter, transformCodeWithMap };
488
+
676
489
  //# sourceMappingURL=transform.js.map