zod 3.26.0-canary.20250703T215303 → 3.26.0-canary.20250708T090717

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 (48) hide show
  1. package/index.cjs +2 -2
  2. package/index.d.cts +2 -2
  3. package/index.d.ts +2 -2
  4. package/index.js +2 -2
  5. package/package.json +1 -1
  6. package/src/index.ts +2 -2
  7. package/src/v4/classic/schemas.ts +8 -9
  8. package/src/v4/classic/tests/brand.test.ts +1 -3
  9. package/src/v4/classic/tests/discriminated-unions.test.ts +27 -0
  10. package/src/v4/classic/tests/index.test.ts +1 -1
  11. package/src/v4/classic/tests/object.test.ts +11 -1
  12. package/src/v4/classic/tests/record.test.ts +11 -1
  13. package/src/v4/classic/tests/recursive-types.test.ts +33 -2
  14. package/src/v4/classic/tests/refine.test.ts +109 -0
  15. package/src/v4/classic/tests/registries.test.ts +9 -0
  16. package/src/v4/classic/tests/to-json-schema.test.ts +78 -17
  17. package/src/v4/core/api.ts +2 -0
  18. package/src/v4/core/checks.ts +8 -10
  19. package/src/v4/core/errors.ts +4 -0
  20. package/src/v4/core/registries.ts +11 -1
  21. package/src/v4/core/schemas.ts +80 -34
  22. package/src/v4/core/to-json-schema.ts +67 -30
  23. package/src/v4/mini/schemas.ts +2 -2
  24. package/src/v4/mini/tests/string.test.ts +6 -0
  25. package/v4/classic/schemas.cjs +4 -4
  26. package/v4/classic/schemas.d.cts +4 -3
  27. package/v4/classic/schemas.d.ts +4 -3
  28. package/v4/classic/schemas.js +4 -4
  29. package/v4/core/checks.cjs +18 -12
  30. package/v4/core/checks.d.cts +2 -1
  31. package/v4/core/checks.d.ts +2 -1
  32. package/v4/core/checks.js +18 -12
  33. package/v4/core/errors.cjs +4 -0
  34. package/v4/core/errors.js +4 -0
  35. package/v4/core/registries.cjs +10 -1
  36. package/v4/core/registries.d.cts +2 -1
  37. package/v4/core/registries.d.ts +2 -1
  38. package/v4/core/registries.js +10 -1
  39. package/v4/core/schemas.cjs +15 -6
  40. package/v4/core/schemas.d.cts +31 -9
  41. package/v4/core/schemas.d.ts +31 -9
  42. package/v4/core/schemas.js +15 -6
  43. package/v4/core/to-json-schema.cjs +51 -26
  44. package/v4/core/to-json-schema.d.cts +6 -2
  45. package/v4/core/to-json-schema.d.ts +6 -2
  46. package/v4/core/to-json-schema.js +51 -26
  47. package/v4/mini/schemas.d.cts +1 -1
  48. package/v4/mini/schemas.d.ts +1 -1
@@ -27,7 +27,7 @@ type MetadataType = Record<string, unknown> | undefined;
27
27
  export class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema extends $ZodType = $ZodType> {
28
28
  _meta!: Meta;
29
29
  _schema!: Schema;
30
- _map: WeakMap<Schema, $replace<Meta, Schema>> = new WeakMap();
30
+ _map: Map<Schema, $replace<Meta, Schema>> = new Map();
31
31
  _idmap: Map<string, Schema> = new Map();
32
32
 
33
33
  add<S extends Schema>(
@@ -45,7 +45,17 @@ export class $ZodRegistry<Meta extends MetadataType = MetadataType, Schema exten
45
45
  return this as any;
46
46
  }
47
47
 
48
+ clear(): this {
49
+ this._map = new Map();
50
+ this._idmap = new Map();
51
+ return this;
52
+ }
53
+
48
54
  remove(schema: Schema): this {
55
+ const meta: any = this._map.get(schema);
56
+ if (meta && typeof meta === "object" && "id" in meta) {
57
+ this._idmap.delete(meta.id!);
58
+ }
49
59
  this._map.delete(schema);
50
60
  return this;
51
61
  }
@@ -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;
@@ -205,18 +204,18 @@ export const $ZodType: core.$constructor<$ZodType> = /*@__PURE__*/ core.$constru
205
204
  ctx?: ParseContextInternal | undefined
206
205
  ): util.MaybeAsync<ParsePayload> => {
207
206
  let isAborted = util.aborted(payload);
207
+
208
208
  let asyncResult!: Promise<unknown> | undefined;
209
209
  for (const ch of checks) {
210
- if (ch._zod.when) {
211
- const shouldRun = ch._zod.when(payload);
212
-
210
+ if (ch._zod.def.when) {
211
+ const shouldRun = ch._zod.def.when(payload);
213
212
  if (!shouldRun) continue;
214
213
  } else if (isAborted) {
215
214
  continue;
216
215
  }
217
-
218
216
  const currLen = payload.issues.length;
219
217
  const _ = ch._zod.check(payload as any) as any as ParsePayload;
218
+
220
219
  if (_ instanceof Promise && ctx?.async === false) {
221
220
  throw new core.$ZodAsyncError();
222
221
  }
@@ -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
  }
@@ -43,7 +47,7 @@ interface EmitParams {
43
47
  | {
44
48
  /** */
45
49
  registry: $ZodRegistry<{ id?: string | undefined }>;
46
- uri: (id: string) => string;
50
+ uri?: ((id: string) => string) | undefined;
47
51
  defs: Record<string, JSONSchema.BaseSchema>;
48
52
  }
49
53
  | undefined;
@@ -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");
@@ -599,6 +614,8 @@ export class JSONSchemaGenerator {
599
614
  // initialize result with root schema fields
600
615
  // Object.assign(result, seen.cached);
601
616
 
617
+ // returns a ref to the schema
618
+ // defId will be empty if the ref points to an external schema (or #)
602
619
  const makeURI = (entry: [schemas.$ZodType<unknown, unknown>, Seen]): { ref: string; defId?: string } => {
603
620
  // comparing the seen objects because sometimes
604
621
  // multiple schemas map to the same seen object.
@@ -610,12 +627,15 @@ export class JSONSchemaGenerator {
610
627
  const externalId = params.external.registry.get(entry[0])?.id; // ?? "__shared";// `__schema${this.counter++}`;
611
628
 
612
629
  // check if schema is in the external registry
613
- if (externalId) return { ref: params.external.uri(externalId) };
630
+ const uriGenerator = params.external.uri ?? ((id) => id);
631
+ if (externalId) {
632
+ return { ref: uriGenerator(externalId) };
633
+ }
614
634
 
615
635
  // otherwise, add to __shared
616
636
  const id: string = entry[1].defId ?? (entry[1].schema.id as string) ?? `schema${this.counter++}`;
617
- entry[1].defId = id;
618
- return { defId: id, ref: `${params.external.uri("__shared")}#/${defsSegment}/${id}` };
637
+ entry[1].defId = id; // set defId so it will be reused if needed
638
+ return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}` };
619
639
  }
620
640
 
621
641
  if (entry[1] === root) {
@@ -632,6 +652,7 @@ export class JSONSchemaGenerator {
632
652
  // stored cached version in `def` property
633
653
  // remove all properties, set $ref
634
654
  const extractToDef = (entry: [schemas.$ZodType<unknown, unknown>, Seen]): void => {
655
+ // if the schema is already a reference, do not extract it
635
656
  if (entry[1].schema.$ref) {
636
657
  return;
637
658
  }
@@ -649,15 +670,29 @@ export class JSONSchemaGenerator {
649
670
  schema.$ref = ref;
650
671
  };
651
672
 
673
+ // throw on cycles
674
+
675
+ // break cycles
676
+ if (params.cycles === "throw") {
677
+ for (const entry of this.seen.entries()) {
678
+ const seen = entry[1];
679
+ if (seen.cycle) {
680
+ throw new Error(
681
+ "Cycle detected: " +
682
+ `#/${seen.cycle?.join("/")}/<root>` +
683
+ '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.'
684
+ );
685
+ }
686
+ }
687
+ }
688
+
652
689
  // extract schemas into $defs
653
690
  for (const entry of this.seen.entries()) {
654
691
  const seen = entry[1];
655
692
 
656
693
  // convert root schema to # $ref
657
- // also prevents root schema from being extracted
658
694
  if (schema === entry[0]) {
659
- // do not copy to defs...this is the root schema
660
- extractToDef(entry);
695
+ extractToDef(entry); // this has special handling for the root schema
661
696
  continue;
662
697
  }
663
698
 
@@ -674,21 +709,13 @@ export class JSONSchemaGenerator {
674
709
  const id = this.metadataRegistry.get(entry[0])?.id;
675
710
  if (id) {
676
711
  extractToDef(entry);
677
-
678
712
  continue;
679
713
  }
680
714
 
681
715
  // break cycles
682
716
  if (seen.cycle) {
683
- if (params.cycles === "throw") {
684
- throw new Error(
685
- "Cycle detected: " +
686
- `#/${seen.cycle?.join("/")}/<root>` +
687
- '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.'
688
- );
689
- } else if (params.cycles === "ref") {
690
- extractToDef(entry);
691
- }
717
+ // any
718
+ extractToDef(entry);
692
719
  continue;
693
720
  }
694
721
 
@@ -736,6 +763,7 @@ export class JSONSchemaGenerator {
736
763
  this.override({
737
764
  zodSchema: zodSchema as schemas.$ZodTypes,
738
765
  jsonSchema: schema,
766
+ path: seen.path ?? [],
739
767
  });
740
768
  };
741
769
 
@@ -752,6 +780,12 @@ export class JSONSchemaGenerator {
752
780
  console.warn(`Invalid target: ${this.target}`);
753
781
  }
754
782
 
783
+ if (params.external?.uri) {
784
+ const id = params.external.registry.get(schema)?.id;
785
+ if (!id) throw new Error("Schema is missing an `id` property");
786
+ result.$id = params.external.uri(id);
787
+ }
788
+
755
789
  Object.assign(result, root.def);
756
790
 
757
791
  // build defs object
@@ -764,11 +798,14 @@ export class JSONSchemaGenerator {
764
798
  }
765
799
 
766
800
  // set definitions in result
767
- if (!params.external && Object.keys(defs).length > 0) {
768
- if (this.target === "draft-2020-12") {
769
- result.$defs = defs;
770
- } else {
771
- result.definitions = defs;
801
+ if (params.external) {
802
+ } else {
803
+ if (Object.keys(defs).length > 0) {
804
+ if (this.target === "draft-2020-12") {
805
+ result.$defs = defs;
806
+ } else {
807
+ result.definitions = defs;
808
+ }
772
809
  }
773
810
  }
774
811
 
@@ -808,7 +845,7 @@ export function toJSONSchema(
808
845
  const schemas: Record<string, JSONSchema.BaseSchema> = {};
809
846
  const external = {
810
847
  registry: input,
811
- uri: (_params as RegistryToJSONSchemaParams)?.uri || ((id) => id),
848
+ uri: (_params as RegistryToJSONSchemaParams)?.uri,
812
849
  defs,
813
850
  };
814
851
  for (const entry of input._idmap.entries()) {
@@ -1023,11 +1023,11 @@ export function partialRecord<Key extends core.$ZodRecordKey, Value extends Some
1023
1023
  keyType: Key,
1024
1024
  valueType: Value,
1025
1025
  params?: string | core.$ZodRecordParams
1026
- ): ZodMiniRecord<ZodMiniUnion<[Key, ZodMiniNever]>, Value> {
1026
+ ): ZodMiniRecord<Key & core.$partial, Value> {
1027
1027
  return new ZodMiniRecord({
1028
1028
  type: "record",
1029
1029
  keyType: union([keyType, never()]),
1030
- valueType: valueType as any as core.$ZodType,
1030
+ valueType: valueType as any,
1031
1031
  ...util.normalizeParams(params),
1032
1032
  }) as any;
1033
1033
  }
@@ -99,6 +99,12 @@ test("z.url", () => {
99
99
  expect(a.parse("http://localhost:3000")).toEqual("http://localhost:3000");
100
100
  expect(a.parse("https://localhost:3000")).toEqual("https://localhost:3000");
101
101
 
102
+ // test trimming
103
+ expect(a.parse(" http://example.com ")).toEqual("http://example.com");
104
+ expect(a.parse(" http://example.com/")).toEqual("http://example.com/");
105
+ expect(a.parse(" http://example.com")).toEqual("http://example.com");
106
+ expect(a.parse(" http://example.com//")).toEqual("http://example.com//");
107
+
102
108
  // invalid URLs
103
109
  expect(() => a.parse("not-a-url")).toThrow();
104
110
  // expect(() => a.parse("http:/example.com")).toThrow();
@@ -1038,10 +1038,10 @@ exports.ZodCustom = core.$constructor("ZodCustom", (inst, def) => {
1038
1038
  exports.ZodType.init(inst, def);
1039
1039
  });
1040
1040
  // custom checks
1041
- function check(fn, params) {
1041
+ function check(fn) {
1042
1042
  const ch = new core.$ZodCheck({
1043
1043
  check: "custom",
1044
- ...index_js_1.util.normalizeParams(params),
1044
+ // ...util.normalizeParams(params),
1045
1045
  });
1046
1046
  ch._zod.check = fn;
1047
1047
  return ch;
@@ -1053,7 +1053,7 @@ function refine(fn, _params = {}) {
1053
1053
  return core._refine(exports.ZodCustom, fn, _params);
1054
1054
  }
1055
1055
  // superRefine
1056
- function superRefine(fn, params) {
1056
+ function superRefine(fn) {
1057
1057
  const ch = check((payload) => {
1058
1058
  payload.addIssue = (issue) => {
1059
1059
  if (typeof issue === "string") {
@@ -1072,7 +1072,7 @@ function superRefine(fn, params) {
1072
1072
  }
1073
1073
  };
1074
1074
  return fn(payload.value, payload);
1075
- }, params);
1075
+ });
1076
1076
  return ch;
1077
1077
  }
1078
1078
  function _instanceof(cls, params = {
@@ -151,6 +151,7 @@ export interface ZodString extends _ZodString<core.$ZodStringInternals<string>>
151
151
  }
152
152
  export declare const ZodString: core.$constructor<ZodString>;
153
153
  export declare function string(params?: string | core.$ZodStringParams): ZodString;
154
+ export declare function string<T extends string>(params?: string | core.$ZodStringParams): core.$ZodType<T, T>;
154
155
  export interface ZodStringFormat<Format extends string = string> extends _ZodString<core.$ZodStringFormatInternals<Format>> {
155
156
  }
156
157
  export declare const ZodStringFormat: core.$constructor<ZodStringFormat>;
@@ -474,7 +475,7 @@ export interface ZodRecord<Key extends core.$ZodRecordKey = core.$ZodRecordKey,
474
475
  }
475
476
  export declare const ZodRecord: core.$constructor<ZodRecord>;
476
477
  export declare function record<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key, Value>;
477
- export declare function partialRecord<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<ZodUnion<[Key, ZodNever]>, Value>;
478
+ export declare function partialRecord<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key & core.$partial, Value>;
478
479
  export interface ZodMap<Key extends core.SomeType = core.$ZodType, Value extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodMapInternals<Key, Value>>, core.$ZodMap<Key, Value> {
479
480
  keyType: Key;
480
481
  valueType: Value;
@@ -601,10 +602,10 @@ export declare function promise<T extends core.SomeType>(innerType: T): ZodPromi
601
602
  export interface ZodCustom<O = unknown, I = unknown> extends _ZodType<core.$ZodCustomInternals<O, I>>, core.$ZodCustom<O, I> {
602
603
  }
603
604
  export declare const ZodCustom: core.$constructor<ZodCustom>;
604
- export declare function check<O = unknown>(fn: core.CheckFn<O>, params?: string | core.$ZodCustomParams): core.$ZodCheck<O>;
605
+ export declare function check<O = unknown>(fn: core.CheckFn<O>): core.$ZodCheck<O>;
605
606
  export declare function custom<O>(fn?: (data: unknown) => unknown, _params?: string | core.$ZodCustomParams | undefined): ZodCustom<O, O>;
606
607
  export declare function refine<T>(fn: (arg: NoInfer<T>) => util.MaybeAsync<unknown>, _params?: string | core.$ZodCustomParams): core.$ZodCheck<T>;
607
- export declare function superRefine<T>(fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>, params?: string | core.$ZodCustomParams): core.$ZodCheck<T>;
608
+ export declare function superRefine<T>(fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>): core.$ZodCheck<T>;
608
609
  type ZodInstanceOfParams = core.Params<ZodCustom, core.$ZodIssueCustom, "type" | "check" | "checks" | "fn" | "abort" | "error" | "params" | "path">;
609
610
  declare function _instanceof<T extends typeof util.Class>(cls: T, params?: ZodInstanceOfParams): ZodCustom<InstanceType<T>, InstanceType<T>>;
610
611
  export { _instanceof as instanceof };
@@ -151,6 +151,7 @@ export interface ZodString extends _ZodString<core.$ZodStringInternals<string>>
151
151
  }
152
152
  export declare const ZodString: core.$constructor<ZodString>;
153
153
  export declare function string(params?: string | core.$ZodStringParams): ZodString;
154
+ export declare function string<T extends string>(params?: string | core.$ZodStringParams): core.$ZodType<T, T>;
154
155
  export interface ZodStringFormat<Format extends string = string> extends _ZodString<core.$ZodStringFormatInternals<Format>> {
155
156
  }
156
157
  export declare const ZodStringFormat: core.$constructor<ZodStringFormat>;
@@ -474,7 +475,7 @@ export interface ZodRecord<Key extends core.$ZodRecordKey = core.$ZodRecordKey,
474
475
  }
475
476
  export declare const ZodRecord: core.$constructor<ZodRecord>;
476
477
  export declare function record<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key, Value>;
477
- export declare function partialRecord<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<ZodUnion<[Key, ZodNever]>, Value>;
478
+ export declare function partialRecord<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key & core.$partial, Value>;
478
479
  export interface ZodMap<Key extends core.SomeType = core.$ZodType, Value extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodMapInternals<Key, Value>>, core.$ZodMap<Key, Value> {
479
480
  keyType: Key;
480
481
  valueType: Value;
@@ -601,10 +602,10 @@ export declare function promise<T extends core.SomeType>(innerType: T): ZodPromi
601
602
  export interface ZodCustom<O = unknown, I = unknown> extends _ZodType<core.$ZodCustomInternals<O, I>>, core.$ZodCustom<O, I> {
602
603
  }
603
604
  export declare const ZodCustom: core.$constructor<ZodCustom>;
604
- export declare function check<O = unknown>(fn: core.CheckFn<O>, params?: string | core.$ZodCustomParams): core.$ZodCheck<O>;
605
+ export declare function check<O = unknown>(fn: core.CheckFn<O>): core.$ZodCheck<O>;
605
606
  export declare function custom<O>(fn?: (data: unknown) => unknown, _params?: string | core.$ZodCustomParams | undefined): ZodCustom<O, O>;
606
607
  export declare function refine<T>(fn: (arg: NoInfer<T>) => util.MaybeAsync<unknown>, _params?: string | core.$ZodCustomParams): core.$ZodCheck<T>;
607
- export declare function superRefine<T>(fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>, params?: string | core.$ZodCustomParams): core.$ZodCheck<T>;
608
+ export declare function superRefine<T>(fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>): core.$ZodCheck<T>;
608
609
  type ZodInstanceOfParams = core.Params<ZodCustom, core.$ZodIssueCustom, "type" | "check" | "checks" | "fn" | "abort" | "error" | "params" | "path">;
609
610
  declare function _instanceof<T extends typeof util.Class>(cls: T, params?: ZodInstanceOfParams): ZodCustom<InstanceType<T>, InstanceType<T>>;
610
611
  export { _instanceof as instanceof };