zod-compiler 1.23.1 → 1.23.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.
Files changed (494) hide show
  1. package/README.md +12 -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 +508 -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 +9 -3
  178. package/dist/core/codegen/schemas/string-bool.d.ts.map +1 -1
  179. package/dist/core/codegen/schemas/string-bool.js +34 -26
  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 +96 -93
  426. package/dist/unplugin/disk-cache.d.ts.map +1 -1
  427. package/dist/unplugin/disk-cache.js +420 -473
  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,642 +1,580 @@
1
- /**
2
- * Build Path: one uninstrumented pass that VALIDATES and BUILDS the stripped
3
- * output together, abandoning the whole parse at the first failing check.
4
- *
5
- * `z.object()` strips unknown keys, so a successful parse cannot return the
6
- * input by reference — it must produce a fresh object. That rules out the Fast
7
- * Path (whose contract is `data === input`), and before this the only remaining
8
- * option was the eager slow walk: a fully instrumented traversal that collects
9
- * issues on every parse, valid or not.
10
- *
11
- * Two passes are wasteful in either direction. Validating first and building
12
- * afterwards reads every property twice (measured 29.7 ns vs 21.6 for the slow
13
- * walk on a 6-field object). Building with issue collection pays the
14
- * instrumentation even when nothing fails. Doing both in ONE pass, with a
15
- * sentinel instead of an issues array, beats both — and a failure costs only
16
- * the checks up to the first bad one, because the issue-producing walk is
17
- * deferred into `.error` exactly as `__zcFinD` does for mutation-free schemas:
18
- *
19
- * object clean object invalid array(8) invalid
20
- * slow walk 21.6 ns 30.4 ns 197.5 ns
21
- * build path 18.1 ns 7.7 ns 9.8 ns
22
- *
23
- * A subtree that rebuilds nothing is validated with its existing Fast Path
24
- * expression and passed through by reference, so only nodes that genuinely
25
- * produce a new value need code here; anything else returns null and keeps the
26
- * eager walk.
27
- *
28
- * Coverage is what decides whether this pass is reached at all, because it is
29
- * all-or-nothing per schema: ONE unmodelled node anywhere in the tree costs the
30
- * whole schema its single-pass parse. Modelled, beyond the stripping containers
31
- * this started with: array size checks and `.refine()`, object-level `.refine()`,
32
- * `.default()` substitution, ordered string rewrites (`.trim()`,
33
- * `.toLowerCase()`), and sync `.transform()`. Still declined, via
34
- * {@link mutatesBeyondStrip} — coerce, `.catch()` (its callback wants the inner
35
- * schema's issue list, which this pass never builds), `z.url()`, and
36
- * `superRefine`.
37
- */
38
- import { declareFastTemps, emitEffectCallable, emitEffectFn, emitRuntimeHelper, emitTemp, escapeString, keyMembershipTest, outputAlwaysDefined, rejectsUndefined, } from "./context.js";
39
- import { createFastGen, generateFast } from "./fast-path.js";
40
- import { EXTRACT_CAP, estimateFastCost, MIN_EXTRACT, predictedInlineSize } from "./fast-size.js";
1
+ import { declareFastTemps, emitEffectCallable, emitEffectFn, emitRuntimeHelper, emitTemp, escapeString, keyMembershipTest, outputAlwaysDefined, rejectsUndefined } from "./context.js";
41
2
  import { ZC_HOP_DECL } from "./issue-decls.js";
42
3
  import { defaultValueExpr, needsPostInnerDefault } from "./schemas/default.js";
4
+ import { estimateFastCost, predictedInlineSize } from "./fast-size.js";
43
5
  import { innerAppliesDefaultOnUndefined } from "./schemas/optional.js";
44
6
  import { fastStringCheck } from "./schemas/string.js";
7
+ import { emitStringBoolMap, stringBoolUsesInline } from "./schemas/string-bool.js";
8
+ import { createFastGen, generateFast } from "./fast-path.js";
9
+ //#region src/core/codegen/build-path.ts
45
10
  /**
46
- * Which nodes of `root` produce a value that is not their input — i.e. are, or
47
- * contain, a stripping object. Everything else can be validated in place and
48
- * passed through, which is what keeps this generator small.
49
- *
50
- * Computed as a fixpoint rather than a plain walk because of recursion: a
51
- * `recursiveRef` is a back-edge with no children, so a local walk reads false
52
- * for it and would pass the whole recursive subtree through by reference —
53
- * leaving every nested value unstripped while the outermost one was rebuilt.
54
- * Resolving the ref against its target closes the cycle, and iterating to a
55
- * fixpoint settles the mutual dependency between the two.
56
- */
11
+ * Which nodes of `root` produce a value that is not their input — a stripping
12
+ * object, coercion, codec, default, overwrite or transform, including
13
+ * containers that contain one. Everything else can be validated in place and
14
+ * passed through, which is what keeps this generator small.
15
+ *
16
+ * Computed as a fixpoint rather than a plain walk because of recursion: a
17
+ * `recursiveRef` is a back-edge with no children, so a local walk reads false
18
+ * for it and would pass the whole recursive subtree through by reference —
19
+ * leaving every nested value unstripped while the outermost one was rebuilt.
20
+ * Resolving the ref against its target closes the cycle, and iterating to a
21
+ * fixpoint settles the mutual dependency between the two.
22
+ */
57
23
  function rebuildSet(root) {
58
- const targets = new Map([[0, root]]);
59
- const nodes = [];
60
- const seen = new Set();
61
- const collect = (node) => {
62
- if (seen.has(node))
63
- return;
64
- seen.add(node);
65
- nodes.push(node);
66
- if (node.type === "recursionTarget")
67
- targets.set(node.refId, node.inner);
68
- for (const child of children(node))
69
- collect(child);
70
- };
71
- collect(root);
72
- const rebuilds = new Set();
73
- for (let changed = true; changed;) {
74
- changed = false;
75
- for (const node of nodes) {
76
- if (rebuilds.has(node))
77
- continue;
78
- const target = node.type === "recursiveRef" ? targets.get(node.refId ?? 0) : undefined;
79
- const rebuild = (node.type === "object" && node.stripUnknownKeys === true) ||
80
- // `.default()` substitutes its own value for `undefined`, so its output
81
- // is not its input even when the inner schema passes through — it must
82
- // never be handed to `passthrough`, whose fast check would reject the
83
- // absent value outright.
84
- node.type === "default" ||
85
- // An overwrite effect (`.trim()`, `.toLowerCase()`) rewrites the string,
86
- // so the node's output is a new value: it has to be BUILT rather than
87
- // validated in place (see buildString).
88
- (node.type === "string" && node.checks.some((c) => c.kind === "overwrite_effect")) ||
89
- // `.transform(fn)` replaces the value with the callback's result.
90
- node.type === "effect" ||
91
- (target !== undefined && rebuilds.has(target)) ||
92
- children(node).some((child) => rebuilds.has(child));
93
- if (rebuild) {
94
- rebuilds.add(node);
95
- changed = true;
96
- }
97
- }
98
- }
99
- return rebuilds;
24
+ const targets = /* @__PURE__ */ new Map([[0, root]]);
25
+ const nodes = [];
26
+ const seen = /* @__PURE__ */ new Set();
27
+ const collect = (node) => {
28
+ if (seen.has(node)) return;
29
+ seen.add(node);
30
+ nodes.push(node);
31
+ if (node.type === "recursionTarget") targets.set(node.refId, node.inner);
32
+ for (const child of children(node)) collect(child);
33
+ };
34
+ collect(root);
35
+ const rebuilds = /* @__PURE__ */ new Set();
36
+ for (let changed = true; changed;) {
37
+ changed = false;
38
+ for (const node of nodes) {
39
+ if (rebuilds.has(node)) continue;
40
+ const target = node.type === "recursiveRef" ? targets.get(node.refId ?? 0) : void 0;
41
+ if (node.type === "object" && node.stripUnknownKeys === true || node.type === "default" || node.type === "stringBool" || node.type === "string" && (node.coerce === true || node.checks.some((c) => c.kind === "overwrite_effect")) || (node.type === "number" || node.type === "boolean" || node.type === "bigint" || node.type === "date") && node.coerce === true || node.type === "effect" || target !== void 0 && rebuilds.has(target) || children(node).some((child) => rebuilds.has(child))) {
42
+ rebuilds.add(node);
43
+ changed = true;
44
+ }
45
+ }
46
+ }
47
+ return rebuilds;
100
48
  }
101
49
  /** Does `ir`, taken as a whole schema, produce a value that is not its input? */
102
- export function rebuildsOutput(ir) {
103
- return rebuildSet(ir).has(ir);
50
+ function rebuildsOutput(ir) {
51
+ return rebuildSet(ir).has(ir);
104
52
  }
105
53
  /**
106
- * True when the subtree mutates for any reason the build pass cannot reproduce —
107
- * coerce, `.catch()`, `z.url()`, `superRefine`. Those rewrite values in ways this
108
- * pass (which validates, substitutes declared defaults, applies ordered string
109
- * rewrites and copies) does not model, so the schema keeps the eager walk.
110
- */
54
+ * True when the subtree mutates for any reason the build pass cannot reproduce —
55
+ * `.catch()`, `z.url()`, `superRefine`. Those rewrite values in ways this pass
56
+ * (which validates, coerces, decodes string booleans, substitutes declared
57
+ * defaults, applies ordered string rewrites and copies) does not model, so the
58
+ * schema keeps the eager walk.
59
+ */
111
60
  function mutatesBeyondStrip(ir) {
112
- return mutatesHere(ir) || children(ir).some(mutatesBeyondStrip);
61
+ return mutatesHere(ir) || children(ir).some(mutatesBeyondStrip);
113
62
  }
114
63
  /**
115
- * Does this node rewrite values on its own account (ignoring its children, and
116
- * ignoring the reshaping a strip object does)? Mirrors the node-local half of
117
- * `hasMutation`; the recursion above supplies the other half.
118
- */
64
+ * Does this node rewrite values on its own account (ignoring its children, and
65
+ * ignoring the reshaping a strip object does)? Mirrors the node-local half of
66
+ * `hasMutation`; the recursion above supplies the other half.
67
+ */
119
68
  function mutatesHere(ir) {
120
- switch (ir.type) {
121
- case "string":
122
- // Overwrite effects are absent: `buildString` applies them in order. A
123
- // `z.url()` check still is not — it trims, normalizes and needs try/catch.
124
- return (ir.coerce === true ||
125
- superRefines(ir.checks) ||
126
- ir.checks.some((c) => c.kind === "string_format" && c.format === "url"));
127
- case "number":
128
- return ir.coerce === true || superRefines(ir.checks);
129
- case "boolean":
130
- case "bigint":
131
- case "date":
132
- return ir.coerce === true;
133
- // `default` and `effect` are absent: substituting a constant for `undefined`
134
- // and applying a sync transform are both modelled (see buildDefault /
135
- // buildEffect), and their inners are reached through `children`.
136
- //
137
- // `catch` is NOT: its catchValue callback receives a ctx carrying the inner
138
- // schema's collected issues, and this pass produces a sentinel instead of an
139
- // issue list — there is nothing to hand it.
140
- case "catch":
141
- case "fallback":
142
- case "stringBool":
143
- return true;
144
- case "object":
145
- case "array":
146
- return superRefines(ir.checks);
147
- default:
148
- return false;
149
- }
69
+ switch (ir.type) {
70
+ case "string": return superRefines(ir.checks) || ir.checks.some((c) => c.kind === "string_format" && c.format === "url");
71
+ case "number": return superRefines(ir.checks);
72
+ case "boolean":
73
+ case "bigint":
74
+ case "date": return false;
75
+ case "catch":
76
+ case "fallback": return true;
77
+ case "object":
78
+ case "array": return superRefines(ir.checks);
79
+ default: return false;
80
+ }
150
81
  }
151
82
  function superRefines(checks) {
152
- return checks !== undefined && checks.some((c) => c.kind === "super_refine_effect");
83
+ return checks !== void 0 && checks.some((c) => c.kind === "super_refine_effect");
153
84
  }
154
85
  function children(ir) {
155
- switch (ir.type) {
156
- case "object":
157
- return ir.catchall
158
- ? [...Object.values(ir.properties), ir.catchall]
159
- : Object.values(ir.properties);
160
- case "array":
161
- return [ir.element];
162
- case "tuple":
163
- return ir.rest === null ? ir.items : [...ir.items, ir.rest];
164
- case "record":
165
- case "map":
166
- return [ir.keyType, ir.valueType];
167
- case "set":
168
- return [ir.valueType];
169
- case "union":
170
- case "discriminatedUnion":
171
- return ir.options;
172
- case "intersection":
173
- return [ir.left, ir.right];
174
- case "optional":
175
- case "nullable":
176
- case "readonly":
177
- case "default":
178
- case "catch":
179
- case "effect":
180
- case "recursionTarget":
181
- return [ir.inner];
182
- case "pipe":
183
- return [ir.in, ir.out];
184
- default:
185
- return [];
186
- }
86
+ switch (ir.type) {
87
+ case "object": return ir.catchall ? [...Object.values(ir.properties), ir.catchall] : Object.values(ir.properties);
88
+ case "array": return [ir.element];
89
+ case "tuple": return ir.rest === null ? ir.items : [...ir.items, ir.rest];
90
+ case "record":
91
+ case "map": return [ir.keyType, ir.valueType];
92
+ case "set": return [ir.valueType];
93
+ case "union":
94
+ case "discriminatedUnion": return ir.options;
95
+ case "intersection": return [ir.left, ir.right];
96
+ case "optional":
97
+ case "nullable":
98
+ case "readonly":
99
+ case "default":
100
+ case "catch":
101
+ case "effect":
102
+ case "recursionTarget": return [ir.inner];
103
+ case "pipe": return [ir.in, ir.out];
104
+ default: return [];
105
+ }
187
106
  }
188
107
  /**
189
- * Host the whole schema as `function NAME(input){…}` returning the built value
190
- * or the FAIL sentinel. Returns the function name, or null when the schema is
191
- * not expressible as a single build pass.
192
- */
193
- export function generateBuild(ir, ctx) {
194
- const rebuilds = rebuildSet(ir);
195
- if (!rebuilds.has(ir) || mutatesBeyondStrip(ir))
196
- return null;
197
- const fail = emitFailSentinel(ctx);
198
- const scope = { temps: [], used: 0 };
199
- const built = build(ir, "input", { ctx, extractable: false, fail, rebuilds, scope });
200
- if (built === null)
201
- return null;
202
- const name = emitTemp(ctx, "vb");
203
- ctx.preamble.push(`function ${name}(input){${declareFastTemps(scope)}${built.code}return ${built.value};}`);
204
- return name;
108
+ * Host the whole schema as `function NAME(input){…}` returning the built value
109
+ * or the FAIL sentinel. Returns the function name, or null when the schema is
110
+ * not expressible as a single build pass.
111
+ */
112
+ function generateBuild(ir, ctx) {
113
+ const rebuilds = rebuildSet(ir);
114
+ if (!rebuilds.has(ir) || mutatesBeyondStrip(ir)) return null;
115
+ const fail = emitFailSentinel(ctx);
116
+ const scope = {
117
+ temps: [],
118
+ used: 0
119
+ };
120
+ const built = build(ir, "input", {
121
+ ctx,
122
+ extractable: false,
123
+ fail,
124
+ rebuilds,
125
+ scope
126
+ });
127
+ if (built === null) return null;
128
+ const name = emitTemp(ctx, "vb");
129
+ ctx.preamble.push(`function ${name}(input){${declareFastTemps(scope)}${built.code}return ${built.value};}`);
130
+ return name;
205
131
  }
206
132
  /** One `{}` per validator, compared by identity — no parse output can equal it. */
207
133
  function emitFailSentinel(ctx) {
208
- if (ctx.buildFailName === undefined) {
209
- ctx.buildFailName = `__bf_${ctx.counter++}`;
210
- ctx.preamble.push(`var ${ctx.buildFailName}={};`);
211
- }
212
- return ctx.buildFailName;
134
+ if (ctx.buildFailName === void 0) {
135
+ ctx.buildFailName = `__bf_${ctx.counter++}`;
136
+ ctx.preamble.push(`var ${ctx.buildFailName}={};`);
137
+ }
138
+ return ctx.buildFailName;
213
139
  }
214
140
  /**
215
- * Statements producing the built value of `ir` read from `input`, or null.
216
- *
217
- * Size-gated exactly like the fast path: once inlining `ir` would push the
218
- * function being assembled past EXTRACT_CAP, the sub-build is hosted as its own
219
- * `__vb_N(p)` returning value-or-FAIL and replaced by a call. Without this a
220
- * deeply nested schema emits one enormous build function — measured at 113 KB
221
- * and 354 KB on the deep fixtures — far past the bytecode size where V8 stops
222
- * running TurboFan on it, which would forfeit the speed this path exists for.
223
- */
141
+ * Statements producing the built value of `ir` read from `input`, or null.
142
+ *
143
+ * Size-gated exactly like the fast path: once inlining `ir` would push the
144
+ * function being assembled past EXTRACT_CAP, the sub-build is hosted as its own
145
+ * `__vb_N(p)` returning value-or-FAIL and replaced by a call. Without this a
146
+ * deeply nested schema emits one enormous build function — measured at 113 KB
147
+ * and 354 KB on the deep fixtures — far past the bytecode size where V8 stops
148
+ * running TurboFan on it, which would forfeit the speed this path exists for.
149
+ */
224
150
  function build(ir, input, g) {
225
- // Resolved before the passthrough shortcut below. A back-edge carries no
226
- // children, so `rebuildsOutput` reads false for it — and passing it through by
227
- // reference would leave every nested recursive value unstripped while the
228
- // outermost one was rebuilt.
229
- if (ir.type === "recursiveRef")
230
- return buildRecursiveCall(ir.refId ?? 0, input, g);
231
- if (ir.type === "recursionTarget")
232
- return buildRecursionTarget(ir, input, g);
233
- if (!g.rebuilds.has(ir))
234
- return passthrough(ir, input, g);
235
- const cache = (g.ctx.fastSizeCache ??= new WeakMap());
236
- if (g.extractable &&
237
- g.scope.used + predictedInlineSize(ir, input.length, cache) > EXTRACT_CAP &&
238
- (g.scope.used > EXTRACT_CAP || estimateFastCost(ir, cache) >= MIN_EXTRACT)) {
239
- const hosted = hostBuild(ir, g);
240
- if (hosted !== null) {
241
- const slot = local(g, "bh");
242
- const code = `${slot}=${hosted}(${input});if(${slot}===${g.fail})return ${g.fail};`;
243
- g.scope.used += code.length;
244
- return { code, value: slot };
245
- }
246
- }
247
- // This node's extraction decision is made; its descendants get to make their
248
- // own, so an oversized hosted helper keeps splitting.
249
- const before = g.scope.used;
250
- const out = buildInline(ir, input, { ...g, extractable: true });
251
- if (out !== null)
252
- g.scope.used = before + out.code.length;
253
- return out;
151
+ if (ir.type === "recursiveRef") return buildRecursiveCall(ir.refId ?? 0, input, g);
152
+ if (ir.type === "recursionTarget") return buildRecursionTarget(ir, input, g);
153
+ if (!g.rebuilds.has(ir)) return passthrough(ir, input, g);
154
+ const cache = g.ctx.fastSizeCache ??= /* @__PURE__ */ new WeakMap();
155
+ if (g.extractable && g.scope.used + predictedInlineSize(ir, input.length, cache) > 38e3 && (g.scope.used > 38e3 || estimateFastCost(ir, cache) >= 1200)) {
156
+ const hosted = hostBuild(ir, g);
157
+ if (hosted !== null) {
158
+ const slot = local(g, "bh");
159
+ const code = `${slot}=${hosted}(${input});if(${slot}===${g.fail})return ${g.fail};`;
160
+ g.scope.used += code.length;
161
+ return {
162
+ code,
163
+ value: slot
164
+ };
165
+ }
166
+ }
167
+ const before = g.scope.used;
168
+ const out = buildInline(ir, input, {
169
+ ...g,
170
+ extractable: true
171
+ });
172
+ if (out !== null) g.scope.used = before + out.code.length;
173
+ return out;
254
174
  }
255
175
  /** Host `ir`'s build in its own function over a fresh parameter; returns its name. */
256
176
  function hostBuild(ir, g) {
257
- const param = emitTemp(g.ctx, "bp");
258
- const scope = { temps: [], used: 0 };
259
- const inner = build(ir, param, { ...g, extractable: false, scope });
260
- if (inner === null)
261
- return null;
262
- const name = emitTemp(g.ctx, "vb");
263
- g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}${inner.code}return ${inner.value};}`);
264
- return name;
177
+ const param = emitTemp(g.ctx, "bp");
178
+ const scope = {
179
+ temps: [],
180
+ used: 0
181
+ };
182
+ const inner = build(ir, param, {
183
+ ...g,
184
+ extractable: false,
185
+ scope
186
+ });
187
+ if (inner === null) return null;
188
+ const name = emitTemp(g.ctx, "vb");
189
+ g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}${inner.code}return ${inner.value};}`);
190
+ return name;
265
191
  }
266
192
  function buildInline(ir, input, g) {
267
- switch (ir.type) {
268
- case "object":
269
- return buildObject(ir, input, g);
270
- case "array":
271
- return buildArray(ir, input, g);
272
- case "tuple":
273
- return buildTuple(ir, input, g);
274
- case "record":
275
- return buildRecord(ir, input, g);
276
- case "optional":
277
- // A default further down the chain consumes undefined into a value, so
278
- // the `undefined → undefined` shortcut must not fire — same rule (and
279
- // same helper) the slow and fast paths already apply.
280
- return innerAppliesDefaultOnUndefined(ir.inner)
281
- ? build(ir.inner, input, g)
282
- : buildSentinel(ir.inner, input, g, "===undefined", "undefined");
283
- case "nullable":
284
- // `null` short-circuits unconditionally in zod, whatever the inner is;
285
- // undefined flows through, so an inner default still fires.
286
- return buildSentinel(ir.inner, input, g, "===null", "null");
287
- case "default":
288
- return buildDefault(ir, input, g);
289
- case "string":
290
- return buildString(ir, input, g);
291
- case "effect":
292
- return buildEffect(ir, input, g);
293
- case "readonly":
294
- return build(ir.inner, input, g);
295
- case "union":
296
- case "discriminatedUnion":
297
- return buildUnion(ir, input, g);
298
- default:
299
- // A rebuilding intersection, map or set: expressible in principle, but
300
- // each needs its own output-shaping rules, so they keep the eager walk
301
- // until there is a measured reason to add them.
302
- return null;
303
- }
193
+ switch (ir.type) {
194
+ case "object": return buildObject(ir, input, g);
195
+ case "array": return buildArray(ir, input, g);
196
+ case "tuple": return buildTuple(ir, input, g);
197
+ case "record": return buildRecord(ir, input, g);
198
+ case "optional": return innerAppliesDefaultOnUndefined(ir.inner) ? build(ir.inner, input, g) : buildSentinel(ir.inner, input, g, "===undefined", "undefined");
199
+ case "nullable": return buildSentinel(ir.inner, input, g, "===null", "null");
200
+ case "default": return buildDefault(ir, input, g);
201
+ case "string": return buildString(ir, input, g);
202
+ case "stringBool": return buildStringBool(ir, input, g);
203
+ case "number":
204
+ case "boolean":
205
+ case "bigint":
206
+ case "date": return buildCoercedPrimitive(ir, input, g);
207
+ case "effect": return buildEffect(ir, input, g);
208
+ case "readonly": return build(ir.inner, input, g);
209
+ case "union":
210
+ case "discriminatedUnion": return buildUnion(ir, input, g);
211
+ default: return null;
212
+ }
304
213
  }
305
214
  /**
306
- * Host the target's build once under a name registered BEFORE its body is
307
- * generated, so the back-edges inside that body resolve to it.
308
- */
215
+ * Host the target's build once under a name registered BEFORE its body is
216
+ * generated, so the back-edges inside that body resolve to it.
217
+ */
309
218
  function buildRecursionTarget(ir, input, g) {
310
- const table = (g.ctx.buildRecNames ??= new Map());
311
- if (!table.has(ir.refId)) {
312
- const name = emitTemp(g.ctx, "vbr");
313
- table.set(ir.refId, name);
314
- const param = emitTemp(g.ctx, "bp");
315
- const scope = { temps: [], used: 0 };
316
- const inner = build(ir.inner, param, { ...g, extractable: false, scope });
317
- if (inner === null) {
318
- table.delete(ir.refId);
319
- return null;
320
- }
321
- g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}${inner.code}return ${inner.value};}`);
322
- }
323
- return buildRecursiveCall(ir.refId, input, g);
219
+ const table = g.ctx.buildRecNames ??= /* @__PURE__ */ new Map();
220
+ if (!table.has(ir.refId)) {
221
+ const name = emitTemp(g.ctx, "vbr");
222
+ table.set(ir.refId, name);
223
+ const param = emitTemp(g.ctx, "bp");
224
+ const scope = {
225
+ temps: [],
226
+ used: 0
227
+ };
228
+ const inner = build(ir.inner, param, {
229
+ ...g,
230
+ extractable: false,
231
+ scope
232
+ });
233
+ if (inner === null) {
234
+ table.delete(ir.refId);
235
+ return null;
236
+ }
237
+ g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}${inner.code}return ${inner.value};}`);
238
+ }
239
+ return buildRecursiveCall(ir.refId, input, g);
324
240
  }
325
241
  /** Call the hosted build for a recursion target, propagating its FAIL. */
326
242
  function buildRecursiveCall(refId, input, g) {
327
- const name = g.ctx.buildRecNames?.get(refId);
328
- if (name === undefined)
329
- return null;
330
- const slot = local(g, "bh");
331
- return {
332
- code: `${slot}=${name}(${input});if(${slot}===${g.fail})return ${g.fail};`,
333
- value: slot,
334
- };
243
+ const name = g.ctx.buildRecNames?.get(refId);
244
+ if (name === void 0) return null;
245
+ const slot = local(g, "bh");
246
+ return {
247
+ code: `${slot}=${name}(${input});if(${slot}===${g.fail})return ${g.fail};`,
248
+ value: slot
249
+ };
335
250
  }
336
251
  /**
337
- * Try each option in declaration order and take the first that builds — which
338
- * is what zod's union does with the first option that parses.
339
- *
340
- * Every option is HOSTED rather than inlined, and that is load-bearing: a
341
- * failing build signals with `return FAIL`, which inside the enclosing function
342
- * would abandon the whole parse instead of moving on to the next option. Behind
343
- * a call, the same signal is just a value to test.
344
- *
345
- * A discriminated union gets the same treatment rather than a switch: the
346
- * options still have to be probed by call, and its dispatch advantage is
347
- * already spent by the enclosing container's own work.
348
- */
252
+ * Try each option in declaration order and take the first that builds — which
253
+ * is what zod's union does with the first option that parses.
254
+ *
255
+ * Every option is HOSTED rather than inlined, and that is load-bearing: a
256
+ * failing build signals with `return FAIL`, which inside the enclosing function
257
+ * would abandon the whole parse instead of moving on to the next option. Behind
258
+ * a call, the same signal is just a value to test.
259
+ *
260
+ * A discriminated union gets the same treatment rather than a switch: the
261
+ * options still have to be probed by call, and its dispatch advantage is
262
+ * already spent by the enclosing container's own work.
263
+ */
349
264
  function buildUnion(ir, input, g) {
350
- const hosted = [];
351
- for (const option of ir.options) {
352
- const fn = g.rebuilds.has(option) ? hostBuild(option, g) : hostPassthrough(option, g);
353
- if (fn === null)
354
- return null;
355
- hosted.push(fn);
356
- }
357
- if (hosted.length === 0)
358
- return null;
359
- const out = local(g, "bu");
360
- let code = `${out}=${hosted[0]}(${input});`;
361
- for (const fn of hosted.slice(1)) {
362
- code += `if(${out}===${g.fail}){${out}=${fn}(${input});}`;
363
- }
364
- code += `if(${out}===${g.fail})return ${g.fail};`;
365
- return { code, value: out };
265
+ const hosted = [];
266
+ for (const option of ir.options) {
267
+ const fn = g.rebuilds.has(option) ? hostBuild(option, g) : hostPassthrough(option, g);
268
+ if (fn === null) return null;
269
+ hosted.push(fn);
270
+ }
271
+ if (hosted.length === 0) return null;
272
+ const out = local(g, "bu");
273
+ let code = `${out}=${hosted[0]}(${input});`;
274
+ for (const fn of hosted.slice(1)) code += `if(${out}===${g.fail}){${out}=${fn}(${input});}`;
275
+ code += `if(${out}===${g.fail})return ${g.fail};`;
276
+ return {
277
+ code,
278
+ value: out
279
+ };
366
280
  }
367
281
  /**
368
- * Host a non-rebuilding option as `value-or-FAIL`, so a union can probe it with
369
- * the same protocol as a rebuilding one.
370
- */
282
+ * Host a non-rebuilding option as `value-or-FAIL`, so a union can probe it with
283
+ * the same protocol as a rebuilding one.
284
+ */
371
285
  function hostPassthrough(ir, g) {
372
- const param = emitTemp(g.ctx, "bp");
373
- const scope = { temps: [], used: 0 };
374
- const expr = generateFast(ir, createFastGen(param, g.ctx, true, scope));
375
- if (expr === null)
376
- return null;
377
- const name = emitTemp(g.ctx, "vp");
378
- g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}return ${expr === "true" ? param : `(${expr})?${param}:${g.fail}`};}`);
379
- return name;
286
+ const param = emitTemp(g.ctx, "bp");
287
+ const scope = {
288
+ temps: [],
289
+ used: 0
290
+ };
291
+ const expr = generateFast(ir, createFastGen(param, g.ctx, true, scope));
292
+ if (expr === null) return null;
293
+ const name = emitTemp(g.ctx, "vp");
294
+ g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}return ${expr === "true" ? param : `(${expr})?${param}:${g.fail}`};}`);
295
+ return name;
380
296
  }
381
297
  /** Validate in place with the Fast Path and hand the input straight back. */
382
298
  function passthrough(ir, input, g) {
383
- const scoped = createFastGen(input, g.ctx, true, g.scope);
384
- const expr = generateFast(ir, scoped);
385
- if (expr === null)
386
- return null;
387
- return { code: expr === "true" ? "" : `if(!(${expr}))return ${g.fail};`, value: input };
299
+ const expr = generateFast(ir, createFastGen(input, g.ctx, true, g.scope));
300
+ if (expr === null) return null;
301
+ return {
302
+ code: expr === "true" ? "" : `if(!(${expr}))return ${g.fail};`,
303
+ value: input
304
+ };
388
305
  }
389
306
  /**
390
- * Rebuild from the declared keys. Sound for a stripping object (that IS the
391
- * output) and for a strict one (unknown keys are rejected, so the declared keys
392
- * are the whole key set). A loose object or one with a `.catchall()` keeps keys
393
- * this pass does not enumerate, so those bail.
394
- */
307
+ * Rebuild from the declared keys. Sound for a stripping object (that IS the
308
+ * output) and for a strict one (unknown keys are rejected, so the declared keys
309
+ * are the whole key set). A loose object or one with a `.catchall()` keeps keys
310
+ * this pass does not enumerate, so those bail.
311
+ */
395
312
  function buildObject(ir, input, g) {
396
- if (ir.catchall !== undefined)
397
- return null;
398
- if (ir.stripUnknownKeys !== true && ir.strict !== true)
399
- return null;
400
- if (ir.suppressAbsentKeys !== undefined && ir.suppressAbsentKeys.length > 0)
401
- return null;
402
- // Object-level `.refine()` runs on the assembled output (below). superRefine
403
- // rewrites the payload, which this pass does not model — mutatesBeyondStrip
404
- // already rejects it, so this is a belt-and-braces narrowing of the type.
405
- const refines = ir.checks ?? [];
406
- if (refines.some((check) => check.kind !== "refine_effect"))
407
- return null;
408
- let code = `if(typeof ${input}!=="object"||${input}===null||Array.isArray(${input}))return ${g.fail};`;
409
- if (ir.strict === true) {
410
- const keyVar = local(g, "bk");
411
- code += `for(${keyVar} in ${input}){if(!(${keyMembershipTest(g.ctx, Object.keys(ir.properties), keyVar)}))return ${g.fail};}`;
412
- }
413
- const slots = [];
414
- for (const [key, propIR] of Object.entries(ir.properties)) {
415
- const keyStr = escapeString(key);
416
- const slot = local(g, "bv");
417
- code += `${slot}=${input}[${keyStr}];`;
418
- const propBuilt = build(propIR, slot, g);
419
- if (propBuilt === null)
420
- return null;
421
- code += propBuilt.code;
422
- slots.push({ always: outputAlwaysDefined(propIR), keyStr, value: propBuilt.value });
423
- }
424
- // Same assembly the eager strip walk uses: the longest LEADING run of
425
- // always-present keys goes into one object literal (V8 stamps it from a
426
- // cached boilerplate map in a single allocation), and everything after the
427
- // first conditional key is appended so insertion order still matches zod.
428
- // The per-key test is zod's own — keep the key when the parsed value is
429
- // defined, or when it was present on the input at all.
430
- const out = local(g, "bo");
431
- const literal = [];
432
- let appends = "";
433
- let leading = true;
434
- for (const slot of slots) {
435
- if (leading && slot.always) {
436
- literal.push(`${slot.keyStr}:${slot.value}`);
437
- continue;
438
- }
439
- leading = false;
440
- appends += slot.always
441
- ? `${out}[${slot.keyStr}]=${slot.value};`
442
- : `if(${slot.value}!==undefined||(${slot.keyStr} in ${input})){${out}[${slot.keyStr}]=${slot.value};}`;
443
- }
444
- code += `${out}={${literal.join(",")}};${appends}`;
445
- // Zod parses the properties into the payload first and skips the check chain
446
- // when that produced issues, so a bad property suppresses the refine — which
447
- // this pass gets for free, having already returned FAIL at that property.
448
- for (const check of refines) {
449
- code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
450
- }
451
- return { code, value: out };
313
+ if (ir.catchall !== void 0) return null;
314
+ if (ir.stripUnknownKeys !== true && ir.strict !== true) return null;
315
+ if (ir.suppressAbsentKeys !== void 0 && ir.suppressAbsentKeys.length > 0) return null;
316
+ const refines = ir.checks ?? [];
317
+ if (refines.some((check) => check.kind !== "refine_effect")) return null;
318
+ let code = `if(typeof ${input}!=="object"||${input}===null||Array.isArray(${input}))return ${g.fail};`;
319
+ if (ir.strict === true) {
320
+ const keyVar = local(g, "bk");
321
+ code += `for(${keyVar} in ${input}){if(!(${keyMembershipTest(g.ctx, Object.keys(ir.properties), keyVar)}))return ${g.fail};}`;
322
+ }
323
+ const slots = [];
324
+ for (const [key, propIR] of Object.entries(ir.properties)) {
325
+ const keyStr = escapeString(key);
326
+ const slot = local(g, "bv");
327
+ code += `${slot}=${input}[${keyStr}];`;
328
+ const propBuilt = build(propIR, slot, g);
329
+ if (propBuilt === null) return null;
330
+ code += propBuilt.code;
331
+ slots.push({
332
+ always: outputAlwaysDefined(propIR),
333
+ keyStr,
334
+ value: propBuilt.value
335
+ });
336
+ }
337
+ const out = local(g, "bo");
338
+ const literal = [];
339
+ let appends = "";
340
+ let leading = true;
341
+ for (const slot of slots) {
342
+ if (leading && slot.always) {
343
+ literal.push(`${slot.keyStr}:${slot.value}`);
344
+ continue;
345
+ }
346
+ leading = false;
347
+ appends += slot.always ? `${out}[${slot.keyStr}]=${slot.value};` : `if(${slot.value}!==undefined||(${slot.keyStr} in ${input})){${out}[${slot.keyStr}]=${slot.value};}`;
348
+ }
349
+ code += `${out}={${literal.join(",")}};${appends}`;
350
+ for (const check of refines) code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
351
+ return {
352
+ code,
353
+ value: out
354
+ };
452
355
  }
453
356
  function buildArray(ir, input, g) {
454
- // Length checks are pure predicates over `input.length`, so they hoist ahead
455
- // of the element loop: a size mismatch bails before a single element is
456
- // validated. Zod reports the per-element issue first when both fail, but the
457
- // build pass produces no issues — only the sentinel — and the deferred walk
458
- // that does produce them keeps zod's order.
459
- let sizes = "";
460
- const refines = [];
461
- for (const check of ir.checks) {
462
- switch (check.kind) {
463
- case "min_length":
464
- sizes += `if(${input}.length<${check.minimum})return ${g.fail};`;
465
- break;
466
- case "max_length":
467
- sizes += `if(${input}.length>${check.maximum})return ${g.fail};`;
468
- break;
469
- case "length_equals":
470
- sizes += `if(${input}.length!==${check.length})return ${g.fail};`;
471
- break;
472
- case "refine_effect":
473
- refines.push(check);
474
- break;
475
- default:
476
- // super_refine (rewrites the value) or a check kind not modelled here.
477
- return null;
478
- }
479
- }
480
- const out = local(g, "ba");
481
- const index = local(g, "bi");
482
- const elem = local(g, "be");
483
- const inner = build(ir.element, elem, g);
484
- if (inner === null)
485
- return null;
486
- let code = `if(!Array.isArray(${input}))return ${g.fail};` +
487
- sizes +
488
- `${out}=new Array(${input}.length);` +
489
- `for(${index}=0;${index}<${input}.length;${index}++){` +
490
- `${elem}=${input}[${index}];${inner.code}${out}[${index}]=${inner.value};}`;
491
- // `.refine()` sees the parsed payload, which for a rebuilding element is the
492
- // freshly assembled array — the same value zod hands its checks.
493
- for (const check of refines) {
494
- code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
495
- }
496
- return { code, value: out };
357
+ let sizes = "";
358
+ const refines = [];
359
+ for (const check of ir.checks) switch (check.kind) {
360
+ case "min_length":
361
+ sizes += `if(${input}.length<${check.minimum})return ${g.fail};`;
362
+ break;
363
+ case "max_length":
364
+ sizes += `if(${input}.length>${check.maximum})return ${g.fail};`;
365
+ break;
366
+ case "length_equals":
367
+ sizes += `if(${input}.length!==${check.length})return ${g.fail};`;
368
+ break;
369
+ case "refine_effect":
370
+ refines.push(check);
371
+ break;
372
+ default: return null;
373
+ }
374
+ const out = local(g, "ba");
375
+ const index = local(g, "bi");
376
+ const elem = local(g, "be");
377
+ const inner = build(ir.element, elem, g);
378
+ if (inner === null) return null;
379
+ let code = `if(!Array.isArray(${input}))return ${g.fail};` + sizes + `${out}=new Array(${input}.length);for(${index}=0;${index}<${input}.length;${index}++){${elem}=${input}[${index}];${inner.code}${out}[${index}]=${inner.value};}`;
380
+ for (const check of refines) code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
381
+ return {
382
+ code,
383
+ value: out
384
+ };
497
385
  }
498
386
  function buildTuple(ir, input, g) {
499
- // Trailing-optional and rest handling shape the output length; keep those on
500
- // the eager walk rather than restating the rules here.
501
- if (ir.rest !== null)
502
- return null;
503
- if (ir.items.some((item) => !rejectsUndefined(item)))
504
- return null;
505
- let code = `if(!Array.isArray(${input})||${input}.length!==${ir.items.length})return ${g.fail};`;
506
- const values = [];
507
- for (const [index, itemIR] of ir.items.entries()) {
508
- const slot = local(g, "bt");
509
- code += `${slot}=${input}[${index}];`;
510
- const inner = build(itemIR, slot, g);
511
- if (inner === null)
512
- return null;
513
- code += inner.code;
514
- values.push(inner.value);
515
- }
516
- const out = local(g, "bl");
517
- code += `${out}=[${values.join(",")}];`;
518
- return { code, value: out };
387
+ if (ir.rest !== null) return null;
388
+ if (ir.items.some((item) => !rejectsUndefined(item))) return null;
389
+ let code = `if(!Array.isArray(${input})||${input}.length!==${ir.items.length})return ${g.fail};`;
390
+ const values = [];
391
+ for (const [index, itemIR] of ir.items.entries()) {
392
+ const slot = local(g, "bt");
393
+ code += `${slot}=${input}[${index}];`;
394
+ const inner = build(itemIR, slot, g);
395
+ if (inner === null) return null;
396
+ code += inner.code;
397
+ values.push(inner.value);
398
+ }
399
+ const out = local(g, "bl");
400
+ code += `${out}=[${values.join(",")}];`;
401
+ return {
402
+ code,
403
+ value: out
404
+ };
519
405
  }
520
406
  function buildRecord(ir, input, g) {
521
- const plainStringKey = ir.keyType.type === "string" && ir.keyType.checks.length === 0 && ir.keyType.coerce !== true;
522
- if (!plainStringKey)
523
- return null;
524
- const out = local(g, "br");
525
- const keyVar = local(g, "brk");
526
- const valVar = local(g, "brv");
527
- const inner = build(ir.valueType, valVar, g);
528
- if (inner === null)
529
- return null;
530
- const hop = emitRuntimeHelper(g.ctx, "__zcHop", ZC_HOP_DECL);
531
- const code = `if(typeof ${input}!=="object"||${input}===null||Array.isArray(${input}))return ${g.fail};` +
532
- `${out}={};` +
533
- `for(${keyVar} in ${input}){if(${hop}.call(${input},${keyVar})){` +
534
- `${valVar}=${input}[${keyVar}];${inner.code}${out}[${keyVar}]=${inner.value};}}`;
535
- return { code, value: out };
407
+ if (!(ir.keyType.type === "string" && ir.keyType.checks.length === 0 && ir.keyType.coerce !== true)) return null;
408
+ const out = local(g, "br");
409
+ const keyVar = local(g, "brk");
410
+ const valVar = local(g, "brv");
411
+ const inner = build(ir.valueType, valVar, g);
412
+ if (inner === null) return null;
413
+ const hop = emitRuntimeHelper(g.ctx, "__zcHop", ZC_HOP_DECL);
414
+ return {
415
+ code: `if(typeof ${input}!=="object"||${input}===null||Array.isArray(${input}))return ${g.fail};${out}={};for(${keyVar} in ${input}){if(${hop}.call(${input},${keyVar})){${valVar}=${input}[${keyVar}];${inner.code}${out}[${keyVar}]=${inner.value};}}`,
416
+ value: out
417
+ };
536
418
  }
537
419
  /**
538
- * `.transform(fn)`: validate the inner schema, then hand its parsed value to the
539
- * callback. Zod's transform is a pipe whose `in` failing aborts the whole thing,
540
- * which is exactly what returning FAIL from the inner build does — so the
541
- * callback runs only on a clean parse, as `slowEffect` guarantees with its issue
542
- * count.
543
- *
544
- * The IR reaches here only for a synchronous single-argument callback: a
545
- * `ctx`-taking or async transform is extracted as a `fallback` instead
546
- * (see extractPipe), so there is no parse context to reproduce.
547
- */
420
+ * `.transform(fn)`: validate the inner schema, then hand its parsed value to the
421
+ * callback. Zod's transform is a pipe whose `in` failing aborts the whole thing,
422
+ * which is exactly what returning FAIL from the inner build does — so the
423
+ * callback runs only on a clean parse, as `slowEffect` guarantees with its issue
424
+ * count.
425
+ *
426
+ * The IR reaches here only for a synchronous single-argument callback: a
427
+ * `ctx`-taking or async transform is extracted as a `fallback` instead
428
+ * (see extractPipe), so there is no parse context to reproduce.
429
+ */
548
430
  function buildEffect(ir, input, g) {
549
- const inner = build(ir.inner, input, g);
550
- if (inner === null)
551
- return null;
552
- const out = local(g, "bx");
553
- return {
554
- code: `${inner.code}${out}=${emitEffectCallable(g.ctx, ir)}(${inner.value});`,
555
- value: out,
556
- };
431
+ const inner = build(ir.inner, input, g);
432
+ if (inner === null) return null;
433
+ const out = local(g, "bx");
434
+ return {
435
+ code: `${inner.code}${out}=${emitEffectCallable(g.ctx, ir)}(${inner.value});`,
436
+ value: out
437
+ };
557
438
  }
558
439
  /**
559
- * A string carrying an overwrite effect (`.trim()`, `.toLowerCase()`, ...): the
560
- * checks are emitted one statement at a time in DECLARATION order, interleaved
561
- * with the rewrites, because a rewrite is visible to every check after it —
562
- * `z.string().trim().min(1)` rejects `" "` where `z.string().min(1).trim()`
563
- * accepts it. That ordering is exactly why the fast path, which sorts checks
564
- * cheapest-first and returns the input unchanged, has to decline these.
565
- *
566
- * Only reached for a rewriting string; a check-only one never enters the rebuild
567
- * set and is validated in place by `passthrough`.
568
- */
440
+ * A coercing and/or overwrite string (`z.coerce.string()`, `.trim()`,
441
+ * `.toLowerCase()`, ...): coerce first, then emit checks one statement at a time
442
+ * in DECLARATION order, interleaved with rewrites, because a rewrite is visible
443
+ * to every check after it — `z.string().trim().min(1)` rejects `" "` where
444
+ * `z.string().min(1).trim()` accepts it. That ordering is exactly why the fast
445
+ * path, which sorts checks cheapest-first and returns the input unchanged, has
446
+ * to decline these.
447
+ *
448
+ * Only reached for a rewriting string; a non-coercing, check-only one never
449
+ * enters the rebuild set and is validated in place by `passthrough`.
450
+ */
569
451
  function buildString(ir, input, g) {
570
- if (ir.coerce === true)
571
- return null;
572
- const value = local(g, "bs");
573
- let code = `if(typeof ${input}!=="string")return ${g.fail};${value}=${input};`;
574
- for (const check of ir.checks) {
575
- switch (check.kind) {
576
- case "overwrite_effect":
577
- code += `${value}=${emitEffectFn(g.ctx, check.source)}(${value});`;
578
- break;
579
- case "refine_effect":
580
- code += `if(!${emitEffectCallable(g.ctx, check)}(${value}))return ${g.fail};`;
581
- break;
582
- case "super_refine_effect":
583
- // Rewrites through zod's payload; mutatesBeyondStrip already rejects it.
584
- return null;
585
- default: {
586
- const expr = fastStringCheck(check, value, g.ctx);
587
- if (expr === null)
588
- return null; // z.url(), unknown format
589
- code += `if(!(${expr}))return ${g.fail};`;
590
- }
591
- }
592
- }
593
- return { code, value };
452
+ const value = local(g, "bs");
453
+ let code = ir.coerce === true ? `try{${value}=String(${input});}catch(_){return ${g.fail};}` : `if(typeof ${input}!=="string")return ${g.fail};${value}=${input};`;
454
+ for (const check of ir.checks) switch (check.kind) {
455
+ case "overwrite_effect":
456
+ code += `${value}=${emitEffectFn(g.ctx, check.source)}(${value});`;
457
+ break;
458
+ case "refine_effect":
459
+ code += `if(!${emitEffectCallable(g.ctx, check)}(${value}))return ${g.fail};`;
460
+ break;
461
+ case "super_refine_effect": return null;
462
+ default: {
463
+ const expr = fastStringCheck(check, value, g.ctx);
464
+ if (expr === null) return null;
465
+ code += `if(!(${expr}))return ${g.fail};`;
466
+ }
467
+ }
468
+ return {
469
+ code,
470
+ value
471
+ };
472
+ }
473
+ /**
474
+ * `z.stringbool()`: normalize once, select the declared truthy/falsy side, and
475
+ * return the boolean directly. The ordinary Fast Path cannot host this codec
476
+ * because its contract returns the original input by reference; the build path
477
+ * is designed for exactly this kind of small output rewrite.
478
+ */
479
+ function buildStringBool(ir, input, g) {
480
+ let code = `if(typeof ${input}!=="string")return ${g.fail};`;
481
+ let normalized = input;
482
+ if (!ir.caseSensitive) {
483
+ normalized = local(g, "bn");
484
+ code += `${normalized}=${input}.toLowerCase();`;
485
+ }
486
+ const out = local(g, "bb");
487
+ if (stringBoolUsesInline(ir)) {
488
+ const membership = (values) => values.map((value) => `${normalized}===${escapeString(value)}`).join("||");
489
+ code += `if(${membership(ir.truthy)}){${out}=true;}else if(${membership(ir.falsy)}){${out}=false;}else{return ${g.fail};}`;
490
+ } else {
491
+ const lookup = emitStringBoolMap(ir, g.ctx);
492
+ code += `${out}=${lookup}.get(${normalized});if(${out}===undefined)return ${g.fail};`;
493
+ }
494
+ return {
495
+ code,
496
+ value: out
497
+ };
498
+ }
499
+ /**
500
+ * Coerce once into a local, then reuse the ordinary Fast Path as the acceptance
501
+ * predicate over the converted value. The build path only needs a verdict on
502
+ * its hot pass; if it fails, the existing deferred slow walk reruns the original
503
+ * coercing schema and produces Zod-identical issues.
504
+ *
505
+ * Number/BigInt/Date conversion can invoke user hooks and throw. Zod catches
506
+ * those throws and reports invalid_type, so the sentinel branch does the same
507
+ * without allocating an issue. Boolean never invokes conversion hooks.
508
+ */
509
+ function buildCoercedPrimitive(ir, input, g) {
510
+ if (ir.coerce !== true) return null;
511
+ const value = local(g, "bc");
512
+ let conversion;
513
+ switch (ir.type) {
514
+ case "number":
515
+ conversion = `Number(${input})`;
516
+ break;
517
+ case "boolean":
518
+ conversion = `Boolean(${input})`;
519
+ break;
520
+ case "bigint":
521
+ conversion = `BigInt(${input})`;
522
+ break;
523
+ case "date":
524
+ conversion = `new Date(${input})`;
525
+ break;
526
+ }
527
+ const predicate = generateFast({
528
+ ...ir,
529
+ coerce: false
530
+ }, createFastGen(value, g.ctx, true, g.scope));
531
+ if (predicate === null) return null;
532
+ const assign = `${value}=${conversion};`;
533
+ return {
534
+ code: (ir.type === "boolean" ? assign : `try{${assign}}catch(_){return ${g.fail};}`) + (predicate === "true" ? "" : `if(!(${predicate}))return ${g.fail};`),
535
+ value
536
+ };
594
537
  }
595
538
  /**
596
- * `.default(v)`: `undefined` yields the declared value without running the
597
- * inner schema, anything else parses normally — the same two branches
598
- * `slowDefault` emits, reading the value off the retained schema so a
599
- * reference-typed default keeps zod's identity (one shared object, not a copy).
600
- *
601
- * The substituted value is not validated, so it makes the fast path a PARTIAL
602
- * predicate (`fc(undefined)` is false where the schema accepts) — which is why
603
- * this records {@link CodeGenContext.buildSubstitutesValue}, on which
604
- * `generateValidator` withholds `.is()`.
605
- */
539
+ * `.default(v)`: `undefined` yields the declared value without running the
540
+ * inner schema, anything else parses normally — the same two branches
541
+ * `slowDefault` emits, reading the value off the retained schema so a
542
+ * reference-typed default keeps zod's identity (one shared object, not a copy).
543
+ *
544
+ * The substituted value is not validated, so it makes the fast path a PARTIAL
545
+ * predicate (`fc(undefined)` is false where the schema accepts) — which is why
546
+ * this records {@link CodeGenContext.buildSubstitutesValue}, on which
547
+ * `generateValidator` withholds `.is()`.
548
+ */
606
549
  function buildDefault(ir, input, g) {
607
- const inner = build(ir.inner, input, g);
608
- if (inner === null)
609
- return null;
610
- // Every `default` node is in the rebuild set, so it is always BUILT and never
611
- // passed through — which makes this flag an exact record of whether the
612
- // finished pass substitutes a value.
613
- g.ctx.buildSubstitutesValue = true;
614
- const out = local(g, "bq");
615
- const value = defaultValueExpr(ir);
616
- // Zod re-applies the default when the inner returns undefined for a defined
617
- // input; only emitted when the inner can actually do that.
618
- const reapply = needsPostInnerDefault(ir) ? `if(${out}===undefined){${out}=${value};}` : "";
619
- return {
620
- code: `if(${input}===undefined){${out}=${value};}` +
621
- `else{${inner.code}${out}=${inner.value};${reapply}}`,
622
- value: out,
623
- };
550
+ const inner = build(ir.inner, input, g);
551
+ if (inner === null) return null;
552
+ g.ctx.buildSubstitutesValue = true;
553
+ const out = local(g, "bq");
554
+ const value = defaultValueExpr(ir);
555
+ const reapply = needsPostInnerDefault(ir) ? `if(${out}===undefined){${out}=${value};}` : "";
556
+ return {
557
+ code: `if(${input}===undefined){${out}=${value};}else{${inner.code}${out}=${inner.value};${reapply}}`,
558
+ value: out
559
+ };
624
560
  }
625
561
  /** `optional` / `nullable` around a rebuilding inner: pass the sentinel through. */
626
562
  function buildSentinel(innerIR, input, g, test, sentinel) {
627
- const inner = build(innerIR, input, g);
628
- if (inner === null)
629
- return null;
630
- const out = local(g, "bw");
631
- return {
632
- code: `if(${input}${test}){${out}=${sentinel};}else{${inner.code}${out}=${inner.value};}`,
633
- value: out,
634
- };
563
+ const inner = build(innerIR, input, g);
564
+ if (inner === null) return null;
565
+ const out = local(g, "bw");
566
+ return {
567
+ code: `if(${input}${test}){${out}=${sentinel};}else{${inner.code}${out}=${inner.value};}`,
568
+ value: out
569
+ };
635
570
  }
636
571
  /** Allocate a `var` the hosted build function declares. */
637
572
  function local(g, prefix) {
638
- const name = emitTemp(g.ctx, prefix);
639
- g.scope.temps.push(name);
640
- return name;
573
+ const name = emitTemp(g.ctx, prefix);
574
+ g.scope.temps.push(name);
575
+ return name;
641
576
  }
577
+ //#endregion
578
+ export { generateBuild, rebuildsOutput };
579
+
642
580
  //# sourceMappingURL=build-path.js.map