zod 4.1.0-canary.20250821T014930 → 4.1.0-canary.20250823T071040

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 (158) hide show
  1. package/index.cjs +17 -7
  2. package/package.json +1 -1
  3. package/src/v4/classic/external.ts +0 -1
  4. package/src/v4/classic/parse.ts +49 -0
  5. package/src/v4/classic/schemas.ts +145 -7
  6. package/src/v4/classic/tests/catch.test.ts +25 -0
  7. package/src/v4/classic/tests/codec-examples.test.ts +538 -0
  8. package/src/v4/classic/tests/codec.test.ts +532 -0
  9. package/src/v4/classic/tests/continuability.test.ts +1 -1
  10. package/src/v4/classic/tests/default.test.ts +32 -0
  11. package/src/v4/classic/tests/firstparty.test.ts +4 -0
  12. package/src/v4/classic/tests/function.test.ts +31 -31
  13. package/src/v4/classic/tests/hash.test.ts +68 -0
  14. package/src/v4/classic/tests/nonoptional.test.ts +15 -0
  15. package/src/v4/classic/tests/object.test.ts +31 -0
  16. package/src/v4/classic/tests/pipe.test.ts +25 -5
  17. package/src/v4/classic/tests/prefault.test.ts +25 -0
  18. package/src/v4/classic/tests/preprocess.test.ts +1 -6
  19. package/src/v4/classic/tests/refine.test.ts +76 -3
  20. package/src/v4/classic/tests/string-formats.test.ts +16 -0
  21. package/src/v4/classic/tests/string.test.ts +82 -1
  22. package/src/v4/classic/tests/stringbool.test.ts +40 -0
  23. package/src/v4/classic/tests/template-literal.test.ts +1 -1
  24. package/src/v4/classic/tests/to-json-schema.test.ts +21 -2
  25. package/src/v4/classic/tests/transform.test.ts +7 -0
  26. package/src/v4/classic/tests/union.test.ts +1 -1
  27. package/src/v4/core/api.ts +25 -35
  28. package/src/v4/core/core.ts +7 -26
  29. package/src/v4/core/index.ts +0 -1
  30. package/src/v4/core/json-schema.ts +1 -0
  31. package/src/v4/core/parse.ts +101 -0
  32. package/src/v4/core/regexes.ts +40 -1
  33. package/src/v4/core/schemas.ts +521 -129
  34. package/src/v4/core/to-json-schema.ts +43 -8
  35. package/src/v4/core/util.ts +73 -0
  36. package/src/v4/mini/external.ts +0 -1
  37. package/src/v4/mini/parse.ts +14 -1
  38. package/src/v4/mini/schemas.ts +153 -12
  39. package/src/v4/mini/tests/codec.test.ts +499 -0
  40. package/src/v4/mini/tests/object.test.ts +9 -0
  41. package/src/v4/mini/tests/string.test.ts +16 -0
  42. package/v3/index.cjs +17 -7
  43. package/v4/classic/coerce.cjs +17 -7
  44. package/v4/classic/compat.cjs +17 -7
  45. package/v4/classic/errors.cjs +17 -7
  46. package/v4/classic/external.cjs +18 -9
  47. package/v4/classic/external.d.cts +1 -1
  48. package/v4/classic/external.d.ts +1 -1
  49. package/v4/classic/external.js +1 -1
  50. package/v4/classic/index.cjs +17 -7
  51. package/v4/classic/iso.cjs +17 -7
  52. package/v4/classic/parse.cjs +27 -8
  53. package/v4/classic/parse.d.cts +8 -0
  54. package/v4/classic/parse.d.ts +8 -0
  55. package/v4/classic/parse.js +9 -0
  56. package/v4/classic/schemas.cjs +76 -11
  57. package/v4/classic/schemas.d.cts +48 -2
  58. package/v4/classic/schemas.d.ts +48 -2
  59. package/v4/classic/schemas.js +51 -3
  60. package/v4/core/api.cjs +36 -35
  61. package/v4/core/api.d.cts +3 -4
  62. package/v4/core/api.d.ts +3 -4
  63. package/v4/core/api.js +19 -24
  64. package/v4/core/checks.cjs +17 -7
  65. package/v4/core/core.cjs +8 -1
  66. package/v4/core/core.d.cts +3 -0
  67. package/v4/core/core.d.ts +3 -0
  68. package/v4/core/core.js +6 -0
  69. package/v4/core/errors.cjs +17 -7
  70. package/v4/core/index.cjs +17 -8
  71. package/v4/core/index.d.cts +0 -1
  72. package/v4/core/index.d.ts +0 -1
  73. package/v4/core/index.js +0 -1
  74. package/v4/core/json-schema.d.cts +1 -0
  75. package/v4/core/json-schema.d.ts +1 -0
  76. package/v4/core/parse.cjs +62 -8
  77. package/v4/core/parse.d.cts +24 -0
  78. package/v4/core/parse.d.ts +24 -0
  79. package/v4/core/parse.js +36 -0
  80. package/v4/core/regexes.cjs +34 -2
  81. package/v4/core/regexes.d.cts +16 -0
  82. package/v4/core/regexes.d.ts +16 -0
  83. package/v4/core/regexes.js +32 -1
  84. package/v4/core/schemas.cjs +326 -84
  85. package/v4/core/schemas.d.cts +61 -3
  86. package/v4/core/schemas.d.ts +61 -3
  87. package/v4/core/schemas.js +308 -76
  88. package/v4/core/to-json-schema.cjs +42 -5
  89. package/v4/core/to-json-schema.d.cts +4 -3
  90. package/v4/core/to-json-schema.d.ts +4 -3
  91. package/v4/core/to-json-schema.js +42 -5
  92. package/v4/core/util.cjs +69 -0
  93. package/v4/core/util.d.cts +10 -0
  94. package/v4/core/util.d.ts +10 -0
  95. package/v4/core/util.js +62 -0
  96. package/v4/locales/ar.cjs +17 -7
  97. package/v4/locales/az.cjs +17 -7
  98. package/v4/locales/be.cjs +17 -7
  99. package/v4/locales/bg.cjs +17 -7
  100. package/v4/locales/ca.cjs +17 -7
  101. package/v4/locales/cs.cjs +17 -7
  102. package/v4/locales/da.cjs +17 -7
  103. package/v4/locales/de.cjs +17 -7
  104. package/v4/locales/en.cjs +17 -7
  105. package/v4/locales/eo.cjs +17 -7
  106. package/v4/locales/es.cjs +17 -7
  107. package/v4/locales/fa.cjs +17 -7
  108. package/v4/locales/fi.cjs +17 -7
  109. package/v4/locales/fr-CA.cjs +17 -7
  110. package/v4/locales/fr.cjs +17 -7
  111. package/v4/locales/he.cjs +17 -7
  112. package/v4/locales/hu.cjs +17 -7
  113. package/v4/locales/id.cjs +17 -7
  114. package/v4/locales/is.cjs +17 -7
  115. package/v4/locales/it.cjs +17 -7
  116. package/v4/locales/ja.cjs +17 -7
  117. package/v4/locales/kh.cjs +17 -7
  118. package/v4/locales/ko.cjs +17 -7
  119. package/v4/locales/mk.cjs +17 -7
  120. package/v4/locales/ms.cjs +17 -7
  121. package/v4/locales/nl.cjs +17 -7
  122. package/v4/locales/no.cjs +17 -7
  123. package/v4/locales/ota.cjs +17 -7
  124. package/v4/locales/pl.cjs +17 -7
  125. package/v4/locales/ps.cjs +17 -7
  126. package/v4/locales/pt.cjs +17 -7
  127. package/v4/locales/ru.cjs +17 -7
  128. package/v4/locales/sl.cjs +17 -7
  129. package/v4/locales/sv.cjs +17 -7
  130. package/v4/locales/ta.cjs +17 -7
  131. package/v4/locales/th.cjs +17 -7
  132. package/v4/locales/tr.cjs +17 -7
  133. package/v4/locales/ua.cjs +17 -7
  134. package/v4/locales/ur.cjs +17 -7
  135. package/v4/locales/vi.cjs +17 -7
  136. package/v4/locales/yo.cjs +17 -7
  137. package/v4/locales/zh-CN.cjs +17 -7
  138. package/v4/locales/zh-TW.cjs +17 -7
  139. package/v4/mini/coerce.cjs +17 -7
  140. package/v4/mini/external.cjs +18 -9
  141. package/v4/mini/external.d.cts +1 -1
  142. package/v4/mini/external.d.ts +1 -1
  143. package/v4/mini/external.js +1 -1
  144. package/v4/mini/index.cjs +17 -7
  145. package/v4/mini/iso.cjs +17 -7
  146. package/v4/mini/parse.cjs +9 -1
  147. package/v4/mini/parse.d.cts +1 -1
  148. package/v4/mini/parse.d.ts +1 -1
  149. package/v4/mini/parse.js +1 -1
  150. package/v4/mini/schemas.cjs +75 -10
  151. package/v4/mini/schemas.d.cts +49 -1
  152. package/v4/mini/schemas.d.ts +49 -1
  153. package/v4/mini/schemas.js +49 -2
  154. package/src/v4/core/function.ts +0 -176
  155. package/v4/core/function.cjs +0 -102
  156. package/v4/core/function.d.cts +0 -52
  157. package/v4/core/function.d.ts +0 -52
  158. package/v4/core/function.js +0 -75
@@ -3,7 +3,7 @@ import * as checks from "./checks.js";
3
3
  import * as core from "./core.js";
4
4
  import { Doc } from "./doc.js";
5
5
  import type * as errors from "./errors.js";
6
- import { safeParse, safeParseAsync } from "./parse.js";
6
+ import { parse, parseAsync, safeParse, safeParseAsync } from "./parse.js";
7
7
  import * as regexes from "./regexes.js";
8
8
  import type { StandardSchemaV1 } from "./standard-schema.js";
9
9
  import * as util from "./util.js";
@@ -25,11 +25,15 @@ export interface ParseContext<T extends errors.$ZodIssueBase = never> {
25
25
  /** @internal */
26
26
  export interface ParseContextInternal<T extends errors.$ZodIssueBase = never> extends ParseContext<T> {
27
27
  readonly async?: boolean | undefined;
28
+ readonly direction?: "forward" | "backward";
29
+ readonly skipChecks?: boolean;
28
30
  }
29
31
 
30
32
  export interface ParsePayload<T = unknown> {
31
33
  value: T;
32
34
  issues: errors.$ZodRawIssue[];
35
+ /** A may to mark a whole payload as aborted. Used in codecs/pipes. */
36
+ aborted?: boolean;
33
37
  }
34
38
 
35
39
  export type CheckFn<T> = (input: ParsePayload<T>) => util.MaybeAsync<void>;
@@ -76,6 +80,7 @@ export interface $ZodTypeDef {
76
80
  | "template_literal"
77
81
  | "promise"
78
82
  | "lazy"
83
+ | "function"
79
84
  | "custom";
80
85
  error?: errors.$ZodErrorMap<never> | undefined;
81
86
  checks?: checks.$ZodCheck<never>[];
@@ -183,7 +188,6 @@ export const $ZodType: core.$constructor<$ZodType> = /*@__PURE__*/ core.$constru
183
188
  if (inst._zod.traits.has("$ZodCheck")) {
184
189
  checks.unshift(inst as any);
185
190
  }
186
- //
187
191
 
188
192
  for (const ch of checks) {
189
193
  for (const fn of ch._zod.onattach) {
@@ -242,9 +246,52 @@ export const $ZodType: core.$constructor<$ZodType> = /*@__PURE__*/ core.$constru
242
246
  return payload;
243
247
  };
244
248
 
249
+ // const handleChecksResult = (
250
+ // checkResult: ParsePayload,
251
+ // originalResult: ParsePayload,
252
+ // ctx: ParseContextInternal
253
+ // ): util.MaybeAsync<ParsePayload> => {
254
+ // // if the checks mutated the value && there are no issues, re-parse the result
255
+ // if (checkResult.value !== originalResult.value && !checkResult.issues.length)
256
+ // return inst._zod.parse(checkResult, ctx);
257
+ // return originalResult;
258
+ // };
259
+ const handleCanaryResult = (canary: ParsePayload, payload: ParsePayload, ctx: ParseContextInternal) => {
260
+ // abort if the canary is aborted
261
+ if (util.aborted(canary)) {
262
+ canary.aborted = true;
263
+ return canary;
264
+ }
265
+
266
+ // run checks first, then
267
+ const checkResult = runChecks(payload, checks, ctx);
268
+ if (checkResult instanceof Promise) {
269
+ if (ctx.async === false) throw new core.$ZodAsyncError();
270
+ return checkResult.then((checkResult) => inst._zod.parse(checkResult, ctx));
271
+ }
272
+ return inst._zod.parse(checkResult, ctx);
273
+ };
274
+
245
275
  inst._zod.run = (payload, ctx) => {
246
- const result = inst._zod.parse(payload, ctx);
276
+ if (ctx.skipChecks) {
277
+ return inst._zod.parse(payload, ctx);
278
+ }
279
+ if (ctx.direction === "backward") {
280
+ // run canary
281
+ // initial pass (no checks)
282
+ const canary = inst._zod.parse({ value: payload.value, issues: [] }, { ...ctx, skipChecks: true });
283
+
284
+ if (canary instanceof Promise) {
285
+ return canary.then((canary) => {
286
+ return handleCanaryResult(canary, payload, ctx);
287
+ });
288
+ }
289
+
290
+ return handleCanaryResult(canary, payload, ctx);
291
+ }
247
292
 
293
+ // forward
294
+ const result = inst._zod.parse(payload, ctx);
248
295
  if (result instanceof Promise) {
249
296
  if (ctx.async === false) throw new core.$ZodAsyncError();
250
297
  return result.then((result) => runChecks(result, checks, ctx));
@@ -1712,27 +1759,72 @@ export interface $ZodObject<
1712
1759
  "~standard": $ZodStandardSchema<this>;
1713
1760
  }
1714
1761
 
1762
+ function normalizeDef(def: $ZodObjectDef) {
1763
+ const keys = Object.keys(def.shape);
1764
+ for (const k of keys) {
1765
+ if (!def.shape[k]._zod.traits.has("$ZodType")) {
1766
+ throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
1767
+ }
1768
+ }
1769
+ const okeys = util.optionalKeys(def.shape);
1770
+
1771
+ return {
1772
+ ...def,
1773
+ keys,
1774
+ keySet: new Set(keys),
1775
+ numKeys: keys.length,
1776
+ optionalKeys: new Set(okeys),
1777
+ };
1778
+ }
1779
+
1780
+ function handleCatchall(
1781
+ proms: Promise<any>[],
1782
+ input: any,
1783
+ payload: ParsePayload,
1784
+ ctx: ParseContext,
1785
+ def: ReturnType<typeof normalizeDef>,
1786
+ inst: $ZodObject
1787
+ ) {
1788
+ const unrecognized: string[] = [];
1789
+ // iterate over input keys
1790
+ const keySet = def.keySet;
1791
+ const _catchall = def.catchall!._zod;
1792
+ const t = _catchall.def.type;
1793
+ for (const key of Object.keys(input)) {
1794
+ if (keySet.has(key)) continue;
1795
+ if (t === "never") {
1796
+ unrecognized.push(key);
1797
+ continue;
1798
+ }
1799
+ const r = _catchall.run({ value: input[key], issues: [] }, ctx);
1800
+
1801
+ if (r instanceof Promise) {
1802
+ proms.push(r.then((r) => handlePropertyResult(r, payload, key, input)));
1803
+ } else {
1804
+ handlePropertyResult(r, payload, key, input);
1805
+ }
1806
+ }
1807
+
1808
+ if (unrecognized.length) {
1809
+ payload.issues.push({
1810
+ code: "unrecognized_keys",
1811
+ keys: unrecognized,
1812
+ input,
1813
+ inst,
1814
+ });
1815
+ }
1816
+
1817
+ if (!proms.length) return payload;
1818
+ return Promise.all(proms).then(() => {
1819
+ return payload;
1820
+ });
1821
+ }
1822
+
1715
1823
  export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$constructor("$ZodObject", (inst, def) => {
1716
1824
  // requires cast because technically $ZodObject doesn't extend
1717
1825
  $ZodType.init(inst, def);
1718
1826
 
1719
- const _normalized = util.cached(() => {
1720
- const keys = Object.keys(def.shape);
1721
- for (const k of keys) {
1722
- if (!def.shape[k]._zod.traits.has("$ZodType")) {
1723
- throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
1724
- }
1725
- }
1726
- const okeys = util.optionalKeys(def.shape);
1727
-
1728
- return {
1729
- shape: def.shape,
1730
- keys,
1731
- keySet: new Set(keys),
1732
- numKeys: keys.length,
1733
- optionalKeys: new Set(okeys),
1734
- };
1735
- });
1827
+ const _normalized = util.cached(() => normalizeDef(def));
1736
1828
 
1737
1829
  util.defineLazy(inst._zod, "propValues", () => {
1738
1830
  const shape = def.shape;
@@ -1747,60 +1839,7 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
1747
1839
  return propValues;
1748
1840
  });
1749
1841
 
1750
- const generateFastpass = (shape: any) => {
1751
- const doc = new Doc(["shape", "payload", "ctx"]);
1752
- const normalized = _normalized.value;
1753
-
1754
- const parseStr = (key: string) => {
1755
- const k = util.esc(key);
1756
- return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
1757
- };
1758
-
1759
- doc.write(`const input = payload.value;`);
1760
-
1761
- const ids: any = Object.create(null);
1762
- let counter = 0;
1763
- for (const key of normalized.keys) {
1764
- ids[key] = `key_${counter++}`;
1765
- }
1766
-
1767
- // A: preserve key order {
1768
- doc.write(`const newResult = {}`);
1769
- for (const key of normalized.keys) {
1770
- const id = ids[key];
1771
- const k = util.esc(key);
1772
- doc.write(`const ${id} = ${parseStr(key)};`);
1773
- doc.write(`
1774
- if (${id}.issues.length) {
1775
- payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
1776
- ...iss,
1777
- path: iss.path ? [${k}, ...iss.path] : [${k}]
1778
- })));
1779
- }
1780
-
1781
- if (${id}.value === undefined) {
1782
- if (${k} in input) {
1783
- newResult[${k}] = undefined;
1784
- }
1785
- } else {
1786
- newResult[${k}] = ${id}.value;
1787
- }
1788
- `);
1789
- }
1790
-
1791
- doc.write(`payload.value = newResult;`);
1792
- doc.write(`return payload;`);
1793
- const fn = doc.compile();
1794
- return (payload: any, ctx: any) => fn(shape, payload, ctx);
1795
- };
1796
-
1797
- let fastpass!: ReturnType<typeof generateFastpass>;
1798
-
1799
1842
  const isObject = util.isObject;
1800
- const jit = !core.globalConfig.jitless;
1801
- const allowsEval = util.allowsEval;
1802
-
1803
- const fastEnabled = jit && allowsEval.value; // && !def.catchall;
1804
1843
  const catchall = def.catchall;
1805
1844
 
1806
1845
  let value!: typeof _normalized.value;
@@ -1819,66 +1858,121 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
1819
1858
  return payload;
1820
1859
  }
1821
1860
 
1822
- const proms: Promise<any>[] = [];
1861
+ payload.value = {};
1823
1862
 
1824
- if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {
1825
- // always synchronous
1826
- if (!fastpass) fastpass = generateFastpass(def.shape);
1827
- payload = fastpass(payload, ctx);
1828
- } else {
1829
- payload.value = {};
1830
-
1831
- const shape = value.shape;
1832
- for (const key of value.keys) {
1833
- const el = shape[key]!;
1834
- const r = el._zod.run({ value: input[key], issues: [] }, ctx);
1835
- if (r instanceof Promise) {
1836
- proms.push(r.then((r) => handlePropertyResult(r, payload, key, input)));
1837
- } else {
1838
- handlePropertyResult(r, payload, key, input);
1839
- }
1863
+ const proms: Promise<any>[] = [];
1864
+ const shape = value.shape;
1865
+ for (const key of value.keys) {
1866
+ const el = shape[key]!;
1867
+ const r = el._zod.run({ value: input[key], issues: [] }, ctx);
1868
+ if (r instanceof Promise) {
1869
+ proms.push(r.then((r) => handlePropertyResult(r, payload, key, input)));
1870
+ } else {
1871
+ handlePropertyResult(r, payload, key, input);
1840
1872
  }
1841
1873
  }
1842
1874
 
1843
1875
  if (!catchall) {
1844
1876
  return proms.length ? Promise.all(proms).then(() => payload) : payload;
1845
1877
  }
1846
- const unrecognized: string[] = [];
1847
- // iterate over input keys
1848
- const keySet = value.keySet;
1849
- const _catchall = catchall._zod;
1850
- const t = _catchall.def.type;
1851
- for (const key of Object.keys(input)) {
1852
- if (keySet.has(key)) continue;
1853
- if (t === "never") {
1854
- unrecognized.push(key);
1855
- continue;
1878
+
1879
+ return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);
1880
+ };
1881
+ });
1882
+
1883
+ export const $ZodObjectJIT: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$constructor(
1884
+ "$ZodObjectJIT",
1885
+ (inst, def) => {
1886
+ // requires cast because technically $ZodObject doesn't extend
1887
+ $ZodObject.init(inst, def);
1888
+
1889
+ const superParse = inst._zod.parse;
1890
+ const _normalized = util.cached(() => normalizeDef(def));
1891
+
1892
+ const generateFastpass = (shape: any) => {
1893
+ const doc = new Doc(["shape", "payload", "ctx"]);
1894
+ const normalized = _normalized.value;
1895
+
1896
+ const parseStr = (key: string) => {
1897
+ const k = util.esc(key);
1898
+ return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
1899
+ };
1900
+
1901
+ doc.write(`const input = payload.value;`);
1902
+
1903
+ const ids: any = Object.create(null);
1904
+ let counter = 0;
1905
+ for (const key of normalized.keys) {
1906
+ ids[key] = `key_${counter++}`;
1856
1907
  }
1857
- const r = _catchall.run({ value: input[key], issues: [] }, ctx);
1858
1908
 
1859
- if (r instanceof Promise) {
1860
- proms.push(r.then((r) => handlePropertyResult(r, payload, key, input)));
1861
- } else {
1862
- handlePropertyResult(r, payload, key, input);
1909
+ // A: preserve key order {
1910
+ doc.write(`const newResult = {}`);
1911
+ for (const key of normalized.keys) {
1912
+ const id = ids[key];
1913
+ const k = util.esc(key);
1914
+ doc.write(`const ${id} = ${parseStr(key)};`);
1915
+ doc.write(`
1916
+ if (${id}.issues.length) {
1917
+ payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
1918
+ ...iss,
1919
+ path: iss.path ? [${k}, ...iss.path] : [${k}]
1920
+ })));
1921
+ }
1922
+
1923
+ if (${id}.value === undefined) {
1924
+ if (${k} in input) {
1925
+ newResult[${k}] = undefined;
1926
+ }
1927
+ } else {
1928
+ newResult[${k}] = ${id}.value;
1929
+ }
1930
+ `);
1863
1931
  }
1864
- }
1865
1932
 
1866
- if (unrecognized.length) {
1867
- payload.issues.push({
1868
- code: "unrecognized_keys",
1933
+ doc.write(`payload.value = newResult;`);
1934
+ doc.write(`return payload;`);
1935
+ const fn = doc.compile();
1936
+ return (payload: any, ctx: any) => fn(shape, payload, ctx);
1937
+ };
1869
1938
 
1870
- keys: unrecognized,
1871
- input,
1872
- inst,
1873
- });
1874
- }
1939
+ let fastpass!: ReturnType<typeof generateFastpass>;
1875
1940
 
1876
- if (!proms.length) return payload;
1877
- return Promise.all(proms).then(() => {
1878
- return payload;
1879
- });
1880
- };
1881
- });
1941
+ const isObject = util.isObject;
1942
+ const jit = !core.globalConfig.jitless;
1943
+ const allowsEval = util.allowsEval;
1944
+
1945
+ const fastEnabled = jit && allowsEval.value; // && !def.catchall;
1946
+ const catchall = def.catchall;
1947
+
1948
+ let value!: typeof _normalized.value;
1949
+
1950
+ inst._zod.parse = (payload, ctx) => {
1951
+ value ??= _normalized.value;
1952
+ const input = payload.value;
1953
+ if (!isObject(input)) {
1954
+ payload.issues.push({
1955
+ expected: "object",
1956
+ code: "invalid_type",
1957
+ input,
1958
+ inst,
1959
+ });
1960
+ return payload;
1961
+ }
1962
+
1963
+ if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {
1964
+ // always synchronous
1965
+ if (!fastpass) fastpass = generateFastpass(def.shape);
1966
+ payload = fastpass(payload, ctx);
1967
+
1968
+ if (!catchall) return payload;
1969
+ return handleCatchall([], input, payload, ctx, value, inst);
1970
+ }
1971
+
1972
+ return superParse(payload, ctx);
1973
+ };
1974
+ }
1975
+ );
1882
1976
 
1883
1977
  /////////////////////////////////////////
1884
1978
  /////////////////////////////////////////
@@ -2971,9 +3065,13 @@ export const $ZodTransform: core.$constructor<$ZodTransform> = /*@__PURE__*/ cor
2971
3065
  "$ZodTransform",
2972
3066
  (inst, def) => {
2973
3067
  $ZodType.init(inst, def);
2974
- inst._zod.parse = (payload, _ctx) => {
3068
+ inst._zod.parse = (payload, ctx) => {
3069
+ if (ctx.direction === "backward") {
3070
+ throw new core.$ZodEncodeError(inst.constructor.name);
3071
+ }
3072
+
2975
3073
  const _out = def.transform(payload.value, payload);
2976
- if (_ctx.async) {
3074
+ if (ctx.async) {
2977
3075
  const output = _out instanceof Promise ? _out : Promise.resolve(_out);
2978
3076
  return output.then((output) => {
2979
3077
  payload.value = output;
@@ -3096,6 +3194,7 @@ export const $ZodNullable: core.$constructor<$ZodNullable> = /*@__PURE__*/ core.
3096
3194
  });
3097
3195
 
3098
3196
  inst._zod.parse = (payload, ctx) => {
3197
+ // Forward direction (decode): allow null to pass through
3099
3198
  if (payload.value === null) return payload;
3100
3199
  return def.innerType._zod.run(payload, ctx);
3101
3200
  };
@@ -3140,13 +3239,19 @@ export const $ZodDefault: core.$constructor<$ZodDefault> = /*@__PURE__*/ core.$c
3140
3239
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
3141
3240
 
3142
3241
  inst._zod.parse = (payload, ctx) => {
3242
+ if (ctx.direction === "backward") {
3243
+ return def.innerType._zod.run(payload, ctx);
3244
+ }
3245
+
3246
+ // Forward direction (decode): apply defaults for undefined input
3143
3247
  if (payload.value === undefined) {
3144
3248
  payload.value = def.defaultValue;
3145
3249
  /**
3146
- * $ZodDefault always returns the default value immediately.
3250
+ * $ZodDefault returns the default value immediately in forward direction.
3147
3251
  * It doesn't pass the default value into the validator ("prefault"). There's no reason to pass the default value through validation. The validity of the default is enforced by TypeScript statically. Otherwise, it's the responsibility of the user to ensure the default is valid. In the case of pipes with divergent in/out types, you can specify the default on the `in` schema of your ZodPipe to set a "prefault" for the pipe. */
3148
3252
  return payload;
3149
3253
  }
3254
+ // Forward direction: continue with default handling
3150
3255
  const result = def.innerType._zod.run(payload, ctx);
3151
3256
  if (result instanceof Promise) {
3152
3257
  return result.then((result) => handleDefaultResult(result, def));
@@ -3200,6 +3305,11 @@ export const $ZodPrefault: core.$constructor<$ZodPrefault> = /*@__PURE__*/ core.
3200
3305
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
3201
3306
 
3202
3307
  inst._zod.parse = (payload, ctx) => {
3308
+ if (ctx.direction === "backward") {
3309
+ return def.innerType._zod.run(payload, ctx);
3310
+ }
3311
+
3312
+ // Forward direction (decode): apply prefault for undefined input
3203
3313
  if (payload.value === undefined) {
3204
3314
  payload.value = def.defaultValue;
3205
3315
  }
@@ -3257,7 +3367,6 @@ function handleNonOptionalResult(payload: ParsePayload, inst: $ZodNonOptional) {
3257
3367
  if (!payload.issues.length && payload.value === undefined) {
3258
3368
  payload.issues.push({
3259
3369
  code: "invalid_type",
3260
-
3261
3370
  expected: "nonoptional",
3262
3371
  input: payload.value,
3263
3372
  inst,
@@ -3335,6 +3444,10 @@ export const $ZodSuccess: core.$constructor<$ZodSuccess> = /*@__PURE__*/ core.$c
3335
3444
  $ZodType.init(inst, def);
3336
3445
 
3337
3446
  inst._zod.parse = (payload, ctx) => {
3447
+ if (ctx.direction === "backward") {
3448
+ throw new core.$ZodEncodeError("ZodSuccess");
3449
+ }
3450
+
3338
3451
  const result = def.innerType._zod.run(payload, ctx);
3339
3452
  if (result instanceof Promise) {
3340
3453
  return result.then((result) => {
@@ -3387,6 +3500,11 @@ export const $ZodCatch: core.$constructor<$ZodCatch> = /*@__PURE__*/ core.$const
3387
3500
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
3388
3501
 
3389
3502
  inst._zod.parse = (payload, ctx) => {
3503
+ if (ctx.direction === "backward") {
3504
+ return def.innerType._zod.run(payload, ctx);
3505
+ }
3506
+
3507
+ // Forward direction (decode): apply catch logic
3390
3508
  const result = def.innerType._zod.run(payload, ctx);
3391
3509
  if (result instanceof Promise) {
3392
3510
  return result.then((result) => {
@@ -3471,6 +3589,10 @@ export interface $ZodPipeDef<A extends SomeType = $ZodType, B extends SomeType =
3471
3589
  type: "pipe";
3472
3590
  in: A;
3473
3591
  out: B;
3592
+ /** Only defined inside $ZodCodec instances. */
3593
+ transform?: (value: core.output<A>, payload: ParsePayload<core.output<A>>) => core.input<B>;
3594
+ /** Only defined inside $ZodCodec instances. */
3595
+ reverseTransform?: (value: core.input<B>, payload: ParsePayload<core.input<B>>) => core.output<A>;
3474
3596
  }
3475
3597
 
3476
3598
  export interface $ZodPipeInternals<A extends SomeType = $ZodType, B extends SomeType = $ZodType>
@@ -3495,19 +3617,114 @@ export const $ZodPipe: core.$constructor<$ZodPipe> = /*@__PURE__*/ core.$constru
3495
3617
  util.defineLazy(inst._zod, "propValues", () => def.in._zod.propValues);
3496
3618
 
3497
3619
  inst._zod.parse = (payload, ctx) => {
3620
+ if (ctx.direction === "backward") {
3621
+ const right = def.out._zod.run(payload, ctx);
3622
+ if (right instanceof Promise) {
3623
+ return right.then((right) => handlePipeResult(right, def.in, ctx));
3624
+ }
3625
+ return handlePipeResult(right, def.in, ctx);
3626
+ }
3627
+
3498
3628
  const left = def.in._zod.run(payload, ctx);
3499
3629
  if (left instanceof Promise) {
3500
- return left.then((left) => handlePipeResult(left, def, ctx));
3630
+ return left.then((left) => handlePipeResult(left, def.out, ctx));
3501
3631
  }
3502
- return handlePipeResult(left, def, ctx);
3632
+ return handlePipeResult(left, def.out, ctx);
3503
3633
  };
3504
3634
  });
3505
3635
 
3506
- function handlePipeResult(left: ParsePayload, def: $ZodPipeDef, ctx: ParseContext) {
3636
+ function handlePipeResult(left: ParsePayload, next: $ZodType, ctx: ParseContextInternal) {
3507
3637
  if (left.issues.length) {
3638
+ // prevent further checks
3639
+ left.aborted = true;
3508
3640
  return left;
3509
3641
  }
3510
- return def.out._zod.run({ value: left.value, issues: left.issues }, ctx);
3642
+ return next._zod.run({ value: left.value, issues: left.issues }, ctx);
3643
+ }
3644
+
3645
+ ////////////////////////////////////////////
3646
+ ////////////////////////////////////////////
3647
+ ////////// //////////
3648
+ ////////// $ZodCodec //////////
3649
+ ////////// //////////
3650
+ ////////////////////////////////////////////
3651
+ ////////////////////////////////////////////
3652
+ export interface $ZodCodecDef<A extends SomeType = $ZodType, B extends SomeType = $ZodType> extends $ZodPipeDef<A, B> {
3653
+ transform: (value: core.output<A>, payload: ParsePayload<core.output<A>>) => core.input<B>;
3654
+ reverseTransform: (value: core.input<B>, payload: ParsePayload<core.input<B>>) => core.output<A>;
3655
+ }
3656
+
3657
+ export interface $ZodCodecInternals<A extends SomeType = $ZodType, B extends SomeType = $ZodType>
3658
+ extends $ZodTypeInternals<core.output<B>, core.input<A>> {
3659
+ def: $ZodCodecDef<A, B>;
3660
+ isst: never;
3661
+ values: A["_zod"]["values"];
3662
+ optin: A["_zod"]["optin"];
3663
+ optout: B["_zod"]["optout"];
3664
+ propValues: A["_zod"]["propValues"];
3665
+ }
3666
+
3667
+ export interface $ZodCodec<A extends SomeType = $ZodType, B extends SomeType = $ZodType> extends $ZodType {
3668
+ _zod: $ZodCodecInternals<A, B>;
3669
+ }
3670
+
3671
+ export const $ZodCodec: core.$constructor<$ZodCodec> = /*@__PURE__*/ core.$constructor("$ZodCodec", (inst, def) => {
3672
+ $ZodType.init(inst, def);
3673
+ util.defineLazy(inst._zod, "values", () => def.in._zod.values);
3674
+ util.defineLazy(inst._zod, "optin", () => def.in._zod.optin);
3675
+ util.defineLazy(inst._zod, "optout", () => def.out._zod.optout);
3676
+ util.defineLazy(inst._zod, "propValues", () => def.in._zod.propValues);
3677
+
3678
+ inst._zod.parse = (payload, ctx) => {
3679
+ const direction = ctx.direction || "forward";
3680
+ if (direction === "forward") {
3681
+ const left = def.in._zod.run(payload, ctx);
3682
+ if (left instanceof Promise) {
3683
+ return left.then((left) => handleCodecAResult(left, def, ctx));
3684
+ }
3685
+ return handleCodecAResult(left, def, ctx);
3686
+ } else {
3687
+ const right = def.out._zod.run(payload, ctx);
3688
+ if (right instanceof Promise) {
3689
+ return right.then((right) => handleCodecAResult(right, def, ctx));
3690
+ }
3691
+ return handleCodecAResult(right, def, ctx);
3692
+ }
3693
+ };
3694
+ });
3695
+
3696
+ function handleCodecAResult(result: ParsePayload, def: $ZodCodecDef, ctx: ParseContextInternal) {
3697
+ if (result.issues.length) {
3698
+ // prevent further checks
3699
+ result.aborted = true;
3700
+ return result;
3701
+ }
3702
+
3703
+ const direction = ctx.direction || "forward";
3704
+
3705
+ if (direction === "forward") {
3706
+ const transformed = def.transform(result.value, result);
3707
+ if (transformed instanceof Promise) {
3708
+ return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx));
3709
+ }
3710
+ return handleCodecTxResult(result, transformed, def.out, ctx);
3711
+ } else {
3712
+ const transformed = def.reverseTransform(result.value, result);
3713
+ if (transformed instanceof Promise) {
3714
+ return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx));
3715
+ }
3716
+ return handleCodecTxResult(result, transformed, def.in, ctx);
3717
+ }
3718
+ }
3719
+
3720
+ function handleCodecTxResult(left: ParsePayload, value: any, nextSchema: SomeType, ctx: ParseContextInternal) {
3721
+ // Check if transform added any issues
3722
+ if (left.issues.length) {
3723
+ left.aborted = true;
3724
+ return left;
3725
+ }
3726
+
3727
+ return nextSchema._zod.run({ value, issues: left.issues }, ctx);
3511
3728
  }
3512
3729
 
3513
3730
  ////////////////////////////////////////////
@@ -3547,6 +3764,9 @@ export const $ZodReadonly: core.$constructor<$ZodReadonly> = /*@__PURE__*/ core.
3547
3764
  util.defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
3548
3765
 
3549
3766
  inst._zod.parse = (payload, ctx) => {
3767
+ if (ctx.direction === "backward") {
3768
+ return def.innerType._zod.run(payload, ctx);
3769
+ }
3550
3770
  const result = def.innerType._zod.run(payload, ctx);
3551
3771
  if (result instanceof Promise) {
3552
3772
  return result.then(handleReadonlyResult);
@@ -3692,6 +3912,174 @@ export const $ZodTemplateLiteral: core.$constructor<$ZodTemplateLiteral> = /*@__
3692
3912
  }
3693
3913
  );
3694
3914
 
3915
+ //////////////////////////////////////////
3916
+ //////////////////////////////////////////
3917
+ ////////// //////////
3918
+ ////////// $ZodFunction //////////
3919
+ ////////// //////////
3920
+ //////////////////////////////////////////
3921
+ //////////////////////////////////////////
3922
+ export type $ZodFunctionArgs = $ZodType<unknown[], unknown[]>;
3923
+ export type $ZodFunctionIn = $ZodFunctionArgs;
3924
+ export type $ZodFunctionOut = $ZodType;
3925
+
3926
+ export type $InferInnerFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
3927
+ ...args: $ZodFunctionIn extends Args ? never[] : core.output<Args>
3928
+ ) => core.input<Returns>;
3929
+
3930
+ export type $InferInnerFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
3931
+ ...args: $ZodFunctionIn extends Args ? never[] : core.output<Args>
3932
+ ) => util.MaybeAsync<core.input<Returns>>;
3933
+
3934
+ export type $InferOuterFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
3935
+ ...args: $ZodFunctionIn extends Args ? never[] : core.input<Args>
3936
+ ) => core.output<Returns>;
3937
+
3938
+ export type $InferOuterFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
3939
+ ...args: $ZodFunctionIn extends Args ? never[] : core.input<Args>
3940
+ ) => util.MaybeAsync<core.output<Returns>>;
3941
+
3942
+ export interface $ZodFunctionDef<
3943
+ In extends $ZodFunctionIn = $ZodFunctionIn,
3944
+ Out extends $ZodFunctionOut = $ZodFunctionOut,
3945
+ > extends $ZodTypeDef {
3946
+ type: "function";
3947
+ input: In;
3948
+ output: Out;
3949
+ }
3950
+
3951
+ export interface $ZodFunctionInternals<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut>
3952
+ extends $ZodTypeInternals<$InferOuterFunctionType<Args, Returns>, $InferInnerFunctionType<Args, Returns>> {
3953
+ def: $ZodFunctionDef<Args, Returns>;
3954
+ isst: errors.$ZodIssueInvalidType;
3955
+ }
3956
+
3957
+ export interface $ZodFunction<
3958
+ Args extends $ZodFunctionIn = $ZodFunctionIn,
3959
+ Returns extends $ZodFunctionOut = $ZodFunctionOut,
3960
+ > extends $ZodType<any, any, $ZodFunctionInternals<Args, Returns>> {
3961
+ /** @deprecated */
3962
+ _def: $ZodFunctionDef<Args, Returns>;
3963
+ _input: $InferInnerFunctionType<Args, Returns>;
3964
+ _output: $InferOuterFunctionType<Args, Returns>;
3965
+
3966
+ implement<F extends $InferInnerFunctionType<Args, Returns>>(
3967
+ func: F
3968
+ ): // allow for return type inference
3969
+ (
3970
+ ...args: Parameters<this["_output"]>
3971
+ ) => ReturnType<F> extends ReturnType<this["_output"]> ? ReturnType<F> : ReturnType<this["_output"]>;
3972
+
3973
+ implementAsync<F extends $InferInnerFunctionTypeAsync<Args, Returns>>(
3974
+ func: F
3975
+ ): F extends $InferOuterFunctionTypeAsync<Args, Returns> ? F : $InferOuterFunctionTypeAsync<Args, Returns>;
3976
+
3977
+ input<const Items extends util.TupleItems, const Rest extends $ZodFunctionOut = $ZodFunctionOut>(
3978
+ args: Items,
3979
+ rest?: Rest
3980
+ ): $ZodFunction<$ZodTuple<Items, Rest>, Returns>;
3981
+ input<NewArgs extends $ZodFunctionIn>(args: NewArgs): $ZodFunction<NewArgs, Returns>;
3982
+ input(...args: any[]): $ZodFunction<any, Returns>;
3983
+
3984
+ output<NewReturns extends $ZodType>(output: NewReturns): $ZodFunction<Args, NewReturns>;
3985
+ }
3986
+
3987
+ export interface $ZodFunctionParams<I extends $ZodFunctionIn, O extends $ZodType> {
3988
+ input?: I;
3989
+ output?: O;
3990
+ }
3991
+
3992
+ export const $ZodFunction: core.$constructor<$ZodFunction> = /*@__PURE__*/ core.$constructor(
3993
+ "$ZodFunction",
3994
+ (inst, def) => {
3995
+ $ZodType.init(inst, def);
3996
+ inst._def = def;
3997
+ inst._zod.def = def;
3998
+
3999
+ inst.implement = (func) => {
4000
+ if (typeof func !== "function") {
4001
+ throw new Error("implement() must be called with a function");
4002
+ }
4003
+ return function (this: any, ...args: never[]) {
4004
+ const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args;
4005
+ const result = Reflect.apply(func, this, parsedArgs as never[]);
4006
+ if (inst._def.output) {
4007
+ return parse(inst._def.output, result);
4008
+ }
4009
+ return result as any;
4010
+ };
4011
+ };
4012
+
4013
+ inst.implementAsync = (func) => {
4014
+ if (typeof func !== "function") {
4015
+ throw new Error("implementAsync() must be called with a function");
4016
+ }
4017
+ return async function (this: any, ...args: never[]) {
4018
+ const parsedArgs = inst._def.input ? await parseAsync(inst._def.input, args) : args;
4019
+ const result = await Reflect.apply(func, this, parsedArgs as never[]);
4020
+ if (inst._def.output) {
4021
+ return await parseAsync(inst._def.output, result);
4022
+ }
4023
+ return result;
4024
+ } as any;
4025
+ };
4026
+
4027
+ inst._zod.parse = (payload, _ctx) => {
4028
+ if (typeof payload.value !== "function") {
4029
+ payload.issues.push({
4030
+ code: "invalid_type",
4031
+ expected: "function",
4032
+ input: payload.value,
4033
+ inst,
4034
+ });
4035
+ return payload;
4036
+ }
4037
+
4038
+ // Check if output is a promise type to determine if we should use async implementation
4039
+ const hasPromiseOutput = inst._def.output && inst._def.output._zod.def.type === "promise";
4040
+
4041
+ if (hasPromiseOutput) {
4042
+ payload.value = inst.implementAsync(payload.value);
4043
+ } else {
4044
+ payload.value = inst.implement(payload.value);
4045
+ }
4046
+ return payload;
4047
+ };
4048
+
4049
+ inst.input = (...args: any[]): $ZodFunction<any, any> => {
4050
+ const F: any = inst.constructor;
4051
+ if (Array.isArray(args[0])) {
4052
+ return new F({
4053
+ type: "function",
4054
+ input: new $ZodTuple({
4055
+ type: "tuple",
4056
+ items: args[0],
4057
+ rest: args[1],
4058
+ }),
4059
+ output: inst._def.output,
4060
+ });
4061
+ }
4062
+
4063
+ return new F({
4064
+ type: "function",
4065
+ input: args[0],
4066
+ output: inst._def.output,
4067
+ });
4068
+ };
4069
+
4070
+ inst.output = (output) => {
4071
+ const F: any = inst.constructor;
4072
+ return new F({
4073
+ type: "function",
4074
+ input: inst._def.input,
4075
+ output,
4076
+ });
4077
+ };
4078
+
4079
+ return inst;
4080
+ }
4081
+ );
4082
+
3695
4083
  /////////////////////////////////////////
3696
4084
  /////////////////////////////////////////
3697
4085
  ////////// //////////
@@ -3864,6 +4252,7 @@ export type $ZodTypes =
3864
4252
  | $ZodSet
3865
4253
  | $ZodLiteral
3866
4254
  | $ZodEnum
4255
+ | $ZodFunction
3867
4256
  | $ZodPromise
3868
4257
  | $ZodLazy
3869
4258
  | $ZodOptional
@@ -3903,4 +4292,7 @@ export type $ZodStringFormatTypes =
3903
4292
  | $ZodBase64
3904
4293
  | $ZodBase64URL
3905
4294
  | $ZodE164
3906
- | $ZodJWT;
4295
+ | $ZodJWT
4296
+ | $ZodCustomStringFormat<"hex">
4297
+ | $ZodCustomStringFormat<util.HashFormat>
4298
+ | $ZodCustomStringFormat<"hostname">;