@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.cjs CHANGED
@@ -37,9 +37,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
37
  enumerable: true
38
38
  }) : target, mod));
39
39
  //#endregion
40
- let kubb_kit = require("kubb/kit");
41
40
  let _kubb_parser_ts = require("@kubb/parser-ts");
42
41
  let kubb_jsx = require("kubb/jsx");
42
+ let kubb_kit = require("kubb/kit");
43
43
  let typescript = require("typescript");
44
44
  typescript = __toESM(typescript, 1);
45
45
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
@@ -254,6 +254,67 @@ function ensureValidVarName(name) {
254
254
  return `_${name}`;
255
255
  }
256
256
  //#endregion
257
+ //#region ../../internals/utils/src/strings.ts
258
+ /**
259
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
260
+ * Returns the string unchanged when no balanced quote pair is found.
261
+ *
262
+ * @example
263
+ * ```ts
264
+ * trimQuotes('"hello"') // 'hello'
265
+ * trimQuotes('hello') // 'hello'
266
+ * ```
267
+ */
268
+ function trimQuotes(text) {
269
+ if (text.length >= 2) {
270
+ const first = text[0];
271
+ const last = text[text.length - 1];
272
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
273
+ }
274
+ return text;
275
+ }
276
+ /**
277
+ * Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
278
+ *
279
+ * Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
280
+ * code matches the repo style without a formatter.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * stringify('hello') // "'hello'"
285
+ * stringify('"hello"') // "'hello'"
286
+ * ```
287
+ */
288
+ function stringify(value) {
289
+ if (value === void 0 || value === null) return "''";
290
+ return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
291
+ }
292
+ /**
293
+ * Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
294
+ * and the Unicode line terminators U+2028 and U+2029.
295
+ *
296
+ * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
301
+ * ```
302
+ */
303
+ function jsStringEscape(input) {
304
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
305
+ switch (character) {
306
+ case "\"":
307
+ case "'":
308
+ case "\\": return `\\${character}`;
309
+ case "\n": return "\\n";
310
+ case "\r": return "\\r";
311
+ case "\u2028": return "\\u2028";
312
+ case "\u2029": return "\\u2029";
313
+ default: return "";
314
+ }
315
+ });
316
+ }
317
+ //#endregion
257
318
  //#region src/constants.ts
258
319
  /**
259
320
  * `optionalType` values that cause a property's type to include `| undefined`.
@@ -838,10 +899,10 @@ function buildIndexSignatures(node, propertyCount, print) {
838
899
  * resolve to the same name, which TypeScript merges into a single value+type declaration.
839
900
  */
840
901
  function getEnumNames({ node, enum: enumOptions, resolver }) {
841
- const resolved = resolver.resolveTypeName(node.name);
902
+ const resolved = resolver.name(node.name);
842
903
  return {
843
904
  enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
844
- typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolved
905
+ typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
845
906
  };
846
907
  }
847
908
  /**
@@ -865,10 +926,10 @@ function Enum({ node, enum: enumOptions, resolver }) {
865
926
  name: enumName,
866
927
  typeName,
867
928
  enums: node.namedEnumValues?.map((v) => [
868
- kubb_kit.ast.trimQuotes(v.name.toString()),
929
+ trimQuotes(v.name.toString()),
869
930
  v.value,
870
931
  v.description
871
- ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [kubb_kit.ast.trimQuotes(v.toString()), v]) ?? [],
932
+ ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
872
933
  type: enumOptions.type,
873
934
  enumKeyCasing: enumOptions.keyCasing
874
935
  });
@@ -1046,32 +1107,36 @@ function buildPropertyJSDocComments(schema, optional) {
1046
1107
  const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
1047
1108
  const exampleValues = meta?.examples ?? [];
1048
1109
  return [
1049
- hasDescription ? `@description ${kubb_kit.ast.jsStringEscape(meta.description)}` : null,
1110
+ hasDescription ? `@description ${jsStringEscape(meta.description)}` : null,
1050
1111
  ...formatComment,
1051
1112
  meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : null,
1052
1113
  !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
1053
1114
  !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
1054
1115
  meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
1055
- meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? kubb_kit.ast.stringify(meta.default) : meta.default}` : null,
1116
+ meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
1056
1117
  ...exampleValues.map((example) => `@example ${example}`),
1057
1118
  meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
1058
1119
  ].filter(Boolean);
1059
1120
  }
1060
- function buildParams(node, { params, resolver }) {
1121
+ /**
1122
+ * Builds the object schema for a group of parameters sharing one `in` location (path, query, or
1123
+ * header), embedding each param's own schema (and JSDoc) directly rather than referencing a
1124
+ * separate per-param type — the group itself is the only type these params get exported as.
1125
+ */
1126
+ function buildParams({ params }) {
1061
1127
  return kubb_kit.ast.factory.createSchema({
1062
1128
  type: "object",
1063
1129
  properties: params.map((param) => kubb_kit.ast.factory.createProperty({
1064
1130
  name: param.name,
1065
1131
  required: param.required,
1066
1132
  schema: kubb_kit.ast.factory.createSchema({
1067
- type: "ref",
1068
- name: resolver.resolveParamName(node, param),
1133
+ ...param.schema,
1069
1134
  optional: !param.required
1070
1135
  })
1071
1136
  }))
1072
1137
  });
1073
1138
  }
1074
- function buildData(node, { resolver }) {
1139
+ function buildOptions(node, { resolver }) {
1075
1140
  const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing: "original" });
1076
1141
  const hasBody = Boolean(node.requestBody?.content?.[0]?.schema);
1077
1142
  const hasRequiredPath = pathParams.some((param) => param.required);
@@ -1086,7 +1151,7 @@ function buildData(node, { resolver }) {
1086
1151
  required: hasBody,
1087
1152
  schema: hasBody ? kubb_kit.ast.factory.createSchema({
1088
1153
  type: "ref",
1089
- name: resolver.resolveDataName(node)
1154
+ name: resolver.response.body(node)
1090
1155
  }) : kubb_kit.ast.factory.createSchema({
1091
1156
  type: "never",
1092
1157
  primitive: void 0,
@@ -1097,10 +1162,8 @@ function buildData(node, { resolver }) {
1097
1162
  name: "path",
1098
1163
  required: hasRequiredPath,
1099
1164
  schema: pathParams.length > 0 ? kubb_kit.ast.factory.createSchema({
1100
- ...buildParams(node, {
1101
- params: pathParams,
1102
- resolver
1103
- }),
1165
+ type: "ref",
1166
+ name: resolver.param.path(node, pathParams[0]),
1104
1167
  optional: !hasRequiredPath
1105
1168
  }) : kubb_kit.ast.factory.createSchema({
1106
1169
  type: "never",
@@ -1112,10 +1175,8 @@ function buildData(node, { resolver }) {
1112
1175
  name: "query",
1113
1176
  required: hasRequiredQuery,
1114
1177
  schema: queryParams.length > 0 ? kubb_kit.ast.factory.createSchema({
1115
- ...buildParams(node, {
1116
- params: queryParams,
1117
- resolver
1118
- }),
1178
+ type: "ref",
1179
+ name: resolver.param.query(node, queryParams[0]),
1119
1180
  optional: !hasRequiredQuery
1120
1181
  }) : kubb_kit.ast.factory.createSchema({
1121
1182
  type: "never",
@@ -1127,10 +1188,8 @@ function buildData(node, { resolver }) {
1127
1188
  name: "headers",
1128
1189
  required: hasRequiredHeader,
1129
1190
  schema: headerParams.length > 0 ? kubb_kit.ast.factory.createSchema({
1130
- ...buildParams(node, {
1131
- params: headerParams,
1132
- resolver
1133
- }),
1191
+ type: "ref",
1192
+ name: resolver.param.headers(node, headerParams[0]),
1134
1193
  optional: !hasRequiredHeader
1135
1194
  }) : kubb_kit.ast.factory.createSchema({
1136
1195
  type: "never",
@@ -1148,7 +1207,7 @@ function buildData(node, { resolver }) {
1148
1207
  * query hooks and `result.data` use.
1149
1208
  */
1150
1209
  function buildResponseRecordEntry(node, res, resolver) {
1151
- const statusName = resolver.resolveResponseStatusName(node, res.statusCode);
1210
+ const statusName = resolver.response.status(node, res.statusCode);
1152
1211
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1153
1212
  if (variants.length <= 1) return kubb_kit.ast.factory.createSchema({
1154
1213
  type: "ref",
@@ -1193,7 +1252,7 @@ function buildResponseUnion(node, { resolver }) {
1193
1252
  type: "union",
1194
1253
  members: responsesWithSchema.map((res) => kubb_kit.ast.factory.createSchema({
1195
1254
  type: "ref",
1196
- name: resolver.resolveResponseStatusName(node, res.statusCode)
1255
+ name: resolver.response.status(node, res.statusCode)
1197
1256
  }))
1198
1257
  });
1199
1258
  }
@@ -1287,7 +1346,7 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1287
1346
  ref(node) {
1288
1347
  if (!node.name) return null;
1289
1348
  const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name : node.name;
1290
- 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);
1349
+ 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);
1291
1350
  },
1292
1351
  enum(node) {
1293
1352
  const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
@@ -1295,7 +1354,7 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1295
1354
  withParentheses: true,
1296
1355
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1297
1356
  }) ?? void 0;
1298
- 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);
1357
+ 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);
1299
1358
  },
1300
1359
  union(node) {
1301
1360
  const members = node.members ?? [];
@@ -1407,15 +1466,14 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1407
1466
  if (!node.name) return;
1408
1467
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1409
1468
  function resolveImportName(schemaName) {
1410
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumOptions.typeSuffix);
1411
- return resolver.resolveTypeName(schemaName);
1469
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1470
+ return resolver.name(schemaName);
1412
1471
  }
1413
1472
  const imports = adapter.getImports(node, (schemaName) => ({
1414
1473
  name: resolveImportName(schemaName),
1415
- path: resolver.resolveFile({
1474
+ path: resolver.file({
1416
1475
  name: schemaName,
1417
- extname: ".ts"
1418
- }, {
1476
+ extname: ".ts",
1419
1477
  root,
1420
1478
  output,
1421
1479
  group: group ?? void 0
@@ -1424,11 +1482,10 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1424
1482
  const enumNode = kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
1425
1483
  const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1426
1484
  const meta = {
1427
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolver.resolveTypeName(node.name),
1428
- file: resolver.resolveFile({
1485
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1486
+ file: resolver.file({
1429
1487
  name: node.name,
1430
- extname: ".ts"
1431
- }, {
1488
+ extname: ".ts",
1432
1489
  root,
1433
1490
  output,
1434
1491
  group: group ?? void 0
@@ -1450,7 +1507,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1450
1507
  baseName: meta.file.baseName,
1451
1508
  path: meta.file.path,
1452
1509
  meta: meta.file.meta,
1453
- banner: resolver.resolveBanner(ctx.meta, {
1510
+ banner: resolver.default.banner(ctx.meta, {
1454
1511
  output,
1455
1512
  config,
1456
1513
  file: {
@@ -1458,7 +1515,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1458
1515
  baseName: meta.file.baseName
1459
1516
  }
1460
1517
  }),
1461
- footer: resolver.resolveFooter(ctx.meta, {
1518
+ footer: resolver.default.footer(ctx.meta, {
1462
1519
  output,
1463
1520
  config,
1464
1521
  file: {
@@ -1488,29 +1545,27 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1488
1545
  const { enum: enumOptions, optionalType, arrayType, syntaxType, group, output, printer } = ctx.options;
1489
1546
  const { adapter, config, resolver, root } = ctx;
1490
1547
  const params = caseParams(node.parameters, "camelcase");
1491
- const meta = { file: resolver.resolveFile({
1548
+ const meta = { file: resolver.file({
1492
1549
  name: node.operationId,
1493
1550
  extname: ".ts",
1494
1551
  tag: node.tags[0] ?? "default",
1495
- path: node.path
1496
- }, {
1552
+ path: node.path,
1497
1553
  root,
1498
1554
  output,
1499
1555
  group: group ?? void 0
1500
1556
  }) };
1501
1557
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1502
1558
  function resolveImportName(schemaName) {
1503
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumOptions.typeSuffix);
1504
- return resolver.resolveTypeName(schemaName);
1559
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1560
+ return resolver.name(schemaName);
1505
1561
  }
1506
1562
  function renderSchemaType({ schema, name, keysToOmit }) {
1507
1563
  if (!schema) return null;
1508
1564
  const imports = adapter.getImports(schema, (schemaName) => ({
1509
1565
  name: resolveImportName(schemaName),
1510
- path: resolver.resolveFile({
1566
+ path: resolver.file({
1511
1567
  name: schemaName,
1512
- extname: ".ts"
1513
- }, {
1568
+ extname: ".ts",
1514
1569
  root,
1515
1570
  output,
1516
1571
  group: group ?? void 0
@@ -1570,13 +1625,24 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1570
1625
  name: baseName
1571
1626
  })] });
1572
1627
  }
1573
- const paramTypes = params.map((param) => renderSchemaType({
1574
- schema: {
1575
- ...param.schema,
1576
- optional: !param.required
1577
- },
1578
- name: resolver.resolveParamName(node, param)
1579
- }));
1628
+ const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
1629
+ ...node,
1630
+ parameters: params
1631
+ }, { paramsCasing: "original" });
1632
+ const paramGroupTypes = [
1633
+ pathParams.length > 0 && renderSchemaType({
1634
+ schema: buildParams({ params: pathParams }),
1635
+ name: resolver.param.path(node, pathParams[0])
1636
+ }),
1637
+ queryParams.length > 0 && renderSchemaType({
1638
+ schema: buildParams({ params: queryParams }),
1639
+ name: resolver.param.query(node, queryParams[0])
1640
+ }),
1641
+ headerParams.length > 0 && renderSchemaType({
1642
+ schema: buildParams({ params: headerParams }),
1643
+ name: resolver.param.headers(node, headerParams[0])
1644
+ })
1645
+ ];
1580
1646
  const requestBodyContent = node.requestBody?.content ?? [];
1581
1647
  function buildRequestType() {
1582
1648
  if (requestBodyContent.length === 0) return null;
@@ -1588,11 +1654,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1588
1654
  ...entry.schema,
1589
1655
  description: node.requestBody.description ?? entry.schema.description
1590
1656
  },
1591
- name: resolver.resolveDataName(node),
1657
+ name: resolver.response.body(node),
1592
1658
  keysToOmit: entry.keysToOmit
1593
1659
  });
1594
1660
  }
1595
- return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
1661
+ return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1596
1662
  ...schema,
1597
1663
  description: node.requestBody.description ?? schema.description
1598
1664
  }));
@@ -1600,29 +1666,29 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1600
1666
  const requestType = buildRequestType();
1601
1667
  const responseTypes = node.responses.map((res) => {
1602
1668
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1603
- if (variants.length > 1) return buildContentTypeVariants(variants, resolver.resolveResponseStatusName(node, res.statusCode));
1669
+ if (variants.length > 1) return buildContentTypeVariants(variants, resolver.response.status(node, res.statusCode));
1604
1670
  const primary = variants[0] ?? res.content?.[0];
1605
1671
  return renderSchemaType({
1606
1672
  schema: primary?.schema ?? null,
1607
- name: resolver.resolveResponseStatusName(node, res.statusCode),
1673
+ name: resolver.response.status(node, res.statusCode),
1608
1674
  keysToOmit: primary?.keysToOmit
1609
1675
  });
1610
1676
  });
1611
- const dataType = renderSchemaType({
1612
- schema: buildData({
1677
+ const optionsType = renderSchemaType({
1678
+ schema: buildOptions({
1613
1679
  ...node,
1614
1680
  parameters: params
1615
1681
  }, { resolver }),
1616
- name: resolver.resolveRequestConfigName(node)
1682
+ name: resolver.response.options(node)
1617
1683
  });
1618
1684
  const responsesType = renderSchemaType({
1619
1685
  schema: buildResponses(node, { resolver }),
1620
- name: resolver.resolveResponsesName(node)
1686
+ name: resolver.response.responses(node)
1621
1687
  });
1622
1688
  function buildResponseType() {
1623
1689
  const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
1624
1690
  if (!node.responses.some(hasSchema)) return null;
1625
- const responseName = resolver.resolveResponseName(node);
1691
+ const responseName = resolver.response.response(node);
1626
1692
  const responsesWithSchema = node.responses.filter(hasSchema);
1627
1693
  if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1628
1694
  name: resolveImportName(schemaName),
@@ -1641,7 +1707,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1641
1707
  baseName: meta.file.baseName,
1642
1708
  path: meta.file.path,
1643
1709
  meta: meta.file.meta,
1644
- banner: resolver.resolveBanner(ctx.meta, {
1710
+ banner: resolver.default.banner(ctx.meta, {
1645
1711
  output,
1646
1712
  config,
1647
1713
  file: {
@@ -1649,7 +1715,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1649
1715
  baseName: meta.file.baseName
1650
1716
  }
1651
1717
  }),
1652
- footer: resolver.resolveFooter(ctx.meta, {
1718
+ footer: resolver.default.footer(ctx.meta, {
1653
1719
  output,
1654
1720
  config,
1655
1721
  file: {
@@ -1658,10 +1724,10 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1658
1724
  }
1659
1725
  }),
1660
1726
  children: [
1661
- paramTypes,
1727
+ paramGroupTypes,
1662
1728
  responseTypes,
1663
1729
  requestType,
1664
- dataType,
1730
+ optionsType,
1665
1731
  responsesType,
1666
1732
  responseType
1667
1733
  ]
@@ -1676,64 +1742,61 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1676
1742
  * to reference the exact names `plugin-ts` produces without duplicating the
1677
1743
  * casing/file-layout rules.
1678
1744
  *
1679
- * The `default` method is supplied by `defineResolver`. It uses PascalCase for
1680
- * type names and PascalCase file paths (dotted names become `/`-joined) for files.
1745
+ * The `default` helpers are supplied by `createResolver`. This plugin overrides the top-level `name`
1746
+ * to use PascalCase for value and type names and `file` to write PascalCase file paths (dotted names
1747
+ * become `/`-joined), and groups the operation-specific naming under the `param`, `response`, and
1748
+ * `enum` namespaces.
1681
1749
  *
1682
1750
  * @example Resolve a type and file name
1683
1751
  * ```ts
1684
1752
  * import { resolverTs } from '@kubb/plugin-ts'
1685
1753
  *
1686
- * resolverTs.default('list pets', 'type') // 'ListPets'
1687
- * resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
1688
- * resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
1754
+ * resolverTs.name('list pets') // 'ListPets'
1755
+ * resolverTs.response.status(node, 200) // 'ListPetsStatus200'
1689
1756
  * ```
1690
1757
  */
1691
- const resolverTs = (0, kubb_kit.defineResolver)(() => {
1692
- return {
1693
- name: "default",
1694
- pluginName: "plugin-ts",
1695
- default(name, type) {
1696
- if (type === "file") return toFilePath(name, pascalCase);
1697
- return ensureValidVarName(pascalCase(name));
1698
- },
1699
- resolveTypeName(name) {
1700
- return ensureValidVarName(pascalCase(name));
1701
- },
1702
- resolvePathName(name, type) {
1703
- if (type === "file") return toFilePath(name, pascalCase);
1704
- return ensureValidVarName(pascalCase(name));
1705
- },
1706
- resolveParamName(node, param) {
1707
- return this.resolveTypeName(`${node.operationId} ${param.in} ${param.name}`);
1708
- },
1709
- resolveResponseStatusName(node, statusCode) {
1710
- return this.resolveTypeName(`${node.operationId} Status ${statusCode}`);
1711
- },
1712
- resolveDataName(node) {
1713
- return this.resolveTypeName(`${node.operationId} Data`);
1758
+ const resolverTs = (0, kubb_kit.createResolver)({
1759
+ pluginName: "plugin-ts",
1760
+ name(name) {
1761
+ return ensureValidVarName(pascalCase(name));
1762
+ },
1763
+ file: { baseName({ name, extname }) {
1764
+ return `${toFilePath(name, pascalCase)}${extname}`;
1765
+ } },
1766
+ param: {
1767
+ name(node, param) {
1768
+ return this.name(`${node.operationId} ${param.in} ${param.name}`);
1714
1769
  },
1715
- resolveRequestConfigName(node) {
1716
- return this.resolveTypeName(`${node.operationId} RequestConfig`);
1770
+ path(node) {
1771
+ return this.name(`${node.operationId} Path`);
1717
1772
  },
1718
- resolveResponsesName(node) {
1719
- return this.resolveTypeName(`${node.operationId} Responses`);
1773
+ query(node) {
1774
+ return this.name(`${node.operationId} Query`);
1720
1775
  },
1721
- resolveResponseName(node) {
1722
- return this.resolveTypeName(`${node.operationId} Response`);
1776
+ headers(node) {
1777
+ return this.name(`${node.operationId} Headers`);
1778
+ }
1779
+ },
1780
+ response: {
1781
+ status(node, statusCode) {
1782
+ return this.name(`${node.operationId} Status ${statusCode}`);
1723
1783
  },
1724
- resolveEnumKeyName(node, enumTypeSuffix = "key") {
1725
- return `${this.resolveTypeName(node.name ?? "")}${enumTypeSuffix}`;
1784
+ options(node) {
1785
+ return this.name(`${node.operationId} Options`);
1726
1786
  },
1727
- resolvePathParamsName(node, param) {
1728
- return this.resolveParamName(node, param);
1787
+ responses(node) {
1788
+ return this.name(`${node.operationId} Responses`);
1729
1789
  },
1730
- resolveQueryParamsName(node, param) {
1731
- return this.resolveParamName(node, param);
1790
+ response(node) {
1791
+ return this.name(`${node.operationId} Response`);
1732
1792
  },
1733
- resolveHeaderParamsName(node, param) {
1734
- return this.resolveParamName(node, param);
1793
+ body(node) {
1794
+ return this.name(`${node.operationId} Body`);
1735
1795
  }
1736
- };
1796
+ },
1797
+ enum: { keyName(node, enumTypeSuffix = "key") {
1798
+ return `${this.name(node.name ?? "")}${enumTypeSuffix}`;
1799
+ } }
1737
1800
  });
1738
1801
  //#endregion
1739
1802
  //#region src/plugin.ts
@@ -1794,10 +1857,7 @@ const pluginTs = (0, kubb_kit.definePlugin)((options) => {
1794
1857
  syntaxType,
1795
1858
  printer
1796
1859
  });
1797
- ctx.setResolver(userResolver ? {
1798
- ...resolverTs,
1799
- ...userResolver
1800
- } : resolverTs);
1860
+ ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverTs, userResolver) : resolverTs);
1801
1861
  if (userMacros?.length) ctx.setMacros(userMacros);
1802
1862
  ctx.addGenerator(typeGenerator);
1803
1863
  } }
@@ -2058,12 +2118,12 @@ function functionPrinter(options) {
2058
2118
  */
2059
2119
  function resolveParamType({ node, param, resolver }) {
2060
2120
  if (!resolver) return param.schema.primitive ?? "unknown";
2061
- const individualName = resolver.resolveParamName(node, param);
2121
+ const individualName = resolver.param.name(node, param);
2062
2122
  const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
2063
2123
  const groupResolvers = {
2064
- path: resolver.resolvePathParamsName,
2065
- query: resolver.resolveQueryParamsName,
2066
- header: resolver.resolveHeaderParamsName
2124
+ path: resolver.param.path,
2125
+ query: resolver.param.query,
2126
+ header: resolver.param.headers
2067
2127
  };
2068
2128
  const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
2069
2129
  if (groupName && groupName !== individualName) return createIndexedAccessType({
@@ -2081,8 +2141,8 @@ function resolveParamType({ node, param, resolver }) {
2081
2141
  function resolveGroupType({ node, params, group, resolver }) {
2082
2142
  if (!resolver || !params.length) return null;
2083
2143
  const firstParam = params[0];
2084
- const groupName = (group === "query" ? resolver.resolveQueryParamsName : resolver.resolveHeaderParamsName).call(resolver, node, firstParam);
2085
- if (groupName === resolver.resolveParamName(node, firstParam)) return null;
2144
+ const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
2145
+ if (groupName === resolver.param.name(node, firstParam)) return null;
2086
2146
  return {
2087
2147
  type: groupName,
2088
2148
  optional: params.every((p) => !p.required)
@@ -2118,7 +2178,7 @@ function createOperationParams(node, options) {
2118
2178
  optional: !param.required
2119
2179
  });
2120
2180
  const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
2121
- const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.resolveDataName(node) ?? "unknown") : void 0;
2181
+ const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
2122
2182
  const bodyProperty = bodyType ? [{
2123
2183
  name: dataName,
2124
2184
  type: bodyType,
@@ -2162,7 +2222,7 @@ function createOperationParams(node, options) {
2162
2222
  }));
2163
2223
  } else {
2164
2224
  if (pathParamsType === "inlineSpread" && pathParams.length) {
2165
- const spreadType = resolver?.resolvePathParamsName(node, pathParams[0]);
2225
+ const spreadType = resolver?.param.path(node, pathParams[0]);
2166
2226
  params.push(createFunctionParameter({
2167
2227
  name: pathName,
2168
2228
  type: spreadType ? wrapType(spreadType) : void 0,
@@ -2232,6 +2292,7 @@ function buildTypeLiteral({ node, params, resolver }) {
2232
2292
  //#endregion
2233
2293
  exports.Enum = Enum;
2234
2294
  exports.Type = Type;
2295
+ exports.buildParams = buildParams;
2235
2296
  exports.createFunctionParameter = createFunctionParameter;
2236
2297
  exports.createFunctionParameters = createFunctionParameters;
2237
2298
  exports.createIndexedAccessType = createIndexedAccessType;