zod 3.26.0-canary.20250703T215303 → 3.26.0-canary.20250707T201657

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/index.cjs CHANGED
@@ -27,7 +27,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.z = void 0;
30
- const z = __importStar(require("./v3/index.cjs"));
30
+ const z = __importStar(require("./v3/external.cjs"));
31
31
  exports.z = z;
32
- __exportStar(require("./v3/index.cjs"), exports);
32
+ __exportStar(require("./v3/external.cjs"), exports);
33
33
  exports.default = z;
package/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import * as z from "./v3/index.cjs";
2
- export * from "./v3/index.cjs";
1
+ import * as z from "./v3/external.cjs";
2
+ export * from "./v3/external.cjs";
3
3
  export { z };
4
4
  export default z;
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as z from "./v3/index.js";
2
- export * from "./v3/index.js";
1
+ import * as z from "./v3/external.js";
2
+ export * from "./v3/external.js";
3
3
  export { z };
4
4
  export default z;
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import * as z from "./v3/index.js";
2
- export * from "./v3/index.js";
1
+ import * as z from "./v3/external.js";
2
+ export * from "./v3/external.js";
3
3
  export { z };
4
4
  export default z;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.26.0-canary.20250703T215303",
3
+ "version": "3.26.0-canary.20250707T201657",
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",
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as z from "./v3/index.js";
2
- export * from "./v3/index.js";
1
+ import * as z from "./v3/external.js";
2
+ export * from "./v3/external.js";
3
3
  export { z };
4
4
  export default z;
@@ -365,6 +365,8 @@ export const ZodString: core.$constructor<ZodString> = /*@__PURE__*/ core.$const
365
365
  inst.duration = (params) => inst.check(iso.duration(params as any));
366
366
  });
367
367
 
368
+ export function string(params?: string | core.$ZodStringParams): ZodString;
369
+ export function string<T extends string>(params?: string | core.$ZodStringParams): core.$ZodType<T, T>;
368
370
  export function string(params?: string | core.$ZodStringParams): ZodString {
369
371
  return core._string(ZodString, params) as any;
370
372
  }
@@ -1357,11 +1359,11 @@ export function partialRecord<Key extends core.$ZodRecordKey, Value extends core
1357
1359
  keyType: Key,
1358
1360
  valueType: Value,
1359
1361
  params?: string | core.$ZodRecordParams
1360
- ): ZodRecord<ZodUnion<[Key, ZodNever]>, Value> {
1362
+ ): ZodRecord<Key & core.$partial, Value> {
1361
1363
  return new ZodRecord({
1362
1364
  type: "record",
1363
1365
  keyType: union([keyType, never()]),
1364
- valueType: valueType as any as core.$ZodType,
1366
+ valueType: valueType as any,
1365
1367
  ...util.normalizeParams(params),
1366
1368
  }) as any;
1367
1369
  }
@@ -59,7 +59,5 @@ test("$branded", () => {
59
59
  test("branded record", () => {
60
60
  const recordWithBrandedNumberKeys = z.record(z.string().brand("SomeBrand"), z.number());
61
61
  type recordWithBrandedNumberKeys = z.infer<typeof recordWithBrandedNumberKeys>;
62
- expectTypeOf<recordWithBrandedNumberKeys>().toEqualTypeOf<
63
- Record<string & z.core.$brand<"SomeBrand">, number | undefined>
64
- >();
62
+ expectTypeOf<recordWithBrandedNumberKeys>().toEqualTypeOf<Record<string & z.core.$brand<"SomeBrand">, number>>();
65
63
  });
@@ -24,6 +24,9 @@ test("_values", () => {
24
24
 
25
25
  const post = z.literal("test").transform((_) => Math.random());
26
26
  expect(post._zod.values).toEqual(new Set(["test"]));
27
+
28
+ // Test that readonly literals pass through their values property
29
+ expect(z.literal("test").readonly()._zod.values).toEqual(new Set(["test"]));
27
30
  });
28
31
 
29
32
  test("valid parse - object", () => {
@@ -590,3 +593,27 @@ test("nested discriminated unions", () => {
590
593
  }
591
594
  `);
592
595
  });
596
+
597
+ test("readonly literal discriminator", () => {
598
+ const discUnion = z.discriminatedUnion("type", [
599
+ z.object({ type: z.literal("a").readonly(), a: z.string() }),
600
+ z.object({ type: z.literal("b"), b: z.number() }),
601
+ ]);
602
+
603
+ // Test that both discriminator values are correctly included in propValues
604
+ const propValues = discUnion._zod.propValues;
605
+ expect(propValues?.type?.has("a")).toBe(true);
606
+ expect(propValues?.type?.has("b")).toBe(true);
607
+
608
+ // Test that the discriminated union works correctly
609
+ const result1 = discUnion.parse({ type: "a", a: "hello" });
610
+ expect(result1).toEqual({ type: "a", a: "hello" });
611
+
612
+ const result2 = discUnion.parse({ type: "b", b: 42 });
613
+ expect(result2).toEqual({ type: "b", b: 42 });
614
+
615
+ // Test that invalid discriminator values are rejected
616
+ expect(() => {
617
+ discUnion.parse({ type: "c", a: "hello" });
618
+ }).toThrow();
619
+ });
@@ -301,7 +301,7 @@ test("z.record", () => {
301
301
  // partial enum
302
302
  const d = z.record(z.enum(["a", "b"]).or(z.never()), z.string());
303
303
  type d = z.output<typeof d>;
304
- expectTypeOf<d>().toEqualTypeOf<Partial<Record<"a" | "b", string>>>();
304
+ expectTypeOf<d>().toEqualTypeOf<Record<"a" | "b", string>>();
305
305
  });
306
306
 
307
307
  test("z.map", () => {
@@ -217,6 +217,16 @@ test("test inferred merged type", async () => {
217
217
  expectTypeOf<asdf>().toEqualTypeOf<{ a: number }>();
218
218
  });
219
219
 
220
+ test("inferred type with Record shape", () => {
221
+ type A = z.ZodObject<Record<string, z.ZodType<string, number>>>;
222
+ expectTypeOf<z.infer<A>>().toEqualTypeOf<Record<string, string>>();
223
+ expectTypeOf<z.input<A>>().toEqualTypeOf<Record<string, number>>();
224
+
225
+ type B = z.ZodObject;
226
+ expectTypeOf<z.infer<B>>().toEqualTypeOf<Record<string, unknown>>();
227
+ expectTypeOf<z.input<B>>().toEqualTypeOf<Record<string, unknown>>();
228
+ });
229
+
220
230
  test("inferred merged object type with optional properties", async () => {
221
231
  const Merged = z
222
232
  .object({ a: z.string(), b: z.string().optional() })
@@ -549,5 +559,5 @@ test("index signature in shape", () => {
549
559
  const schema = makeZodObj("foo");
550
560
  type schema = z.infer<typeof schema>;
551
561
 
552
- expectTypeOf<schema>().toEqualTypeOf<Record<string, unknown>>();
562
+ expectTypeOf<schema>().toEqualTypeOf<Record<string, string>>();
553
563
  });
@@ -17,7 +17,7 @@ test("type inference", () => {
17
17
  expectTypeOf<booleanRecord>().toEqualTypeOf<Record<string, boolean>>();
18
18
  expectTypeOf<recordWithEnumKeys>().toEqualTypeOf<Record<"Tuna" | "Salmon", string>>();
19
19
  expectTypeOf<recordWithLiteralKey>().toEqualTypeOf<Record<"Tuna" | "Salmon", string>>();
20
- expectTypeOf<recordWithLiteralUnionKeys>().toEqualTypeOf<Partial<Record<"Tuna" | "Salmon", string>>>();
20
+ expectTypeOf<recordWithLiteralUnionKeys>().toEqualTypeOf<Record<"Tuna" | "Salmon", string>>();
21
21
  });
22
22
 
23
23
  test("enum exhaustiveness", () => {
@@ -330,3 +330,13 @@ test("async parsing", async () => {
330
330
  ]]
331
331
  `);
332
332
  });
333
+
334
+ test("partial record", () => {
335
+ const schema = z.partialRecord(z.string(), z.string());
336
+ type schema = z.infer<typeof schema>;
337
+ expectTypeOf<schema>().toEqualTypeOf<Partial<Record<string, string>>>();
338
+
339
+ const Keys = z.enum(["id", "name", "email"]).or(z.never());
340
+ const Person = z.partialRecord(Keys, z.string());
341
+ expectTypeOf<z.infer<typeof Person>>().toEqualTypeOf<Partial<Record<"id" | "name" | "email", string>>>();
342
+ });
@@ -160,9 +160,10 @@ test("deferred self-recursion", () => {
160
160
  const Output = z.object({
161
161
  id: z.int(), //.nonnegative(),
162
162
  name: z.string(),
163
- features: z.array(Feature), //.array(), // <—
163
+ get features(): z.ZodArray<typeof Feature> {
164
+ return Feature.array();
165
+ },
164
166
  });
165
-
166
167
  type Output = z.output<typeof Output>;
167
168
 
168
169
  type _Feature = {
@@ -28,10 +28,9 @@ describe("toJSONSchema", () => {
28
28
  "type": "null",
29
29
  }
30
30
  `);
31
- expect(z.toJSONSchema(z.undefined())).toMatchInlineSnapshot(`
31
+ expect(z.toJSONSchema(z.undefined(), { unrepresentable: "any" })).toMatchInlineSnapshot(`
32
32
  {
33
33
  "$schema": "https://json-schema.org/draft/2020-12/schema",
34
- "not": {},
35
34
  }
36
35
  `);
37
36
  expect(z.toJSONSchema(z.any())).toMatchInlineSnapshot(`
@@ -232,6 +231,7 @@ describe("toJSONSchema", () => {
232
231
  expect(() => z.toJSONSchema(z.int64())).toThrow("BigInt cannot be represented in JSON Schema");
233
232
  expect(() => z.toJSONSchema(z.symbol())).toThrow("Symbols cannot be represented in JSON Schema");
234
233
  expect(() => z.toJSONSchema(z.void())).toThrow("Void cannot be represented in JSON Schema");
234
+ expect(() => z.toJSONSchema(z.undefined())).toThrow("Undefined cannot be represented in JSON Schema");
235
235
  expect(() => z.toJSONSchema(z.date())).toThrow("Date cannot be represented in JSON Schema");
236
236
  expect(() => z.toJSONSchema(z.map(z.string(), z.number()))).toThrow("Map cannot be represented in JSON Schema");
237
237
  expect(() => z.toJSONSchema(z.set(z.string()))).toThrow("Set cannot be represented in JSON Schema");
@@ -1259,6 +1259,35 @@ test("override execution order", () => {
1259
1259
  `);
1260
1260
  });
1261
1261
 
1262
+ test("override with path", () => {
1263
+ const userSchema = z.object({
1264
+ name: z.string(),
1265
+ age: z.number(),
1266
+ });
1267
+
1268
+ const capturedPaths: (string | number)[][] = [];
1269
+
1270
+ z.toJSONSchema(userSchema, {
1271
+ override(ctx) {
1272
+ capturedPaths.push(ctx.path);
1273
+ },
1274
+ });
1275
+
1276
+ expect(capturedPaths).toMatchInlineSnapshot(`
1277
+ [
1278
+ [
1279
+ "properties",
1280
+ "age",
1281
+ ],
1282
+ [
1283
+ "properties",
1284
+ "name",
1285
+ ],
1286
+ [],
1287
+ ]
1288
+ `);
1289
+ });
1290
+
1262
1291
  test("pipe", () => {
1263
1292
  const mySchema = z
1264
1293
  .string()
@@ -1858,9 +1887,8 @@ test("input type", () => {
1858
1887
  e: z.string().prefault("hello"),
1859
1888
  f: z.string().catch("hello"),
1860
1889
  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()]),
1890
+ h: z.union([z.string(), z.number().default(2)]),
1891
+ i: z.union([z.string(), z.string().optional()]),
1864
1892
  });
1865
1893
  expect(z.toJSONSchema(schema, { io: "input" })).toMatchInlineSnapshot(`
1866
1894
  {
@@ -1898,9 +1926,6 @@ test("input type", () => {
1898
1926
  "not": {},
1899
1927
  },
1900
1928
  "h": {
1901
- "not": {},
1902
- },
1903
- "i": {
1904
1929
  "anyOf": [
1905
1930
  {
1906
1931
  "type": "string",
@@ -1911,7 +1936,7 @@ test("input type", () => {
1911
1936
  },
1912
1937
  ],
1913
1938
  },
1914
- "j": {
1939
+ "i": {
1915
1940
  "anyOf": [
1916
1941
  {
1917
1942
  "type": "string",
@@ -1966,9 +1991,6 @@ test("input type", () => {
1966
1991
  "not": {},
1967
1992
  },
1968
1993
  "h": {
1969
- "not": {},
1970
- },
1971
- "i": {
1972
1994
  "anyOf": [
1973
1995
  {
1974
1996
  "type": "string",
@@ -1979,7 +2001,7 @@ test("input type", () => {
1979
2001
  },
1980
2002
  ],
1981
2003
  },
1982
- "j": {
2004
+ "i": {
1983
2005
  "anyOf": [
1984
2006
  {
1985
2007
  "type": "string",
@@ -1997,7 +2019,7 @@ test("input type", () => {
1997
2019
  "e",
1998
2020
  "f",
1999
2021
  "g",
2000
- "i",
2022
+ "h",
2001
2023
  ],
2002
2024
  "type": "object",
2003
2025
  }
@@ -46,6 +46,10 @@ export class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema exten
46
46
  }
47
47
 
48
48
  remove(schema: Schema): this {
49
+ const meta: any = this._map.get(schema);
50
+ if (meta && typeof meta === "object" && "id" in meta) {
51
+ this._idmap.delete(meta.id!);
52
+ }
49
53
  this._map.delete(schema);
50
54
  return this;
51
55
  }
@@ -90,7 +90,7 @@ export interface _$ZodTypeInternals {
90
90
  // types: Types;
91
91
 
92
92
  /** @internal Randomly generated ID for this schema. */
93
- id: string;
93
+ // id: string;
94
94
 
95
95
  /** @internal List of deferred initializers. */
96
96
  deferred: util.AnyFunc[] | undefined;
@@ -171,8 +171,7 @@ export interface _$ZodType<T extends $ZodTypeInternals = $ZodTypeInternals>
171
171
 
172
172
  export const $ZodType: core.$constructor<$ZodType> = /*@__PURE__*/ core.$constructor("$ZodType", (inst, def) => {
173
173
  inst ??= {} as any;
174
- // avoids issues with using Math.random() in Next.js caching
175
- util.defineLazy(inst._zod, "id", () => def.type + "_" + util.randomString(10));
174
+
176
175
  inst._zod.def = def; // set _def property
177
176
  inst._zod.bag = inst._zod.bag || {}; // initialize _bag object
178
177
  inst._zod.version = version;
@@ -428,7 +427,9 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
428
427
  $ZodStringFormat.init(inst, def);
429
428
  inst._zod.check = (payload) => {
430
429
  try {
431
- const url = new URL(payload.value);
430
+ const orig = payload.value;
431
+ const url = new URL(orig);
432
+ const href = url.href;
432
433
 
433
434
  if (def.hostname) {
434
435
  def.hostname.lastIndex = 0;
@@ -460,6 +461,13 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
460
461
  }
461
462
  }
462
463
 
464
+ // payload.value = url.href;
465
+ if (!orig.endsWith("/") && href.endsWith("/")) {
466
+ payload.value = href.slice(0, -1);
467
+ } else {
468
+ payload.value = href;
469
+ }
470
+
463
471
  return;
464
472
  } catch (_) {
465
473
  payload.issues.push({
@@ -1489,14 +1497,15 @@ export interface $ZodArrayDef<T extends SomeType = $ZodType> extends $ZodTypeDef
1489
1497
  element: T;
1490
1498
  }
1491
1499
 
1492
- export interface $ZodArrayInternals<T extends SomeType = $ZodType>
1493
- extends $ZodTypeInternals<core.output<T>[], core.input<T>[]> {
1500
+ export interface $ZodArrayInternals<T extends SomeType = $ZodType> extends _$ZodTypeInternals {
1501
+ //$ZodTypeInternals<core.output<T>[], core.input<T>[]> {
1494
1502
  def: $ZodArrayDef<T>;
1495
1503
  isst: errors.$ZodIssueInvalidType;
1504
+ output: core.output<T>[];
1505
+ input: core.input<T>[];
1496
1506
  }
1497
1507
 
1498
- export interface $ZodArray<T extends SomeType = $ZodType>
1499
- extends $ZodType<core.output<T>[], core.input<T>[], $ZodArrayInternals<T>> {}
1508
+ export interface $ZodArray<T extends SomeType = $ZodType> extends $ZodType<any, any, $ZodArrayInternals<T>> {}
1500
1509
 
1501
1510
  function handleArrayResult(result: ParsePayload<any>, final: ParsePayload<any[]>, index: number) {
1502
1511
  if (result.issues.length) {
@@ -1560,7 +1569,9 @@ type OptionalOutSchema = { _zod: { optout: "optional" } };
1560
1569
  type OptionalInSchema = { _zod: { optin: "optional" } };
1561
1570
 
1562
1571
  export type $InferObjectOutput<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = string extends keyof T
1563
- ? Record<string, unknown>
1572
+ ? util.IsAny<T[keyof T]> extends true
1573
+ ? Record<string, unknown>
1574
+ : Record<string, core.output<T[keyof T]>>
1564
1575
  : keyof (T & Extra) extends never
1565
1576
  ? Record<string, never>
1566
1577
  : util.Prettify<
@@ -1572,7 +1583,9 @@ export type $InferObjectOutput<T extends $ZodLooseShape, Extra extends Record<st
1572
1583
  >;
1573
1584
 
1574
1585
  export type $InferObjectInput<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = string extends keyof T
1575
- ? Record<string, unknown>
1586
+ ? util.IsAny<T[keyof T]> extends true
1587
+ ? Record<string, unknown>
1588
+ : Record<string, core.input<T[keyof T]>>
1576
1589
  : keyof (T & Extra) extends never
1577
1590
  ? Record<string, never>
1578
1591
  : util.Prettify<
@@ -1711,8 +1724,9 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
1711
1724
  doc.write(`const input = payload.value;`);
1712
1725
 
1713
1726
  const ids: any = Object.create(null);
1727
+ let counter = 0;
1714
1728
  for (const key of normalized.keys) {
1715
- ids[key] = util.randomString(15);
1729
+ ids[key] = `key_${counter++}`;
1716
1730
  }
1717
1731
 
1718
1732
  // A: preserve key order {
@@ -1886,17 +1900,20 @@ export interface $ZodUnionDef<Options extends readonly SomeType[] = readonly $Zo
1886
1900
  type IsOptionalIn<T extends SomeType> = T extends OptionalInSchema ? true : false;
1887
1901
  type IsOptionalOut<T extends SomeType> = T extends OptionalOutSchema ? true : false;
1888
1902
 
1889
- export interface $ZodUnionInternals<T extends readonly SomeType[] = readonly $ZodType[]>
1890
- extends $ZodTypeInternals<$InferUnionOutput<T[number]>, $InferUnionInput<T[number]>> {
1903
+ export interface $ZodUnionInternals<T extends readonly SomeType[] = readonly $ZodType[]> extends _$ZodTypeInternals {
1891
1904
  def: $ZodUnionDef<T>;
1892
1905
  isst: errors.$ZodIssueInvalidUnion;
1893
1906
  pattern: T[number]["_zod"]["pattern"];
1907
+ values: T[number]["_zod"]["values"]; //GetValues<T[number]>;
1908
+ output: $InferUnionOutput<T[number]>;
1909
+ input: $InferUnionInput<T[number]>;
1894
1910
  // if any element in the union is optional, then the union is optional
1895
1911
  optin: IsOptionalIn<T[number]> extends false ? "optional" | undefined : "optional";
1896
1912
  optout: IsOptionalOut<T[number]> extends false ? "optional" | undefined : "optional";
1897
1913
  }
1898
1914
 
1899
- export interface $ZodUnion<T extends readonly SomeType[] = readonly $ZodType[]> extends $ZodType {
1915
+ export interface $ZodUnion<T extends readonly SomeType[] = readonly $ZodType[]>
1916
+ extends $ZodType<any, any, $ZodUnionInternals<T>> {
1900
1917
  _zod: $ZodUnionInternals<T>;
1901
1918
  }
1902
1919
 
@@ -2089,6 +2106,8 @@ export interface $ZodIntersectionInternals<A extends SomeType = $ZodType, B exte
2089
2106
  extends $ZodTypeInternals<core.output<A> & core.output<B>, core.input<A> & core.input<B>> {
2090
2107
  def: $ZodIntersectionDef<A, B>;
2091
2108
  isst: never;
2109
+ optin: A["_zod"]["optin"] | B["_zod"]["optin"];
2110
+ optout: A["_zod"]["optout"] | B["_zod"]["optout"];
2092
2111
  }
2093
2112
 
2094
2113
  export interface $ZodIntersection<A extends SomeType = $ZodType, B extends SomeType = $ZodType> extends $ZodType {
@@ -2359,38 +2378,53 @@ export interface $ZodRecordDef<Key extends $ZodRecordKey = $ZodRecordKey, Value
2359
2378
  valueType: Value;
2360
2379
  }
2361
2380
 
2381
+ // export type $InferZodRecordOutput<
2382
+ // Key extends $ZodRecordKey = $ZodRecordKey,
2383
+ // Value extends SomeType = $ZodType,
2384
+ // > = undefined extends Key["_zod"]["values"]
2385
+ // ? string extends core.output<Key>
2386
+ // ? Record<core.output<Key>, core.output<Value>>
2387
+ // : number extends core.output<Key>
2388
+ // ? Record<core.output<Key>, core.output<Value>>
2389
+ // : symbol extends core.output<Key>
2390
+ // ? Record<core.output<Key>, core.output<Value>>
2391
+ // : Record<core.output<Key>, core.output<Value>>
2392
+ // : Record<core.output<Key>, core.output<Value>>;
2362
2393
  export type $InferZodRecordOutput<
2363
2394
  Key extends $ZodRecordKey = $ZodRecordKey,
2364
2395
  Value extends SomeType = $ZodType,
2365
- > = undefined extends Key["_zod"]["values"]
2366
- ? string extends core.output<Key>
2367
- ? Record<core.output<Key>, core.output<Value>>
2368
- : number extends core.output<Key>
2369
- ? Record<core.output<Key>, core.output<Value>>
2370
- : symbol extends core.output<Key>
2371
- ? Record<core.output<Key>, core.output<Value>>
2372
- : Partial<Record<core.output<Key>, core.output<Value>>>
2396
+ > = Key extends $partial
2397
+ ? Partial<Record<core.output<Key>, core.output<Value>>>
2373
2398
  : Record<core.output<Key>, core.output<Value>>;
2374
2399
 
2400
+ // export type $InferZodRecordInput<
2401
+ // Key extends $ZodRecordKey = $ZodRecordKey,
2402
+ // Value extends SomeType = $ZodType,
2403
+ // > = undefined extends Key["_zod"]["values"]
2404
+ // ? string extends core.input<Key>
2405
+ // ? Record<core.input<Key>, core.input<Value>>
2406
+ // : number extends core.input<Key>
2407
+ // ? Record<core.input<Key>, core.input<Value>>
2408
+ // : symbol extends core.input<Key>
2409
+ // ? Record<core.input<Key>, core.input<Value>>
2410
+ // : Record<core.input<Key>, core.input<Value>>
2411
+ // : Record<core.input<Key>, core.input<Value>>;
2375
2412
  export type $InferZodRecordInput<
2376
2413
  Key extends $ZodRecordKey = $ZodRecordKey,
2377
2414
  Value extends SomeType = $ZodType,
2378
- > = undefined extends Key["_zod"]["values"]
2379
- ? string extends core.input<Key>
2380
- ? Record<core.input<Key>, core.input<Value>>
2381
- : number extends core.input<Key>
2382
- ? Record<core.input<Key>, core.input<Value>>
2383
- : symbol extends core.input<Key>
2384
- ? Record<core.input<Key>, core.input<Value>>
2385
- : Partial<Record<core.input<Key>, core.input<Value>>>
2415
+ > = Key extends $partial
2416
+ ? Partial<Record<core.input<Key>, core.input<Value>>>
2386
2417
  : Record<core.input<Key>, core.input<Value>>;
2387
2418
 
2388
2419
  export interface $ZodRecordInternals<Key extends $ZodRecordKey = $ZodRecordKey, Value extends SomeType = $ZodType>
2389
2420
  extends $ZodTypeInternals<$InferZodRecordOutput<Key, Value>, $InferZodRecordInput<Key, Value>> {
2390
2421
  def: $ZodRecordDef<Key, Value>;
2391
2422
  isst: errors.$ZodIssueInvalidType | errors.$ZodIssueInvalidKey<Record<PropertyKey, unknown>>;
2423
+ optin?: "optional" | undefined;
2424
+ optout?: "optional" | undefined;
2392
2425
  }
2393
2426
 
2427
+ export type $partial = { "~~partial": true };
2394
2428
  export interface $ZodRecord<Key extends $ZodRecordKey = $ZodRecordKey, Value extends SomeType = $ZodType>
2395
2429
  extends $ZodType {
2396
2430
  _zod: $ZodRecordInternals<Key, Value>;
@@ -2521,6 +2555,8 @@ export interface $ZodMapInternals<Key extends SomeType = $ZodType, Value extends
2521
2555
  extends $ZodTypeInternals<Map<core.output<Key>, core.output<Value>>, Map<core.input<Key>, core.input<Value>>> {
2522
2556
  def: $ZodMapDef<Key, Value>;
2523
2557
  isst: errors.$ZodIssueInvalidType | errors.$ZodIssueInvalidKey | errors.$ZodIssueInvalidElement<unknown>;
2558
+ optin?: "optional" | undefined;
2559
+ optout?: "optional" | undefined;
2524
2560
  }
2525
2561
 
2526
2562
  export interface $ZodMap<Key extends SomeType = $ZodType, Value extends SomeType = $ZodType> extends $ZodType {
@@ -2620,6 +2656,8 @@ export interface $ZodSetInternals<T extends SomeType = $ZodType>
2620
2656
  extends $ZodTypeInternals<Set<core.output<T>>, Set<core.input<T>>> {
2621
2657
  def: $ZodSetDef<T>;
2622
2658
  isst: errors.$ZodIssueInvalidType;
2659
+ optin?: "optional" | undefined;
2660
+ optout?: "optional" | undefined;
2623
2661
  }
2624
2662
 
2625
2663
  export interface $ZodSet<T extends SomeType = $ZodType> extends $ZodType {
@@ -3030,6 +3068,7 @@ export interface $ZodDefaultInternals<T extends SomeType = $ZodType>
3030
3068
  extends $ZodTypeInternals<util.NoUndefined<core.output<T>>, core.input<T> | undefined> {
3031
3069
  def: $ZodDefaultDef<T>;
3032
3070
  optin: "optional";
3071
+ optout?: "optional" | undefined; // required
3033
3072
  isst: never;
3034
3073
  values: T["_zod"]["values"];
3035
3074
  }
@@ -3090,6 +3129,7 @@ export interface $ZodPrefaultInternals<T extends SomeType = $ZodType>
3090
3129
  extends $ZodTypeInternals<util.NoUndefined<core.output<T>>, core.input<T> | undefined> {
3091
3130
  def: $ZodPrefaultDef<T>;
3092
3131
  optin: "optional";
3132
+ optout?: "optional" | undefined;
3093
3133
  isst: never;
3094
3134
  values: T["_zod"]["values"];
3095
3135
  }
@@ -3132,6 +3172,8 @@ export interface $ZodNonOptionalInternals<T extends SomeType = $ZodType>
3132
3172
  def: $ZodNonOptionalDef<T>;
3133
3173
  isst: errors.$ZodIssueInvalidType;
3134
3174
  values: T["_zod"]["values"];
3175
+ optin: "optional" | undefined;
3176
+ optout: "optional" | undefined;
3135
3177
  }
3136
3178
 
3137
3179
  export interface $ZodNonOptional<T extends SomeType = $ZodType> extends $ZodType {
@@ -3225,6 +3267,8 @@ export interface $ZodSuccessDef<T extends SomeType = $ZodType> extends $ZodTypeD
3225
3267
  export interface $ZodSuccessInternals<T extends SomeType = $ZodType> extends $ZodTypeInternals<boolean, core.input<T>> {
3226
3268
  def: $ZodSuccessDef<T>;
3227
3269
  isst: never;
3270
+ optin: T["_zod"]["optin"];
3271
+ optout: "optional" | undefined;
3228
3272
  }
3229
3273
 
3230
3274
  export interface $ZodSuccess<T extends SomeType = $ZodType> extends $ZodType {
@@ -3432,6 +3476,7 @@ export interface $ZodReadonlyInternals<T extends SomeType = $ZodType>
3432
3476
  optout: T["_zod"]["optout"];
3433
3477
  isst: never;
3434
3478
  propValues: T["_zod"]["propValues"];
3479
+ values: T["_zod"]["values"];
3435
3480
  }
3436
3481
 
3437
3482
  export interface $ZodReadonly<T extends SomeType = $ZodType> extends $ZodType {
@@ -3443,6 +3488,7 @@ export const $ZodReadonly: core.$constructor<$ZodReadonly> = /*@__PURE__*/ core.
3443
3488
  (inst, def) => {
3444
3489
  $ZodType.init(inst, def);
3445
3490
  util.defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
3491
+ util.defineLazy(inst._zod, "values", () => def.innerType._zod.values);
3446
3492
  util.defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
3447
3493
  util.defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
3448
3494
 
@@ -17,9 +17,13 @@ interface JSONSchemaGeneratorParams {
17
17
  * - `"any"` — Unrepresentable types become `{}` */
18
18
  unrepresentable?: "throw" | "any";
19
19
  /** Arbitrary custom logic that can be used to modify the generated JSON Schema. */
20
- override?: (ctx: { zodSchema: schemas.$ZodTypes; jsonSchema: JSONSchema.BaseSchema }) => void;
20
+ override?: (ctx: {
21
+ zodSchema: schemas.$ZodTypes;
22
+ jsonSchema: JSONSchema.BaseSchema;
23
+ path: (string | number)[];
24
+ }) => void;
21
25
  /** Whether to extract the `"input"` or `"output"` type. Relevant to transforms, Error converting schema to JSONz, defaults, coerced primitives, etc.
22
- * - `"output" — Default. Convert the output schema.
26
+ * - `"output"` Default. Convert the output schema.
23
27
  * - `"input"` — Convert the input schema. */
24
28
  io?: "input" | "output";
25
29
  }
@@ -61,13 +65,19 @@ interface Seen {
61
65
  cycle?: (string | number)[] | undefined;
62
66
  isParent?: boolean | undefined;
63
67
  ref?: schemas.$ZodType | undefined | null;
68
+ /** JSON Schema property path for this schema */
69
+ path?: (string | number)[] | undefined;
64
70
  }
65
71
 
66
72
  export class JSONSchemaGenerator {
67
73
  metadataRegistry: $ZodRegistry<Record<string, any>>;
68
74
  target: "draft-7" | "draft-2020-12";
69
75
  unrepresentable: "throw" | "any";
70
- override: (ctx: { zodSchema: schemas.$ZodTypes; jsonSchema: JSONSchema.BaseSchema }) => void;
76
+ override: (ctx: {
77
+ zodSchema: schemas.$ZodTypes;
78
+ jsonSchema: JSONSchema.BaseSchema;
79
+ path: (string | number)[];
80
+ }) => void;
71
81
  io: "input" | "output";
72
82
 
73
83
  counter = 0;
@@ -110,7 +120,7 @@ export class JSONSchemaGenerator {
110
120
  }
111
121
 
112
122
  // initialize
113
- const result: Seen = { schema: {}, count: 1, cycle: undefined };
123
+ const result: Seen = { schema: {}, count: 1, cycle: undefined, path: _params.path };
114
124
  this.seen.set(schema, result);
115
125
 
116
126
  // custom method overrides default behavior
@@ -217,9 +227,10 @@ export class JSONSchemaGenerator {
217
227
  case "unknown": {
218
228
  break;
219
229
  }
220
- case "undefined":
221
- case "never": {
222
- _json.not = {};
230
+ case "undefined": {
231
+ if (this.unrepresentable === "throw") {
232
+ throw new Error("Undefined cannot be represented in JSON Schema");
233
+ }
223
234
  break;
224
235
  }
225
236
  case "void": {
@@ -228,6 +239,10 @@ export class JSONSchemaGenerator {
228
239
  }
229
240
  break;
230
241
  }
242
+ case "never": {
243
+ _json.not = {};
244
+ break;
245
+ }
231
246
  case "date": {
232
247
  if (this.unrepresentable === "throw") {
233
248
  throw new Error("Date cannot be represented in JSON Schema");
@@ -736,6 +751,7 @@ export class JSONSchemaGenerator {
736
751
  this.override({
737
752
  zodSchema: zodSchema as schemas.$ZodTypes,
738
753
  jsonSchema: schema,
754
+ path: seen.path ?? [],
739
755
  });
740
756
  };
741
757