@kubb/plugin-ts 5.0.0-beta.81 → 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,10 +1,9 @@
1
1
  import { n as __name, t as __exportAll } from "./rolldown-runtime-CNktS9qV.js";
2
- import { extractRefName, isStringType, jsStringEscape, mapSchemaItems, mapSchemaProperties, stringify, syncSchemaRef, trimQuotes } from "@kubb/ast/utils";
3
2
  import { parserTs } from "@kubb/parser-ts";
4
- import { File, jsxRenderer } from "@kubb/renderer-jsx";
3
+ import { File, jsxRenderer } from "kubb/jsx";
4
+ import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
5
5
  import ts from "typescript";
6
- import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
7
- import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
6
+ import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
8
7
  //#region ../../internals/utils/src/casing.ts
9
8
  /**
10
9
  * Shared implementation for camelCase and PascalCase conversion.
@@ -216,6 +215,67 @@ function ensureValidVarName(name) {
216
215
  return `_${name}`;
217
216
  }
218
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
219
279
  //#region src/constants.ts
220
280
  /**
221
281
  * `optionalType` values that cause a property's type to include `| undefined`.
@@ -756,7 +816,7 @@ function buildTupleNode(node, print) {
756
816
  */
757
817
  function buildPropertyType(schema, baseType, optionalType, optional) {
758
818
  const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
759
- const meta = syncSchemaRef(schema);
819
+ const meta = ast.syncSchemaRef(schema);
760
820
  let type = baseType;
761
821
  if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
762
822
  if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
@@ -800,10 +860,10 @@ function buildIndexSignatures(node, propertyCount, print) {
800
860
  * resolve to the same name, which TypeScript merges into a single value+type declaration.
801
861
  */
802
862
  function getEnumNames({ node, enum: enumOptions, resolver }) {
803
- const resolved = resolver.resolveTypeName(node.name);
863
+ const resolved = resolver.name(node.name);
804
864
  return {
805
865
  enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
806
- 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
807
867
  };
808
868
  }
809
869
  /**
@@ -1002,7 +1062,7 @@ function isSchemaOptional(schema) {
1002
1062
  return Boolean("optional" in schema && schema.optional || "nullish" in schema && schema.nullish);
1003
1063
  }
1004
1064
  function buildPropertyJSDocComments(schema, optional) {
1005
- const meta = syncSchemaRef(schema);
1065
+ const meta = ast.syncSchemaRef(schema);
1006
1066
  const isArray = meta?.primitive === "array";
1007
1067
  const hasDescription = meta && "description" in meta && meta.description;
1008
1068
  const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
@@ -1019,21 +1079,25 @@ function buildPropertyJSDocComments(schema, optional) {
1019
1079
  meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
1020
1080
  ].filter(Boolean);
1021
1081
  }
1022
- 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 }) {
1023
1088
  return ast.factory.createSchema({
1024
1089
  type: "object",
1025
1090
  properties: params.map((param) => ast.factory.createProperty({
1026
1091
  name: param.name,
1027
1092
  required: param.required,
1028
1093
  schema: ast.factory.createSchema({
1029
- type: "ref",
1030
- name: resolver.resolveParamName(node, param),
1094
+ ...param.schema,
1031
1095
  optional: !param.required
1032
1096
  })
1033
1097
  }))
1034
1098
  });
1035
1099
  }
1036
- function buildData(node, { resolver }) {
1100
+ function buildOptions(node, { resolver }) {
1037
1101
  const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing: "original" });
1038
1102
  const hasBody = Boolean(node.requestBody?.content?.[0]?.schema);
1039
1103
  const hasRequiredPath = pathParams.some((param) => param.required);
@@ -1048,7 +1112,7 @@ function buildData(node, { resolver }) {
1048
1112
  required: hasBody,
1049
1113
  schema: hasBody ? ast.factory.createSchema({
1050
1114
  type: "ref",
1051
- name: resolver.resolveDataName(node)
1115
+ name: resolver.response.body(node)
1052
1116
  }) : ast.factory.createSchema({
1053
1117
  type: "never",
1054
1118
  primitive: void 0,
@@ -1059,10 +1123,8 @@ function buildData(node, { resolver }) {
1059
1123
  name: "path",
1060
1124
  required: hasRequiredPath,
1061
1125
  schema: pathParams.length > 0 ? ast.factory.createSchema({
1062
- ...buildParams(node, {
1063
- params: pathParams,
1064
- resolver
1065
- }),
1126
+ type: "ref",
1127
+ name: resolver.param.path(node, pathParams[0]),
1066
1128
  optional: !hasRequiredPath
1067
1129
  }) : ast.factory.createSchema({
1068
1130
  type: "never",
@@ -1074,10 +1136,8 @@ function buildData(node, { resolver }) {
1074
1136
  name: "query",
1075
1137
  required: hasRequiredQuery,
1076
1138
  schema: queryParams.length > 0 ? ast.factory.createSchema({
1077
- ...buildParams(node, {
1078
- params: queryParams,
1079
- resolver
1080
- }),
1139
+ type: "ref",
1140
+ name: resolver.param.query(node, queryParams[0]),
1081
1141
  optional: !hasRequiredQuery
1082
1142
  }) : ast.factory.createSchema({
1083
1143
  type: "never",
@@ -1089,10 +1149,8 @@ function buildData(node, { resolver }) {
1089
1149
  name: "headers",
1090
1150
  required: hasRequiredHeader,
1091
1151
  schema: headerParams.length > 0 ? ast.factory.createSchema({
1092
- ...buildParams(node, {
1093
- params: headerParams,
1094
- resolver
1095
- }),
1152
+ type: "ref",
1153
+ name: resolver.param.headers(node, headerParams[0]),
1096
1154
  optional: !hasRequiredHeader
1097
1155
  }) : ast.factory.createSchema({
1098
1156
  type: "never",
@@ -1110,7 +1168,7 @@ function buildData(node, { resolver }) {
1110
1168
  * query hooks and `result.data` use.
1111
1169
  */
1112
1170
  function buildResponseRecordEntry(node, res, resolver) {
1113
- const statusName = resolver.resolveResponseStatusName(node, res.statusCode);
1171
+ const statusName = resolver.response.status(node, res.statusCode);
1114
1172
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1115
1173
  if (variants.length <= 1) return ast.factory.createSchema({
1116
1174
  type: "ref",
@@ -1155,7 +1213,7 @@ function buildResponseUnion(node, { resolver }) {
1155
1213
  type: "union",
1156
1214
  members: responsesWithSchema.map((res) => ast.factory.createSchema({
1157
1215
  type: "ref",
1158
- name: resolver.resolveResponseStatusName(node, res.statusCode)
1216
+ name: resolver.response.status(node, res.statusCode)
1159
1217
  }))
1160
1218
  });
1161
1219
  }
@@ -1248,8 +1306,8 @@ const printerTs = ast.createPrinter((options) => {
1248
1306
  time: dateOrStringNode,
1249
1307
  ref(node) {
1250
1308
  if (!node.name) return null;
1251
- const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? extractRefName(node.ref) ?? node.name : node.name;
1252
- 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);
1309
+ const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? ast.extractRefName(node.ref) ?? node.name : node.name;
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);
1253
1311
  },
1254
1312
  enum(node) {
1255
1313
  const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
@@ -1257,18 +1315,18 @@ const printerTs = ast.createPrinter((options) => {
1257
1315
  withParentheses: true,
1258
1316
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1259
1317
  }) ?? void 0;
1260
- 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);
1261
1319
  },
1262
1320
  union(node) {
1263
1321
  const members = node.members ?? [];
1264
1322
  const hasStringLiteral = members.some((m) => {
1265
1323
  return ast.narrowSchema(m, ast.schemaTypes.enum)?.primitive === "string";
1266
1324
  });
1267
- const hasPlainString = members.some((m) => isStringType(m));
1325
+ const hasPlainString = members.some((m) => ast.isStringType(m));
1268
1326
  if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
1269
1327
  withParentheses: true,
1270
1328
  nodes: members.map((m) => {
1271
- if (isStringType(m)) return createIntersectionDeclaration({
1329
+ if (ast.isStringType(m)) return createIntersectionDeclaration({
1272
1330
  nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
1273
1331
  withParentheses: true
1274
1332
  });
@@ -1288,7 +1346,7 @@ const printerTs = ast.createPrinter((options) => {
1288
1346
  },
1289
1347
  array(node) {
1290
1348
  return createArrayDeclaration({
1291
- nodes: mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
1349
+ nodes: ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
1292
1350
  arrayType: this.options.arrayType
1293
1351
  }) ?? null;
1294
1352
  },
@@ -1298,11 +1356,11 @@ const printerTs = ast.createPrinter((options) => {
1298
1356
  object(node) {
1299
1357
  const { transform, options } = this;
1300
1358
  const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
1301
- const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
1359
+ const propertyNodes = ast.mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
1302
1360
  const baseType = output ?? keywordTypeNodes.unknown;
1303
1361
  const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
1304
1362
  const type = buildPropertyType(property.schema, baseType, options.optionalType, optional);
1305
- const propMeta = syncSchemaRef(property.schema);
1363
+ const propMeta = ast.syncSchemaRef(property.schema);
1306
1364
  return appendJSDocToNode({
1307
1365
  node: createPropertySignature({
1308
1366
  questionToken: optional ? addsQuestionToken : false,
@@ -1323,7 +1381,7 @@ const printerTs = ast.createPrinter((options) => {
1323
1381
  const { name, syntaxType = "type", description, keysToOmit } = this.options;
1324
1382
  const transformed = this.transform(node);
1325
1383
  if (!transformed) return null;
1326
- const meta = syncSchemaRef(node);
1384
+ const meta = ast.syncSchemaRef(node);
1327
1385
  if (!name) {
1328
1386
  const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
1329
1387
  const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
@@ -1369,15 +1427,14 @@ const typeGenerator = defineGenerator({
1369
1427
  if (!node.name) return;
1370
1428
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1371
1429
  function resolveImportName(schemaName) {
1372
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumOptions.typeSuffix);
1373
- 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);
1374
1432
  }
1375
1433
  const imports = adapter.getImports(node, (schemaName) => ({
1376
1434
  name: resolveImportName(schemaName),
1377
- path: resolver.resolveFile({
1435
+ path: resolver.file({
1378
1436
  name: schemaName,
1379
- extname: ".ts"
1380
- }, {
1437
+ extname: ".ts",
1381
1438
  root,
1382
1439
  output,
1383
1440
  group: group ?? void 0
@@ -1386,11 +1443,10 @@ const typeGenerator = defineGenerator({
1386
1443
  const enumNode = ast.narrowSchema(node, ast.schemaTypes.enum);
1387
1444
  const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1388
1445
  const meta = {
1389
- name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolver.resolveTypeName(node.name),
1390
- 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({
1391
1448
  name: node.name,
1392
- extname: ".ts"
1393
- }, {
1449
+ extname: ".ts",
1394
1450
  root,
1395
1451
  output,
1396
1452
  group: group ?? void 0
@@ -1412,7 +1468,7 @@ const typeGenerator = defineGenerator({
1412
1468
  baseName: meta.file.baseName,
1413
1469
  path: meta.file.path,
1414
1470
  meta: meta.file.meta,
1415
- banner: resolver.resolveBanner(ctx.meta, {
1471
+ banner: resolver.default.banner(ctx.meta, {
1416
1472
  output,
1417
1473
  config,
1418
1474
  file: {
@@ -1420,7 +1476,7 @@ const typeGenerator = defineGenerator({
1420
1476
  baseName: meta.file.baseName
1421
1477
  }
1422
1478
  }),
1423
- footer: resolver.resolveFooter(ctx.meta, {
1479
+ footer: resolver.default.footer(ctx.meta, {
1424
1480
  output,
1425
1481
  config,
1426
1482
  file: {
@@ -1450,29 +1506,27 @@ const typeGenerator = defineGenerator({
1450
1506
  const { enum: enumOptions, optionalType, arrayType, syntaxType, group, output, printer } = ctx.options;
1451
1507
  const { adapter, config, resolver, root } = ctx;
1452
1508
  const params = caseParams(node.parameters, "camelcase");
1453
- const meta = { file: resolver.resolveFile({
1509
+ const meta = { file: resolver.file({
1454
1510
  name: node.operationId,
1455
1511
  extname: ".ts",
1456
1512
  tag: node.tags[0] ?? "default",
1457
- path: node.path
1458
- }, {
1513
+ path: node.path,
1459
1514
  root,
1460
1515
  output,
1461
1516
  group: group ?? void 0
1462
1517
  }) };
1463
1518
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1464
1519
  function resolveImportName(schemaName) {
1465
- if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumOptions.typeSuffix);
1466
- 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);
1467
1522
  }
1468
1523
  function renderSchemaType({ schema, name, keysToOmit }) {
1469
1524
  if (!schema) return null;
1470
1525
  const imports = adapter.getImports(schema, (schemaName) => ({
1471
1526
  name: resolveImportName(schemaName),
1472
- path: resolver.resolveFile({
1527
+ path: resolver.file({
1473
1528
  name: schemaName,
1474
- extname: ".ts"
1475
- }, {
1529
+ extname: ".ts",
1476
1530
  root,
1477
1531
  output,
1478
1532
  group: group ?? void 0
@@ -1532,13 +1586,24 @@ const typeGenerator = defineGenerator({
1532
1586
  name: baseName
1533
1587
  })] });
1534
1588
  }
1535
- const paramTypes = params.map((param) => renderSchemaType({
1536
- schema: {
1537
- ...param.schema,
1538
- optional: !param.required
1539
- },
1540
- name: resolver.resolveParamName(node, param)
1541
- }));
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
+ ];
1542
1607
  const requestBodyContent = node.requestBody?.content ?? [];
1543
1608
  function buildRequestType() {
1544
1609
  if (requestBodyContent.length === 0) return null;
@@ -1550,11 +1615,11 @@ const typeGenerator = defineGenerator({
1550
1615
  ...entry.schema,
1551
1616
  description: node.requestBody.description ?? entry.schema.description
1552
1617
  },
1553
- name: resolver.resolveDataName(node),
1618
+ name: resolver.response.body(node),
1554
1619
  keysToOmit: entry.keysToOmit
1555
1620
  });
1556
1621
  }
1557
- return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
1622
+ return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1558
1623
  ...schema,
1559
1624
  description: node.requestBody.description ?? schema.description
1560
1625
  }));
@@ -1562,29 +1627,29 @@ const typeGenerator = defineGenerator({
1562
1627
  const requestType = buildRequestType();
1563
1628
  const responseTypes = node.responses.map((res) => {
1564
1629
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1565
- 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));
1566
1631
  const primary = variants[0] ?? res.content?.[0];
1567
1632
  return renderSchemaType({
1568
1633
  schema: primary?.schema ?? null,
1569
- name: resolver.resolveResponseStatusName(node, res.statusCode),
1634
+ name: resolver.response.status(node, res.statusCode),
1570
1635
  keysToOmit: primary?.keysToOmit
1571
1636
  });
1572
1637
  });
1573
- const dataType = renderSchemaType({
1574
- schema: buildData({
1638
+ const optionsType = renderSchemaType({
1639
+ schema: buildOptions({
1575
1640
  ...node,
1576
1641
  parameters: params
1577
1642
  }, { resolver }),
1578
- name: resolver.resolveRequestConfigName(node)
1643
+ name: resolver.response.options(node)
1579
1644
  });
1580
1645
  const responsesType = renderSchemaType({
1581
1646
  schema: buildResponses(node, { resolver }),
1582
- name: resolver.resolveResponsesName(node)
1647
+ name: resolver.response.responses(node)
1583
1648
  });
1584
1649
  function buildResponseType() {
1585
1650
  const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
1586
1651
  if (!node.responses.some(hasSchema)) return null;
1587
- const responseName = resolver.resolveResponseName(node);
1652
+ const responseName = resolver.response.response(node);
1588
1653
  const responsesWithSchema = node.responses.filter(hasSchema);
1589
1654
  if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1590
1655
  name: resolveImportName(schemaName),
@@ -1603,7 +1668,7 @@ const typeGenerator = defineGenerator({
1603
1668
  baseName: meta.file.baseName,
1604
1669
  path: meta.file.path,
1605
1670
  meta: meta.file.meta,
1606
- banner: resolver.resolveBanner(ctx.meta, {
1671
+ banner: resolver.default.banner(ctx.meta, {
1607
1672
  output,
1608
1673
  config,
1609
1674
  file: {
@@ -1611,7 +1676,7 @@ const typeGenerator = defineGenerator({
1611
1676
  baseName: meta.file.baseName
1612
1677
  }
1613
1678
  }),
1614
- footer: resolver.resolveFooter(ctx.meta, {
1679
+ footer: resolver.default.footer(ctx.meta, {
1615
1680
  output,
1616
1681
  config,
1617
1682
  file: {
@@ -1620,10 +1685,10 @@ const typeGenerator = defineGenerator({
1620
1685
  }
1621
1686
  }),
1622
1687
  children: [
1623
- paramTypes,
1688
+ paramGroupTypes,
1624
1689
  responseTypes,
1625
1690
  requestType,
1626
- dataType,
1691
+ optionsType,
1627
1692
  responsesType,
1628
1693
  responseType
1629
1694
  ]
@@ -1638,64 +1703,61 @@ const typeGenerator = defineGenerator({
1638
1703
  * to reference the exact names `plugin-ts` produces without duplicating the
1639
1704
  * casing/file-layout rules.
1640
1705
  *
1641
- * The `default` method is supplied by `defineResolver`. It uses PascalCase for
1642
- * 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.
1643
1710
  *
1644
1711
  * @example Resolve a type and file name
1645
1712
  * ```ts
1646
1713
  * import { resolverTs } from '@kubb/plugin-ts'
1647
1714
  *
1648
- * resolverTs.default('list pets', 'type') // 'ListPets'
1649
- * resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
1650
- * resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
1715
+ * resolverTs.name('list pets') // 'ListPets'
1716
+ * resolverTs.response.status(node, 200) // 'ListPetsStatus200'
1651
1717
  * ```
1652
1718
  */
1653
- const resolverTs = defineResolver(() => {
1654
- return {
1655
- name: "default",
1656
- pluginName: "plugin-ts",
1657
- default(name, type) {
1658
- if (type === "file") return toFilePath(name, pascalCase);
1659
- return ensureValidVarName(pascalCase(name));
1660
- },
1661
- resolveTypeName(name) {
1662
- return ensureValidVarName(pascalCase(name));
1663
- },
1664
- resolvePathName(name, type) {
1665
- if (type === "file") return toFilePath(name, pascalCase);
1666
- return ensureValidVarName(pascalCase(name));
1667
- },
1668
- resolveParamName(node, param) {
1669
- return this.resolveTypeName(`${node.operationId} ${param.in} ${param.name}`);
1670
- },
1671
- resolveResponseStatusName(node, statusCode) {
1672
- return this.resolveTypeName(`${node.operationId} Status ${statusCode}`);
1673
- },
1674
- resolveDataName(node) {
1675
- 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}`);
1676
1730
  },
1677
- resolveRequestConfigName(node) {
1678
- return this.resolveTypeName(`${node.operationId} RequestConfig`);
1731
+ path(node) {
1732
+ return this.name(`${node.operationId} Path`);
1679
1733
  },
1680
- resolveResponsesName(node) {
1681
- return this.resolveTypeName(`${node.operationId} Responses`);
1734
+ query(node) {
1735
+ return this.name(`${node.operationId} Query`);
1682
1736
  },
1683
- resolveResponseName(node) {
1684
- 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}`);
1685
1744
  },
1686
- resolveEnumKeyName(node, enumTypeSuffix = "key") {
1687
- return `${this.resolveTypeName(node.name ?? "")}${enumTypeSuffix}`;
1745
+ options(node) {
1746
+ return this.name(`${node.operationId} Options`);
1688
1747
  },
1689
- resolvePathParamsName(node, param) {
1690
- return this.resolveParamName(node, param);
1748
+ responses(node) {
1749
+ return this.name(`${node.operationId} Responses`);
1691
1750
  },
1692
- resolveQueryParamsName(node, param) {
1693
- return this.resolveParamName(node, param);
1751
+ response(node) {
1752
+ return this.name(`${node.operationId} Response`);
1694
1753
  },
1695
- resolveHeaderParamsName(node, param) {
1696
- return this.resolveParamName(node, param);
1754
+ body(node) {
1755
+ return this.name(`${node.operationId} Body`);
1697
1756
  }
1698
- };
1757
+ },
1758
+ enum: { keyName(node, enumTypeSuffix = "key") {
1759
+ return `${this.name(node.name ?? "")}${enumTypeSuffix}`;
1760
+ } }
1699
1761
  });
1700
1762
  //#endregion
1701
1763
  //#region src/plugin.ts
@@ -1712,7 +1774,7 @@ const pluginTsName = "plugin-ts";
1712
1774
  *
1713
1775
  * @example
1714
1776
  * ```ts
1715
- * import { defineConfig } from 'kubb'
1777
+ * import { defineConfig } from 'kubb/config'
1716
1778
  * import { pluginTs } from '@kubb/plugin-ts'
1717
1779
  *
1718
1780
  * export default defineConfig({
@@ -1756,10 +1818,7 @@ const pluginTs = definePlugin((options) => {
1756
1818
  syntaxType,
1757
1819
  printer
1758
1820
  });
1759
- ctx.setResolver(userResolver ? {
1760
- ...resolverTs,
1761
- ...userResolver
1762
- } : resolverTs);
1821
+ ctx.setResolver(userResolver ? Resolver.merge(resolverTs, userResolver) : resolverTs);
1763
1822
  if (userMacros?.length) ctx.setMacros(userMacros);
1764
1823
  ctx.addGenerator(typeGenerator);
1765
1824
  } }
@@ -2020,12 +2079,12 @@ function functionPrinter(options) {
2020
2079
  */
2021
2080
  function resolveParamType({ node, param, resolver }) {
2022
2081
  if (!resolver) return param.schema.primitive ?? "unknown";
2023
- const individualName = resolver.resolveParamName(node, param);
2082
+ const individualName = resolver.param.name(node, param);
2024
2083
  const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
2025
2084
  const groupResolvers = {
2026
- path: resolver.resolvePathParamsName,
2027
- query: resolver.resolveQueryParamsName,
2028
- header: resolver.resolveHeaderParamsName
2085
+ path: resolver.param.path,
2086
+ query: resolver.param.query,
2087
+ header: resolver.param.headers
2029
2088
  };
2030
2089
  const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
2031
2090
  if (groupName && groupName !== individualName) return createIndexedAccessType({
@@ -2043,8 +2102,8 @@ function resolveParamType({ node, param, resolver }) {
2043
2102
  function resolveGroupType({ node, params, group, resolver }) {
2044
2103
  if (!resolver || !params.length) return null;
2045
2104
  const firstParam = params[0];
2046
- const groupName = (group === "query" ? resolver.resolveQueryParamsName : resolver.resolveHeaderParamsName).call(resolver, node, firstParam);
2047
- 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;
2048
2107
  return {
2049
2108
  type: groupName,
2050
2109
  optional: params.every((p) => !p.required)
@@ -2080,7 +2139,7 @@ function createOperationParams(node, options) {
2080
2139
  optional: !param.required
2081
2140
  });
2082
2141
  const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
2083
- 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;
2084
2143
  const bodyProperty = bodyType ? [{
2085
2144
  name: dataName,
2086
2145
  type: bodyType,
@@ -2124,7 +2183,7 @@ function createOperationParams(node, options) {
2124
2183
  }));
2125
2184
  } else {
2126
2185
  if (pathParamsType === "inlineSpread" && pathParams.length) {
2127
- const spreadType = resolver?.resolvePathParamsName(node, pathParams[0]);
2186
+ const spreadType = resolver?.param.path(node, pathParams[0]);
2128
2187
  params.push(createFunctionParameter({
2129
2188
  name: pathName,
2130
2189
  type: spreadType ? wrapType(spreadType) : void 0,
@@ -2192,6 +2251,6 @@ function buildTypeLiteral({ node, params, resolver }) {
2192
2251
  })) });
2193
2252
  }
2194
2253
  //#endregion
2195
- 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 };
2196
2255
 
2197
2256
  //# sourceMappingURL=index.js.map