@orpc/openapi 0.0.0-next-20241126131150 → 0.0.0-next.18dacf3

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/dist/index.js CHANGED
@@ -1,6 +1,10 @@
1
+ import {
2
+ eachContractProcedureLeaf
3
+ } from "./chunk-KZIT2WCV.js";
4
+
1
5
  // src/generator.ts
2
- import { eachContractRouterLeaf } from "@orpc/contract";
3
- import { toContractRouter } from "@orpc/server";
6
+ import { isContractProcedure } from "@orpc/contract";
7
+ import { LAZY_LOADER_SYMBOL } from "@orpc/server";
4
8
  import { findDeepMatches, isPlainObject, omit } from "@orpc/shared";
5
9
  import { preSerialize } from "@orpc/transformer";
6
10
  import {
@@ -18,7 +22,7 @@ import {
18
22
  Format
19
23
  } from "json-schema-typed/draft-2020-12";
20
24
 
21
- // ../../node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.mjs
25
+ // ../../node_modules/.pnpm/zod@3.24.1/node_modules/zod/lib/index.mjs
22
26
  var util;
23
27
  (function(util2) {
24
28
  util2.assertEqual = (val) => val;
@@ -169,6 +173,9 @@ var ZodIssueCode = util.arrayToEnum([
169
173
  "not_finite"
170
174
  ]);
171
175
  var ZodError = class _ZodError extends Error {
176
+ get errors() {
177
+ return this.issues;
178
+ }
172
179
  constructor(issues) {
173
180
  super();
174
181
  this.issues = [];
@@ -187,9 +194,6 @@ var ZodError = class _ZodError extends Error {
187
194
  this.name = "ZodError";
188
195
  this.issues = issues;
189
196
  }
190
- get errors() {
191
- return this.issues;
192
- }
193
197
  format(_mapper) {
194
198
  const mapper = _mapper || function(issue) {
195
199
  return issue.message;
@@ -396,8 +400,11 @@ function addIssueToContext(ctx, issueData) {
396
400
  path: ctx.path,
397
401
  errorMaps: [
398
402
  ctx.common.contextualErrorMap,
403
+ // contextual error map is first priority
399
404
  ctx.schemaErrorMap,
405
+ // then schema-bound map if available
400
406
  overrideMap,
407
+ // then global override map
401
408
  overrideMap === errorMap ? void 0 : errorMap
402
409
  // then global default map
403
410
  ].filter((x) => !!x)
@@ -548,34 +555,6 @@ function processCreateParams(params) {
548
555
  return { errorMap: customMap, description };
549
556
  }
550
557
  var ZodType = class {
551
- constructor(def) {
552
- this.spa = this.safeParseAsync;
553
- this._def = def;
554
- this.parse = this.parse.bind(this);
555
- this.safeParse = this.safeParse.bind(this);
556
- this.parseAsync = this.parseAsync.bind(this);
557
- this.safeParseAsync = this.safeParseAsync.bind(this);
558
- this.spa = this.spa.bind(this);
559
- this.refine = this.refine.bind(this);
560
- this.refinement = this.refinement.bind(this);
561
- this.superRefine = this.superRefine.bind(this);
562
- this.optional = this.optional.bind(this);
563
- this.nullable = this.nullable.bind(this);
564
- this.nullish = this.nullish.bind(this);
565
- this.array = this.array.bind(this);
566
- this.promise = this.promise.bind(this);
567
- this.or = this.or.bind(this);
568
- this.and = this.and.bind(this);
569
- this.transform = this.transform.bind(this);
570
- this.brand = this.brand.bind(this);
571
- this.default = this.default.bind(this);
572
- this.catch = this.catch.bind(this);
573
- this.describe = this.describe.bind(this);
574
- this.pipe = this.pipe.bind(this);
575
- this.readonly = this.readonly.bind(this);
576
- this.isNullable = this.isNullable.bind(this);
577
- this.isOptional = this.isOptional.bind(this);
578
- }
579
558
  get description() {
580
559
  return this._def.description;
581
560
  }
@@ -639,6 +618,43 @@ var ZodType = class {
639
618
  const result = this._parseSync({ data, path: ctx.path, parent: ctx });
640
619
  return handleResult(ctx, result);
641
620
  }
621
+ "~validate"(data) {
622
+ var _a, _b;
623
+ const ctx = {
624
+ common: {
625
+ issues: [],
626
+ async: !!this["~standard"].async
627
+ },
628
+ path: [],
629
+ schemaErrorMap: this._def.errorMap,
630
+ parent: null,
631
+ data,
632
+ parsedType: getParsedType(data)
633
+ };
634
+ if (!this["~standard"].async) {
635
+ try {
636
+ const result = this._parseSync({ data, path: [], parent: ctx });
637
+ return isValid(result) ? {
638
+ value: result.value
639
+ } : {
640
+ issues: ctx.common.issues
641
+ };
642
+ } catch (err) {
643
+ if ((_b = (_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === null || _b === void 0 ? void 0 : _b.includes("encountered")) {
644
+ this["~standard"].async = true;
645
+ }
646
+ ctx.common = {
647
+ issues: [],
648
+ async: true
649
+ };
650
+ }
651
+ }
652
+ return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result) ? {
653
+ value: result.value
654
+ } : {
655
+ issues: ctx.common.issues
656
+ });
657
+ }
642
658
  async parseAsync(data, params) {
643
659
  const result = await this.safeParseAsync(data, params);
644
660
  if (result.success)
@@ -716,6 +732,39 @@ var ZodType = class {
716
732
  superRefine(refinement) {
717
733
  return this._refinement(refinement);
718
734
  }
735
+ constructor(def) {
736
+ this.spa = this.safeParseAsync;
737
+ this._def = def;
738
+ this.parse = this.parse.bind(this);
739
+ this.safeParse = this.safeParse.bind(this);
740
+ this.parseAsync = this.parseAsync.bind(this);
741
+ this.safeParseAsync = this.safeParseAsync.bind(this);
742
+ this.spa = this.spa.bind(this);
743
+ this.refine = this.refine.bind(this);
744
+ this.refinement = this.refinement.bind(this);
745
+ this.superRefine = this.superRefine.bind(this);
746
+ this.optional = this.optional.bind(this);
747
+ this.nullable = this.nullable.bind(this);
748
+ this.nullish = this.nullish.bind(this);
749
+ this.array = this.array.bind(this);
750
+ this.promise = this.promise.bind(this);
751
+ this.or = this.or.bind(this);
752
+ this.and = this.and.bind(this);
753
+ this.transform = this.transform.bind(this);
754
+ this.brand = this.brand.bind(this);
755
+ this.default = this.default.bind(this);
756
+ this.catch = this.catch.bind(this);
757
+ this.describe = this.describe.bind(this);
758
+ this.pipe = this.pipe.bind(this);
759
+ this.readonly = this.readonly.bind(this);
760
+ this.isNullable = this.isNullable.bind(this);
761
+ this.isOptional = this.isOptional.bind(this);
762
+ this["~standard"] = {
763
+ version: 1,
764
+ vendor: "zod",
765
+ validate: (data) => this["~validate"](data)
766
+ };
767
+ }
719
768
  optional() {
720
769
  return ZodOptional.create(this, this._def);
721
770
  }
@@ -726,7 +775,7 @@ var ZodType = class {
726
775
  return this.nullable().optional();
727
776
  }
728
777
  array() {
729
- return ZodArray.create(this, this._def);
778
+ return ZodArray.create(this);
730
779
  }
731
780
  promise() {
732
781
  return ZodPromise.create(this, this._def);
@@ -792,16 +841,20 @@ var ZodType = class {
792
841
  };
793
842
  var cuidRegex = /^c[^\s-]{8,}$/i;
794
843
  var cuid2Regex = /^[0-9a-z]+$/;
795
- var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/;
844
+ var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
796
845
  var uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
797
846
  var nanoidRegex = /^[a-z0-9_-]{21}$/i;
847
+ var jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
798
848
  var durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
799
849
  var emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
800
850
  var _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
801
851
  var emojiRegex;
802
852
  var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
803
- var ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;
853
+ var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
854
+ var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
855
+ var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
804
856
  var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
857
+ var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
805
858
  var dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
806
859
  var dateRegex = new RegExp(`^${dateRegexSource}$`);
807
860
  function timeRegexSource(args) {
@@ -834,6 +887,33 @@ function isValidIP(ip, version) {
834
887
  }
835
888
  return false;
836
889
  }
890
+ function isValidJWT(jwt, alg) {
891
+ if (!jwtRegex.test(jwt))
892
+ return false;
893
+ try {
894
+ const [header] = jwt.split(".");
895
+ const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
896
+ const decoded = JSON.parse(atob(base64));
897
+ if (typeof decoded !== "object" || decoded === null)
898
+ return false;
899
+ if (!decoded.typ || !decoded.alg)
900
+ return false;
901
+ if (alg && decoded.alg !== alg)
902
+ return false;
903
+ return true;
904
+ } catch (_a) {
905
+ return false;
906
+ }
907
+ }
908
+ function isValidCidr(ip, version) {
909
+ if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {
910
+ return true;
911
+ }
912
+ if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {
913
+ return true;
914
+ }
915
+ return false;
916
+ }
837
917
  var ZodString = class _ZodString extends ZodType {
838
918
  _parse(input) {
839
919
  if (this._def.coerce) {
@@ -1090,6 +1170,26 @@ var ZodString = class _ZodString extends ZodType {
1090
1170
  });
1091
1171
  status.dirty();
1092
1172
  }
1173
+ } else if (check.kind === "jwt") {
1174
+ if (!isValidJWT(input.data, check.alg)) {
1175
+ ctx = this._getOrReturnCtx(input, ctx);
1176
+ addIssueToContext(ctx, {
1177
+ validation: "jwt",
1178
+ code: ZodIssueCode.invalid_string,
1179
+ message: check.message
1180
+ });
1181
+ status.dirty();
1182
+ }
1183
+ } else if (check.kind === "cidr") {
1184
+ if (!isValidCidr(input.data, check.version)) {
1185
+ ctx = this._getOrReturnCtx(input, ctx);
1186
+ addIssueToContext(ctx, {
1187
+ validation: "cidr",
1188
+ code: ZodIssueCode.invalid_string,
1189
+ message: check.message
1190
+ });
1191
+ status.dirty();
1192
+ }
1093
1193
  } else if (check.kind === "base64") {
1094
1194
  if (!base64Regex.test(input.data)) {
1095
1195
  ctx = this._getOrReturnCtx(input, ctx);
@@ -1100,6 +1200,16 @@ var ZodString = class _ZodString extends ZodType {
1100
1200
  });
1101
1201
  status.dirty();
1102
1202
  }
1203
+ } else if (check.kind === "base64url") {
1204
+ if (!base64urlRegex.test(input.data)) {
1205
+ ctx = this._getOrReturnCtx(input, ctx);
1206
+ addIssueToContext(ctx, {
1207
+ validation: "base64url",
1208
+ code: ZodIssueCode.invalid_string,
1209
+ message: check.message
1210
+ });
1211
+ status.dirty();
1212
+ }
1103
1213
  } else {
1104
1214
  util.assertNever(check);
1105
1215
  }
@@ -1146,9 +1256,21 @@ var ZodString = class _ZodString extends ZodType {
1146
1256
  base64(message) {
1147
1257
  return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });
1148
1258
  }
1259
+ base64url(message) {
1260
+ return this._addCheck({
1261
+ kind: "base64url",
1262
+ ...errorUtil.errToObj(message)
1263
+ });
1264
+ }
1265
+ jwt(options) {
1266
+ return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) });
1267
+ }
1149
1268
  ip(options) {
1150
1269
  return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
1151
1270
  }
1271
+ cidr(options) {
1272
+ return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });
1273
+ }
1152
1274
  datetime(options) {
1153
1275
  var _a, _b;
1154
1276
  if (typeof options === "string") {
@@ -1239,8 +1361,7 @@ var ZodString = class _ZodString extends ZodType {
1239
1361
  });
1240
1362
  }
1241
1363
  /**
1242
- * @deprecated Use z.string().min(1) instead.
1243
- * @see {@link ZodString.min}
1364
+ * Equivalent to `.min(1)`
1244
1365
  */
1245
1366
  nonempty(message) {
1246
1367
  return this.min(1, errorUtil.errToObj(message));
@@ -1302,9 +1423,15 @@ var ZodString = class _ZodString extends ZodType {
1302
1423
  get isIP() {
1303
1424
  return !!this._def.checks.find((ch) => ch.kind === "ip");
1304
1425
  }
1426
+ get isCIDR() {
1427
+ return !!this._def.checks.find((ch) => ch.kind === "cidr");
1428
+ }
1305
1429
  get isBase64() {
1306
1430
  return !!this._def.checks.find((ch) => ch.kind === "base64");
1307
1431
  }
1432
+ get isBase64url() {
1433
+ return !!this._def.checks.find((ch) => ch.kind === "base64url");
1434
+ }
1308
1435
  get minLength() {
1309
1436
  let min = null;
1310
1437
  for (const ch of this._def.checks) {
@@ -1582,17 +1709,15 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
1582
1709
  }
1583
1710
  _parse(input) {
1584
1711
  if (this._def.coerce) {
1585
- input.data = BigInt(input.data);
1712
+ try {
1713
+ input.data = BigInt(input.data);
1714
+ } catch (_a) {
1715
+ return this._getInvalidInput(input);
1716
+ }
1586
1717
  }
1587
1718
  const parsedType = this._getType(input);
1588
1719
  if (parsedType !== ZodParsedType.bigint) {
1589
- const ctx2 = this._getOrReturnCtx(input);
1590
- addIssueToContext(ctx2, {
1591
- code: ZodIssueCode.invalid_type,
1592
- expected: ZodParsedType.bigint,
1593
- received: ctx2.parsedType
1594
- });
1595
- return INVALID;
1720
+ return this._getInvalidInput(input);
1596
1721
  }
1597
1722
  let ctx = void 0;
1598
1723
  const status = new ParseStatus();
@@ -1639,6 +1764,15 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
1639
1764
  }
1640
1765
  return { status: status.value, value: input.data };
1641
1766
  }
1767
+ _getInvalidInput(input) {
1768
+ const ctx = this._getOrReturnCtx(input);
1769
+ addIssueToContext(ctx, {
1770
+ code: ZodIssueCode.invalid_type,
1771
+ expected: ZodParsedType.bigint,
1772
+ received: ctx.parsedType
1773
+ });
1774
+ return INVALID;
1775
+ }
1642
1776
  gte(value, message) {
1643
1777
  return this.setLimit("min", value, true, errorUtil.toString(message));
1644
1778
  }
@@ -3809,10 +3943,15 @@ var NON_LOGIC_KEYWORDS = [
3809
3943
  var UNSUPPORTED_JSON_SCHEMA = { not: {} };
3810
3944
  var UNDEFINED_JSON_SCHEMA = { const: "undefined" };
3811
3945
  function zodToJsonSchema(schema, options) {
3946
+ if (schema["~standard"].vendor !== "zod") {
3947
+ console.warn(`Generate JSON schema not support ${schema["~standard"].vendor} yet`);
3948
+ return {};
3949
+ }
3950
+ const schema__ = schema;
3812
3951
  if (!options?.isHandledCustomJSONSchema) {
3813
- const customJSONSchema = getCustomJSONSchema(schema._def, options);
3952
+ const customJSONSchema = getCustomJSONSchema(schema__._def, options);
3814
3953
  if (customJSONSchema) {
3815
- const json = zodToJsonSchema(schema, {
3954
+ const json = zodToJsonSchema(schema__, {
3816
3955
  ...options,
3817
3956
  isHandledCustomJSONSchema: true
3818
3957
  });
@@ -3823,13 +3962,13 @@ function zodToJsonSchema(schema, options) {
3823
3962
  }
3824
3963
  }
3825
3964
  const childOptions = { ...options, isHandledCustomJSONSchema: false };
3826
- const customType = getCustomZodType(schema._def);
3965
+ const customType = getCustomZodType(schema__._def);
3827
3966
  switch (customType) {
3828
3967
  case "Blob": {
3829
3968
  return { type: "string", contentMediaType: "*/*" };
3830
3969
  }
3831
3970
  case "File": {
3832
- const mimeType = getCustomZodFileMimeType(schema._def) ?? "*/*";
3971
+ const mimeType = getCustomZodFileMimeType(schema__._def) ?? "*/*";
3833
3972
  return { type: "string", contentMediaType: mimeType };
3834
3973
  }
3835
3974
  case "Invalid Date": {
@@ -3846,10 +3985,10 @@ function zodToJsonSchema(schema, options) {
3846
3985
  }
3847
3986
  }
3848
3987
  const _expectedCustomType = customType;
3849
- const typeName = schema._def.typeName;
3988
+ const typeName = schema__._def.typeName;
3850
3989
  switch (typeName) {
3851
3990
  case ZodFirstPartyTypeKind.ZodString: {
3852
- const schema_ = schema;
3991
+ const schema_ = schema__;
3853
3992
  const json = { type: "string" };
3854
3993
  for (const check of schema_._def.checks) {
3855
3994
  switch (check.kind) {
@@ -3917,6 +4056,12 @@ function zodToJsonSchema(schema, options) {
3917
4056
  case "ip":
3918
4057
  json.format = Format.IPv4;
3919
4058
  break;
4059
+ case "jwt":
4060
+ json.pattern = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$";
4061
+ break;
4062
+ case "base64url":
4063
+ json.pattern = "^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$";
4064
+ break;
3920
4065
  default: {
3921
4066
  const _expect = check.kind;
3922
4067
  }
@@ -3925,7 +4070,7 @@ function zodToJsonSchema(schema, options) {
3925
4070
  return json;
3926
4071
  }
3927
4072
  case ZodFirstPartyTypeKind.ZodNumber: {
3928
- const schema_ = schema;
4073
+ const schema_ = schema__;
3929
4074
  const json = { type: "number" };
3930
4075
  for (const check of schema_._def.checks) {
3931
4076
  switch (check.kind) {
@@ -3970,23 +4115,23 @@ function zodToJsonSchema(schema, options) {
3970
4115
  return UNDEFINED_JSON_SCHEMA;
3971
4116
  }
3972
4117
  case ZodFirstPartyTypeKind.ZodLiteral: {
3973
- const schema_ = schema;
4118
+ const schema_ = schema__;
3974
4119
  return { const: schema_._def.value };
3975
4120
  }
3976
4121
  case ZodFirstPartyTypeKind.ZodEnum: {
3977
- const schema_ = schema;
4122
+ const schema_ = schema__;
3978
4123
  return {
3979
4124
  enum: schema_._def.values
3980
4125
  };
3981
4126
  }
3982
4127
  case ZodFirstPartyTypeKind.ZodNativeEnum: {
3983
- const schema_ = schema;
4128
+ const schema_ = schema__;
3984
4129
  return {
3985
4130
  enum: Object.values(schema_._def.values)
3986
4131
  };
3987
4132
  }
3988
4133
  case ZodFirstPartyTypeKind.ZodArray: {
3989
- const schema_ = schema;
4134
+ const schema_ = schema__;
3990
4135
  const def = schema_._def;
3991
4136
  const json = { type: "array" };
3992
4137
  if (def.exactLength) {
@@ -4002,7 +4147,7 @@ function zodToJsonSchema(schema, options) {
4002
4147
  return json;
4003
4148
  }
4004
4149
  case ZodFirstPartyTypeKind.ZodTuple: {
4005
- const schema_ = schema;
4150
+ const schema_ = schema__;
4006
4151
  const prefixItems = [];
4007
4152
  const json = { type: "array" };
4008
4153
  for (const item of schema_._def.items) {
@@ -4020,7 +4165,7 @@ function zodToJsonSchema(schema, options) {
4020
4165
  return json;
4021
4166
  }
4022
4167
  case ZodFirstPartyTypeKind.ZodObject: {
4023
- const schema_ = schema;
4168
+ const schema_ = schema__;
4024
4169
  const json = { type: "object" };
4025
4170
  const properties = {};
4026
4171
  const required = [];
@@ -4056,7 +4201,7 @@ function zodToJsonSchema(schema, options) {
4056
4201
  return json;
4057
4202
  }
4058
4203
  case ZodFirstPartyTypeKind.ZodRecord: {
4059
- const schema_ = schema;
4204
+ const schema_ = schema__;
4060
4205
  const json = { type: "object" };
4061
4206
  json.additionalProperties = zodToJsonSchema(
4062
4207
  schema_._def.valueType,
@@ -4065,14 +4210,14 @@ function zodToJsonSchema(schema, options) {
4065
4210
  return json;
4066
4211
  }
4067
4212
  case ZodFirstPartyTypeKind.ZodSet: {
4068
- const schema_ = schema;
4213
+ const schema_ = schema__;
4069
4214
  return {
4070
4215
  type: "array",
4071
4216
  items: zodToJsonSchema(schema_._def.valueType, childOptions)
4072
4217
  };
4073
4218
  }
4074
4219
  case ZodFirstPartyTypeKind.ZodMap: {
4075
- const schema_ = schema;
4220
+ const schema_ = schema__;
4076
4221
  return {
4077
4222
  type: "array",
4078
4223
  items: {
@@ -4088,7 +4233,7 @@ function zodToJsonSchema(schema, options) {
4088
4233
  }
4089
4234
  case ZodFirstPartyTypeKind.ZodUnion:
4090
4235
  case ZodFirstPartyTypeKind.ZodDiscriminatedUnion: {
4091
- const schema_ = schema;
4236
+ const schema_ = schema__;
4092
4237
  const anyOf = [];
4093
4238
  for (const s of schema_._def.options) {
4094
4239
  anyOf.push(zodToJsonSchema(s, childOptions));
@@ -4096,7 +4241,7 @@ function zodToJsonSchema(schema, options) {
4096
4241
  return { anyOf };
4097
4242
  }
4098
4243
  case ZodFirstPartyTypeKind.ZodIntersection: {
4099
- const schema_ = schema;
4244
+ const schema_ = schema__;
4100
4245
  const allOf = [];
4101
4246
  for (const s of [schema_._def.left, schema_._def.right]) {
4102
4247
  allOf.push(zodToJsonSchema(s, childOptions));
@@ -4104,7 +4249,7 @@ function zodToJsonSchema(schema, options) {
4104
4249
  return { allOf };
4105
4250
  }
4106
4251
  case ZodFirstPartyTypeKind.ZodLazy: {
4107
- const schema_ = schema;
4252
+ const schema_ = schema__;
4108
4253
  const maxLazyDepth = childOptions?.maxLazyDepth ?? 5;
4109
4254
  const lazyDepth = childOptions?.lazyDepth ?? 0;
4110
4255
  if (lazyDepth > maxLazyDepth) {
@@ -4121,44 +4266,44 @@ function zodToJsonSchema(schema, options) {
4121
4266
  return {};
4122
4267
  }
4123
4268
  case ZodFirstPartyTypeKind.ZodOptional: {
4124
- const schema_ = schema;
4269
+ const schema_ = schema__;
4125
4270
  const inner = zodToJsonSchema(schema_._def.innerType, childOptions);
4126
4271
  return {
4127
4272
  anyOf: [UNDEFINED_JSON_SCHEMA, inner]
4128
4273
  };
4129
4274
  }
4130
4275
  case ZodFirstPartyTypeKind.ZodReadonly: {
4131
- const schema_ = schema;
4276
+ const schema_ = schema__;
4132
4277
  return zodToJsonSchema(schema_._def.innerType, childOptions);
4133
4278
  }
4134
4279
  case ZodFirstPartyTypeKind.ZodDefault: {
4135
- const schema_ = schema;
4280
+ const schema_ = schema__;
4136
4281
  return zodToJsonSchema(schema_._def.innerType, childOptions);
4137
4282
  }
4138
4283
  case ZodFirstPartyTypeKind.ZodEffects: {
4139
- const schema_ = schema;
4284
+ const schema_ = schema__;
4140
4285
  if (schema_._def.effect.type === "transform" && childOptions?.mode === "output") {
4141
4286
  return {};
4142
4287
  }
4143
4288
  return zodToJsonSchema(schema_._def.schema, childOptions);
4144
4289
  }
4145
4290
  case ZodFirstPartyTypeKind.ZodCatch: {
4146
- const schema_ = schema;
4291
+ const schema_ = schema__;
4147
4292
  return zodToJsonSchema(schema_._def.innerType, childOptions);
4148
4293
  }
4149
4294
  case ZodFirstPartyTypeKind.ZodBranded: {
4150
- const schema_ = schema;
4295
+ const schema_ = schema__;
4151
4296
  return zodToJsonSchema(schema_._def.type, childOptions);
4152
4297
  }
4153
4298
  case ZodFirstPartyTypeKind.ZodPipeline: {
4154
- const schema_ = schema;
4299
+ const schema_ = schema__;
4155
4300
  return zodToJsonSchema(
4156
4301
  childOptions?.mode === "output" ? schema_._def.out : schema_._def.in,
4157
4302
  childOptions
4158
4303
  );
4159
4304
  }
4160
4305
  case ZodFirstPartyTypeKind.ZodNullable: {
4161
- const schema_ = schema;
4306
+ const schema_ = schema__;
4162
4307
  const inner = zodToJsonSchema(schema_._def.innerType, childOptions);
4163
4308
  return {
4164
4309
  anyOf: [{ type: "null" }, inner]
@@ -4210,7 +4355,7 @@ function extractJSONSchema(schema, check, matches = []) {
4210
4355
  }
4211
4356
 
4212
4357
  // src/generator.ts
4213
- function generateOpenAPI(opts, options) {
4358
+ async function generateOpenAPI(opts, options) {
4214
4359
  const throwOnMissingTagDefinition = options?.throwOnMissingTagDefinition ?? false;
4215
4360
  const ignoreUndefinedPathProcedures = options?.ignoreUndefinedPathProcedures ?? false;
4216
4361
  const builder = new OpenApiBuilder({
@@ -4218,197 +4363,214 @@ function generateOpenAPI(opts, options) {
4218
4363
  openapi: "3.1.0"
4219
4364
  });
4220
4365
  const rootTags = opts.tags?.map((tag) => tag.name) ?? [];
4221
- const router = toContractRouter(opts.router);
4222
- eachContractRouterLeaf(router, (procedure, path_) => {
4223
- const internal = procedure.zz$cp;
4224
- if (ignoreUndefinedPathProcedures && internal.path === void 0) {
4225
- return;
4226
- }
4227
- const path = internal.path ?? `/${path_.map(encodeURIComponent).join("/")}`;
4228
- const method = internal.method ?? "POST";
4229
- let inputSchema = internal.InputSchema ? zodToJsonSchema(internal.InputSchema, { mode: "input" }) : {};
4230
- const outputSchema = internal.OutputSchema ? zodToJsonSchema(internal.OutputSchema, { mode: "output" }) : {};
4231
- const params = (() => {
4232
- const names = path.match(/\{([^}]+)\}/g);
4233
- if (!names || !names.length) {
4234
- return void 0;
4366
+ const pending = [{
4367
+ path: [],
4368
+ router: opts.router
4369
+ }];
4370
+ for (const item of pending) {
4371
+ const lazies = eachContractProcedureLeaf(item, ({ contract, path }) => {
4372
+ if (!isContractProcedure(contract)) {
4373
+ return;
4235
4374
  }
4236
- if (typeof inputSchema !== "object" || inputSchema.type !== "object") {
4237
- throw new Error(
4238
- `When path has parameters, input schema must be an object [${path_.join(".")}]`
4239
- );
4375
+ const internal = contract.zz$cp;
4376
+ if (ignoreUndefinedPathProcedures && internal.path === void 0) {
4377
+ return;
4240
4378
  }
4241
- return names.map((raw) => raw.slice(1, -1)).map((name) => {
4242
- let schema = inputSchema.properties?.[name];
4243
- const required = inputSchema.required?.includes(name);
4244
- if (schema === void 0) {
4245
- throw new Error(
4246
- `Parameter ${name} is missing in input schema [${path_.join(".")}]`
4247
- );
4379
+ const httpPath = internal.path ?? `/${path.map(encodeURIComponent).join("/")}`;
4380
+ const method = internal.method ?? "POST";
4381
+ let inputSchema = internal.InputSchema ? zodToJsonSchema(internal.InputSchema, { mode: "input" }) : {};
4382
+ const outputSchema = internal.OutputSchema ? zodToJsonSchema(internal.OutputSchema, { mode: "output" }) : {};
4383
+ const params = (() => {
4384
+ const names = httpPath.match(/\{([^}]+)\}/g);
4385
+ if (!names || !names.length) {
4386
+ return void 0;
4248
4387
  }
4249
- if (!required) {
4388
+ if (typeof inputSchema !== "object" || inputSchema.type !== "object") {
4250
4389
  throw new Error(
4251
- `Parameter ${name} must be required in input schema [${path_.join(".")}]`
4390
+ `When path has parameters, input schema must be an object [${path.join(".")}]`
4252
4391
  );
4253
4392
  }
4254
- const examples = inputSchema.examples?.filter((example) => {
4255
- return isPlainObject(example) && name in example;
4256
- }).map((example) => {
4257
- return example[name];
4258
- });
4259
- schema = {
4260
- examples: examples?.length ? examples : void 0,
4261
- ...schema === true ? {} : schema === false ? UNSUPPORTED_JSON_SCHEMA : schema
4262
- };
4263
- inputSchema = {
4264
- ...inputSchema,
4265
- properties: inputSchema.properties ? Object.entries(inputSchema.properties).reduce(
4266
- (acc, [key, value]) => {
4267
- if (key !== name) {
4268
- acc[key] = value;
4269
- }
4270
- return acc;
4271
- },
4272
- {}
4273
- ) : void 0,
4274
- required: inputSchema.required?.filter((v) => v !== name),
4275
- examples: inputSchema.examples?.map((example) => {
4276
- if (!isPlainObject(example))
4277
- return example;
4278
- return Object.entries(example).reduce(
4279
- (acc, [key, value]) => {
4280
- if (key !== name) {
4281
- acc[key] = value;
4282
- }
4283
- return acc;
4284
- },
4285
- {}
4393
+ return names.map((raw) => raw.slice(1, -1)).map((name) => {
4394
+ let schema = inputSchema.properties?.[name];
4395
+ const required = inputSchema.required?.includes(name);
4396
+ if (schema === void 0) {
4397
+ throw new Error(
4398
+ `Parameter ${name} is missing in input schema [${path.join(".")}]`
4286
4399
  );
4287
- })
4288
- };
4289
- return {
4290
- name,
4291
- in: "path",
4292
- required: true,
4293
- schema,
4294
- example: internal.inputExample?.[name]
4295
- };
4296
- });
4297
- })();
4298
- const query = (() => {
4299
- if (method !== "GET" || Object.keys(inputSchema).length === 0) {
4300
- return void 0;
4301
- }
4302
- if (typeof inputSchema !== "object" || inputSchema.type !== "object") {
4303
- throw new Error(
4304
- `When method is GET, input schema must be an object [${path_.join(".")}]`
4305
- );
4306
- }
4307
- return Object.entries(inputSchema.properties ?? {}).map(
4308
- ([name, schema]) => {
4400
+ }
4401
+ if (!required) {
4402
+ throw new Error(
4403
+ `Parameter ${name} must be required in input schema [${path.join(".")}]`
4404
+ );
4405
+ }
4309
4406
  const examples = inputSchema.examples?.filter((example) => {
4310
4407
  return isPlainObject(example) && name in example;
4311
4408
  }).map((example) => {
4312
4409
  return example[name];
4313
4410
  });
4314
- const schema_ = {
4411
+ schema = {
4315
4412
  examples: examples?.length ? examples : void 0,
4316
4413
  ...schema === true ? {} : schema === false ? UNSUPPORTED_JSON_SCHEMA : schema
4317
4414
  };
4415
+ inputSchema = {
4416
+ ...inputSchema,
4417
+ properties: inputSchema.properties ? Object.entries(inputSchema.properties).reduce(
4418
+ (acc, [key, value]) => {
4419
+ if (key !== name) {
4420
+ acc[key] = value;
4421
+ }
4422
+ return acc;
4423
+ },
4424
+ {}
4425
+ ) : void 0,
4426
+ required: inputSchema.required?.filter((v) => v !== name),
4427
+ examples: inputSchema.examples?.map((example) => {
4428
+ if (!isPlainObject(example))
4429
+ return example;
4430
+ return Object.entries(example).reduce(
4431
+ (acc, [key, value]) => {
4432
+ if (key !== name) {
4433
+ acc[key] = value;
4434
+ }
4435
+ return acc;
4436
+ },
4437
+ {}
4438
+ );
4439
+ })
4440
+ };
4318
4441
  return {
4319
4442
  name,
4320
- in: "query",
4321
- style: "deepObject",
4322
- required: inputSchema?.required?.includes(name) ?? false,
4323
- schema: schema_,
4443
+ in: "path",
4444
+ required: true,
4445
+ schema,
4324
4446
  example: internal.inputExample?.[name]
4325
4447
  };
4448
+ });
4449
+ })();
4450
+ const query = (() => {
4451
+ if (method !== "GET" || Object.keys(inputSchema).length === 0) {
4452
+ return void 0;
4326
4453
  }
4327
- );
4328
- })();
4329
- const parameters = [...params ?? [], ...query ?? []];
4330
- const requestBody = (() => {
4331
- if (method === "GET") {
4332
- return void 0;
4333
- }
4334
- const { schema, matches } = extractJSONSchema(inputSchema, isFileSchema);
4335
- const files = matches;
4336
- const isStillHasFileSchema = findDeepMatches(isFileSchema, schema).values.length > 0;
4337
- if (files.length) {
4338
- parameters.push({
4339
- name: "content-disposition",
4340
- in: "header",
4341
- required: schema === void 0,
4342
- schema: {
4343
- type: "string",
4344
- pattern: "filename",
4345
- example: 'filename="file.png"',
4346
- description: "To define the file name. Required when the request body is a file."
4454
+ if (typeof inputSchema !== "object" || inputSchema.type !== "object") {
4455
+ throw new Error(
4456
+ `When method is GET, input schema must be an object [${path.join(".")}]`
4457
+ );
4458
+ }
4459
+ return Object.entries(inputSchema.properties ?? {}).map(
4460
+ ([name, schema]) => {
4461
+ const examples = inputSchema.examples?.filter((example) => {
4462
+ return isPlainObject(example) && name in example;
4463
+ }).map((example) => {
4464
+ return example[name];
4465
+ });
4466
+ const schema_ = {
4467
+ examples: examples?.length ? examples : void 0,
4468
+ ...schema === true ? {} : schema === false ? UNSUPPORTED_JSON_SCHEMA : schema
4469
+ };
4470
+ return {
4471
+ name,
4472
+ in: "query",
4473
+ style: "deepObject",
4474
+ required: inputSchema?.required?.includes(name) ?? false,
4475
+ schema: schema_,
4476
+ example: internal.inputExample?.[name]
4477
+ };
4347
4478
  }
4348
- });
4349
- }
4350
- const content = {};
4351
- for (const file of files) {
4352
- content[file.contentMediaType] = {
4353
- schema: file
4354
- };
4355
- }
4356
- if (schema !== void 0) {
4357
- content[isStillHasFileSchema ? "multipart/form-data" : "application/json"] = {
4358
- schema,
4359
- example: internal.inputExample
4360
- };
4361
- }
4362
- return {
4363
- required: Boolean(internal.InputSchema?.isOptional()),
4364
- content
4365
- };
4366
- })();
4367
- const successResponse = (() => {
4368
- const { schema, matches } = extractJSONSchema(outputSchema, isFileSchema);
4369
- const files = matches;
4370
- const isStillHasFileSchema = findDeepMatches(isFileSchema, schema).values.length > 0;
4371
- const content = {};
4372
- for (const file of files) {
4373
- content[file.contentMediaType] = {
4374
- schema: file
4479
+ );
4480
+ })();
4481
+ const parameters = [...params ?? [], ...query ?? []];
4482
+ const requestBody = (() => {
4483
+ if (method === "GET") {
4484
+ return void 0;
4485
+ }
4486
+ const { schema, matches } = extractJSONSchema(inputSchema, isFileSchema);
4487
+ const files = matches;
4488
+ const isStillHasFileSchema = findDeepMatches(isFileSchema, schema).values.length > 0;
4489
+ if (files.length) {
4490
+ parameters.push({
4491
+ name: "content-disposition",
4492
+ in: "header",
4493
+ required: schema === void 0,
4494
+ schema: {
4495
+ type: "string",
4496
+ pattern: "filename",
4497
+ example: 'filename="file.png"',
4498
+ description: "To define the file name. Required when the request body is a file."
4499
+ }
4500
+ });
4501
+ }
4502
+ const content = {};
4503
+ for (const file of files) {
4504
+ content[file.contentMediaType] = {
4505
+ schema: file
4506
+ };
4507
+ }
4508
+ if (schema !== void 0) {
4509
+ content[isStillHasFileSchema ? "multipart/form-data" : "application/json"] = {
4510
+ schema,
4511
+ example: internal.inputExample
4512
+ };
4513
+ }
4514
+ return {
4515
+ required: Boolean(
4516
+ internal.InputSchema && "isOptional" in internal.InputSchema && typeof internal.InputSchema.isOptional === "function" ? internal.InputSchema.isOptional() : false
4517
+ ),
4518
+ content
4375
4519
  };
4376
- }
4377
- if (schema !== void 0) {
4378
- content[isStillHasFileSchema ? "multipart/form-data" : "application/json"] = {
4379
- schema,
4380
- example: internal.outputExample
4520
+ })();
4521
+ const successResponse = (() => {
4522
+ const { schema, matches } = extractJSONSchema(outputSchema, isFileSchema);
4523
+ const files = matches;
4524
+ const isStillHasFileSchema = findDeepMatches(isFileSchema, schema).values.length > 0;
4525
+ const content = {};
4526
+ for (const file of files) {
4527
+ content[file.contentMediaType] = {
4528
+ schema: file
4529
+ };
4530
+ }
4531
+ if (schema !== void 0) {
4532
+ content[isStillHasFileSchema ? "multipart/form-data" : "application/json"] = {
4533
+ schema,
4534
+ example: internal.outputExample
4535
+ };
4536
+ }
4537
+ return {
4538
+ description: "OK",
4539
+ content
4381
4540
  };
4541
+ })();
4542
+ if (throwOnMissingTagDefinition && internal.tags) {
4543
+ const missingTag = internal.tags.find((tag) => !rootTags.includes(tag));
4544
+ if (missingTag !== void 0) {
4545
+ throw new Error(
4546
+ `Tag "${missingTag}" is missing definition. Please define it in OpenAPI root tags object. [${path.join(".")}]`
4547
+ );
4548
+ }
4382
4549
  }
4383
- return {
4384
- description: "OK",
4385
- content
4550
+ const operation = {
4551
+ summary: internal.summary,
4552
+ description: internal.description,
4553
+ deprecated: internal.deprecated,
4554
+ tags: internal.tags,
4555
+ operationId: path.join("."),
4556
+ parameters: parameters.length ? parameters : void 0,
4557
+ requestBody,
4558
+ responses: {
4559
+ 200: successResponse
4560
+ }
4386
4561
  };
4387
- })();
4388
- if (throwOnMissingTagDefinition && internal.tags) {
4389
- const missingTag = internal.tags.find((tag) => !rootTags.includes(tag));
4390
- if (missingTag !== void 0) {
4391
- throw new Error(
4392
- `Tag "${missingTag}" is missing definition. Please define it in OpenAPI root tags object. [${path_.join(".")}]`
4393
- );
4394
- }
4395
- }
4396
- const operation = {
4397
- summary: internal.summary,
4398
- description: internal.description,
4399
- deprecated: internal.deprecated,
4400
- tags: internal.tags,
4401
- operationId: path_.join("."),
4402
- parameters: parameters.length ? parameters : void 0,
4403
- requestBody,
4404
- responses: {
4405
- 200: successResponse
4406
- }
4407
- };
4408
- builder.addPath(path, {
4409
- [method.toLocaleLowerCase()]: operation
4562
+ builder.addPath(httpPath, {
4563
+ [method.toLocaleLowerCase()]: operation
4564
+ });
4410
4565
  });
4411
- });
4566
+ for (const lazy of lazies) {
4567
+ const router = (await lazy.lazy[LAZY_LOADER_SYMBOL]()).default;
4568
+ pending.push({
4569
+ path: lazy.path,
4570
+ router
4571
+ });
4572
+ }
4573
+ }
4412
4574
  return preSerialize(builder.getSpec());
4413
4575
  }
4414
4576
  function isFileSchema(schema) {