zod 3.26.0-canary.20250707T201657 → 3.26.0-canary.20250708T225111

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.20250707T201657",
3
+ "version": "3.26.0-canary.20250708T225111",
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",
@@ -1937,10 +1937,10 @@ export const ZodCustom: core.$constructor<ZodCustom> = /*@__PURE__*/ core.$const
1937
1937
  });
1938
1938
 
1939
1939
  // custom checks
1940
- export function check<O = unknown>(fn: core.CheckFn<O>, params?: string | core.$ZodCustomParams): core.$ZodCheck<O> {
1940
+ export function check<O = unknown>(fn: core.CheckFn<O>): core.$ZodCheck<O> {
1941
1941
  const ch = new core.$ZodCheck({
1942
1942
  check: "custom",
1943
- ...util.normalizeParams(params),
1943
+ // ...util.normalizeParams(params),
1944
1944
  });
1945
1945
 
1946
1946
  ch._zod.check = fn;
@@ -1962,10 +1962,7 @@ export function refine<T>(
1962
1962
  }
1963
1963
 
1964
1964
  // superRefine
1965
- export function superRefine<T>(
1966
- fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>,
1967
- params?: string | core.$ZodCustomParams
1968
- ): core.$ZodCheck<T> {
1965
+ export function superRefine<T>(fn: (arg: T, payload: RefinementCtx<T>) => void | Promise<void>): core.$ZodCheck<T> {
1969
1966
  const ch = check<T>((payload) => {
1970
1967
  (payload as RefinementCtx).addIssue = (issue) => {
1971
1968
  if (typeof issue === "string") {
@@ -1983,7 +1980,7 @@ export function superRefine<T>(
1983
1980
  };
1984
1981
 
1985
1982
  return fn(payload.value, payload as RefinementCtx<T>);
1986
- }, params);
1983
+ });
1987
1984
  return ch;
1988
1985
  }
1989
1986
 
@@ -321,7 +321,7 @@ test("all errors", () => {
321
321
  });
322
322
 
323
323
  const schema = z.strictObject({
324
- username: z.string(),
324
+ username: z.string().brand<"username">(),
325
325
  favoriteNumbers: z.array(z.number()),
326
326
  nesting: z.object({
327
327
  a: z.string(),
@@ -336,8 +336,33 @@ const result = schema.safeParse({
336
336
  extra: 1234,
337
337
  });
338
338
 
339
+ const tree = z.treeifyError(result.error!);
340
+
341
+ expectTypeOf(tree).toEqualTypeOf<{
342
+ errors: string[];
343
+ properties?: {
344
+ username?: {
345
+ errors: string[];
346
+ };
347
+ favoriteNumbers?: {
348
+ errors: string[];
349
+ items?: {
350
+ errors: string[];
351
+ }[];
352
+ };
353
+ nesting?: {
354
+ errors: string[];
355
+ properties?: {
356
+ a?: {
357
+ errors: string[];
358
+ };
359
+ };
360
+ };
361
+ };
362
+ }>();
363
+
339
364
  test("z.treeifyError", () => {
340
- expect(z.treeifyError(result.error!)).toMatchInlineSnapshot(`
365
+ expect(tree).toMatchInlineSnapshot(`
341
366
  {
342
367
  "errors": [
343
368
  "Unrecognized key: "extra"",
@@ -324,3 +324,33 @@ test("recursion compatibility", () => {
324
324
  },
325
325
  });
326
326
  });
327
+
328
+ // biome-ignore lint: sadf
329
+ export type RecursiveA = z.ZodUnion<
330
+ [
331
+ z.ZodObject<{
332
+ a: z.ZodDefault<RecursiveA>;
333
+ b: z.ZodPrefault<RecursiveA>;
334
+ c: z.ZodNonOptional<RecursiveA>;
335
+ d: z.ZodOptional<RecursiveA>;
336
+ e: z.ZodNullable<RecursiveA>;
337
+ g: z.ZodReadonly<RecursiveA>;
338
+ h: z.ZodPipe<RecursiveA, z.ZodString>;
339
+ i: z.ZodArray<RecursiveA>;
340
+ j: z.ZodSet<RecursiveA>;
341
+ k: z.ZodMap<RecursiveA, RecursiveA>;
342
+ l: z.ZodRecord<z.ZodString, RecursiveA>;
343
+ m: z.ZodUnion<[RecursiveA, RecursiveA]>;
344
+ n: z.ZodIntersection<RecursiveA, RecursiveA>;
345
+ o: z.ZodLazy<RecursiveA>;
346
+ p: z.ZodPromise<RecursiveA>;
347
+ q: z.ZodCatch<RecursiveA>;
348
+ r: z.ZodSuccess<RecursiveA>;
349
+ s: z.ZodTransform<RecursiveA, string>;
350
+ t: z.ZodTuple<[RecursiveA, RecursiveA]>;
351
+ u: z.ZodObject<{
352
+ a: RecursiveA;
353
+ }>;
354
+ }>,
355
+ ]
356
+ >;
@@ -421,3 +421,112 @@ describe("type refinement", () => {
421
421
  });
422
422
  });
423
423
  */
424
+
425
+ test("when", () => {
426
+ const schema = z
427
+ .strictObject({
428
+ password: z.string().min(8),
429
+ confirmPassword: z.string(),
430
+ other: z.string(),
431
+ })
432
+ .refine(
433
+ (data) => {
434
+ console.log("running check...");
435
+ console.log(data);
436
+ console.log(data.password);
437
+ return data.password === data.confirmPassword;
438
+ },
439
+ {
440
+ message: "Passwords do not match",
441
+ path: ["confirmPassword"],
442
+ when(payload) {
443
+ if (payload.value === undefined) return false;
444
+ if (payload.value === null) return false;
445
+ // no issues with confirmPassword or password
446
+ return payload.issues.every((iss) => iss.path?.[0] !== "confirmPassword" && iss.path?.[0] !== "password");
447
+ },
448
+ }
449
+ );
450
+
451
+ expect(schema.safeParse(undefined)).toMatchInlineSnapshot(`
452
+ {
453
+ "error": [ZodError: [
454
+ {
455
+ "expected": "object",
456
+ "code": "invalid_type",
457
+ "path": [],
458
+ "message": "Invalid input: expected object, received undefined"
459
+ }
460
+ ]],
461
+ "success": false,
462
+ }
463
+ `);
464
+ expect(schema.safeParse(null)).toMatchInlineSnapshot(`
465
+ {
466
+ "error": [ZodError: [
467
+ {
468
+ "expected": "object",
469
+ "code": "invalid_type",
470
+ "path": [],
471
+ "message": "Invalid input: expected object, received null"
472
+ }
473
+ ]],
474
+ "success": false,
475
+ }
476
+ `);
477
+ expect(
478
+ schema.safeParse({
479
+ password: "asdf",
480
+ confirmPassword: "asdfg",
481
+ other: "qwer",
482
+ })
483
+ ).toMatchInlineSnapshot(`
484
+ {
485
+ "error": [ZodError: [
486
+ {
487
+ "origin": "string",
488
+ "code": "too_small",
489
+ "minimum": 8,
490
+ "inclusive": true,
491
+ "path": [
492
+ "password"
493
+ ],
494
+ "message": "Too small: expected string to have >=8 characters"
495
+ }
496
+ ]],
497
+ "success": false,
498
+ }
499
+ `);
500
+
501
+ expect(
502
+ schema.safeParse({
503
+ password: "asdf",
504
+ confirmPassword: "asdfg",
505
+ other: 1234,
506
+ })
507
+ ).toMatchInlineSnapshot(`
508
+ {
509
+ "error": [ZodError: [
510
+ {
511
+ "origin": "string",
512
+ "code": "too_small",
513
+ "minimum": 8,
514
+ "inclusive": true,
515
+ "path": [
516
+ "password"
517
+ ],
518
+ "message": "Too small: expected string to have >=8 characters"
519
+ },
520
+ {
521
+ "expected": "string",
522
+ "code": "invalid_type",
523
+ "path": [
524
+ "other"
525
+ ],
526
+ "message": "Invalid input: expected string, received number"
527
+ }
528
+ ]],
529
+ "success": false,
530
+ }
531
+ `);
532
+ });
@@ -193,3 +193,12 @@ test("function meta with replacement", () => {
193
193
 
194
194
  expect(myReg.get(mySchema)!.defaulter("hello", true)).toEqual(5);
195
195
  });
196
+
197
+ test("test .clear()", () => {
198
+ const reg = z.registry();
199
+ const a = z.string();
200
+ reg.add(a);
201
+ expect(reg.has(a)).toEqual(true);
202
+ reg.clear();
203
+ expect(reg.has(a)).toEqual(false);
204
+ });
@@ -1746,16 +1746,17 @@ test("basic registry", () => {
1746
1746
  myRegistry.add(User, { id: "User" });
1747
1747
  myRegistry.add(Post, { id: "Post" });
1748
1748
 
1749
- const result = z.z.toJSONSchema(myRegistry);
1749
+ const result = z.z.toJSONSchema(myRegistry, { uri: (id) => `https://example.com/${id}.json` });
1750
1750
  expect(result).toMatchInlineSnapshot(`
1751
1751
  {
1752
1752
  "schemas": {
1753
1753
  "Post": {
1754
+ "$id": "https://example.com/Post.json",
1754
1755
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1755
1756
  "additionalProperties": false,
1756
1757
  "properties": {
1757
1758
  "author": {
1758
- "$ref": "User",
1759
+ "$ref": "https://example.com/User.json",
1759
1760
  },
1760
1761
  "content": {
1761
1762
  "type": "string",
@@ -1772,6 +1773,7 @@ test("basic registry", () => {
1772
1773
  "type": "object",
1773
1774
  },
1774
1775
  "User": {
1776
+ "$id": "https://example.com/User.json",
1775
1777
  "$schema": "https://json-schema.org/draft/2020-12/schema",
1776
1778
  "additionalProperties": false,
1777
1779
  "properties": {
@@ -1780,7 +1782,7 @@ test("basic registry", () => {
1780
1782
  },
1781
1783
  "posts": {
1782
1784
  "items": {
1783
- "$ref": "Post",
1785
+ "$ref": "https://example.com/Post.json",
1784
1786
  },
1785
1787
  "type": "array",
1786
1788
  },
@@ -2273,3 +2275,40 @@ test("custom toJSONSchema", () => {
2273
2275
  }
2274
2276
  `);
2275
2277
  });
2278
+
2279
+ test("cycle detection - root", () => {
2280
+ const schema = z.object({
2281
+ name: z.string(),
2282
+ get subcategories() {
2283
+ return z.array(schema);
2284
+ },
2285
+ });
2286
+
2287
+ expect(() => z.toJSONSchema(schema, { cycles: "throw" })).toThrowErrorMatchingInlineSnapshot(`
2288
+ [Error: Cycle detected: #/properties/subcategories/items/<root>
2289
+
2290
+ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.]
2291
+ `);
2292
+ });
2293
+
2294
+ test("cycle detection - mutual recursion", () => {
2295
+ const A = z.object({
2296
+ name: z.string(),
2297
+ get subcategories() {
2298
+ return z.array(B);
2299
+ },
2300
+ });
2301
+
2302
+ const B = z.object({
2303
+ name: z.string(),
2304
+ get subcategories() {
2305
+ return z.array(A);
2306
+ },
2307
+ });
2308
+
2309
+ expect(() => z.toJSONSchema(A, { cycles: "throw" })).toThrowErrorMatchingInlineSnapshot(`
2310
+ [Error: Cycle detected: #/properties/subcategories/items/properties/subcategories/items/<root>
2311
+
2312
+ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.]
2313
+ `);
2314
+ });
@@ -779,6 +779,8 @@ export function _nan<T extends schemas.$ZodNaN>(Class: util.SchemaClass<T>, para
779
779
  });
780
780
  }
781
781
 
782
+ // export type $ZodCheckParams = CheckParams<checks.$ZodCheck, "abort">;
783
+
782
784
  export type $ZodCheckLessThanParams = CheckParams<checks.$ZodCheckLessThan, "inclusive" | "value">;
783
785
  export function _lt(
784
786
  value: util.Numeric,
@@ -13,18 +13,16 @@ export interface $ZodCheckDef {
13
13
  error?: errors.$ZodErrorMap<never> | undefined;
14
14
  /** If true, no later checks will be executed if this check fails. Default `false`. */
15
15
  abort?: boolean | undefined;
16
+ /** If provided, this check will only be executed if the function returns `true`. Defaults to `payload => z.util.isAborted(payload)`. */
17
+ when?: ((payload: schemas.ParsePayload) => boolean) | undefined;
16
18
  }
17
19
 
18
20
  export interface $ZodCheckInternals<T> {
19
21
  def: $ZodCheckDef;
20
22
  /** The set of issues this check might throw. */
21
23
  issc?: errors.$ZodIssueBase;
22
- // "_check"(input: $ZodResult<T>): util.MaybeAsync<void>;
23
24
  check(payload: schemas.ParsePayload<T>): util.MaybeAsync<void>;
24
- // _parseB(payload: ParsePayload<any>, ctx: ParseContext): util.MaybeAsync<ParsePayload>;
25
25
  onattach: ((schema: schemas.$ZodType) => void)[];
26
- // "_async": boolean;
27
- when?: ((payload: schemas.ParsePayload) => boolean) | undefined;
28
26
  }
29
27
 
30
28
  export interface $ZodCheck<in T = never> {
@@ -452,7 +450,7 @@ export const $ZodCheckMaxSize: core.$constructor<$ZodCheckMaxSize> = /*@__PURE__
452
450
  (inst, def) => {
453
451
  $ZodCheck.init(inst, def);
454
452
 
455
- inst._zod.when = (payload) => {
453
+ inst._zod.def.when ??= (payload) => {
456
454
  const val = payload.value;
457
455
  return !util.nullish(val) && (val as any).size !== undefined;
458
456
  };
@@ -501,7 +499,7 @@ export const $ZodCheckMinSize: core.$constructor<$ZodCheckMinSize> = /*@__PURE__
501
499
  (inst, def) => {
502
500
  $ZodCheck.init(inst, def);
503
501
 
504
- inst._zod.when = (payload) => {
502
+ inst._zod.def.when ??= (payload) => {
505
503
  const val = payload.value;
506
504
  return !util.nullish(val) && (val as any).size !== undefined;
507
505
  };
@@ -550,7 +548,7 @@ export const $ZodCheckSizeEquals: core.$constructor<$ZodCheckSizeEquals> = /*@__
550
548
  (inst, def) => {
551
549
  $ZodCheck.init(inst, def);
552
550
 
553
- inst._zod.when = (payload) => {
551
+ inst._zod.def.when ??= (payload) => {
554
552
  const val = payload.value;
555
553
  return !util.nullish(val) && (val as any).size !== undefined;
556
554
  };
@@ -604,7 +602,7 @@ export const $ZodCheckMaxLength: core.$constructor<$ZodCheckMaxLength> = /*@__PU
604
602
  (inst, def) => {
605
603
  $ZodCheck.init(inst, def);
606
604
 
607
- inst._zod.when = (payload) => {
605
+ inst._zod.def.when ??= (payload) => {
608
606
  const val = payload.value;
609
607
  return !util.nullish(val) && (val as any).length !== undefined;
610
608
  };
@@ -655,7 +653,7 @@ export const $ZodCheckMinLength: core.$constructor<$ZodCheckMinLength> = /*@__PU
655
653
  (inst, def) => {
656
654
  $ZodCheck.init(inst, def);
657
655
 
658
- inst._zod.when = (payload) => {
656
+ inst._zod.def.when ??= (payload) => {
659
657
  const val = payload.value;
660
658
  return !util.nullish(val) && (val as any).length !== undefined;
661
659
  };
@@ -707,7 +705,7 @@ export const $ZodCheckLengthEquals: core.$constructor<$ZodCheckLengthEquals> = /
707
705
  (inst, def) => {
708
706
  $ZodCheck.init(inst, def);
709
707
 
710
- inst._zod.when = (payload) => {
708
+ inst._zod.def.when ??= (payload) => {
711
709
  const val = payload.value;
712
710
  return !util.nullish(val) && (val as any).length !== undefined;
713
711
  };
@@ -203,6 +203,10 @@ const initializer = (inst: $ZodError, def: $ZodIssue[]): void => {
203
203
  enumerable: true,
204
204
  // configurable: false,
205
205
  });
206
+ Object.defineProperty(inst, "toString", {
207
+ value: () => inst.message,
208
+ enumerable: false,
209
+ });
206
210
  };
207
211
 
208
212
  export const $ZodError: $constructor<$ZodError> = $constructor("$ZodError", initializer);
@@ -291,13 +295,15 @@ export function formatError<T>(error: $ZodError, _mapper?: any) {
291
295
  return fieldErrors;
292
296
  }
293
297
 
294
- export type $ZodErrorTree<T, U = string> = T extends [any, ...any[]]
295
- ? { errors: U[]; items?: { [K in keyof T]?: $ZodErrorTree<T[K], U> } }
296
- : T extends any[]
297
- ? { errors: U[]; items?: Array<$ZodErrorTree<T[number], U>> }
298
- : T extends object
299
- ? { errors: U[]; properties?: { [K in keyof T]?: $ZodErrorTree<T[K], U> } }
300
- : { errors: U[] };
298
+ export type $ZodErrorTree<T, U = string> = T extends util.Primitive
299
+ ? { errors: U[] }
300
+ : T extends [any, ...any[]]
301
+ ? { errors: U[]; items?: { [K in keyof T]?: $ZodErrorTree<T[K], U> } }
302
+ : T extends any[]
303
+ ? { errors: U[]; items?: Array<$ZodErrorTree<T[number], U>> }
304
+ : T extends object
305
+ ? { errors: U[]; properties?: { [K in keyof T]?: $ZodErrorTree<T[K], U> } }
306
+ : { errors: U[] };
301
307
 
302
308
  export function treeifyError<T>(error: $ZodError<T>): $ZodErrorTree<T>;
303
309
  export function treeifyError<T, U>(error: $ZodError<T>, mapper?: (issue: $ZodIssue) => U): $ZodErrorTree<T, U>;
@@ -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,6 +45,12 @@ 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 {
49
55
  const meta: any = this._map.get(schema);
50
56
  if (meta && typeof meta === "object" && "id" in meta) {
@@ -204,18 +204,18 @@ export const $ZodType: core.$constructor<$ZodType> = /*@__PURE__*/ core.$constru
204
204
  ctx?: ParseContextInternal | undefined
205
205
  ): util.MaybeAsync<ParsePayload> => {
206
206
  let isAborted = util.aborted(payload);
207
+
207
208
  let asyncResult!: Promise<unknown> | undefined;
208
209
  for (const ch of checks) {
209
- if (ch._zod.when) {
210
- const shouldRun = ch._zod.when(payload);
211
-
210
+ if (ch._zod.def.when) {
211
+ const shouldRun = ch._zod.def.when(payload);
212
212
  if (!shouldRun) continue;
213
213
  } else if (isAborted) {
214
214
  continue;
215
215
  }
216
-
217
216
  const currLen = payload.issues.length;
218
217
  const _ = ch._zod.check(payload as any) as any as ParsePayload;
218
+
219
219
  if (_ instanceof Promise && ctx?.async === false) {
220
220
  throw new core.$ZodAsyncError();
221
221
  }
@@ -47,7 +47,7 @@ interface EmitParams {
47
47
  | {
48
48
  /** */
49
49
  registry: $ZodRegistry<{ id?: string | undefined }>;
50
- uri: (id: string) => string;
50
+ uri?: ((id: string) => string) | undefined;
51
51
  defs: Record<string, JSONSchema.BaseSchema>;
52
52
  }
53
53
  | undefined;
@@ -614,6 +614,8 @@ export class JSONSchemaGenerator {
614
614
  // initialize result with root schema fields
615
615
  // Object.assign(result, seen.cached);
616
616
 
617
+ // returns a ref to the schema
618
+ // defId will be empty if the ref points to an external schema (or #)
617
619
  const makeURI = (entry: [schemas.$ZodType<unknown, unknown>, Seen]): { ref: string; defId?: string } => {
618
620
  // comparing the seen objects because sometimes
619
621
  // multiple schemas map to the same seen object.
@@ -625,12 +627,15 @@ export class JSONSchemaGenerator {
625
627
  const externalId = params.external.registry.get(entry[0])?.id; // ?? "__shared";// `__schema${this.counter++}`;
626
628
 
627
629
  // check if schema is in the external registry
628
- 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
+ }
629
634
 
630
635
  // otherwise, add to __shared
631
636
  const id: string = entry[1].defId ?? (entry[1].schema.id as string) ?? `schema${this.counter++}`;
632
- entry[1].defId = id;
633
- 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}` };
634
639
  }
635
640
 
636
641
  if (entry[1] === root) {
@@ -647,6 +652,7 @@ export class JSONSchemaGenerator {
647
652
  // stored cached version in `def` property
648
653
  // remove all properties, set $ref
649
654
  const extractToDef = (entry: [schemas.$ZodType<unknown, unknown>, Seen]): void => {
655
+ // if the schema is already a reference, do not extract it
650
656
  if (entry[1].schema.$ref) {
651
657
  return;
652
658
  }
@@ -664,15 +670,29 @@ export class JSONSchemaGenerator {
664
670
  schema.$ref = ref;
665
671
  };
666
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
+
667
689
  // extract schemas into $defs
668
690
  for (const entry of this.seen.entries()) {
669
691
  const seen = entry[1];
670
692
 
671
693
  // convert root schema to # $ref
672
- // also prevents root schema from being extracted
673
694
  if (schema === entry[0]) {
674
- // do not copy to defs...this is the root schema
675
- extractToDef(entry);
695
+ extractToDef(entry); // this has special handling for the root schema
676
696
  continue;
677
697
  }
678
698
 
@@ -689,21 +709,13 @@ export class JSONSchemaGenerator {
689
709
  const id = this.metadataRegistry.get(entry[0])?.id;
690
710
  if (id) {
691
711
  extractToDef(entry);
692
-
693
712
  continue;
694
713
  }
695
714
 
696
715
  // break cycles
697
716
  if (seen.cycle) {
698
- if (params.cycles === "throw") {
699
- throw new Error(
700
- "Cycle detected: " +
701
- `#/${seen.cycle?.join("/")}/<root>` +
702
- '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.'
703
- );
704
- } else if (params.cycles === "ref") {
705
- extractToDef(entry);
706
- }
717
+ // any
718
+ extractToDef(entry);
707
719
  continue;
708
720
  }
709
721
 
@@ -768,6 +780,12 @@ export class JSONSchemaGenerator {
768
780
  console.warn(`Invalid target: ${this.target}`);
769
781
  }
770
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
+
771
789
  Object.assign(result, root.def);
772
790
 
773
791
  // build defs object
@@ -780,11 +798,14 @@ export class JSONSchemaGenerator {
780
798
  }
781
799
 
782
800
  // set definitions in result
783
- if (!params.external && Object.keys(defs).length > 0) {
784
- if (this.target === "draft-2020-12") {
785
- result.$defs = defs;
786
- } else {
787
- 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
+ }
788
809
  }
789
810
  }
790
811
 
@@ -824,7 +845,7 @@ export function toJSONSchema(
824
845
  const schemas: Record<string, JSONSchema.BaseSchema> = {};
825
846
  const external = {
826
847
  registry: input,
827
- uri: (_params as RegistryToJSONSchemaParams)?.uri || ((id) => id),
848
+ uri: (_params as RegistryToJSONSchemaParams)?.uri,
828
849
  defs,
829
850
  };
830
851
  for (const entry of input._idmap.entries()) {
@@ -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 = {
@@ -602,10 +602,10 @@ export declare function promise<T extends core.SomeType>(innerType: T): ZodPromi
602
602
  export interface ZodCustom<O = unknown, I = unknown> extends _ZodType<core.$ZodCustomInternals<O, I>>, core.$ZodCustom<O, I> {
603
603
  }
604
604
  export declare const ZodCustom: core.$constructor<ZodCustom>;
605
- 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>;
606
606
  export declare function custom<O>(fn?: (data: unknown) => unknown, _params?: string | core.$ZodCustomParams | undefined): ZodCustom<O, O>;
607
607
  export declare function refine<T>(fn: (arg: NoInfer<T>) => util.MaybeAsync<unknown>, _params?: string | core.$ZodCustomParams): core.$ZodCheck<T>;
608
- 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>;
609
609
  type ZodInstanceOfParams = core.Params<ZodCustom, core.$ZodIssueCustom, "type" | "check" | "checks" | "fn" | "abort" | "error" | "params" | "path">;
610
610
  declare function _instanceof<T extends typeof util.Class>(cls: T, params?: ZodInstanceOfParams): ZodCustom<InstanceType<T>, InstanceType<T>>;
611
611
  export { _instanceof as instanceof };