zod 4.0.5 → 4.0.7

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 (86) hide show
  1. package/package.json +1 -1
  2. package/src/v3/tests/string.test.ts +2 -2
  3. package/src/v3/types.ts +3 -1
  4. package/src/v4/classic/errors.ts +9 -2
  5. package/src/v4/classic/schemas.ts +11 -9
  6. package/src/v4/classic/tests/catch.test.ts +4 -5
  7. package/src/v4/classic/tests/discriminated-unions.test.ts +12 -0
  8. package/src/v4/classic/tests/error-utils.test.ts +43 -0
  9. package/src/v4/classic/tests/literal.test.ts +25 -0
  10. package/src/v4/classic/tests/partial.test.ts +193 -0
  11. package/src/v4/classic/tests/pickomit.test.ts +5 -5
  12. package/src/v4/classic/tests/preprocess.test.ts +4 -15
  13. package/src/v4/classic/tests/record.test.ts +15 -1
  14. package/src/v4/classic/tests/recursive-types.test.ts +67 -0
  15. package/src/v4/classic/tests/string.test.ts +81 -4
  16. package/src/v4/classic/tests/template-literal.test.ts +3 -0
  17. package/src/v4/classic/tests/to-json-schema.test.ts +1 -0
  18. package/src/v4/classic/tests/transform.test.ts +104 -0
  19. package/src/v4/classic/tests/union.test.ts +45 -3
  20. package/src/v4/core/checks.ts +2 -2
  21. package/src/v4/core/errors.ts +8 -15
  22. package/src/v4/core/regexes.ts +1 -1
  23. package/src/v4/core/registries.ts +3 -2
  24. package/src/v4/core/schemas.ts +91 -99
  25. package/src/v4/core/to-json-schema.ts +1 -0
  26. package/src/v4/core/util.ts +175 -115
  27. package/src/v4/core/versions.ts +1 -1
  28. package/src/v4/locales/bg.ts +136 -0
  29. package/src/v4/locales/da.ts +141 -0
  30. package/src/v4/locales/index.ts +2 -0
  31. package/src/v4/locales/is.ts +127 -0
  32. package/src/v4/mini/schemas.ts +3 -1
  33. package/v3/types.cjs +2 -0
  34. package/v3/types.d.cts +4 -1
  35. package/v3/types.d.ts +4 -1
  36. package/v3/types.js +2 -0
  37. package/v4/classic/errors.cjs +9 -2
  38. package/v4/classic/errors.js +9 -2
  39. package/v4/classic/schemas.cjs +5 -3
  40. package/v4/classic/schemas.d.cts +3 -3
  41. package/v4/classic/schemas.d.ts +3 -3
  42. package/v4/classic/schemas.js +5 -3
  43. package/v4/core/checks.d.cts +2 -2
  44. package/v4/core/checks.d.ts +2 -2
  45. package/v4/core/errors.cjs +4 -9
  46. package/v4/core/errors.d.cts +4 -6
  47. package/v4/core/errors.d.ts +4 -6
  48. package/v4/core/errors.js +4 -9
  49. package/v4/core/regexes.cjs +1 -1
  50. package/v4/core/regexes.d.cts +1 -1
  51. package/v4/core/regexes.d.ts +1 -1
  52. package/v4/core/regexes.js +1 -1
  53. package/v4/core/registries.cjs +2 -1
  54. package/v4/core/registries.d.cts +1 -1
  55. package/v4/core/registries.d.ts +1 -1
  56. package/v4/core/registries.js +2 -1
  57. package/v4/core/schemas.cjs +48 -88
  58. package/v4/core/schemas.d.cts +9 -4
  59. package/v4/core/schemas.d.ts +9 -4
  60. package/v4/core/schemas.js +48 -88
  61. package/v4/core/to-json-schema.cjs +1 -0
  62. package/v4/core/to-json-schema.js +1 -0
  63. package/v4/core/util.cjs +163 -112
  64. package/v4/core/util.d.cts +1 -0
  65. package/v4/core/util.d.ts +1 -0
  66. package/v4/core/util.js +162 -112
  67. package/v4/core/versions.cjs +1 -1
  68. package/v4/core/versions.js +1 -1
  69. package/v4/locales/bg.cjs +156 -0
  70. package/v4/locales/bg.d.cts +5 -0
  71. package/v4/locales/bg.d.ts +5 -0
  72. package/v4/locales/bg.js +128 -0
  73. package/v4/locales/da.cjs +157 -0
  74. package/v4/locales/da.d.cts +4 -0
  75. package/v4/locales/da.d.ts +4 -0
  76. package/v4/locales/da.js +131 -0
  77. package/v4/locales/index.cjs +5 -1
  78. package/v4/locales/index.d.cts +2 -0
  79. package/v4/locales/index.d.ts +2 -0
  80. package/v4/locales/index.js +2 -0
  81. package/v4/locales/is.cjs +145 -0
  82. package/v4/locales/is.d.cts +5 -0
  83. package/v4/locales/is.d.ts +5 -0
  84. package/v4/locales/is.js +117 -0
  85. package/v4/mini/schemas.cjs +3 -1
  86. package/v4/mini/schemas.js +3 -1
@@ -121,6 +121,9 @@ export interface _$ZodTypeInternals {
121
121
  */
122
122
  values?: util.PrimitiveSet | undefined;
123
123
 
124
+ /** Default value bubbled up from */
125
+ // default?: unknown | undefined;
126
+
124
127
  /** @internal A set of literal discriminators used for the fast path in discriminated unions. */
125
128
  propValues?: util.PropValues | undefined;
126
129
 
@@ -414,6 +417,7 @@ export const $ZodEmail: core.$constructor<$ZodEmail> = /*@__PURE__*/ core.$const
414
417
  export interface $ZodURLDef extends $ZodStringFormatDef<"url"> {
415
418
  hostname?: RegExp | undefined;
416
419
  protocol?: RegExp | undefined;
420
+ normalize?: boolean | undefined;
417
421
  }
418
422
  export interface $ZodURLInternals extends $ZodStringFormatInternals<"url"> {
419
423
  def: $ZodURLDef;
@@ -427,9 +431,10 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
427
431
  $ZodStringFormat.init(inst, def);
428
432
  inst._zod.check = (payload) => {
429
433
  try {
430
- const orig = payload.value;
431
- const url = new URL(orig);
432
- const href = url.href;
434
+ // Trim whitespace from input
435
+ const trimmed = payload.value.trim();
436
+ // @ts-ignore
437
+ const url = new URL(trimmed);
433
438
 
434
439
  if (def.hostname) {
435
440
  def.hostname.lastIndex = 0;
@@ -461,11 +466,13 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
461
466
  }
462
467
  }
463
468
 
464
- // payload.value = url.href;
465
- if (!orig.endsWith("/") && href.endsWith("/")) {
466
- payload.value = href.slice(0, -1);
469
+ // Set the output value based on normalize flag
470
+ if (def.normalize) {
471
+ // Use normalized URL
472
+ payload.value = url.href;
467
473
  } else {
468
- payload.value = href;
474
+ // Preserve the original input (trimmed)
475
+ payload.value = trimmed;
469
476
  }
470
477
 
471
478
  return;
@@ -719,6 +726,7 @@ export const $ZodIPv6: core.$constructor<$ZodIPv6> = /*@__PURE__*/ core.$constru
719
726
 
720
727
  inst._zod.check = (payload) => {
721
728
  try {
729
+ // @ts-ignore
722
730
  new URL(`http://[${payload.value}]`);
723
731
  // return;
724
732
  } catch {
@@ -782,6 +790,7 @@ export const $ZodCIDRv6: core.$constructor<$ZodCIDRv6> = /*@__PURE__*/ core.$con
782
790
  const prefixNum = Number(prefix);
783
791
  if (`${prefixNum}` !== prefix) throw new Error();
784
792
  if (prefixNum < 0 || prefixNum > 128) throw new Error();
793
+ // @ts-ignore
785
794
  new URL(`http://[${address}]`);
786
795
  } catch {
787
796
  payload.issues.push({
@@ -801,6 +810,7 @@ export function isValidBase64(data: string): boolean {
801
810
  if (data === "") return true;
802
811
  if (data.length % 4 !== 0) return false;
803
812
  try {
813
+ // @ts-ignore
804
814
  atob(data);
805
815
  return true;
806
816
  } catch {
@@ -900,6 +910,7 @@ export function isValidJWT(token: string, algorithm: util.JWTAlgorithm | null =
900
910
  if (tokensParts.length !== 3) return false;
901
911
  const [header] = tokensParts;
902
912
  if (!header) return false;
913
+ // @ts-ignore
903
914
  const parsedHeader = JSON.parse(atob(header));
904
915
  if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT") return false;
905
916
  if (!parsedHeader.alg) return false;
@@ -1582,6 +1593,36 @@ export type $InferObjectOutput<T extends $ZodLooseShape, Extra extends Record<st
1582
1593
  } & Extra
1583
1594
  >;
1584
1595
 
1596
+ // experimental
1597
+ // export type $InferObjectOutput<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = keyof (T &
1598
+ // Extra) extends never
1599
+ // ? Record<string, never>
1600
+ // : string extends keyof T
1601
+ // ? util.Prettify<
1602
+ // {
1603
+ // [k: string]: util.IsAny<T[string]["_zod"]["output"]> extends true ? unknown : T[string]["_zod"]["output"];
1604
+ // } & $InferObjectOutputNoIndex<util.OmitIndexSignature<T>, Extra>
1605
+ // >
1606
+ // : util.Prettify<$InferObjectOutputNoIndex<T, Extra>>;
1607
+
1608
+ // export type $InferObjectOutputNoIndex<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = {
1609
+ // [k in keyof T as string extends k
1610
+ // ? never
1611
+ // : k extends string
1612
+ // ? T[k] extends OptionalOutSchema
1613
+ // ? never
1614
+ // : k
1615
+ // : never]: T[k]["_zod"]["output"];
1616
+ // } & {
1617
+ // [k in keyof T as string extends k
1618
+ // ? never
1619
+ // : k extends string
1620
+ // ? T[k] extends OptionalOutSchema
1621
+ // ? k
1622
+ // : never
1623
+ // : never]?: T[k]["_zod"]["output"];
1624
+ // } & Extra;
1625
+
1585
1626
  export type $InferObjectInput<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = string extends keyof T
1586
1627
  ? util.IsAny<T[keyof T]> extends true
1587
1628
  ? Record<string, unknown>
@@ -1596,33 +1637,16 @@ export type $InferObjectInput<T extends $ZodLooseShape, Extra extends Record<str
1596
1637
  } & Extra
1597
1638
  >;
1598
1639
 
1599
- function handleObjectResult(result: ParsePayload, final: ParsePayload, key: PropertyKey) {
1600
- // if(isOptional)
1640
+ function handlePropertyResult(result: ParsePayload, final: ParsePayload, key: PropertyKey, input: any) {
1601
1641
  if (result.issues.length) {
1602
1642
  final.issues.push(...util.prefixIssues(key, result.issues));
1603
1643
  }
1604
1644
 
1605
- (final.value as any)[key] = result.value;
1606
- }
1607
-
1608
- function handleOptionalObjectResult(result: ParsePayload, final: ParsePayload, key: PropertyKey, input: any) {
1609
- if (result.issues.length) {
1610
- // validation failed against value schema
1611
- if (input[key] === undefined) {
1612
- // if input was undefined, ignore the error
1613
- if (key in input) {
1614
- (final.value as any)[key] = undefined;
1615
- } else {
1616
- (final.value as any)[key] = result.value;
1617
- }
1618
- } else {
1619
- final.issues.push(...util.prefixIssues(key, result.issues));
1645
+ if (result.value === undefined) {
1646
+ if (key in input) {
1647
+ (final.value as any)[key] = undefined;
1620
1648
  }
1621
- } else if (result.value === undefined) {
1622
- // validation returned `undefined`
1623
- if (key in input) (final.value as any)[key] = undefined;
1624
1649
  } else {
1625
- // non-undefined value
1626
1650
  (final.value as any)[key] = result.value;
1627
1651
  }
1628
1652
  }
@@ -1732,41 +1756,25 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
1732
1756
  // A: preserve key order {
1733
1757
  doc.write(`const newResult = {}`);
1734
1758
  for (const key of normalized.keys) {
1735
- if (normalized.optionalKeys.has(key)) {
1736
- const id = ids[key];
1737
- doc.write(`const ${id} = ${parseStr(key)};`);
1738
- const k = util.esc(key);
1739
- doc.write(`
1759
+ const id = ids[key];
1760
+ const k = util.esc(key);
1761
+ doc.write(`const ${id} = ${parseStr(key)};`);
1762
+ doc.write(`
1740
1763
  if (${id}.issues.length) {
1741
- if (input[${k}] === undefined) {
1742
- if (${k} in input) {
1743
- newResult[${k}] = undefined;
1744
- }
1745
- } else {
1746
- payload.issues = payload.issues.concat(
1747
- ${id}.issues.map((iss) => ({
1748
- ...iss,
1749
- path: iss.path ? [${k}, ...iss.path] : [${k}],
1750
- }))
1751
- );
1764
+ payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
1765
+ ...iss,
1766
+ path: iss.path ? [${k}, ...iss.path] : [${k}]
1767
+ })));
1768
+ }
1769
+
1770
+ if (${id}.value === undefined) {
1771
+ if (${k} in input) {
1772
+ newResult[${k}] = undefined;
1752
1773
  }
1753
- } else if (${id}.value === undefined) {
1754
- if (${k} in input) newResult[${k}] = undefined;
1755
1774
  } else {
1756
1775
  newResult[${k}] = ${id}.value;
1757
1776
  }
1758
- `);
1759
- } else {
1760
- const id = ids[key];
1761
- // const id = ids[key];
1762
- doc.write(`const ${id} = ${parseStr(key)};`);
1763
- doc.write(`
1764
- if (${id}.issues.length) payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
1765
- ...iss,
1766
- path: iss.path ? [${util.esc(key)}, ...iss.path] : [${util.esc(key)}]
1767
- })));`);
1768
- doc.write(`newResult[${util.esc(key)}] = ${id}.value`);
1769
- }
1777
+ `);
1770
1778
  }
1771
1779
 
1772
1780
  doc.write(`payload.value = newResult;`);
@@ -1811,39 +1819,16 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
1811
1819
  const shape = value.shape;
1812
1820
  for (const key of value.keys) {
1813
1821
  const el = shape[key]!;
1814
-
1815
- // do not add omitted optional keys
1816
- // if (!(key in input)) {
1817
- // if (optionalKeys.has(key)) continue;
1818
- // payload.issues.push({
1819
- // code: "invalid_type",
1820
- // path: [key],
1821
- // expected: "nonoptional",
1822
- // note: `Missing required key: "${key}"`,
1823
- // input,
1824
- // inst,
1825
- // });
1826
- // }
1827
-
1828
1822
  const r = el._zod.run({ value: input[key], issues: [] }, ctx);
1829
- const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
1830
-
1831
1823
  if (r instanceof Promise) {
1832
- proms.push(
1833
- r.then((r) =>
1834
- isOptional ? handleOptionalObjectResult(r, payload, key, input) : handleObjectResult(r, payload, key)
1835
- )
1836
- );
1837
- } else if (isOptional) {
1838
- handleOptionalObjectResult(r, payload, key, input);
1824
+ proms.push(r.then((r) => handlePropertyResult(r, payload, key, input)));
1839
1825
  } else {
1840
- handleObjectResult(r, payload, key);
1826
+ handlePropertyResult(r, payload, key, input);
1841
1827
  }
1842
1828
  }
1843
1829
  }
1844
1830
 
1845
1831
  if (!catchall) {
1846
- // return payload;
1847
1832
  return proms.length ? Promise.all(proms).then(() => payload) : payload;
1848
1833
  }
1849
1834
  const unrecognized: string[] = [];
@@ -1860,9 +1845,9 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
1860
1845
  const r = _catchall.run({ value: input[key], issues: [] }, ctx);
1861
1846
 
1862
1847
  if (r instanceof Promise) {
1863
- proms.push(r.then((r) => handleObjectResult(r, payload, key)));
1848
+ proms.push(r.then((r) => handlePropertyResult(r, payload, key, input)));
1864
1849
  } else {
1865
- handleObjectResult(r, payload, key);
1850
+ handlePropertyResult(r, payload, key, input);
1866
1851
  }
1867
1852
  }
1868
1853
 
@@ -1925,6 +1910,12 @@ function handleUnionResults(results: ParsePayload[], final: ParsePayload, inst:
1925
1910
  }
1926
1911
  }
1927
1912
 
1913
+ const nonaborted = results.filter((r) => !util.aborted(r));
1914
+ if (nonaborted.length > 0) {
1915
+ final.value = nonaborted[0].value;
1916
+ return nonaborted[0];
1917
+ }
1918
+
1928
1919
  final.issues.push({
1929
1920
  code: "invalid_union",
1930
1921
  input: final.value,
@@ -2737,8 +2728,8 @@ export const $ZodEnum: core.$constructor<$ZodEnum> = /*@__PURE__*/ core.$constru
2737
2728
  $ZodType.init(inst, def);
2738
2729
 
2739
2730
  const values = util.getEnumValues(def.entries);
2740
-
2741
- inst._zod.values = new Set<util.Primitive>(values);
2731
+ const valuesSet = new Set<util.Primitive>(values);
2732
+ inst._zod.values = valuesSet;
2742
2733
 
2743
2734
  inst._zod.pattern = new RegExp(
2744
2735
  `^(${values
@@ -2749,7 +2740,7 @@ export const $ZodEnum: core.$constructor<$ZodEnum> = /*@__PURE__*/ core.$constru
2749
2740
 
2750
2741
  inst._zod.parse = (payload, _ctx) => {
2751
2742
  const input = payload.value;
2752
- if (inst._zod.values.has(input)) {
2743
+ if (valuesSet.has(input)) {
2753
2744
  return payload;
2754
2745
  }
2755
2746
  payload.issues.push({
@@ -2795,7 +2786,7 @@ export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$c
2795
2786
  inst._zod.pattern = new RegExp(
2796
2787
  `^(${def.values
2797
2788
 
2798
- .map((o) => (typeof o === "string" ? util.escapeRegex(o) : o ? o.toString() : String(o)))
2789
+ .map((o) => (typeof o === "string" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o)))
2799
2790
  .join("|")})$`
2800
2791
  );
2801
2792
 
@@ -2865,10 +2856,12 @@ export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$c
2865
2856
  //////////////////////////////////////////
2866
2857
 
2867
2858
  // provide a fallback in case the File interface isn't provided in the environment
2868
- type _File = typeof globalThis extends { File: new (...args: any[]) => any }
2869
- ? InstanceType<typeof globalThis.File>
2870
- : {};
2871
- interface File extends _File {}
2859
+ type _File = typeof globalThis extends { File: infer F extends new (...args: any[]) => any } ? InstanceType<F> : {};
2860
+ /** Do not reference this directly. */
2861
+ export interface File extends _File {
2862
+ type: string;
2863
+ size: number;
2864
+ }
2872
2865
 
2873
2866
  export interface $ZodFileDef extends $ZodTypeDef {
2874
2867
  type: "file";
@@ -2893,6 +2886,7 @@ export const $ZodFile: core.$constructor<$ZodFile> = /*@__PURE__*/ core.$constru
2893
2886
 
2894
2887
  inst._zod.parse = (payload, _ctx) => {
2895
2888
  const input = payload.value;
2889
+ // @ts-ignore
2896
2890
  if (input instanceof File) return payload;
2897
2891
  payload.issues.push({
2898
2892
  expected: "file",
@@ -3315,11 +3309,8 @@ export interface $ZodCatchDef<T extends SomeType = $ZodType> extends $ZodTypeDef
3315
3309
  }
3316
3310
 
3317
3311
  export interface $ZodCatchInternals<T extends SomeType = $ZodType>
3318
- extends $ZodTypeInternals<core.output<T>, core.input<T> | util.Whatever> {
3312
+ extends $ZodTypeInternals<core.output<T>, core.input<T>> {
3319
3313
  def: $ZodCatchDef<T>;
3320
- // qin: T["_zod"]["qin"];
3321
- // qout: T["_zod"]["qout"];
3322
-
3323
3314
  optin: T["_zod"]["optin"];
3324
3315
  optout: T["_zod"]["optout"];
3325
3316
  isst: never;
@@ -3332,7 +3323,7 @@ export interface $ZodCatch<T extends SomeType = $ZodType> extends $ZodType {
3332
3323
 
3333
3324
  export const $ZodCatch: core.$constructor<$ZodCatch> = /*@__PURE__*/ core.$constructor("$ZodCatch", (inst, def) => {
3334
3325
  $ZodType.init(inst, def);
3335
- inst._zod.optin = "optional";
3326
+ util.defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
3336
3327
  util.defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
3337
3328
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
3338
3329
 
@@ -3365,6 +3356,7 @@ export const $ZodCatch: core.$constructor<$ZodCatch> = /*@__PURE__*/ core.$const
3365
3356
  },
3366
3357
  input: payload.value,
3367
3358
  });
3359
+
3368
3360
  payload.issues = [];
3369
3361
  }
3370
3362
 
@@ -3453,7 +3445,7 @@ export const $ZodPipe: core.$constructor<$ZodPipe> = /*@__PURE__*/ core.$constru
3453
3445
  });
3454
3446
 
3455
3447
  function handlePipeResult(left: ParsePayload, def: $ZodPipeDef, ctx: ParseContext) {
3456
- if (util.aborted(left)) {
3448
+ if (left.issues.length) {
3457
3449
  return left;
3458
3450
  }
3459
3451
  return def.out._zod.run({ value: left.value, issues: left.issues }, ctx);
@@ -777,6 +777,7 @@ export class JSONSchemaGenerator {
777
777
  } else if (this.target === "draft-7") {
778
778
  result.$schema = "http://json-schema.org/draft-07/schema#";
779
779
  } else {
780
+ // @ts-ignore
780
781
  console.warn(`Invalid target: ${this.target}`);
781
782
  }
782
783