zod 3.26.0-canary.20250703T214020 → 3.26.0-canary.20250703T215303

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.26.0-canary.20250703T214020",
3
+ "version": "3.26.0-canary.20250703T215303",
4
4
  "type": "module",
5
5
  "author": "Colin McDonnell <zod@colinhacks.com>",
6
6
  "description": "TypeScript-first schema declaration and validation library with static type inference",
@@ -37,6 +37,26 @@ test("optionality", () => {
37
37
  const e = z.string().default("asdf").nullable();
38
38
  expect(e._zod.optin).toEqual("optional");
39
39
  expect(e._zod.optout).toEqual(undefined);
40
+
41
+ // z.undefined should NOT be optional
42
+ const f = z.undefined();
43
+ expect(f._zod.optin).toEqual("optional");
44
+ expect(f._zod.optout).toEqual("optional");
45
+ expectTypeOf<typeof f._zod.optin>().toEqualTypeOf<"optional" | undefined>();
46
+ expectTypeOf<typeof f._zod.optout>().toEqualTypeOf<"optional" | undefined>();
47
+
48
+ // z.union should be optional if any of the types are optional
49
+ const g = z.union([z.string(), z.undefined()]);
50
+ expect(g._zod.optin).toEqual("optional");
51
+ expect(g._zod.optout).toEqual("optional");
52
+ expectTypeOf<typeof g._zod.optin>().toEqualTypeOf<"optional" | undefined>();
53
+ expectTypeOf<typeof g._zod.optout>().toEqualTypeOf<"optional" | undefined>();
54
+
55
+ const h = z.union([z.string(), z.optional(z.string())]);
56
+ expect(h._zod.optin).toEqual("optional");
57
+ expect(h._zod.optout).toEqual("optional");
58
+ expectTypeOf<typeof h._zod.optin>().toEqualTypeOf<"optional">();
59
+ expectTypeOf<typeof h._zod.optout>().toEqualTypeOf<"optional">();
40
60
  });
41
61
 
42
62
  test("pipe optionality", () => {
@@ -31,7 +31,7 @@ describe("toJSONSchema", () => {
31
31
  expect(z.toJSONSchema(z.undefined())).toMatchInlineSnapshot(`
32
32
  {
33
33
  "$schema": "https://json-schema.org/draft/2020-12/schema",
34
- "type": "null",
34
+ "not": {},
35
35
  }
36
36
  `);
37
37
  expect(z.toJSONSchema(z.any())).toMatchInlineSnapshot(`
@@ -1856,6 +1856,11 @@ test("input type", () => {
1856
1856
  c: z.string().default("hello"),
1857
1857
  d: z.string().nullable(),
1858
1858
  e: z.string().prefault("hello"),
1859
+ f: z.string().catch("hello"),
1860
+ g: z.never(),
1861
+ h: z.undefined(),
1862
+ i: z.union([z.string(), z.number().default(2)]),
1863
+ j: z.union([z.string(), z.string().optional()]),
1859
1864
  });
1860
1865
  expect(z.toJSONSchema(schema, { io: "input" })).toMatchInlineSnapshot(`
1861
1866
  {
@@ -1885,10 +1890,42 @@ test("input type", () => {
1885
1890
  "default": "hello",
1886
1891
  "type": "string",
1887
1892
  },
1893
+ "f": {
1894
+ "default": "hello",
1895
+ "type": "string",
1896
+ },
1897
+ "g": {
1898
+ "not": {},
1899
+ },
1900
+ "h": {
1901
+ "not": {},
1902
+ },
1903
+ "i": {
1904
+ "anyOf": [
1905
+ {
1906
+ "type": "string",
1907
+ },
1908
+ {
1909
+ "default": 2,
1910
+ "type": "number",
1911
+ },
1912
+ ],
1913
+ },
1914
+ "j": {
1915
+ "anyOf": [
1916
+ {
1917
+ "type": "string",
1918
+ },
1919
+ {
1920
+ "type": "string",
1921
+ },
1922
+ ],
1923
+ },
1888
1924
  },
1889
1925
  "required": [
1890
1926
  "a",
1891
1927
  "d",
1928
+ "g",
1892
1929
  ],
1893
1930
  "type": "object",
1894
1931
  }
@@ -1921,12 +1958,46 @@ test("input type", () => {
1921
1958
  "e": {
1922
1959
  "type": "string",
1923
1960
  },
1961
+ "f": {
1962
+ "default": "hello",
1963
+ "type": "string",
1964
+ },
1965
+ "g": {
1966
+ "not": {},
1967
+ },
1968
+ "h": {
1969
+ "not": {},
1970
+ },
1971
+ "i": {
1972
+ "anyOf": [
1973
+ {
1974
+ "type": "string",
1975
+ },
1976
+ {
1977
+ "default": 2,
1978
+ "type": "number",
1979
+ },
1980
+ ],
1981
+ },
1982
+ "j": {
1983
+ "anyOf": [
1984
+ {
1985
+ "type": "string",
1986
+ },
1987
+ {
1988
+ "type": "string",
1989
+ },
1990
+ ],
1991
+ },
1924
1992
  },
1925
1993
  "required": [
1926
1994
  "a",
1927
1995
  "c",
1928
1996
  "d",
1929
1997
  "e",
1998
+ "f",
1999
+ "g",
2000
+ "i",
1930
2001
  ],
1931
2002
  "type": "object",
1932
2003
  }
@@ -1238,6 +1238,8 @@ export const $ZodUndefined: core.$constructor<$ZodUndefined> = /*@__PURE__*/ cor
1238
1238
  $ZodType.init(inst, def);
1239
1239
  inst._zod.pattern = regexes.undefined;
1240
1240
  inst._zod.values = new Set([undefined]);
1241
+ inst._zod.optin = "optional";
1242
+ inst._zod.optout = "optional";
1241
1243
 
1242
1244
  inst._zod.parse = (payload, _ctx) => {
1243
1245
  const input = payload.value;
@@ -1374,7 +1376,6 @@ export interface $ZodNever extends $ZodType {
1374
1376
 
1375
1377
  export const $ZodNever: core.$constructor<$ZodNever> = /*@__PURE__*/ core.$constructor("$ZodNever", (inst, def) => {
1376
1378
  $ZodType.init(inst, def);
1377
-
1378
1379
  inst._zod.parse = (payload, _ctx) => {
1379
1380
  payload.issues.push({
1380
1381
  expected: "never",
@@ -1882,11 +1883,17 @@ export interface $ZodUnionDef<Options extends readonly SomeType[] = readonly $Zo
1882
1883
  options: Options;
1883
1884
  }
1884
1885
 
1886
+ type IsOptionalIn<T extends SomeType> = T extends OptionalInSchema ? true : false;
1887
+ type IsOptionalOut<T extends SomeType> = T extends OptionalOutSchema ? true : false;
1888
+
1885
1889
  export interface $ZodUnionInternals<T extends readonly SomeType[] = readonly $ZodType[]>
1886
1890
  extends $ZodTypeInternals<$InferUnionOutput<T[number]>, $InferUnionInput<T[number]>> {
1887
1891
  def: $ZodUnionDef<T>;
1888
1892
  isst: errors.$ZodIssueInvalidUnion;
1889
1893
  pattern: T[number]["_zod"]["pattern"];
1894
+ // if any element in the union is optional, then the union is optional
1895
+ optin: IsOptionalIn<T[number]> extends false ? "optional" | undefined : "optional";
1896
+ optout: IsOptionalOut<T[number]> extends false ? "optional" | undefined : "optional";
1890
1897
  }
1891
1898
 
1892
1899
  export interface $ZodUnion<T extends readonly SomeType[] = readonly $ZodType[]> extends $ZodType {
@@ -1914,6 +1921,14 @@ function handleUnionResults(results: ParsePayload[], final: ParsePayload, inst:
1914
1921
  export const $ZodUnion: core.$constructor<$ZodUnion> = /*@__PURE__*/ core.$constructor("$ZodUnion", (inst, def) => {
1915
1922
  $ZodType.init(inst, def);
1916
1923
 
1924
+ util.defineLazy(inst._zod, "optin", () =>
1925
+ def.options.some((o) => o._zod.optin === "optional") ? "optional" : undefined
1926
+ );
1927
+
1928
+ util.defineLazy(inst._zod, "optout", () =>
1929
+ def.options.some((o) => o._zod.optout === "optional") ? "optional" : undefined
1930
+ );
1931
+
1917
1932
  util.defineLazy(inst._zod, "values", () => {
1918
1933
  if (def.options.every((o) => o._zod.values)) {
1919
1934
  return new Set<util.Primitive>(def.options.flatMap((option) => Array.from(option._zod.values!)));
@@ -3272,7 +3287,7 @@ export interface $ZodCatch<T extends SomeType = $ZodType> extends $ZodType {
3272
3287
 
3273
3288
  export const $ZodCatch: core.$constructor<$ZodCatch> = /*@__PURE__*/ core.$constructor("$ZodCatch", (inst, def) => {
3274
3289
  $ZodType.init(inst, def);
3275
- util.defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
3290
+ inst._zod.optin = "optional";
3276
3291
  util.defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
3277
3292
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
3278
3293
 
@@ -207,11 +207,6 @@ export class JSONSchemaGenerator {
207
207
  }
208
208
  break;
209
209
  }
210
- case "undefined": {
211
- const json = _json as JSONSchema.NullSchema;
212
- json.type = "null";
213
- break;
214
- }
215
210
  case "null": {
216
211
  _json.type = "null";
217
212
  break;
@@ -222,6 +217,7 @@ export class JSONSchemaGenerator {
222
217
  case "unknown": {
223
218
  break;
224
219
  }
220
+ case "undefined":
225
221
  case "never": {
226
222
  _json.not = {};
227
223
  break;
@@ -546,6 +546,8 @@ exports.$ZodUndefined = core.$constructor("$ZodUndefined", (inst, def) => {
546
546
  exports.$ZodType.init(inst, def);
547
547
  inst._zod.pattern = regexes.undefined;
548
548
  inst._zod.values = new Set([undefined]);
549
+ inst._zod.optin = "optional";
550
+ inst._zod.optout = "optional";
549
551
  inst._zod.parse = (payload, _ctx) => {
550
552
  const input = payload.value;
551
553
  if (typeof input === "undefined")
@@ -909,6 +911,8 @@ function handleUnionResults(results, final, inst, ctx) {
909
911
  }
910
912
  exports.$ZodUnion = core.$constructor("$ZodUnion", (inst, def) => {
911
913
  exports.$ZodType.init(inst, def);
914
+ util.defineLazy(inst._zod, "optin", () => def.options.some((o) => o._zod.optin === "optional") ? "optional" : undefined);
915
+ util.defineLazy(inst._zod, "optout", () => def.options.some((o) => o._zod.optout === "optional") ? "optional" : undefined);
912
916
  util.defineLazy(inst._zod, "values", () => {
913
917
  if (def.options.every((o) => o._zod.values)) {
914
918
  return new Set(def.options.flatMap((option) => Array.from(option._zod.values)));
@@ -1550,7 +1554,7 @@ exports.$ZodSuccess = core.$constructor("$ZodSuccess", (inst, def) => {
1550
1554
  });
1551
1555
  exports.$ZodCatch = core.$constructor("$ZodCatch", (inst, def) => {
1552
1556
  exports.$ZodType.init(inst, def);
1553
- util.defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
1557
+ inst._zod.optin = "optional";
1554
1558
  util.defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
1555
1559
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
1556
1560
  inst._zod.parse = (payload, ctx) => {
@@ -598,10 +598,14 @@ export interface $ZodUnionDef<Options extends readonly SomeType[] = readonly $Zo
598
598
  type: "union";
599
599
  options: Options;
600
600
  }
601
+ type IsOptionalIn<T extends SomeType> = T extends OptionalInSchema ? true : false;
602
+ type IsOptionalOut<T extends SomeType> = T extends OptionalOutSchema ? true : false;
601
603
  export interface $ZodUnionInternals<T extends readonly SomeType[] = readonly $ZodType[]> extends $ZodTypeInternals<$InferUnionOutput<T[number]>, $InferUnionInput<T[number]>> {
602
604
  def: $ZodUnionDef<T>;
603
605
  isst: errors.$ZodIssueInvalidUnion;
604
606
  pattern: T[number]["_zod"]["pattern"];
607
+ optin: IsOptionalIn<T[number]> extends false ? "optional" | undefined : "optional";
608
+ optout: IsOptionalOut<T[number]> extends false ? "optional" | undefined : "optional";
605
609
  }
606
610
  export interface $ZodUnion<T extends readonly SomeType[] = readonly $ZodType[]> extends $ZodType {
607
611
  _zod: $ZodUnionInternals<T>;
@@ -598,10 +598,14 @@ export interface $ZodUnionDef<Options extends readonly SomeType[] = readonly $Zo
598
598
  type: "union";
599
599
  options: Options;
600
600
  }
601
+ type IsOptionalIn<T extends SomeType> = T extends OptionalInSchema ? true : false;
602
+ type IsOptionalOut<T extends SomeType> = T extends OptionalOutSchema ? true : false;
601
603
  export interface $ZodUnionInternals<T extends readonly SomeType[] = readonly $ZodType[]> extends $ZodTypeInternals<$InferUnionOutput<T[number]>, $InferUnionInput<T[number]>> {
602
604
  def: $ZodUnionDef<T>;
603
605
  isst: errors.$ZodIssueInvalidUnion;
604
606
  pattern: T[number]["_zod"]["pattern"];
607
+ optin: IsOptionalIn<T[number]> extends false ? "optional" | undefined : "optional";
608
+ optout: IsOptionalOut<T[number]> extends false ? "optional" | undefined : "optional";
605
609
  }
606
610
  export interface $ZodUnion<T extends readonly SomeType[] = readonly $ZodType[]> extends $ZodType {
607
611
  _zod: $ZodUnionInternals<T>;
@@ -515,6 +515,8 @@ export const $ZodUndefined = /*@__PURE__*/ core.$constructor("$ZodUndefined", (i
515
515
  $ZodType.init(inst, def);
516
516
  inst._zod.pattern = regexes.undefined;
517
517
  inst._zod.values = new Set([undefined]);
518
+ inst._zod.optin = "optional";
519
+ inst._zod.optout = "optional";
518
520
  inst._zod.parse = (payload, _ctx) => {
519
521
  const input = payload.value;
520
522
  if (typeof input === "undefined")
@@ -878,6 +880,8 @@ function handleUnionResults(results, final, inst, ctx) {
878
880
  }
879
881
  export const $ZodUnion = /*@__PURE__*/ core.$constructor("$ZodUnion", (inst, def) => {
880
882
  $ZodType.init(inst, def);
883
+ util.defineLazy(inst._zod, "optin", () => def.options.some((o) => o._zod.optin === "optional") ? "optional" : undefined);
884
+ util.defineLazy(inst._zod, "optout", () => def.options.some((o) => o._zod.optout === "optional") ? "optional" : undefined);
881
885
  util.defineLazy(inst._zod, "values", () => {
882
886
  if (def.options.every((o) => o._zod.values)) {
883
887
  return new Set(def.options.flatMap((option) => Array.from(option._zod.values)));
@@ -1519,7 +1523,7 @@ export const $ZodSuccess = /*@__PURE__*/ core.$constructor("$ZodSuccess", (inst,
1519
1523
  });
1520
1524
  export const $ZodCatch = /*@__PURE__*/ core.$constructor("$ZodCatch", (inst, def) => {
1521
1525
  $ZodType.init(inst, def);
1522
- util.defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
1526
+ inst._zod.optin = "optional";
1523
1527
  util.defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
1524
1528
  util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
1525
1529
  inst._zod.parse = (payload, ctx) => {
@@ -141,11 +141,6 @@ class JSONSchemaGenerator {
141
141
  }
142
142
  break;
143
143
  }
144
- case "undefined": {
145
- const json = _json;
146
- json.type = "null";
147
- break;
148
- }
149
144
  case "null": {
150
145
  _json.type = "null";
151
146
  break;
@@ -156,6 +151,7 @@ class JSONSchemaGenerator {
156
151
  case "unknown": {
157
152
  break;
158
153
  }
154
+ case "undefined":
159
155
  case "never": {
160
156
  _json.not = {};
161
157
  break;
@@ -137,11 +137,6 @@ export class JSONSchemaGenerator {
137
137
  }
138
138
  break;
139
139
  }
140
- case "undefined": {
141
- const json = _json;
142
- json.type = "null";
143
- break;
144
- }
145
140
  case "null": {
146
141
  _json.type = "null";
147
142
  break;
@@ -152,6 +147,7 @@ export class JSONSchemaGenerator {
152
147
  case "unknown": {
153
148
  break;
154
149
  }
150
+ case "undefined":
155
151
  case "never": {
156
152
  _json.not = {};
157
153
  break;