zod 4.5.4 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/compile.cjs +19 -0
  2. package/index.cjs +19 -0
  3. package/locales/index.cjs +19 -0
  4. package/mini/index.cjs +19 -0
  5. package/package.json +8 -7
  6. package/src/v3/helpers/errorUtil.ts +1 -1
  7. package/src/v4/classic/checks.ts +0 -1
  8. package/src/v4/classic/external.ts +2 -0
  9. package/src/v4/classic/from-json-schema.ts +248 -25
  10. package/src/v4/classic/schemas.ts +255 -164
  11. package/src/v4/classic/tests/assignability.test.ts +59 -9
  12. package/src/v4/classic/tests/bigint.test.ts +6 -0
  13. package/src/v4/classic/tests/continuability.test.ts +2 -2
  14. package/src/v4/classic/tests/cyclic-data.test.ts +274 -0
  15. package/src/v4/classic/tests/enum.test.ts +9 -0
  16. package/src/v4/classic/tests/error.test.ts +130 -1
  17. package/src/v4/classic/tests/firstparty.test.ts +4 -0
  18. package/src/v4/classic/tests/from-json-schema.test.ts +157 -0
  19. package/src/v4/classic/tests/iban.test.ts +81 -0
  20. package/src/v4/classic/tests/instance-footprint.test.ts +18 -2
  21. package/src/v4/classic/tests/instanceof.test.ts +27 -7
  22. package/src/v4/classic/tests/issue-schema.test.ts +88 -56
  23. package/src/v4/classic/tests/object.test.ts +56 -0
  24. package/src/v4/classic/tests/optin-ladder.test.ts +3 -2
  25. package/src/v4/classic/tests/properties.test.ts +225 -0
  26. package/src/v4/classic/tests/recursive-types.test.ts +1 -1
  27. package/src/v4/classic/tests/standard-schema.test.ts +19 -0
  28. package/src/v4/classic/tests/string.test.ts +25 -0
  29. package/src/v4/classic/tests/template-literal.test.ts +33 -1
  30. package/src/v4/classic/tests/to-json-schema.test.ts +147 -3
  31. package/src/v4/classic/tests/validate.test.ts +569 -0
  32. package/src/v4/core/api.ts +30 -6
  33. package/src/v4/core/checks.ts +1 -101
  34. package/src/v4/core/compile.ts +193 -81
  35. package/src/v4/core/doc.ts +6 -2
  36. package/src/v4/core/errors.ts +3 -6
  37. package/src/v4/core/json-schema-generator.ts +2 -2
  38. package/src/v4/core/json-schema-processors.ts +226 -68
  39. package/src/v4/core/memoizer.ts +78 -28
  40. package/src/v4/core/parse.ts +37 -16
  41. package/src/v4/core/regexes.ts +10 -4
  42. package/src/v4/core/schemas.ts +314 -83
  43. package/src/v4/core/tests/cached.test.ts +54 -0
  44. package/src/v4/core/tests/compile-generative.test.ts +445 -0
  45. package/src/v4/core/tests/compile.test.ts +222 -2
  46. package/src/v4/core/tests/email-regex.test.ts +140 -0
  47. package/src/v4/core/tests/polyfill-collision.test.ts +46 -0
  48. package/src/v4/core/to-json-schema.ts +10 -8
  49. package/src/v4/core/util.ts +222 -147
  50. package/src/v4/core/versions.ts +2 -2
  51. package/src/v4/core/visit.ts +11 -0
  52. package/src/v4/locales/ar.ts +1 -0
  53. package/src/v4/locales/az.ts +1 -0
  54. package/src/v4/locales/be.ts +1 -0
  55. package/src/v4/locales/bg.ts +1 -0
  56. package/src/v4/locales/bn.ts +1 -0
  57. package/src/v4/locales/ca.ts +1 -0
  58. package/src/v4/locales/ckb.ts +1 -0
  59. package/src/v4/locales/cs.ts +1 -0
  60. package/src/v4/locales/da.ts +1 -0
  61. package/src/v4/locales/de.ts +1 -0
  62. package/src/v4/locales/el.ts +1 -0
  63. package/src/v4/locales/en.ts +1 -0
  64. package/src/v4/locales/eo.ts +1 -0
  65. package/src/v4/locales/es.ts +1 -0
  66. package/src/v4/locales/fa.ts +1 -0
  67. package/src/v4/locales/fi.ts +1 -0
  68. package/src/v4/locales/fr-CA.ts +1 -0
  69. package/src/v4/locales/fr.ts +1 -0
  70. package/src/v4/locales/gu.ts +1 -0
  71. package/src/v4/locales/he.ts +1 -0
  72. package/src/v4/locales/hi.ts +1 -0
  73. package/src/v4/locales/hr.ts +1 -0
  74. package/src/v4/locales/hu.ts +1 -0
  75. package/src/v4/locales/hy.ts +1 -0
  76. package/src/v4/locales/id.ts +1 -0
  77. package/src/v4/locales/is.ts +1 -0
  78. package/src/v4/locales/it.ts +1 -0
  79. package/src/v4/locales/ja.ts +1 -0
  80. package/src/v4/locales/ka.ts +1 -0
  81. package/src/v4/locales/km.ts +1 -0
  82. package/src/v4/locales/kn.ts +1 -0
  83. package/src/v4/locales/ko.ts +1 -0
  84. package/src/v4/locales/lt.ts +1 -0
  85. package/src/v4/locales/mk.ts +1 -0
  86. package/src/v4/locales/ms.ts +1 -0
  87. package/src/v4/locales/ne.ts +1 -0
  88. package/src/v4/locales/nl.ts +1 -0
  89. package/src/v4/locales/nn.ts +1 -0
  90. package/src/v4/locales/no.ts +1 -0
  91. package/src/v4/locales/ota.ts +1 -0
  92. package/src/v4/locales/pl.ts +1 -0
  93. package/src/v4/locales/ps.ts +1 -0
  94. package/src/v4/locales/pt-BR.ts +1 -0
  95. package/src/v4/locales/pt.ts +1 -0
  96. package/src/v4/locales/ro.ts +1 -0
  97. package/src/v4/locales/ru.ts +1 -0
  98. package/src/v4/locales/sk.ts +1 -0
  99. package/src/v4/locales/sl.ts +1 -0
  100. package/src/v4/locales/sv.ts +1 -0
  101. package/src/v4/locales/ta.ts +1 -0
  102. package/src/v4/locales/th.ts +1 -0
  103. package/src/v4/locales/tk.ts +1 -0
  104. package/src/v4/locales/tr.ts +1 -0
  105. package/src/v4/locales/uk.ts +1 -0
  106. package/src/v4/locales/ur.ts +1 -0
  107. package/src/v4/locales/uz.ts +1 -0
  108. package/src/v4/locales/vi.ts +1 -0
  109. package/src/v4/locales/yo.ts +1 -0
  110. package/src/v4/locales/zh-CN.ts +1 -0
  111. package/src/v4/locales/zh-TW.ts +1 -0
  112. package/src/v4/mini/checks.ts +0 -1
  113. package/src/v4/mini/external.ts +2 -0
  114. package/src/v4/mini/schemas.ts +38 -2
  115. package/src/v4/mini/tests/checks.test.ts +1 -1
  116. package/src/v4/mini/tests/computed.test.ts +11 -17
  117. package/src/v4/mini/tests/index.test.ts +8 -0
  118. package/src/v4/mini/tests/string.test.ts +16 -0
  119. package/v3/ZodError.cjs +19 -0
  120. package/v3/errors.cjs +19 -0
  121. package/v3/external.cjs +19 -0
  122. package/v3/helpers/enumUtil.cjs +19 -0
  123. package/v3/helpers/errorUtil.cjs +20 -1
  124. package/v3/helpers/errorUtil.js +1 -1
  125. package/v3/helpers/parseUtil.cjs +19 -0
  126. package/v3/helpers/partialUtil.cjs +19 -0
  127. package/v3/helpers/typeAliases.cjs +19 -0
  128. package/v3/helpers/util.cjs +19 -0
  129. package/v3/index.cjs +19 -0
  130. package/v3/standard-schema.cjs +19 -0
  131. package/v3/types.cjs +19 -0
  132. package/v4/classic/checks.cjs +20 -2
  133. package/v4/classic/checks.d.cts +1 -1
  134. package/v4/classic/checks.d.ts +1 -1
  135. package/v4/classic/checks.js +1 -1
  136. package/v4/classic/coerce.cjs +19 -0
  137. package/v4/classic/compat.cjs +19 -0
  138. package/v4/classic/deep-partial.cjs +19 -0
  139. package/v4/classic/errors.cjs +19 -0
  140. package/v4/classic/external.cjs +22 -1
  141. package/v4/classic/external.d.cts +1 -1
  142. package/v4/classic/external.d.ts +1 -1
  143. package/v4/classic/external.js +1 -1
  144. package/v4/classic/from-json-schema.cjs +264 -24
  145. package/v4/classic/from-json-schema.js +245 -24
  146. package/v4/classic/in-out.cjs +19 -0
  147. package/v4/classic/index.cjs +19 -0
  148. package/v4/classic/iso.cjs +19 -0
  149. package/v4/classic/parse.cjs +19 -0
  150. package/v4/classic/schemas.cjs +100 -31
  151. package/v4/classic/schemas.d.cts +17 -1
  152. package/v4/classic/schemas.d.ts +17 -1
  153. package/v4/classic/schemas.js +77 -29
  154. package/v4/core/api.cjs +37 -2
  155. package/v4/core/api.d.cts +6 -4
  156. package/v4/core/api.d.ts +6 -4
  157. package/v4/core/api.js +17 -2
  158. package/v4/core/checks.cjs +19 -96
  159. package/v4/core/checks.d.cts +1 -1
  160. package/v4/core/checks.d.ts +1 -1
  161. package/v4/core/checks.js +0 -96
  162. package/v4/core/compile.cjs +164 -65
  163. package/v4/core/compile.d.cts +18 -4
  164. package/v4/core/compile.d.ts +18 -4
  165. package/v4/core/compile.js +145 -66
  166. package/v4/core/core.cjs +19 -0
  167. package/v4/core/doc.cjs +26 -2
  168. package/v4/core/doc.js +7 -2
  169. package/v4/core/errors.cjs +21 -5
  170. package/v4/core/errors.js +2 -5
  171. package/v4/core/index.cjs +19 -0
  172. package/v4/core/json-schema-generator.cjs +20 -1
  173. package/v4/core/json-schema-generator.js +2 -2
  174. package/v4/core/json-schema-processors.cjs +215 -63
  175. package/v4/core/json-schema-processors.d.cts +17 -0
  176. package/v4/core/json-schema-processors.d.ts +17 -0
  177. package/v4/core/json-schema-processors.js +195 -64
  178. package/v4/core/json-schema.cjs +19 -0
  179. package/v4/core/memoizer.cjs +114 -23
  180. package/v4/core/memoizer.js +72 -23
  181. package/v4/core/parse.cjs +56 -16
  182. package/v4/core/parse.js +37 -16
  183. package/v4/core/regexes.cjs +29 -6
  184. package/v4/core/regexes.d.cts +2 -0
  185. package/v4/core/regexes.d.ts +2 -0
  186. package/v4/core/regexes.js +8 -4
  187. package/v4/core/registries.cjs +19 -0
  188. package/v4/core/schemas.cjs +285 -66
  189. package/v4/core/schemas.d.cts +34 -3
  190. package/v4/core/schemas.d.ts +34 -3
  191. package/v4/core/schemas.js +264 -65
  192. package/v4/core/standard-schema.cjs +19 -0
  193. package/v4/core/to-json-schema.cjs +29 -7
  194. package/v4/core/to-json-schema.d.cts +7 -3
  195. package/v4/core/to-json-schema.d.ts +7 -3
  196. package/v4/core/to-json-schema.js +8 -7
  197. package/v4/core/util.cjs +181 -143
  198. package/v4/core/util.d.cts +25 -4
  199. package/v4/core/util.d.ts +25 -4
  200. package/v4/core/util.js +160 -143
  201. package/v4/core/versions.cjs +21 -2
  202. package/v4/core/versions.d.cts +1 -1
  203. package/v4/core/versions.d.ts +1 -1
  204. package/v4/core/versions.js +2 -2
  205. package/v4/core/visit.cjs +31 -0
  206. package/v4/core/visit.js +12 -0
  207. package/v4/index.cjs +19 -0
  208. package/v4/locales/ar.cjs +1 -0
  209. package/v4/locales/ar.js +1 -0
  210. package/v4/locales/az.cjs +1 -0
  211. package/v4/locales/az.js +1 -0
  212. package/v4/locales/be.cjs +1 -0
  213. package/v4/locales/be.js +1 -0
  214. package/v4/locales/bg.cjs +1 -0
  215. package/v4/locales/bg.js +1 -0
  216. package/v4/locales/bn.cjs +1 -0
  217. package/v4/locales/bn.js +1 -0
  218. package/v4/locales/ca.cjs +1 -0
  219. package/v4/locales/ca.js +1 -0
  220. package/v4/locales/ckb.cjs +1 -0
  221. package/v4/locales/ckb.js +1 -0
  222. package/v4/locales/cs.cjs +1 -0
  223. package/v4/locales/cs.js +1 -0
  224. package/v4/locales/da.cjs +1 -0
  225. package/v4/locales/da.js +1 -0
  226. package/v4/locales/de.cjs +1 -0
  227. package/v4/locales/de.js +1 -0
  228. package/v4/locales/el.cjs +1 -0
  229. package/v4/locales/el.js +1 -0
  230. package/v4/locales/en.cjs +1 -0
  231. package/v4/locales/en.js +1 -0
  232. package/v4/locales/eo.cjs +1 -0
  233. package/v4/locales/eo.js +1 -0
  234. package/v4/locales/es.cjs +1 -0
  235. package/v4/locales/es.js +1 -0
  236. package/v4/locales/fa.cjs +1 -0
  237. package/v4/locales/fa.js +1 -0
  238. package/v4/locales/fi.cjs +1 -0
  239. package/v4/locales/fi.js +1 -0
  240. package/v4/locales/fr-CA.cjs +1 -0
  241. package/v4/locales/fr-CA.js +1 -0
  242. package/v4/locales/fr.cjs +1 -0
  243. package/v4/locales/fr.js +1 -0
  244. package/v4/locales/gu.cjs +1 -0
  245. package/v4/locales/gu.js +1 -0
  246. package/v4/locales/he.cjs +1 -0
  247. package/v4/locales/he.js +1 -0
  248. package/v4/locales/hi.cjs +1 -0
  249. package/v4/locales/hi.js +1 -0
  250. package/v4/locales/hr.cjs +1 -0
  251. package/v4/locales/hr.js +1 -0
  252. package/v4/locales/hu.cjs +1 -0
  253. package/v4/locales/hu.js +1 -0
  254. package/v4/locales/hy.cjs +1 -0
  255. package/v4/locales/hy.js +1 -0
  256. package/v4/locales/id.cjs +1 -0
  257. package/v4/locales/id.js +1 -0
  258. package/v4/locales/index.cjs +19 -0
  259. package/v4/locales/is.cjs +1 -0
  260. package/v4/locales/is.js +1 -0
  261. package/v4/locales/it.cjs +1 -0
  262. package/v4/locales/it.js +1 -0
  263. package/v4/locales/ja.cjs +1 -0
  264. package/v4/locales/ja.js +1 -0
  265. package/v4/locales/ka.cjs +1 -0
  266. package/v4/locales/ka.js +1 -0
  267. package/v4/locales/km.cjs +1 -0
  268. package/v4/locales/km.js +1 -0
  269. package/v4/locales/kn.cjs +1 -0
  270. package/v4/locales/kn.js +1 -0
  271. package/v4/locales/ko.cjs +1 -0
  272. package/v4/locales/ko.js +1 -0
  273. package/v4/locales/lt.cjs +1 -0
  274. package/v4/locales/lt.js +1 -0
  275. package/v4/locales/mk.cjs +1 -0
  276. package/v4/locales/mk.js +1 -0
  277. package/v4/locales/ms.cjs +1 -0
  278. package/v4/locales/ms.js +1 -0
  279. package/v4/locales/ne.cjs +1 -0
  280. package/v4/locales/ne.js +1 -0
  281. package/v4/locales/nl.cjs +1 -0
  282. package/v4/locales/nl.js +1 -0
  283. package/v4/locales/nn.cjs +1 -0
  284. package/v4/locales/nn.js +1 -0
  285. package/v4/locales/no.cjs +1 -0
  286. package/v4/locales/no.js +1 -0
  287. package/v4/locales/ota.cjs +1 -0
  288. package/v4/locales/ota.js +1 -0
  289. package/v4/locales/pl.cjs +1 -0
  290. package/v4/locales/pl.js +1 -0
  291. package/v4/locales/ps.cjs +1 -0
  292. package/v4/locales/ps.js +1 -0
  293. package/v4/locales/pt-BR.cjs +1 -0
  294. package/v4/locales/pt-BR.js +1 -0
  295. package/v4/locales/pt.cjs +1 -0
  296. package/v4/locales/pt.js +1 -0
  297. package/v4/locales/ro.cjs +1 -0
  298. package/v4/locales/ro.js +1 -0
  299. package/v4/locales/ru.cjs +1 -0
  300. package/v4/locales/ru.js +1 -0
  301. package/v4/locales/sk.cjs +1 -0
  302. package/v4/locales/sk.js +1 -0
  303. package/v4/locales/sl.cjs +1 -0
  304. package/v4/locales/sl.js +1 -0
  305. package/v4/locales/sv.cjs +1 -0
  306. package/v4/locales/sv.js +1 -0
  307. package/v4/locales/ta.cjs +1 -0
  308. package/v4/locales/ta.js +1 -0
  309. package/v4/locales/th.cjs +1 -0
  310. package/v4/locales/th.js +1 -0
  311. package/v4/locales/tk.cjs +1 -0
  312. package/v4/locales/tk.js +1 -0
  313. package/v4/locales/tr.cjs +1 -0
  314. package/v4/locales/tr.js +1 -0
  315. package/v4/locales/uk.cjs +1 -0
  316. package/v4/locales/uk.js +1 -0
  317. package/v4/locales/ur.cjs +1 -0
  318. package/v4/locales/ur.js +1 -0
  319. package/v4/locales/uz.cjs +1 -0
  320. package/v4/locales/uz.js +1 -0
  321. package/v4/locales/vi.cjs +1 -0
  322. package/v4/locales/vi.js +1 -0
  323. package/v4/locales/yo.cjs +1 -0
  324. package/v4/locales/yo.js +1 -0
  325. package/v4/locales/zh-CN.cjs +1 -0
  326. package/v4/locales/zh-CN.js +1 -0
  327. package/v4/locales/zh-TW.cjs +1 -0
  328. package/v4/locales/zh-TW.js +1 -0
  329. package/v4/mini/checks.cjs +20 -2
  330. package/v4/mini/checks.d.cts +1 -1
  331. package/v4/mini/checks.d.ts +1 -1
  332. package/v4/mini/checks.js +1 -1
  333. package/v4/mini/coerce.cjs +19 -0
  334. package/v4/mini/deep-partial.cjs +19 -0
  335. package/v4/mini/external.cjs +22 -1
  336. package/v4/mini/external.d.cts +1 -1
  337. package/v4/mini/external.d.ts +1 -1
  338. package/v4/mini/external.js +1 -1
  339. package/v4/mini/in-out.cjs +19 -0
  340. package/v4/mini/index.cjs +19 -0
  341. package/v4/mini/iso.cjs +19 -0
  342. package/v4/mini/parse.cjs +19 -0
  343. package/v4/mini/schemas.cjs +42 -4
  344. package/v4/mini/schemas.d.cts +8 -0
  345. package/v4/mini/schemas.d.ts +8 -0
  346. package/v4/mini/schemas.js +19 -2
  347. package/v4-mini/index.cjs +19 -0
@@ -2,9 +2,9 @@ import { $ZodAsyncError } from "./core.js";
2
2
  import { Doc } from "./doc.js";
3
3
  import { isBackEdge, isRecursiveSchema } from "./memoizer.js";
4
4
  import * as regexes from "./regexes.js";
5
- import { isValidBase64, isValidBase64URL, isValidCIDRv6, isValidCreditCard, isValidIPv6, isValidJWT, mergeValues, parseURLObject, stripTabAndNewline, urlHostnameOk, urlProtocolOk, } from "./schemas.js";
5
+ import { isValidBase64, isValidBase64URL, isValidCIDRv6, isValidCreditCard, isValidIBAN, isValidIPv6, isValidJWT, mergeValues, parseURLObject, stripTabAndNewline, urlHostnameOk, urlProtocolOk, } from "./schemas.js";
6
6
  import * as util from "./util.js";
7
- /** Sentinel value returned by the compiled fast path when validation fails. Internal. */
7
+ /** @internal Sentinel the compiled fast path returns when validation fails. */
8
8
  export const INVALID = Symbol.for("zod.compile.invalid");
9
9
  // Set on the parse ctx when a compiled wrapper falls back to the runtime, so nested compiled wrappers skip their fast paths for the rest of that parse.
10
10
  const FALLBACK_FLAG = Symbol.for("zod.compile.fallback");
@@ -55,45 +55,9 @@ function compileValidator(schema, parser) {
55
55
  export function compile(schema, options) {
56
56
  try {
57
57
  const parser = compileFn(schema);
58
- const clone = util.clone(schema);
59
- // Capture the source-of-truth runtime eagerly. If schema._zod.run is itself a shim installed by global-mode (`__originalRun` set), unwrap past it. Otherwise capturing the live property lazily would let a later self- replacement of schema._zod.run feed our wrapper back into itself.
60
- const liveRun = schema._zod.run;
61
- const originalRun = liveRun.__originalRun ?? liveRun;
62
- // Delegate to the *original* schema's run on bypass/fallback (not the
63
- // clone's). The original closed over its own `inst` at construction time;
64
- // issue payloads use that reference to derive things like the class name
65
- // for `z.instanceof(Test)`. Calling the clone's freshly-initialized run
66
- // would push issues with `inst === clone`, producing diverging error
67
- // messages from the original schema.
68
- const wrapped = (payload, ctx) => {
69
- if (ctx?.async ||
70
- ctx?.direction === "backward" ||
71
- ctx?.skipChecks ||
72
- ctx?.[FALLBACK_FLAG]) {
73
- return originalRun(payload, ctx);
74
- }
75
- // A memoized back-edge: only the runtime can close a reference cycle, and a transform on one must raise $ZodCyclicError from its own parse.
76
- if (ctx && isBackEdge(ctx, payload.value)) {
77
- return originalRun(payload, ctx);
78
- }
79
- const out = parser(payload.value);
80
- if (out !== INVALID) {
81
- payload.value = out;
82
- return payload;
83
- }
84
- // Mark this parse as runtime-driven: under global mode every nested schema carries its own compiled wrapper, and without the flag the parent's runtime fallback re-enters each child's fast path, running user callbacks a third time on invalid input.
85
- if (ctx)
86
- ctx[FALLBACK_FLAG] = true;
87
- return originalRun(payload, ctx);
88
- };
89
- // Let later compiles of (or through) this run unwrap to the true runtime — both the global shim and repeated z.compile calls rely on this. The bag also carries the parser and the validator, so the standalone validate can skip the payload and wrapper on the happy path.
90
- wrapped.__originalRun = originalRun;
91
- clone._zod.bag.fallbackRun = originalRun;
58
+ const clone = withParser(schema, parser);
59
+ // withParser leaves the parser as its own validator; the generated assert-only variant is better when we have one
92
60
  clone._zod.bag.validator = compileValidator(schema, parser);
93
- clone._zod.run = wrapped;
94
- // The fast parse/safeParse closures fall back through the source schema's methods. If the source is shim- or wrapper-managed, those methods route into a compiled run and would execute user callbacks a third time on invalid input — the plain method → wrapper path is exactly 2x, so skip.
95
- if (!liveRun.__originalRun)
96
- installCompiledUserMethods(clone, schema, parser);
97
61
  return clone;
98
62
  }
99
63
  catch (err) {
@@ -103,6 +67,59 @@ export function compile(schema, options) {
103
67
  return schema;
104
68
  }
105
69
  }
70
+ /**
71
+ * Install an already-generated parser as a schema's fast path. Returns a clone; the original is
72
+ * unchanged.
73
+ *
74
+ * The parser takes the input and returns the parsed value, or `INVALID` to hand the parse to the
75
+ * runtime. It must be synchronous and forward-direction, and it must build fresh output rather than
76
+ * return its input — Zod cannot check either, and a wrong *success* is returned to the caller as-is.
77
+ *
78
+ * `compile()` is the ordinary entry point. This is for a build-time or native compiler that produces
79
+ * a parser where `new Function` is unavailable.
80
+ */
81
+ export function withParser(schema, parser) {
82
+ // generated code never receives the parse context, so only the runtime can close a reference cycle; compileFn refuses these too
83
+ if (isRecursiveSchema(schema)) {
84
+ throw new ZodCompileUnsupportedError("a schema whose subtree contains a reference cycle");
85
+ }
86
+ const clone = util.clone(schema);
87
+ // Capture the source-of-truth runtime eagerly. If schema._zod.run is itself a shim installed by global-mode (`__originalRun` set), unwrap past it. Otherwise capturing the live property lazily would let a later self- replacement of schema._zod.run feed our wrapper back into itself.
88
+ const liveRun = schema._zod.run;
89
+ const originalRun = liveRun.__originalRun ?? liveRun;
90
+ // Delegate to the *original* schema's run on bypass/fallback, not the clone's. The original closed over its own `inst` at construction time, and issue payloads use that reference to derive things like the class name for `z.instanceof(Test)`; calling the clone's freshly-initialized run would push issues with `inst === clone` and diverge from the original schema's error messages.
91
+ const wrapped = (payload, ctx) => {
92
+ if (ctx?.async ||
93
+ ctx?.direction === "backward" ||
94
+ ctx?.skipChecks ||
95
+ ctx?.[FALLBACK_FLAG]) {
96
+ return originalRun(payload, ctx);
97
+ }
98
+ // A memoized back-edge: only the runtime can close a reference cycle, and a transform on one must raise $ZodCyclicError from its own parse.
99
+ if (ctx && isBackEdge(ctx, payload.value)) {
100
+ return originalRun(payload, ctx);
101
+ }
102
+ const out = parser(payload.value);
103
+ if (out !== INVALID) {
104
+ payload.value = out;
105
+ return payload;
106
+ }
107
+ // Mark this parse as runtime-driven: under global mode every nested schema carries its own compiled wrapper, and without the flag the parent's runtime fallback re-enters each child's fast path, running user callbacks a third time on invalid input.
108
+ if (ctx)
109
+ ctx[FALLBACK_FLAG] = true;
110
+ return originalRun(payload, ctx);
111
+ };
112
+ // Let later compiles of (or through) this run unwrap to the true runtime — both the global shim and repeated z.compile calls rely on this. The bag also carries the parser and the validator, so the standalone validate can skip the payload and wrapper on the happy path.
113
+ wrapped.__originalRun = originalRun;
114
+ clone._zod.bag.fallbackRun = originalRun;
115
+ // a supplied parser answers `validate` too: one implementation means parse and validate cannot disagree, and its undefined `definite` keeps the runtime re-parse on every rejection
116
+ clone._zod.bag.validator = parser;
117
+ clone._zod.run = wrapped;
118
+ // The fast parse/safeParse closures fall back through the source schema's methods. If the source is shim- or wrapper-managed, those methods route into a compiled run and would execute user callbacks a third time on invalid input — the plain method → wrapper path is exactly 2x, so skip.
119
+ if (!liveRun.__originalRun)
120
+ installCompiledUserMethods(clone, schema, parser);
121
+ return clone;
122
+ }
106
123
  function installCompiledUserMethods(target, source, parser) {
107
124
  const targetAny = target;
108
125
  const sourceAny = source;
@@ -128,9 +145,8 @@ function installCompiledUserMethods(target, source, parser) {
128
145
  }
129
146
  }
130
147
  /**
131
- * Generate the standalone compiled function: a parser by default, a validator under
132
- * `assertOnly`. Returns either the parsed value, `true` where nothing reads the output,
133
- * or the `INVALID` sentinel. Internal — consumers should use `compile()`.
148
+ * @internal Generate the standalone compiled function: a parser by default, a validator under
149
+ * `assertOnly`. Returns the parsed value, `true` where nothing reads the output, or `INVALID`. Consumers use `compile()`.
134
150
  */
135
151
  export function compileFn(schema, options) {
136
152
  // Cycle-breaking is keyed on the parse context, which generated code never receives. `shape` can be a getter that throws (z.pick() with an unrecognized mask key), so treat "can't tell" as recursive.
@@ -146,6 +162,7 @@ export function compileFn(schema, options) {
146
162
  constants: new Map(),
147
163
  constantCounter: 0,
148
164
  varCounter: 0,
165
+ definite: true,
149
166
  };
150
167
  const doc = new Doc(["input"]);
151
168
  const outputAccessor = generateCheck(doc, ctx, schema, "input", !options?.assertOnly);
@@ -174,6 +191,7 @@ export function compileFn(schema, options) {
174
191
  if (options?.debug) {
175
192
  fn.code = fullCode;
176
193
  }
194
+ fn.definite = ctx.definite;
177
195
  return fn;
178
196
  }
179
197
  function addConstant(ctx, value) {
@@ -186,6 +204,11 @@ function addConstant(ctx, value) {
186
204
  ctx.constants.set(name, value);
187
205
  return name;
188
206
  }
207
+ /** Hoists a user-supplied callback. Anything the schema's author wrote can throw, and generated code can reject an earlier sibling before ever reaching it, so this clears `definite` — a rejection is then no longer proof that the interpreter would have rejected rather than thrown. */
208
+ function addUserConstant(ctx, fn) {
209
+ ctx.definite = false;
210
+ return addConstant(ctx, fn);
211
+ }
189
212
  function newVar(ctx) {
190
213
  return `v${ctx.varCounter++}`;
191
214
  }
@@ -221,6 +244,8 @@ function compileChild(doc, ctx, schema, accessor, needsValue = true) {
221
244
  }
222
245
  }
223
246
  function emitRuntimeIsland(doc, ctx, schema, accessor) {
247
+ // an islanded child answers INVALID for an async run too, which the interpreter throws for
248
+ ctx.definite = false;
224
249
  const schemaConst = addConstant(ctx, schema);
225
250
  const runConst = addConstant(ctx, runtimeRun);
226
251
  const outVar = newVar(ctx);
@@ -304,6 +329,9 @@ function generateChecks(doc, ctx, schema, accessor) {
304
329
  case "property":
305
330
  generatePropertyCheck(doc, ctx, def, currentAccessor);
306
331
  break;
332
+ case "properties":
333
+ generatePropertiesChecks(doc, ctx, def, currentAccessor, false);
334
+ break;
307
335
  case "overwrite": {
308
336
  // Overwrite transforms the value - create new variable for transformed result
309
337
  const newAccessor = newVar(ctx);
@@ -429,6 +457,26 @@ function generateMimeTypeCheck(doc, ctx, def, accessor) {
429
457
  doc.write(`if (!${mimeSet}.has(${accessor}.type)) return INVALID;`);
430
458
  }
431
459
  }
460
+ // asserts each named property in place; children compile assert-only because z.properties never rebuilds its input
461
+ function generatePropertiesChecks(doc, ctx, def, accessor, schemaRole) {
462
+ // a custom `when` gates the assertion at runtime; inside a union a wrongly-run branch is absorbed as a branch failure rather than falling back, so refuse at codegen the way the check role does
463
+ if (def.when) {
464
+ throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
465
+ }
466
+ // matches the runtime gate for whichever role this is: a schema rejects a primitive outright, a check only a nullish value
467
+ doc.write(schemaRole
468
+ ? `if (${accessor} === null || (typeof ${accessor} !== "object" && typeof ${accessor} !== "function")) return INVALID;`
469
+ : `if (${accessor} == null) return INVALID;`);
470
+ const shape = def.shape;
471
+ for (const key of Reflect.ownKeys(shape)) {
472
+ // a symbol has no source literal, so it is hoisted as a constant
473
+ const keyExpr = typeof key === "symbol" ? addConstant(ctx, key) : util.esc(key);
474
+ // cache the property read so a getter runs exactly once, matching the runtime
475
+ const inputVar = newVar(ctx);
476
+ doc.write(`const ${inputVar} = ${accessor}[${keyExpr}];`);
477
+ compileChild(doc, ctx, shape[key], inputVar, false);
478
+ }
479
+ }
432
480
  function generatePropertyCheck(doc, ctx, def, accessor) {
433
481
  const propAccessor = `${accessor}[${JSON.stringify(def.property)}]`;
434
482
  generateCheck(doc, ctx, def.schema, propAccessor);
@@ -461,7 +509,7 @@ function generateCustomRefineCheck(doc, ctx, check, accessor) {
461
509
  if (isAsyncFunction(def.fn)) {
462
510
  throw new ZodCompileAsyncError("z.compile: async .refine() predicates are not supported");
463
511
  }
464
- const fnConst = addConstant(ctx, def.fn);
512
+ const fnConst = addUserConstant(ctx, def.fn);
465
513
  const throwAsyncConst = addConstant(ctx, throwAsync);
466
514
  const resVar = newVar(ctx);
467
515
  doc.write(`const ${resVar} = ${fnConst}(${accessor});`);
@@ -489,7 +537,7 @@ function generateCustomRefineCheck(doc, ctx, check, accessor) {
489
537
  throwAsync();
490
538
  return fakePayload.issues.length === 0 ? fakePayload.value : INVALID;
491
539
  };
492
- const helperConst = addConstant(ctx, helperFn);
540
+ const helperConst = addUserConstant(ctx, helperFn);
493
541
  const outVar = newVar(ctx);
494
542
  doc.write(`const ${outVar} = ${helperConst}(${accessor});`);
495
543
  doc.write(`if (${outVar} === INVALID) return INVALID;`);
@@ -566,6 +614,11 @@ function generateStringFormatCheck(doc, ctx, def, accessor) {
566
614
  doc.write(`if (!${validator}(${accessor})) return INVALID;`);
567
615
  return accessor;
568
616
  }
617
+ if (fmt === "iban") {
618
+ const validator = addConstant(ctx, isValidIBAN);
619
+ doc.write(`if (!${validator}(${accessor})) return INVALID;`);
620
+ return accessor;
621
+ }
569
622
  const formatDef = def;
570
623
  if (fmt === "url" ||
571
624
  fmt === "httpurl" ||
@@ -764,6 +817,10 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
764
817
  case "custom":
765
818
  typeAccessor = generateCustomCheck(doc, ctx, schema, accessor);
766
819
  break;
820
+ case "properties":
821
+ generatePropertiesChecks(doc, ctx, schema._zod.def, accessor, true);
822
+ typeAccessor = accessor;
823
+ break;
767
824
  case "transform":
768
825
  typeAccessor = generateTransformCheck(doc, ctx, schema, accessor);
769
826
  break;
@@ -1481,6 +1538,8 @@ function literalEquality(ctx, accessor, value) {
1481
1538
  }
1482
1539
  function generateIntersectionCheck(doc, ctx, schema, accessor) {
1483
1540
  const def = schema._zod.def;
1541
+ // An unmergeable merge, and a child failing before the merge is even reached, both return INVALID for a case the interpreter answers with a throw.
1542
+ ctx.definite = false;
1484
1543
  const leftOutput = compileChild(doc, ctx, def.left, accessor);
1485
1544
  const rightOutput = compileChild(doc, ctx, def.right, accessor);
1486
1545
  // Hoist the runtime merge helper so recursive object/array merge semantics stay in one place. If the merge is invalid, return INVALID and let the runtime fallback construct canonical errors.
@@ -1550,14 +1609,15 @@ function generateRecordCheck(doc, ctx, schema, accessor) {
1550
1609
  // The runtime runs it against each own enumerable key and writes the value
1551
1610
  // under the key it produced, so compile it once and call it per key.
1552
1611
  const isLoose = def.mode === "loose";
1553
- const keyFast = addConstant(ctx, compileFn(def.keyType));
1612
+ // the key compiles in its own context, so carry its verdict out: a key schema that can answer INVALID undecidably makes this validator undecidable too
1613
+ const keyFn = compileFn(def.keyType);
1614
+ if (keyFn.definite === false)
1615
+ ctx.definite = false;
1616
+ const keyFast = addConstant(ctx, keyFn);
1554
1617
  const numericConst = addConstant(ctx, regexes.number);
1555
- const propIsEnumerableConst = addConstant(ctx, Object.prototype.propertyIsEnumerable);
1556
1618
  const outKeyVar = newVar(ctx);
1557
- doc.write(`for (const ${kVar} of Reflect.ownKeys(${accessor})) {`);
1558
- doc.indented((d) => {
1559
- d.write(`if (${kVar} === "__proto__") continue;`);
1560
- d.write(`if (!${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
1619
+ // the body runs once per string key and once per symbol key, since a key schema can accept symbols
1620
+ emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
1561
1621
  d.write(`let ${outKeyVar} = ${keyFast}(${kVar});`);
1562
1622
  // Numeric-string retry, mirroring the runtime: a key the schema rejects as a string is tried again as a number, so z.record(z.number(), …) matches the numeric keys JavaScript stringified on the way in.
1563
1623
  d.write(`if (${outKeyVar} === INVALID && typeof ${kVar} === "string" && ${numericConst}.test(${kVar})) ${outKeyVar} = ${keyFast}(Number(${kVar}));`);
@@ -1576,22 +1636,41 @@ function generateRecordCheck(doc, ctx, schema, accessor) {
1576
1636
  const valOutput = compileChild(d, ctx, def.valueType, valueVar);
1577
1637
  d.write(`${outputVar}[${outKeyVar}] = ${valOutput};`);
1578
1638
  });
1579
- doc.write(`}`);
1580
1639
  return outputVar;
1581
1640
  }
1582
- // Plain z.string() keys: iterate enumerable own keys and validate each value. Runtime uses Reflect.ownKeys so symbol keys participate in validation; matching that here prevents silently accepting objects with enumerable Symbol keys under z.record(z.string(), ...).
1583
- const propIsEnumerable = addConstant(ctx, Object.prototype.propertyIsEnumerable);
1584
- doc.write(`for (const ${kVar} of Reflect.ownKeys(${accessor})) {`);
1585
- doc.indented((d) => {
1586
- d.write(`if (${kVar} === "__proto__") continue;`);
1587
- d.write(`if (!${propIsEnumerable}.call(${accessor}, ${kVar})) continue;`);
1588
- d.write(`if (typeof ${kVar} !== "string") return INVALID;`);
1641
+ // Plain z.string() keys: every own enumerable string key's value is validated, and an own enumerable symbol key fails the string key schema, as it does in the runtime's Reflect.ownKeys walk.
1642
+ emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
1589
1643
  d.write(`const ${valVar} = ${accessor}[${kVar}];`);
1590
1644
  const valOutput = compileChild(d, ctx, def.valueType, valVar);
1591
1645
  d.write(`${outputVar}[${kVar}] = ${valOutput};`);
1646
+ }, `return INVALID;`);
1647
+ return outputVar;
1648
+ }
1649
+ // Walks the own enumerable keys of a plain object in Reflect.ownKeys order — strings from getOwnPropertyNames, then symbols — instead of Reflect.ownKeys, whose accumulator made that walk 3–6x the cost of the loop it fed. Both snapshots are taken before any value is read and every key is rechecked with propertyIsEnumerable when visited, exactly the runtime's walk, so a getter that adds, deletes, hides or reveals a key mid-walk sees the runtime's verdict; for-in and Object.keys were no faster and each lost a case (for-in enumerates the prototype chain after the own keys, Object.keys drops a key that is non-enumerable at snapshot time). `body` is written once for the string loop and once for the symbol loop unless `onSymbol` replaces the latter.
1650
+ function emitOwnKeys(doc, ctx, accessor, kVar, body, onSymbol) {
1651
+ const propIsEnumerableConst = addConstant(ctx, Object.prototype.propertyIsEnumerable);
1652
+ const symsVar = newVar(ctx);
1653
+ const keysVar = newVar(ctx);
1654
+ const iVar = newVar(ctx);
1655
+ doc.write(`const ${symsVar} = Object.getOwnPropertySymbols(${accessor});`);
1656
+ doc.write(`const ${keysVar} = Object.getOwnPropertyNames(${accessor});`);
1657
+ doc.write(`for (let ${iVar} = 0; ${iVar} < ${keysVar}.length; ${iVar}++) {`);
1658
+ doc.indented((d) => {
1659
+ d.write(`const ${kVar} = ${keysVar}[${iVar}];`);
1660
+ d.write(`if (${kVar} === "__proto__" || !${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
1661
+ body(d);
1662
+ });
1663
+ doc.write(`}`);
1664
+ doc.write(`for (let ${iVar} = 0; ${iVar} < ${symsVar}.length; ${iVar}++) {`);
1665
+ doc.indented((d) => {
1666
+ d.write(`const ${kVar} = ${symsVar}[${iVar}];`);
1667
+ d.write(`if (!${propIsEnumerableConst}.call(${accessor}, ${kVar})) continue;`);
1668
+ if (onSymbol)
1669
+ d.write(onSymbol);
1670
+ else
1671
+ body(d);
1592
1672
  });
1593
1673
  doc.write(`}`);
1594
- return outputVar;
1595
1674
  }
1596
1675
  function literalPropertyKey(ctx, key) {
1597
1676
  if (typeof key === "string")
@@ -1647,7 +1726,7 @@ function generateTemplateLiteralCheck(doc, ctx, schema, accessor) {
1647
1726
  function generateLazyCheck(doc, ctx, schema, accessor) {
1648
1727
  // For lazy schemas, we use a cached parser that falls back to runtime Zod parsing This handles recursive schemas correctly by avoiding infinite compilation loops
1649
1728
  const def = schema._zod.def;
1650
- const getterConst = addConstant(ctx, def.getter);
1729
+ const getterConst = addUserConstant(ctx, def.getter);
1651
1730
  const cacheConst = addConstant(ctx, { parser: null });
1652
1731
  doc.write(`if (!${cacheConst}.parser) {`);
1653
1732
  doc.indented((d) => {
@@ -1671,7 +1750,7 @@ function generatePipeCheck(doc, ctx, schema, accessor) {
1671
1750
  // Validate input type first
1672
1751
  const inputOutput = generateCheck(doc, ctx, def.in, accessor);
1673
1752
  if (def.transform) {
1674
- // Apply transform and validate output. The transform may read its second `payload` argument (codec transforms like z.stringbool() push issues there) so wrap the call in a helper that spoofs a payload. Pushed issues signal INVALID and the wrapper falls back to the runtime.
1753
+ // Apply transform and validate output. The transform may read its second `payload` argument (codec transforms like z.stringbool() push issues there) so wrap the call in a helper that spoofs a payload. Pushed issues signal INVALID and the wrapper falls back to the runtime, and a plain function handing back a promise answers INVALID too — union parity, but not a decidable rejection at the top level.
1675
1754
  if (isAsyncFunction(def.transform)) {
1676
1755
  throw new ZodCompileAsyncError("z.compile: async transforms in pipes are not supported");
1677
1756
  }
@@ -1685,7 +1764,7 @@ function generatePipeCheck(doc, ctx, schema, accessor) {
1685
1764
  return INVALID;
1686
1765
  return fakePayload.issues.length === 0 ? result : INVALID;
1687
1766
  };
1688
- const helperConst = addConstant(ctx, helperFn);
1767
+ const helperConst = addUserConstant(ctx, helperFn);
1689
1768
  const transformedVar = newVar(ctx);
1690
1769
  doc.write(`const ${transformedVar} = ${helperConst}(${inputOutput});`);
1691
1770
  doc.write(`if (${transformedVar} === INVALID) return INVALID;`);
@@ -1709,7 +1788,7 @@ function generateCustomCheck(doc, ctx, schema, accessor) {
1709
1788
  throw new ZodCompileAsyncError("z.compile: async custom predicates are not supported");
1710
1789
  }
1711
1790
  // Custom schema with a predicate function (e.g. z.instanceof). `isAsyncFunction` above is syntactic, so a plain function returning a promise reaches here, and a promise is truthy — it would read as a pass where the interpreter throws.
1712
- const fnConst = addConstant(ctx, def.fn);
1791
+ const fnConst = addUserConstant(ctx, def.fn);
1713
1792
  const throwAsyncConst = addConstant(ctx, throwAsync);
1714
1793
  const resVar = newVar(ctx);
1715
1794
  doc.write(`const ${resVar} = ${fnConst}(${accessor});`);
@@ -1746,7 +1825,7 @@ function generateCatchCheck(doc, ctx, schema, accessor) {
1746
1825
  });
1747
1826
  doc.write(`})();`);
1748
1827
  const innerConst = addConstant(ctx, def.innerType);
1749
- const catchConst = addConstant(ctx, def.catchValue);
1828
+ const catchConst = addUserConstant(ctx, def.catchValue);
1750
1829
  const catchHelperConst = addConstant(ctx, runtimeCatch);
1751
1830
  doc.write(`if (${outputVar} === INVALID) {`);
1752
1831
  doc.indented((d) => {
@@ -1773,7 +1852,7 @@ function generateTransformCheck(doc, ctx, schema, accessor) {
1773
1852
  return INVALID;
1774
1853
  return fakePayload.issues.length === 0 ? result : INVALID;
1775
1854
  };
1776
- const helperConst = addConstant(ctx, helperFn);
1855
+ const helperConst = addUserConstant(ctx, helperFn);
1777
1856
  const outputVar = newVar(ctx);
1778
1857
  doc.write(`const ${outputVar} = ${helperConst}(${accessor});`);
1779
1858
  doc.write(`if (${outputVar} === INVALID) return INVALID;`);
package/v4/core/core.cjs CHANGED
@@ -146,3 +146,22 @@ function config(newConfig) {
146
146
  Object.assign(exports.globalConfig, newConfig);
147
147
  return exports.globalConfig;
148
148
  }
149
+
150
+ // seal-cjs-exports
151
+ (function () {
152
+ var keys = Object.getOwnPropertyNames(exports);
153
+ for (var i = 0; i < keys.length; i++) {
154
+ var desc = Object.getOwnPropertyDescriptor(exports, keys[i]);
155
+ if (!desc || !desc.get || !desc.configurable) continue;
156
+ var value;
157
+ try {
158
+ value = desc.get();
159
+ } catch (e) {
160
+ continue;
161
+ }
162
+ // a circular require may not have settled this one yet, so leave it live
163
+ if (value === undefined) continue;
164
+ Object.defineProperty(exports, keys[i], { value: value, writable: false, enumerable: desc.enumerable, configurable: false });
165
+ }
166
+ Object.freeze(exports);
167
+ })();
package/v4/core/doc.cjs CHANGED
@@ -8,10 +8,15 @@ class Doc {
8
8
  this.args = args;
9
9
  this.closed = closed;
10
10
  }
11
+ // the compiler catches a child's throw and keeps writing into this doc, so the indent has to unwind with it
11
12
  indented(fn) {
12
13
  this.indent += 1;
13
- fn(this);
14
- this.indent -= 1;
14
+ try {
15
+ fn(this);
16
+ }
17
+ finally {
18
+ this.indent -= 1;
19
+ }
15
20
  }
16
21
  write(arg) {
17
22
  if (typeof arg === "function") {
@@ -35,3 +40,22 @@ class Doc {
35
40
  }
36
41
  }
37
42
  exports.Doc = Doc;
43
+
44
+ // seal-cjs-exports
45
+ (function () {
46
+ var keys = Object.getOwnPropertyNames(exports);
47
+ for (var i = 0; i < keys.length; i++) {
48
+ var desc = Object.getOwnPropertyDescriptor(exports, keys[i]);
49
+ if (!desc || !desc.get || !desc.configurable) continue;
50
+ var value;
51
+ try {
52
+ value = desc.get();
53
+ } catch (e) {
54
+ continue;
55
+ }
56
+ // a circular require may not have settled this one yet, so leave it live
57
+ if (value === undefined) continue;
58
+ Object.defineProperty(exports, keys[i], { value: value, writable: false, enumerable: desc.enumerable, configurable: false });
59
+ }
60
+ Object.freeze(exports);
61
+ })();
package/v4/core/doc.js CHANGED
@@ -5,10 +5,15 @@ export class Doc {
5
5
  this.args = args;
6
6
  this.closed = closed;
7
7
  }
8
+ // the compiler catches a child's throw and keeps writing into this doc, so the indent has to unwind with it
8
9
  indented(fn) {
9
10
  this.indent += 1;
10
- fn(this);
11
- this.indent -= 1;
11
+ try {
12
+ fn(this);
13
+ }
14
+ finally {
15
+ this.indent -= 1;
16
+ }
12
17
  }
13
18
  write(arg) {
14
19
  if (typeof arg === "function") {
@@ -51,7 +51,6 @@ const _messageDesc = {
51
51
  enumerable: true,
52
52
  configurable: true,
53
53
  };
54
- const _zodDesc = { value: undefined, enumerable: false };
55
54
  const _issuesDesc = { value: undefined, enumerable: false };
56
55
  /* Prototypes that already carry the lazy `toString`. Seeded with the
57
56
  * intrinsics so that `init` on a foreign object — it accepts any object —
@@ -59,12 +58,10 @@ const _issuesDesc = { value: undefined, enumerable: false };
59
58
  const _installedToString = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
60
59
  const initializer = (inst, def) => {
61
60
  inst.name = "$ZodError";
62
- _zodDesc.value = inst._zod;
63
- Object.defineProperty(inst, "_zod", _zodDesc);
61
+ // `_zod` is already non-enumerable: $constructor's init defined it with this same descriptor
64
62
  _issuesDesc.value = def;
65
63
  Object.defineProperty(inst, "issues", _issuesDesc);
66
- // Clear the shared slots; a retained `value` pins the last error's issues.
67
- _zodDesc.value = undefined;
64
+ // Clear the shared slot; a retained `value` pins the last error's issues.
68
65
  _issuesDesc.value = undefined;
69
66
  Object.defineProperty(inst, "message", _messageDesc);
70
67
  /* `toString` lives as a non-enumerable lazy getter on the shared
@@ -299,3 +296,22 @@ function prettifyError(error) {
299
296
  // Convert Map to formatted string
300
297
  return lines.join("\n");
301
298
  }
299
+
300
+ // seal-cjs-exports
301
+ (function () {
302
+ var keys = Object.getOwnPropertyNames(exports);
303
+ for (var i = 0; i < keys.length; i++) {
304
+ var desc = Object.getOwnPropertyDescriptor(exports, keys[i]);
305
+ if (!desc || !desc.get || !desc.configurable) continue;
306
+ var value;
307
+ try {
308
+ value = desc.get();
309
+ } catch (e) {
310
+ continue;
311
+ }
312
+ // a circular require may not have settled this one yet, so leave it live
313
+ if (value === undefined) continue;
314
+ Object.defineProperty(exports, keys[i], { value: value, writable: false, enumerable: desc.enumerable, configurable: false });
315
+ }
316
+ Object.freeze(exports);
317
+ })();
package/v4/core/errors.js CHANGED
@@ -20,7 +20,6 @@ const _messageDesc = {
20
20
  enumerable: true,
21
21
  configurable: true,
22
22
  };
23
- const _zodDesc = { value: undefined, enumerable: false };
24
23
  const _issuesDesc = { value: undefined, enumerable: false };
25
24
  /* Prototypes that already carry the lazy `toString`. Seeded with the
26
25
  * intrinsics so that `init` on a foreign object — it accepts any object —
@@ -28,12 +27,10 @@ const _issuesDesc = { value: undefined, enumerable: false };
28
27
  const _installedToString = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
29
28
  const initializer = (inst, def) => {
30
29
  inst.name = "$ZodError";
31
- _zodDesc.value = inst._zod;
32
- Object.defineProperty(inst, "_zod", _zodDesc);
30
+ // `_zod` is already non-enumerable: $constructor's init defined it with this same descriptor
33
31
  _issuesDesc.value = def;
34
32
  Object.defineProperty(inst, "issues", _issuesDesc);
35
- // Clear the shared slots; a retained `value` pins the last error's issues.
36
- _zodDesc.value = undefined;
33
+ // Clear the shared slot; a retained `value` pins the last error's issues.
37
34
  _issuesDesc.value = undefined;
38
35
  Object.defineProperty(inst, "message", _messageDesc);
39
36
  /* `toString` lives as a non-enumerable lazy getter on the shared
package/v4/core/index.cjs CHANGED
@@ -49,3 +49,22 @@ Object.defineProperty(exports, "toJSONSchema", { enumerable: true, get: function
49
49
  var json_schema_generator_js_1 = require("./json-schema-generator.cjs");
50
50
  Object.defineProperty(exports, "JSONSchemaGenerator", { enumerable: true, get: function () { return json_schema_generator_js_1.JSONSchemaGenerator; } });
51
51
  exports.JSONSchema = __importStar(require("./json-schema.cjs"));
52
+
53
+ // seal-cjs-exports
54
+ (function () {
55
+ var keys = Object.getOwnPropertyNames(exports);
56
+ for (var i = 0; i < keys.length; i++) {
57
+ var desc = Object.getOwnPropertyDescriptor(exports, keys[i]);
58
+ if (!desc || !desc.get || !desc.configurable) continue;
59
+ var value;
60
+ try {
61
+ value = desc.get();
62
+ } catch (e) {
63
+ continue;
64
+ }
65
+ // a circular require may not have settled this one yet, so leave it live
66
+ if (value === undefined) continue;
67
+ Object.defineProperty(exports, keys[i], { value: value, writable: false, enumerable: desc.enumerable, configurable: false });
68
+ }
69
+ Object.freeze(exports);
70
+ })();
@@ -74,7 +74,7 @@ class JSONSchemaGenerator {
74
74
  * This must be called before emit().
75
75
  */
76
76
  process(schema, _params = { path: [], schemaPath: [] }) {
77
- return (0, to_json_schema_js_1.process)(schema, this.ctx, _params);
77
+ return (0, to_json_schema_js_1.processSchema)(schema, this.ctx, _params);
78
78
  }
79
79
  /**
80
80
  * Emit the final JSON Schema after processing.
@@ -101,3 +101,22 @@ class JSONSchemaGenerator {
101
101
  }
102
102
  }
103
103
  exports.JSONSchemaGenerator = JSONSchemaGenerator;
104
+
105
+ // seal-cjs-exports
106
+ (function () {
107
+ var keys = Object.getOwnPropertyNames(exports);
108
+ for (var i = 0; i < keys.length; i++) {
109
+ var desc = Object.getOwnPropertyDescriptor(exports, keys[i]);
110
+ if (!desc || !desc.get || !desc.configurable) continue;
111
+ var value;
112
+ try {
113
+ value = desc.get();
114
+ } catch (e) {
115
+ continue;
116
+ }
117
+ // a circular require may not have settled this one yet, so leave it live
118
+ if (value === undefined) continue;
119
+ Object.defineProperty(exports, keys[i], { value: value, writable: false, enumerable: desc.enumerable, configurable: false });
120
+ }
121
+ Object.freeze(exports);
122
+ })();
@@ -1,5 +1,5 @@
1
1
  import { allProcessors } from "./json-schema-processors.js";
2
- import { extractDefs, finalize, initializeContext, process, } from "./to-json-schema.js";
2
+ import { extractDefs, finalize, initializeContext, processSchema, } from "./to-json-schema.js";
3
3
  /**
4
4
  * Legacy class-based interface for JSON Schema generation.
5
5
  * This class wraps the new functional implementation to provide backward compatibility.
@@ -71,7 +71,7 @@ export class JSONSchemaGenerator {
71
71
  * This must be called before emit().
72
72
  */
73
73
  process(schema, _params = { path: [], schemaPath: [] }) {
74
- return process(schema, this.ctx, _params);
74
+ return processSchema(schema, this.ctx, _params);
75
75
  }
76
76
  /**
77
77
  * Emit the final JSON Schema after processing.