zod 3.25.74 → 3.25.76

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.
@@ -635,6 +635,8 @@ export interface $ZodIntersectionDef<Left extends SomeType = $ZodType, Right ext
635
635
  export interface $ZodIntersectionInternals<A extends SomeType = $ZodType, B extends SomeType = $ZodType> extends $ZodTypeInternals<core.output<A> & core.output<B>, core.input<A> & core.input<B>> {
636
636
  def: $ZodIntersectionDef<A, B>;
637
637
  isst: never;
638
+ optin: A["_zod"]["optin"] | B["_zod"]["optin"];
639
+ optout: A["_zod"]["optout"] | B["_zod"]["optout"];
638
640
  }
639
641
  export interface $ZodIntersection<A extends SomeType = $ZodType, B extends SomeType = $ZodType> extends $ZodType {
640
642
  _zod: $ZodIntersectionInternals<A, B>;
@@ -686,6 +688,8 @@ export type $InferZodRecordInput<Key extends $ZodRecordKey = $ZodRecordKey, Valu
686
688
  export interface $ZodRecordInternals<Key extends $ZodRecordKey = $ZodRecordKey, Value extends SomeType = $ZodType> extends $ZodTypeInternals<$InferZodRecordOutput<Key, Value>, $InferZodRecordInput<Key, Value>> {
687
689
  def: $ZodRecordDef<Key, Value>;
688
690
  isst: errors.$ZodIssueInvalidType | errors.$ZodIssueInvalidKey<Record<PropertyKey, unknown>>;
691
+ optin?: "optional" | undefined;
692
+ optout?: "optional" | undefined;
689
693
  }
690
694
  export type $partial = {
691
695
  "~~partial": true;
@@ -702,6 +706,8 @@ export interface $ZodMapDef<Key extends SomeType = $ZodType, Value extends SomeT
702
706
  export interface $ZodMapInternals<Key extends SomeType = $ZodType, Value extends SomeType = $ZodType> extends $ZodTypeInternals<Map<core.output<Key>, core.output<Value>>, Map<core.input<Key>, core.input<Value>>> {
703
707
  def: $ZodMapDef<Key, Value>;
704
708
  isst: errors.$ZodIssueInvalidType | errors.$ZodIssueInvalidKey | errors.$ZodIssueInvalidElement<unknown>;
709
+ optin?: "optional" | undefined;
710
+ optout?: "optional" | undefined;
705
711
  }
706
712
  export interface $ZodMap<Key extends SomeType = $ZodType, Value extends SomeType = $ZodType> extends $ZodType {
707
713
  _zod: $ZodMapInternals<Key, Value>;
@@ -714,6 +720,8 @@ export interface $ZodSetDef<T extends SomeType = $ZodType> extends $ZodTypeDef {
714
720
  export interface $ZodSetInternals<T extends SomeType = $ZodType> extends $ZodTypeInternals<Set<core.output<T>>, Set<core.input<T>>> {
715
721
  def: $ZodSetDef<T>;
716
722
  isst: errors.$ZodIssueInvalidType;
723
+ optin?: "optional" | undefined;
724
+ optout?: "optional" | undefined;
717
725
  }
718
726
  export interface $ZodSet<T extends SomeType = $ZodType> extends $ZodType {
719
727
  _zod: $ZodSetInternals<T>;
@@ -826,6 +834,7 @@ export interface $ZodDefaultDef<T extends SomeType = $ZodType> extends $ZodTypeD
826
834
  export interface $ZodDefaultInternals<T extends SomeType = $ZodType> extends $ZodTypeInternals<util.NoUndefined<core.output<T>>, core.input<T> | undefined> {
827
835
  def: $ZodDefaultDef<T>;
828
836
  optin: "optional";
837
+ optout?: "optional" | undefined;
829
838
  isst: never;
830
839
  values: T["_zod"]["values"];
831
840
  }
@@ -842,6 +851,7 @@ export interface $ZodPrefaultDef<T extends SomeType = $ZodType> extends $ZodType
842
851
  export interface $ZodPrefaultInternals<T extends SomeType = $ZodType> extends $ZodTypeInternals<util.NoUndefined<core.output<T>>, core.input<T> | undefined> {
843
852
  def: $ZodPrefaultDef<T>;
844
853
  optin: "optional";
854
+ optout?: "optional" | undefined;
845
855
  isst: never;
846
856
  values: T["_zod"]["values"];
847
857
  }
@@ -857,6 +867,8 @@ export interface $ZodNonOptionalInternals<T extends SomeType = $ZodType> extends
857
867
  def: $ZodNonOptionalDef<T>;
858
868
  isst: errors.$ZodIssueInvalidType;
859
869
  values: T["_zod"]["values"];
870
+ optin: "optional" | undefined;
871
+ optout: "optional" | undefined;
860
872
  }
861
873
  export interface $ZodNonOptional<T extends SomeType = $ZodType> extends $ZodType {
862
874
  _zod: $ZodNonOptionalInternals<T>;
@@ -869,6 +881,8 @@ export interface $ZodSuccessDef<T extends SomeType = $ZodType> extends $ZodTypeD
869
881
  export interface $ZodSuccessInternals<T extends SomeType = $ZodType> extends $ZodTypeInternals<boolean, core.input<T>> {
870
882
  def: $ZodSuccessDef<T>;
871
883
  isst: never;
884
+ optin: T["_zod"]["optin"];
885
+ optout: "optional" | undefined;
872
886
  }
873
887
  export interface $ZodSuccess<T extends SomeType = $ZodType> extends $ZodType {
874
888
  _zod: $ZodSuccessInternals<T>;
@@ -35,8 +35,8 @@ export const $ZodType = /*@__PURE__*/ core.$constructor("$ZodType", (inst, def)
35
35
  let isAborted = util.aborted(payload);
36
36
  let asyncResult;
37
37
  for (const ch of checks) {
38
- if (ch._zod.when) {
39
- const shouldRun = ch._zod.when(payload);
38
+ if (ch._zod.def.when) {
39
+ const shouldRun = ch._zod.def.when(payload);
40
40
  if (!shouldRun)
41
41
  continue;
42
42
  }
@@ -151,9 +151,10 @@ class JSONSchemaGenerator {
151
151
  case "unknown": {
152
152
  break;
153
153
  }
154
- case "undefined":
155
- case "never": {
156
- _json.not = {};
154
+ case "undefined": {
155
+ if (this.unrepresentable === "throw") {
156
+ throw new Error("Undefined cannot be represented in JSON Schema");
157
+ }
157
158
  break;
158
159
  }
159
160
  case "void": {
@@ -162,6 +163,10 @@ class JSONSchemaGenerator {
162
163
  }
163
164
  break;
164
165
  }
166
+ case "never": {
167
+ _json.not = {};
168
+ break;
169
+ }
165
170
  case "date": {
166
171
  if (this.unrepresentable === "throw") {
167
172
  throw new Error("Date cannot be represented in JSON Schema");
@@ -531,6 +536,8 @@ class JSONSchemaGenerator {
531
536
  throw new Error("Unprocessed schema. This is a bug in Zod.");
532
537
  // initialize result with root schema fields
533
538
  // Object.assign(result, seen.cached);
539
+ // returns a ref to the schema
540
+ // defId will be empty if the ref points to an external schema (or #)
534
541
  const makeURI = (entry) => {
535
542
  // comparing the seen objects because sometimes
536
543
  // multiple schemas map to the same seen object.
@@ -540,12 +547,14 @@ class JSONSchemaGenerator {
540
547
  if (params.external) {
541
548
  const externalId = params.external.registry.get(entry[0])?.id; // ?? "__shared";// `__schema${this.counter++}`;
542
549
  // check if schema is in the external registry
543
- if (externalId)
544
- return { ref: params.external.uri(externalId) };
550
+ const uriGenerator = params.external.uri ?? ((id) => id);
551
+ if (externalId) {
552
+ return { ref: uriGenerator(externalId) };
553
+ }
545
554
  // otherwise, add to __shared
546
555
  const id = entry[1].defId ?? entry[1].schema.id ?? `schema${this.counter++}`;
547
- entry[1].defId = id;
548
- return { defId: id, ref: `${params.external.uri("__shared")}#/${defsSegment}/${id}` };
556
+ entry[1].defId = id; // set defId so it will be reused if needed
557
+ return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}` };
549
558
  }
550
559
  if (entry[1] === root) {
551
560
  return { ref: "#" };
@@ -559,6 +568,7 @@ class JSONSchemaGenerator {
559
568
  // stored cached version in `def` property
560
569
  // remove all properties, set $ref
561
570
  const extractToDef = (entry) => {
571
+ // if the schema is already a reference, do not extract it
562
572
  if (entry[1].schema.$ref) {
563
573
  return;
564
574
  }
@@ -575,14 +585,24 @@ class JSONSchemaGenerator {
575
585
  }
576
586
  schema.$ref = ref;
577
587
  };
588
+ // throw on cycles
589
+ // break cycles
590
+ if (params.cycles === "throw") {
591
+ for (const entry of this.seen.entries()) {
592
+ const seen = entry[1];
593
+ if (seen.cycle) {
594
+ throw new Error("Cycle detected: " +
595
+ `#/${seen.cycle?.join("/")}/<root>` +
596
+ '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.');
597
+ }
598
+ }
599
+ }
578
600
  // extract schemas into $defs
579
601
  for (const entry of this.seen.entries()) {
580
602
  const seen = entry[1];
581
603
  // convert root schema to # $ref
582
- // also prevents root schema from being extracted
583
604
  if (schema === entry[0]) {
584
- // do not copy to defs...this is the root schema
585
- extractToDef(entry);
605
+ extractToDef(entry); // this has special handling for the root schema
586
606
  continue;
587
607
  }
588
608
  // extract schemas that are in the external registry
@@ -601,14 +621,8 @@ class JSONSchemaGenerator {
601
621
  }
602
622
  // break cycles
603
623
  if (seen.cycle) {
604
- if (params.cycles === "throw") {
605
- throw new Error("Cycle detected: " +
606
- `#/${seen.cycle?.join("/")}/<root>` +
607
- '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.');
608
- }
609
- else if (params.cycles === "ref") {
610
- extractToDef(entry);
611
- }
624
+ // any
625
+ extractToDef(entry);
612
626
  continue;
613
627
  }
614
628
  // extract reused schemas
@@ -666,6 +680,12 @@ class JSONSchemaGenerator {
666
680
  else {
667
681
  console.warn(`Invalid target: ${this.target}`);
668
682
  }
683
+ if (params.external?.uri) {
684
+ const id = params.external.registry.get(schema)?.id;
685
+ if (!id)
686
+ throw new Error("Schema is missing an `id` property");
687
+ result.$id = params.external.uri(id);
688
+ }
669
689
  Object.assign(result, root.def);
670
690
  // build defs object
671
691
  const defs = params.external?.defs ?? {};
@@ -676,12 +696,16 @@ class JSONSchemaGenerator {
676
696
  }
677
697
  }
678
698
  // set definitions in result
679
- if (!params.external && Object.keys(defs).length > 0) {
680
- if (this.target === "draft-2020-12") {
681
- result.$defs = defs;
682
- }
683
- else {
684
- result.definitions = defs;
699
+ if (params.external) {
700
+ }
701
+ else {
702
+ if (Object.keys(defs).length > 0) {
703
+ if (this.target === "draft-2020-12") {
704
+ result.$defs = defs;
705
+ }
706
+ else {
707
+ result.definitions = defs;
708
+ }
685
709
  }
686
710
  }
687
711
  try {
@@ -707,7 +731,7 @@ function toJSONSchema(input, _params) {
707
731
  const schemas = {};
708
732
  const external = {
709
733
  registry: input,
710
- uri: _params?.uri || ((id) => id),
734
+ uri: _params?.uri,
711
735
  defs,
712
736
  };
713
737
  for (const entry of input._idmap.entries()) {
@@ -39,7 +39,7 @@ interface EmitParams {
39
39
  registry: $ZodRegistry<{
40
40
  id?: string | undefined;
41
41
  }>;
42
- uri: (id: string) => string;
42
+ uri?: ((id: string) => string) | undefined;
43
43
  defs: Record<string, JSONSchema.BaseSchema>;
44
44
  } | undefined;
45
45
  }
@@ -39,7 +39,7 @@ interface EmitParams {
39
39
  registry: $ZodRegistry<{
40
40
  id?: string | undefined;
41
41
  }>;
42
- uri: (id: string) => string;
42
+ uri?: ((id: string) => string) | undefined;
43
43
  defs: Record<string, JSONSchema.BaseSchema>;
44
44
  } | undefined;
45
45
  }
@@ -147,9 +147,10 @@ export class JSONSchemaGenerator {
147
147
  case "unknown": {
148
148
  break;
149
149
  }
150
- case "undefined":
151
- case "never": {
152
- _json.not = {};
150
+ case "undefined": {
151
+ if (this.unrepresentable === "throw") {
152
+ throw new Error("Undefined cannot be represented in JSON Schema");
153
+ }
153
154
  break;
154
155
  }
155
156
  case "void": {
@@ -158,6 +159,10 @@ export class JSONSchemaGenerator {
158
159
  }
159
160
  break;
160
161
  }
162
+ case "never": {
163
+ _json.not = {};
164
+ break;
165
+ }
161
166
  case "date": {
162
167
  if (this.unrepresentable === "throw") {
163
168
  throw new Error("Date cannot be represented in JSON Schema");
@@ -527,6 +532,8 @@ export class JSONSchemaGenerator {
527
532
  throw new Error("Unprocessed schema. This is a bug in Zod.");
528
533
  // initialize result with root schema fields
529
534
  // Object.assign(result, seen.cached);
535
+ // returns a ref to the schema
536
+ // defId will be empty if the ref points to an external schema (or #)
530
537
  const makeURI = (entry) => {
531
538
  // comparing the seen objects because sometimes
532
539
  // multiple schemas map to the same seen object.
@@ -536,12 +543,14 @@ export class JSONSchemaGenerator {
536
543
  if (params.external) {
537
544
  const externalId = params.external.registry.get(entry[0])?.id; // ?? "__shared";// `__schema${this.counter++}`;
538
545
  // check if schema is in the external registry
539
- if (externalId)
540
- return { ref: params.external.uri(externalId) };
546
+ const uriGenerator = params.external.uri ?? ((id) => id);
547
+ if (externalId) {
548
+ return { ref: uriGenerator(externalId) };
549
+ }
541
550
  // otherwise, add to __shared
542
551
  const id = entry[1].defId ?? entry[1].schema.id ?? `schema${this.counter++}`;
543
- entry[1].defId = id;
544
- return { defId: id, ref: `${params.external.uri("__shared")}#/${defsSegment}/${id}` };
552
+ entry[1].defId = id; // set defId so it will be reused if needed
553
+ return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}` };
545
554
  }
546
555
  if (entry[1] === root) {
547
556
  return { ref: "#" };
@@ -555,6 +564,7 @@ export class JSONSchemaGenerator {
555
564
  // stored cached version in `def` property
556
565
  // remove all properties, set $ref
557
566
  const extractToDef = (entry) => {
567
+ // if the schema is already a reference, do not extract it
558
568
  if (entry[1].schema.$ref) {
559
569
  return;
560
570
  }
@@ -571,14 +581,24 @@ export class JSONSchemaGenerator {
571
581
  }
572
582
  schema.$ref = ref;
573
583
  };
584
+ // throw on cycles
585
+ // break cycles
586
+ if (params.cycles === "throw") {
587
+ for (const entry of this.seen.entries()) {
588
+ const seen = entry[1];
589
+ if (seen.cycle) {
590
+ throw new Error("Cycle detected: " +
591
+ `#/${seen.cycle?.join("/")}/<root>` +
592
+ '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.');
593
+ }
594
+ }
595
+ }
574
596
  // extract schemas into $defs
575
597
  for (const entry of this.seen.entries()) {
576
598
  const seen = entry[1];
577
599
  // convert root schema to # $ref
578
- // also prevents root schema from being extracted
579
600
  if (schema === entry[0]) {
580
- // do not copy to defs...this is the root schema
581
- extractToDef(entry);
601
+ extractToDef(entry); // this has special handling for the root schema
582
602
  continue;
583
603
  }
584
604
  // extract schemas that are in the external registry
@@ -597,14 +617,8 @@ export class JSONSchemaGenerator {
597
617
  }
598
618
  // break cycles
599
619
  if (seen.cycle) {
600
- if (params.cycles === "throw") {
601
- throw new Error("Cycle detected: " +
602
- `#/${seen.cycle?.join("/")}/<root>` +
603
- '\n\nSet the `cycles` parameter to `"ref"` to resolve cyclical schemas with defs.');
604
- }
605
- else if (params.cycles === "ref") {
606
- extractToDef(entry);
607
- }
620
+ // any
621
+ extractToDef(entry);
608
622
  continue;
609
623
  }
610
624
  // extract reused schemas
@@ -662,6 +676,12 @@ export class JSONSchemaGenerator {
662
676
  else {
663
677
  console.warn(`Invalid target: ${this.target}`);
664
678
  }
679
+ if (params.external?.uri) {
680
+ const id = params.external.registry.get(schema)?.id;
681
+ if (!id)
682
+ throw new Error("Schema is missing an `id` property");
683
+ result.$id = params.external.uri(id);
684
+ }
665
685
  Object.assign(result, root.def);
666
686
  // build defs object
667
687
  const defs = params.external?.defs ?? {};
@@ -672,12 +692,16 @@ export class JSONSchemaGenerator {
672
692
  }
673
693
  }
674
694
  // set definitions in result
675
- if (!params.external && Object.keys(defs).length > 0) {
676
- if (this.target === "draft-2020-12") {
677
- result.$defs = defs;
678
- }
679
- else {
680
- result.definitions = defs;
695
+ if (params.external) {
696
+ }
697
+ else {
698
+ if (Object.keys(defs).length > 0) {
699
+ if (this.target === "draft-2020-12") {
700
+ result.$defs = defs;
701
+ }
702
+ else {
703
+ result.definitions = defs;
704
+ }
681
705
  }
682
706
  }
683
707
  try {
@@ -702,7 +726,7 @@ export function toJSONSchema(input, _params) {
702
726
  const schemas = {};
703
727
  const external = {
704
728
  registry: input,
705
- uri: _params?.uri || ((id) => id),
729
+ uri: _params?.uri,
706
730
  defs,
707
731
  };
708
732
  for (const entry of input._idmap.entries()) {