@kubb/plugin-ts 5.0.0-beta.84 → 5.0.0-beta.85

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,7 +1,7 @@
1
1
  import { n as __name, t as __exportAll } from "./rolldown-runtime-CNktS9qV.js";
2
- import { ast, defineGenerator, definePlugin, defineResolver } from "kubb/kit";
3
2
  import { parserTs } from "@kubb/parser-ts";
4
3
  import { File, jsxRenderer } from "kubb/jsx";
4
+ import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
5
5
  import ts from "typescript";
6
6
  import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
7
7
  //#region ../../internals/utils/src/casing.ts
@@ -215,6 +215,67 @@ function ensureValidVarName(name) {
215
215
  return `_${name}`;
216
216
  }
217
217
  //#endregion
218
+ //#region ../../internals/utils/src/strings.ts
219
+ /**
220
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
221
+ * Returns the string unchanged when no balanced quote pair is found.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * trimQuotes('"hello"') // 'hello'
226
+ * trimQuotes('hello') // 'hello'
227
+ * ```
228
+ */
229
+ function trimQuotes(text) {
230
+ if (text.length >= 2) {
231
+ const first = text[0];
232
+ const last = text[text.length - 1];
233
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
234
+ }
235
+ return text;
236
+ }
237
+ /**
238
+ * Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
239
+ *
240
+ * Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
241
+ * code matches the repo style without a formatter.
242
+ *
243
+ * @example
244
+ * ```ts
245
+ * stringify('hello') // "'hello'"
246
+ * stringify('"hello"') // "'hello'"
247
+ * ```
248
+ */
249
+ function stringify(value) {
250
+ if (value === void 0 || value === null) return "''";
251
+ return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
252
+ }
253
+ /**
254
+ * Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
255
+ * and the Unicode line terminators U+2028 and U+2029.
256
+ *
257
+ * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
262
+ * ```
263
+ */
264
+ function jsStringEscape(input) {
265
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
266
+ switch (character) {
267
+ case "\"":
268
+ case "'":
269
+ case "\\": return `\\${character}`;
270
+ case "\n": return "\\n";
271
+ case "\r": return "\\r";
272
+ case "\u2028": return "\\u2028";
273
+ case "\u2029": return "\\u2029";
274
+ default: return "";
275
+ }
276
+ });
277
+ }
278
+ //#endregion
218
279
  //#region src/constants.ts
219
280
  /**
220
281
  * `optionalType` values that cause a property's type to include `| undefined`.
@@ -799,10 +860,10 @@ function buildIndexSignatures(node, propertyCount, print) {
799
860
  * resolve to the same name, which TypeScript merges into a single value+type declaration.
800
861
  */
801
862
  function getEnumNames({ node, enum: enumOptions, resolver }) {
802
- const resolved = resolver.resolveTypeName(node.name);
863
+ const resolved = resolver.name(node.name);
803
864
  return {
804
865
  enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
805
- typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolved
866
+ typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
806
867
  };
807
868
  }
808
869
  /**
@@ -826,10 +887,10 @@ function Enum({ node, enum: enumOptions, resolver }) {
826
887
  name: enumName,
827
888
  typeName,
828
889
  enums: node.namedEnumValues?.map((v) => [
829
- ast.trimQuotes(v.name.toString()),
890
+ trimQuotes(v.name.toString()),
830
891
  v.value,
831
892
  v.description
832
- ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [ast.trimQuotes(v.toString()), v]) ?? [],
893
+ ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
833
894
  type: enumOptions.type,
834
895
  enumKeyCasing: enumOptions.keyCasing
835
896
  });
@@ -1007,32 +1068,36 @@ function buildPropertyJSDocComments(schema, optional) {
1007
1068
  const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
1008
1069
  const exampleValues = meta?.examples ?? [];
1009
1070
  return [
1010
- hasDescription ? `@description ${ast.jsStringEscape(meta.description)}` : null,
1071
+ hasDescription ? `@description ${jsStringEscape(meta.description)}` : null,
1011
1072
  ...formatComment,
1012
1073
  meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : null,
1013
1074
  !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
1014
1075
  !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
1015
1076
  meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
1016
- meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? ast.stringify(meta.default) : meta.default}` : null,
1077
+ meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
1017
1078
  ...exampleValues.map((example) => `@example ${example}`),
1018
1079
  meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
1019
1080
  ].filter(Boolean);
1020
1081
  }
1021
- function buildParams(node, { params, resolver }) {
1082
+ /**
1083
+ * Builds the object schema for a group of parameters sharing one `in` location (path, query, or
1084
+ * header), embedding each param's own schema (and JSDoc) directly rather than referencing a
1085
+ * separate per-param type — the group itself is the only type these params get exported as.
1086
+ */
1087
+ function buildParams({ params }) {
1022
1088
  return ast.factory.createSchema({
1023
1089
  type: "object",
1024
1090
  properties: params.map((param) => ast.factory.createProperty({
1025
1091
  name: param.name,
1026
1092
  required: param.required,
1027
1093
  schema: ast.factory.createSchema({
1028
- type: "ref",
1029
- name: resolver.resolveParamName(node, param),
1094
+ ...param.schema,
1030
1095
  optional: !param.required
1031
1096
  })
1032
1097
  }))
1033
1098
  });
1034
1099
  }
1035
- function buildData(node, { resolver }) {
1100
+ function buildOptions(node, { resolver }) {
1036
1101
  const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing: "original" });
1037
1102
  const hasBody = Boolean(node.requestBody?.content?.[0]?.schema);
1038
1103
  const hasRequiredPath = pathParams.some((param) => param.required);
@@ -1047,7 +1112,7 @@ function buildData(node, { resolver }) {
1047
1112
  required: hasBody,
1048
1113
  schema: hasBody ? ast.factory.createSchema({
1049
1114
  type: "ref",
1050
- name: resolver.resolveDataName(node)
1115
+ name: resolver.response.body(node)
1051
1116
  }) : ast.factory.createSchema({
1052
1117
  type: "never",
1053
1118
  primitive: void 0,
@@ -1058,10 +1123,8 @@ function buildData(node, { resolver }) {
1058
1123
  name: "path",
1059
1124
  required: hasRequiredPath,
1060
1125
  schema: pathParams.length > 0 ? ast.factory.createSchema({
1061
- ...buildParams(node, {
1062
- params: pathParams,
1063
- resolver
1064
- }),
1126
+ type: "ref",
1127
+ name: resolver.param.path(node, pathParams[0]),
1065
1128
  optional: !hasRequiredPath
1066
1129
  }) : ast.factory.createSchema({
1067
1130
  type: "never",
@@ -1073,10 +1136,8 @@ function buildData(node, { resolver }) {
1073
1136
  name: "query",
1074
1137
  required: hasRequiredQuery,
1075
1138
  schema: queryParams.length > 0 ? ast.factory.createSchema({
1076
- ...buildParams(node, {
1077
- params: queryParams,
1078
- resolver
1079
- }),
1139
+ type: "ref",
1140
+ name: resolver.param.query(node, queryParams[0]),
1080
1141
  optional: !hasRequiredQuery
1081
1142
  }) : ast.factory.createSchema({
1082
1143
  type: "never",
@@ -1088,10 +1149,8 @@ function buildData(node, { resolver }) {
1088
1149
  name: "headers",
1089
1150
  required: hasRequiredHeader,
1090
1151
  schema: headerParams.length > 0 ? ast.factory.createSchema({
1091
- ...buildParams(node, {
1092
- params: headerParams,
1093
- resolver
1094
- }),
1152
+ type: "ref",
1153
+ name: resolver.param.headers(node, headerParams[0]),
1095
1154
  optional: !hasRequiredHeader
1096
1155
  }) : ast.factory.createSchema({
1097
1156
  type: "never",
@@ -1109,7 +1168,7 @@ function buildData(node, { resolver }) {
1109
1168
  * query hooks and `result.data` use.
1110
1169
  */
1111
1170
  function buildResponseRecordEntry(node, res, resolver) {
1112
- const statusName = resolver.resolveResponseStatusName(node, res.statusCode);
1171
+ const statusName = resolver.response.status(node, res.statusCode);
1113
1172
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1114
1173
  if (variants.length <= 1) return ast.factory.createSchema({
1115
1174
  type: "ref",
@@ -1154,7 +1213,7 @@ function buildResponseUnion(node, { resolver }) {
1154
1213
  type: "union",
1155
1214
  members: responsesWithSchema.map((res) => ast.factory.createSchema({
1156
1215
  type: "ref",
1157
- name: resolver.resolveResponseStatusName(node, res.statusCode)
1216
+ name: resolver.response.status(node, res.statusCode)
1158
1217
  }))
1159
1218
  });
1160
1219
  }
@@ -1248,7 +1307,7 @@ const printerTs = ast.createPrinter((options) => {
1248
1307
  ref(node) {
1249
1308
  if (!node.name) return null;
1250
1309
  const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? ast.extractRefName(node.ref) ?? node.name : node.name;
1251
- return createTypeReferenceNode(node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.resolveEnumKeyName({ name: refName }, this.options.enum.typeSuffix) : node.ref ? this.options.resolver.resolveTypeName(refName) : refName, void 0);
1310
+ return createTypeReferenceNode(node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.enum.keyName({ name: refName }, this.options.enum.typeSuffix) : node.ref ? this.options.resolver.name(refName) : refName, void 0);
1252
1311
  },
1253
1312
  enum(node) {
1254
1313
  const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
@@ -1256,7 +1315,7 @@ const printerTs = ast.createPrinter((options) => {
1256
1315
  withParentheses: true,
1257
1316
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1258
1317
  }) ?? void 0;
1259
- return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix ? this.options.resolver.resolveEnumKeyName(node, this.options.enum.typeSuffix) : this.options.resolver.resolveTypeName(node.name), void 0);
1318
+ return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix ? this.options.resolver.enum.keyName(node, this.options.enum.typeSuffix) : this.options.resolver.name(node.name), void 0);
1260
1319
  },
1261
1320
  union(node) {
1262
1321
  const members = node.members ?? [];
@@ -1368,15 +1427,14 @@ const typeGenerator = defineGenerator({
1368
1427
  if (!node.name) return;
1369
1428
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1370
1429
  function resolveImportName(schemaName) {
1371
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumOptions.typeSuffix);
1372
- return resolver.resolveTypeName(schemaName);
1430
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1431
+ return resolver.name(schemaName);
1373
1432
  }
1374
1433
  const imports = adapter.getImports(node, (schemaName) => ({
1375
1434
  name: resolveImportName(schemaName),
1376
- path: resolver.resolveFile({
1435
+ path: resolver.file({
1377
1436
  name: schemaName,
1378
- extname: ".ts"
1379
- }, {
1437
+ extname: ".ts",
1380
1438
  root,
1381
1439
  output,
1382
1440
  group: group ?? void 0
@@ -1385,11 +1443,10 @@ const typeGenerator = defineGenerator({
1385
1443
  const enumNode = ast.narrowSchema(node, ast.schemaTypes.enum);
1386
1444
  const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1387
1445
  const meta = {
1388
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolver.resolveTypeName(node.name),
1389
- file: resolver.resolveFile({
1446
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1447
+ file: resolver.file({
1390
1448
  name: node.name,
1391
- extname: ".ts"
1392
- }, {
1449
+ extname: ".ts",
1393
1450
  root,
1394
1451
  output,
1395
1452
  group: group ?? void 0
@@ -1411,7 +1468,7 @@ const typeGenerator = defineGenerator({
1411
1468
  baseName: meta.file.baseName,
1412
1469
  path: meta.file.path,
1413
1470
  meta: meta.file.meta,
1414
- banner: resolver.resolveBanner(ctx.meta, {
1471
+ banner: resolver.default.banner(ctx.meta, {
1415
1472
  output,
1416
1473
  config,
1417
1474
  file: {
@@ -1419,7 +1476,7 @@ const typeGenerator = defineGenerator({
1419
1476
  baseName: meta.file.baseName
1420
1477
  }
1421
1478
  }),
1422
- footer: resolver.resolveFooter(ctx.meta, {
1479
+ footer: resolver.default.footer(ctx.meta, {
1423
1480
  output,
1424
1481
  config,
1425
1482
  file: {
@@ -1449,29 +1506,27 @@ const typeGenerator = defineGenerator({
1449
1506
  const { enum: enumOptions, optionalType, arrayType, syntaxType, group, output, printer } = ctx.options;
1450
1507
  const { adapter, config, resolver, root } = ctx;
1451
1508
  const params = caseParams(node.parameters, "camelcase");
1452
- const meta = { file: resolver.resolveFile({
1509
+ const meta = { file: resolver.file({
1453
1510
  name: node.operationId,
1454
1511
  extname: ".ts",
1455
1512
  tag: node.tags[0] ?? "default",
1456
- path: node.path
1457
- }, {
1513
+ path: node.path,
1458
1514
  root,
1459
1515
  output,
1460
1516
  group: group ?? void 0
1461
1517
  }) };
1462
1518
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1463
1519
  function resolveImportName(schemaName) {
1464
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumOptions.typeSuffix);
1465
- return resolver.resolveTypeName(schemaName);
1520
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1521
+ return resolver.name(schemaName);
1466
1522
  }
1467
1523
  function renderSchemaType({ schema, name, keysToOmit }) {
1468
1524
  if (!schema) return null;
1469
1525
  const imports = adapter.getImports(schema, (schemaName) => ({
1470
1526
  name: resolveImportName(schemaName),
1471
- path: resolver.resolveFile({
1527
+ path: resolver.file({
1472
1528
  name: schemaName,
1473
- extname: ".ts"
1474
- }, {
1529
+ extname: ".ts",
1475
1530
  root,
1476
1531
  output,
1477
1532
  group: group ?? void 0
@@ -1531,13 +1586,24 @@ const typeGenerator = defineGenerator({
1531
1586
  name: baseName
1532
1587
  })] });
1533
1588
  }
1534
- const paramTypes = params.map((param) => renderSchemaType({
1535
- schema: {
1536
- ...param.schema,
1537
- optional: !param.required
1538
- },
1539
- name: resolver.resolveParamName(node, param)
1540
- }));
1589
+ const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
1590
+ ...node,
1591
+ parameters: params
1592
+ }, { paramsCasing: "original" });
1593
+ const paramGroupTypes = [
1594
+ pathParams.length > 0 && renderSchemaType({
1595
+ schema: buildParams({ params: pathParams }),
1596
+ name: resolver.param.path(node, pathParams[0])
1597
+ }),
1598
+ queryParams.length > 0 && renderSchemaType({
1599
+ schema: buildParams({ params: queryParams }),
1600
+ name: resolver.param.query(node, queryParams[0])
1601
+ }),
1602
+ headerParams.length > 0 && renderSchemaType({
1603
+ schema: buildParams({ params: headerParams }),
1604
+ name: resolver.param.headers(node, headerParams[0])
1605
+ })
1606
+ ];
1541
1607
  const requestBodyContent = node.requestBody?.content ?? [];
1542
1608
  function buildRequestType() {
1543
1609
  if (requestBodyContent.length === 0) return null;
@@ -1549,11 +1615,11 @@ const typeGenerator = defineGenerator({
1549
1615
  ...entry.schema,
1550
1616
  description: node.requestBody.description ?? entry.schema.description
1551
1617
  },
1552
- name: resolver.resolveDataName(node),
1618
+ name: resolver.response.body(node),
1553
1619
  keysToOmit: entry.keysToOmit
1554
1620
  });
1555
1621
  }
1556
- return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
1622
+ return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1557
1623
  ...schema,
1558
1624
  description: node.requestBody.description ?? schema.description
1559
1625
  }));
@@ -1561,29 +1627,29 @@ const typeGenerator = defineGenerator({
1561
1627
  const requestType = buildRequestType();
1562
1628
  const responseTypes = node.responses.map((res) => {
1563
1629
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1564
- if (variants.length > 1) return buildContentTypeVariants(variants, resolver.resolveResponseStatusName(node, res.statusCode));
1630
+ if (variants.length > 1) return buildContentTypeVariants(variants, resolver.response.status(node, res.statusCode));
1565
1631
  const primary = variants[0] ?? res.content?.[0];
1566
1632
  return renderSchemaType({
1567
1633
  schema: primary?.schema ?? null,
1568
- name: resolver.resolveResponseStatusName(node, res.statusCode),
1634
+ name: resolver.response.status(node, res.statusCode),
1569
1635
  keysToOmit: primary?.keysToOmit
1570
1636
  });
1571
1637
  });
1572
- const dataType = renderSchemaType({
1573
- schema: buildData({
1638
+ const optionsType = renderSchemaType({
1639
+ schema: buildOptions({
1574
1640
  ...node,
1575
1641
  parameters: params
1576
1642
  }, { resolver }),
1577
- name: resolver.resolveRequestConfigName(node)
1643
+ name: resolver.response.options(node)
1578
1644
  });
1579
1645
  const responsesType = renderSchemaType({
1580
1646
  schema: buildResponses(node, { resolver }),
1581
- name: resolver.resolveResponsesName(node)
1647
+ name: resolver.response.responses(node)
1582
1648
  });
1583
1649
  function buildResponseType() {
1584
1650
  const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
1585
1651
  if (!node.responses.some(hasSchema)) return null;
1586
- const responseName = resolver.resolveResponseName(node);
1652
+ const responseName = resolver.response.response(node);
1587
1653
  const responsesWithSchema = node.responses.filter(hasSchema);
1588
1654
  if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1589
1655
  name: resolveImportName(schemaName),
@@ -1602,7 +1668,7 @@ const typeGenerator = defineGenerator({
1602
1668
  baseName: meta.file.baseName,
1603
1669
  path: meta.file.path,
1604
1670
  meta: meta.file.meta,
1605
- banner: resolver.resolveBanner(ctx.meta, {
1671
+ banner: resolver.default.banner(ctx.meta, {
1606
1672
  output,
1607
1673
  config,
1608
1674
  file: {
@@ -1610,7 +1676,7 @@ const typeGenerator = defineGenerator({
1610
1676
  baseName: meta.file.baseName
1611
1677
  }
1612
1678
  }),
1613
- footer: resolver.resolveFooter(ctx.meta, {
1679
+ footer: resolver.default.footer(ctx.meta, {
1614
1680
  output,
1615
1681
  config,
1616
1682
  file: {
@@ -1619,10 +1685,10 @@ const typeGenerator = defineGenerator({
1619
1685
  }
1620
1686
  }),
1621
1687
  children: [
1622
- paramTypes,
1688
+ paramGroupTypes,
1623
1689
  responseTypes,
1624
1690
  requestType,
1625
- dataType,
1691
+ optionsType,
1626
1692
  responsesType,
1627
1693
  responseType
1628
1694
  ]
@@ -1637,64 +1703,61 @@ const typeGenerator = defineGenerator({
1637
1703
  * to reference the exact names `plugin-ts` produces without duplicating the
1638
1704
  * casing/file-layout rules.
1639
1705
  *
1640
- * The `default` method is supplied by `defineResolver`. It uses PascalCase for
1641
- * type names and PascalCase file paths (dotted names become `/`-joined) for files.
1706
+ * The `default` helpers are supplied by `createResolver`. This plugin overrides the top-level `name`
1707
+ * to use PascalCase for value and type names and `file` to write PascalCase file paths (dotted names
1708
+ * become `/`-joined), and groups the operation-specific naming under the `param`, `response`, and
1709
+ * `enum` namespaces.
1642
1710
  *
1643
1711
  * @example Resolve a type and file name
1644
1712
  * ```ts
1645
1713
  * import { resolverTs } from '@kubb/plugin-ts'
1646
1714
  *
1647
- * resolverTs.default('list pets', 'type') // 'ListPets'
1648
- * resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
1649
- * resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
1715
+ * resolverTs.name('list pets') // 'ListPets'
1716
+ * resolverTs.response.status(node, 200) // 'ListPetsStatus200'
1650
1717
  * ```
1651
1718
  */
1652
- const resolverTs = defineResolver(() => {
1653
- return {
1654
- name: "default",
1655
- pluginName: "plugin-ts",
1656
- default(name, type) {
1657
- if (type === "file") return toFilePath(name, pascalCase);
1658
- return ensureValidVarName(pascalCase(name));
1659
- },
1660
- resolveTypeName(name) {
1661
- return ensureValidVarName(pascalCase(name));
1662
- },
1663
- resolvePathName(name, type) {
1664
- if (type === "file") return toFilePath(name, pascalCase);
1665
- return ensureValidVarName(pascalCase(name));
1666
- },
1667
- resolveParamName(node, param) {
1668
- return this.resolveTypeName(`${node.operationId} ${param.in} ${param.name}`);
1669
- },
1670
- resolveResponseStatusName(node, statusCode) {
1671
- return this.resolveTypeName(`${node.operationId} Status ${statusCode}`);
1672
- },
1673
- resolveDataName(node) {
1674
- return this.resolveTypeName(`${node.operationId} Data`);
1719
+ const resolverTs = createResolver({
1720
+ pluginName: "plugin-ts",
1721
+ name(name) {
1722
+ return ensureValidVarName(pascalCase(name));
1723
+ },
1724
+ file: { baseName({ name, extname }) {
1725
+ return `${toFilePath(name, pascalCase)}${extname}`;
1726
+ } },
1727
+ param: {
1728
+ name(node, param) {
1729
+ return this.name(`${node.operationId} ${param.in} ${param.name}`);
1675
1730
  },
1676
- resolveRequestConfigName(node) {
1677
- return this.resolveTypeName(`${node.operationId} RequestConfig`);
1731
+ path(node) {
1732
+ return this.name(`${node.operationId} Path`);
1678
1733
  },
1679
- resolveResponsesName(node) {
1680
- return this.resolveTypeName(`${node.operationId} Responses`);
1734
+ query(node) {
1735
+ return this.name(`${node.operationId} Query`);
1681
1736
  },
1682
- resolveResponseName(node) {
1683
- return this.resolveTypeName(`${node.operationId} Response`);
1737
+ headers(node) {
1738
+ return this.name(`${node.operationId} Headers`);
1739
+ }
1740
+ },
1741
+ response: {
1742
+ status(node, statusCode) {
1743
+ return this.name(`${node.operationId} Status ${statusCode}`);
1684
1744
  },
1685
- resolveEnumKeyName(node, enumTypeSuffix = "key") {
1686
- return `${this.resolveTypeName(node.name ?? "")}${enumTypeSuffix}`;
1745
+ options(node) {
1746
+ return this.name(`${node.operationId} Options`);
1687
1747
  },
1688
- resolvePathParamsName(node, param) {
1689
- return this.resolveParamName(node, param);
1748
+ responses(node) {
1749
+ return this.name(`${node.operationId} Responses`);
1690
1750
  },
1691
- resolveQueryParamsName(node, param) {
1692
- return this.resolveParamName(node, param);
1751
+ response(node) {
1752
+ return this.name(`${node.operationId} Response`);
1693
1753
  },
1694
- resolveHeaderParamsName(node, param) {
1695
- return this.resolveParamName(node, param);
1754
+ body(node) {
1755
+ return this.name(`${node.operationId} Body`);
1696
1756
  }
1697
- };
1757
+ },
1758
+ enum: { keyName(node, enumTypeSuffix = "key") {
1759
+ return `${this.name(node.name ?? "")}${enumTypeSuffix}`;
1760
+ } }
1698
1761
  });
1699
1762
  //#endregion
1700
1763
  //#region src/plugin.ts
@@ -1755,10 +1818,7 @@ const pluginTs = definePlugin((options) => {
1755
1818
  syntaxType,
1756
1819
  printer
1757
1820
  });
1758
- ctx.setResolver(userResolver ? {
1759
- ...resolverTs,
1760
- ...userResolver
1761
- } : resolverTs);
1821
+ ctx.setResolver(userResolver ? Resolver.merge(resolverTs, userResolver) : resolverTs);
1762
1822
  if (userMacros?.length) ctx.setMacros(userMacros);
1763
1823
  ctx.addGenerator(typeGenerator);
1764
1824
  } }
@@ -2019,12 +2079,12 @@ function functionPrinter(options) {
2019
2079
  */
2020
2080
  function resolveParamType({ node, param, resolver }) {
2021
2081
  if (!resolver) return param.schema.primitive ?? "unknown";
2022
- const individualName = resolver.resolveParamName(node, param);
2082
+ const individualName = resolver.param.name(node, param);
2023
2083
  const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
2024
2084
  const groupResolvers = {
2025
- path: resolver.resolvePathParamsName,
2026
- query: resolver.resolveQueryParamsName,
2027
- header: resolver.resolveHeaderParamsName
2085
+ path: resolver.param.path,
2086
+ query: resolver.param.query,
2087
+ header: resolver.param.headers
2028
2088
  };
2029
2089
  const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
2030
2090
  if (groupName && groupName !== individualName) return createIndexedAccessType({
@@ -2042,8 +2102,8 @@ function resolveParamType({ node, param, resolver }) {
2042
2102
  function resolveGroupType({ node, params, group, resolver }) {
2043
2103
  if (!resolver || !params.length) return null;
2044
2104
  const firstParam = params[0];
2045
- const groupName = (group === "query" ? resolver.resolveQueryParamsName : resolver.resolveHeaderParamsName).call(resolver, node, firstParam);
2046
- if (groupName === resolver.resolveParamName(node, firstParam)) return null;
2105
+ const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
2106
+ if (groupName === resolver.param.name(node, firstParam)) return null;
2047
2107
  return {
2048
2108
  type: groupName,
2049
2109
  optional: params.every((p) => !p.required)
@@ -2079,7 +2139,7 @@ function createOperationParams(node, options) {
2079
2139
  optional: !param.required
2080
2140
  });
2081
2141
  const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
2082
- const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.resolveDataName(node) ?? "unknown") : void 0;
2142
+ const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
2083
2143
  const bodyProperty = bodyType ? [{
2084
2144
  name: dataName,
2085
2145
  type: bodyType,
@@ -2123,7 +2183,7 @@ function createOperationParams(node, options) {
2123
2183
  }));
2124
2184
  } else {
2125
2185
  if (pathParamsType === "inlineSpread" && pathParams.length) {
2126
- const spreadType = resolver?.resolvePathParamsName(node, pathParams[0]);
2186
+ const spreadType = resolver?.param.path(node, pathParams[0]);
2127
2187
  params.push(createFunctionParameter({
2128
2188
  name: pathName,
2129
2189
  type: spreadType ? wrapType(spreadType) : void 0,
@@ -2191,6 +2251,6 @@ function buildTypeLiteral({ node, params, resolver }) {
2191
2251
  })) });
2192
2252
  }
2193
2253
  //#endregion
2194
- export { Enum, Type, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createOperationParams, createTypeLiteral, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
2254
+ export { Enum, Type, buildParams, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createOperationParams, createTypeLiteral, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
2195
2255
 
2196
2256
  //# sourceMappingURL=index.js.map