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

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");
@@ -231,7 +231,7 @@ const reservedWords = /* @__PURE__ */ new Set([
231
231
  */
232
232
  function isValidVarName(name) {
233
233
  if (!name || reservedWords.has(name)) return false;
234
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
234
+ return isIdentifier(name);
235
235
  }
236
236
  /**
237
237
  * Returns `name` when it's a syntactically valid JavaScript variable name,
@@ -253,6 +253,83 @@ function ensureValidVarName(name) {
253
253
  if (!name || isValidVarName(name)) return name;
254
254
  return `_${name}`;
255
255
  }
256
+ /**
257
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
258
+ *
259
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
260
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
261
+ * deciding whether an object key needs quoting.
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * isIdentifier('name') // true
266
+ * isIdentifier('x-total')// false
267
+ * ```
268
+ */
269
+ function isIdentifier(name) {
270
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
271
+ }
272
+ //#endregion
273
+ //#region ../../internals/utils/src/strings.ts
274
+ /**
275
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
276
+ * Returns the string unchanged when no balanced quote pair is found.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * trimQuotes('"hello"') // 'hello'
281
+ * trimQuotes('hello') // 'hello'
282
+ * ```
283
+ */
284
+ function trimQuotes(text) {
285
+ if (text.length >= 2) {
286
+ const first = text[0];
287
+ const last = text[text.length - 1];
288
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
289
+ }
290
+ return text;
291
+ }
292
+ /**
293
+ * Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
294
+ *
295
+ * Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
296
+ * code matches the repo style without a formatter.
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * stringify('hello') // "'hello'"
301
+ * stringify('"hello"') // "'hello'"
302
+ * ```
303
+ */
304
+ function stringify(value) {
305
+ if (value === void 0 || value === null) return "''";
306
+ return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
307
+ }
308
+ /**
309
+ * Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
310
+ * and the Unicode line terminators U+2028 and U+2029.
311
+ *
312
+ * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
313
+ *
314
+ * @example
315
+ * ```ts
316
+ * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
317
+ * ```
318
+ */
319
+ function jsStringEscape(input) {
320
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
321
+ switch (character) {
322
+ case "\"":
323
+ case "'":
324
+ case "\\": return `\\${character}`;
325
+ case "\n": return "\\n";
326
+ case "\r": return "\\r";
327
+ case "\u2028": return "\\u2028";
328
+ case "\u2029": return "\\u2029";
329
+ default: return "";
330
+ }
331
+ });
332
+ }
256
333
  //#endregion
257
334
  //#region src/constants.ts
258
335
  /**
@@ -838,10 +915,10 @@ function buildIndexSignatures(node, propertyCount, print) {
838
915
  * resolve to the same name, which TypeScript merges into a single value+type declaration.
839
916
  */
840
917
  function getEnumNames({ node, enum: enumOptions, resolver }) {
841
- const resolved = resolver.resolveTypeName(node.name);
918
+ const resolved = resolver.name(node.name);
842
919
  return {
843
920
  enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
844
- typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.resolveEnumKeyName(node, enumOptions.typeSuffix) : resolved
921
+ typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
845
922
  };
846
923
  }
847
924
  /**
@@ -865,10 +942,10 @@ function Enum({ node, enum: enumOptions, resolver }) {
865
942
  name: enumName,
866
943
  typeName,
867
944
  enums: node.namedEnumValues?.map((v) => [
868
- kubb_kit.ast.trimQuotes(v.name.toString()),
945
+ trimQuotes(v.name.toString()),
869
946
  v.value,
870
947
  v.description
871
- ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [kubb_kit.ast.trimQuotes(v.toString()), v]) ?? [],
948
+ ]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
872
949
  type: enumOptions.type,
873
950
  enumKeyCasing: enumOptions.keyCasing
874
951
  });
@@ -1046,32 +1123,36 @@ function buildPropertyJSDocComments(schema, optional) {
1046
1123
  const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
1047
1124
  const exampleValues = meta?.examples ?? [];
1048
1125
  return [
1049
- hasDescription ? `@description ${kubb_kit.ast.jsStringEscape(meta.description)}` : null,
1126
+ hasDescription ? `@description ${jsStringEscape(meta.description)}` : null,
1050
1127
  ...formatComment,
1051
1128
  meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : null,
1052
1129
  !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
1053
1130
  !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
1054
1131
  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,
1132
+ meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
1056
1133
  ...exampleValues.map((example) => `@example ${example}`),
1057
1134
  meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
1058
1135
  ].filter(Boolean);
1059
1136
  }
1060
- function buildParams(node, { params, resolver }) {
1137
+ /**
1138
+ * Builds the object schema for a group of parameters sharing one `in` location (path, query, or
1139
+ * header), embedding each param's own schema (and JSDoc) directly rather than referencing a
1140
+ * separate per-param type — the group itself is the only type these params get exported as.
1141
+ */
1142
+ function buildParams({ params }) {
1061
1143
  return kubb_kit.ast.factory.createSchema({
1062
1144
  type: "object",
1063
1145
  properties: params.map((param) => kubb_kit.ast.factory.createProperty({
1064
1146
  name: param.name,
1065
1147
  required: param.required,
1066
1148
  schema: kubb_kit.ast.factory.createSchema({
1067
- type: "ref",
1068
- name: resolver.resolveParamName(node, param),
1149
+ ...param.schema,
1069
1150
  optional: !param.required
1070
1151
  })
1071
1152
  }))
1072
1153
  });
1073
1154
  }
1074
- function buildData(node, { resolver }) {
1155
+ function buildOptions(node, { resolver }) {
1075
1156
  const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing: "original" });
1076
1157
  const hasBody = Boolean(node.requestBody?.content?.[0]?.schema);
1077
1158
  const hasRequiredPath = pathParams.some((param) => param.required);
@@ -1086,7 +1167,7 @@ function buildData(node, { resolver }) {
1086
1167
  required: hasBody,
1087
1168
  schema: hasBody ? kubb_kit.ast.factory.createSchema({
1088
1169
  type: "ref",
1089
- name: resolver.resolveDataName(node)
1170
+ name: resolver.response.body(node)
1090
1171
  }) : kubb_kit.ast.factory.createSchema({
1091
1172
  type: "never",
1092
1173
  primitive: void 0,
@@ -1097,10 +1178,8 @@ function buildData(node, { resolver }) {
1097
1178
  name: "path",
1098
1179
  required: hasRequiredPath,
1099
1180
  schema: pathParams.length > 0 ? kubb_kit.ast.factory.createSchema({
1100
- ...buildParams(node, {
1101
- params: pathParams,
1102
- resolver
1103
- }),
1181
+ type: "ref",
1182
+ name: resolver.param.path(node, pathParams[0]),
1104
1183
  optional: !hasRequiredPath
1105
1184
  }) : kubb_kit.ast.factory.createSchema({
1106
1185
  type: "never",
@@ -1112,10 +1191,8 @@ function buildData(node, { resolver }) {
1112
1191
  name: "query",
1113
1192
  required: hasRequiredQuery,
1114
1193
  schema: queryParams.length > 0 ? kubb_kit.ast.factory.createSchema({
1115
- ...buildParams(node, {
1116
- params: queryParams,
1117
- resolver
1118
- }),
1194
+ type: "ref",
1195
+ name: resolver.param.query(node, queryParams[0]),
1119
1196
  optional: !hasRequiredQuery
1120
1197
  }) : kubb_kit.ast.factory.createSchema({
1121
1198
  type: "never",
@@ -1127,10 +1204,8 @@ function buildData(node, { resolver }) {
1127
1204
  name: "headers",
1128
1205
  required: hasRequiredHeader,
1129
1206
  schema: headerParams.length > 0 ? kubb_kit.ast.factory.createSchema({
1130
- ...buildParams(node, {
1131
- params: headerParams,
1132
- resolver
1133
- }),
1207
+ type: "ref",
1208
+ name: resolver.param.headers(node, headerParams[0]),
1134
1209
  optional: !hasRequiredHeader
1135
1210
  }) : kubb_kit.ast.factory.createSchema({
1136
1211
  type: "never",
@@ -1148,7 +1223,7 @@ function buildData(node, { resolver }) {
1148
1223
  * query hooks and `result.data` use.
1149
1224
  */
1150
1225
  function buildResponseRecordEntry(node, res, resolver) {
1151
- const statusName = resolver.resolveResponseStatusName(node, res.statusCode);
1226
+ const statusName = resolver.response.status(node, res.statusCode);
1152
1227
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1153
1228
  if (variants.length <= 1) return kubb_kit.ast.factory.createSchema({
1154
1229
  type: "ref",
@@ -1193,7 +1268,7 @@ function buildResponseUnion(node, { resolver }) {
1193
1268
  type: "union",
1194
1269
  members: responsesWithSchema.map((res) => kubb_kit.ast.factory.createSchema({
1195
1270
  type: "ref",
1196
- name: resolver.resolveResponseStatusName(node, res.statusCode)
1271
+ name: resolver.response.status(node, res.statusCode)
1197
1272
  }))
1198
1273
  });
1199
1274
  }
@@ -1287,7 +1362,7 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1287
1362
  ref(node) {
1288
1363
  if (!node.name) return null;
1289
1364
  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);
1365
+ 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
1366
  },
1292
1367
  enum(node) {
1293
1368
  const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
@@ -1295,7 +1370,7 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1295
1370
  withParentheses: true,
1296
1371
  nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
1297
1372
  }) ?? 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);
1373
+ 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
1374
  },
1300
1375
  union(node) {
1301
1376
  const members = node.members ?? [];
@@ -1393,6 +1468,15 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
1393
1468
  //#endregion
1394
1469
  //#region src/generators/typeGenerator.tsx
1395
1470
  /**
1471
+ * Resolves the imported type name for a referenced schema. An enum schema emitted
1472
+ * as a `const` object imports its suffixed key alias (e.g. `StatusKey`); every other
1473
+ * schema imports its plain resolved name.
1474
+ */
1475
+ function resolveImportName({ schemaName, enumOptions, enumSchemaNames, resolver }) {
1476
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
1477
+ return resolver.name(schemaName);
1478
+ }
1479
+ /**
1396
1480
  * Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
1397
1481
  * schema in the spec plus per-operation request, response, and parameter
1398
1482
  * types. Drop-replace with a custom `Generator<PluginTs>` to change how
@@ -1406,16 +1490,16 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1406
1490
  const { adapter, config, resolver, root } = ctx;
1407
1491
  if (!node.name) return;
1408
1492
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1409
- 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);
1412
- }
1413
1493
  const imports = adapter.getImports(node, (schemaName) => ({
1414
- name: resolveImportName(schemaName),
1415
- path: resolver.resolveFile({
1494
+ name: resolveImportName({
1495
+ schemaName,
1496
+ enumOptions,
1497
+ enumSchemaNames,
1498
+ resolver
1499
+ }),
1500
+ path: resolver.file({
1416
1501
  name: schemaName,
1417
- extname: ".ts"
1418
- }, {
1502
+ extname: ".ts",
1419
1503
  root,
1420
1504
  output,
1421
1505
  group: group ?? void 0
@@ -1424,11 +1508,10 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1424
1508
  const enumNode = kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
1425
1509
  const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
1426
1510
  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({
1511
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
1512
+ file: resolver.file({
1429
1513
  name: node.name,
1430
- extname: ".ts"
1431
- }, {
1514
+ extname: ".ts",
1432
1515
  root,
1433
1516
  output,
1434
1517
  group: group ?? void 0
@@ -1450,7 +1533,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1450
1533
  baseName: meta.file.baseName,
1451
1534
  path: meta.file.path,
1452
1535
  meta: meta.file.meta,
1453
- banner: resolver.resolveBanner(ctx.meta, {
1536
+ banner: resolver.default.banner(ctx.meta, {
1454
1537
  output,
1455
1538
  config,
1456
1539
  file: {
@@ -1458,7 +1541,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1458
1541
  baseName: meta.file.baseName
1459
1542
  }
1460
1543
  }),
1461
- footer: resolver.resolveFooter(ctx.meta, {
1544
+ footer: resolver.default.footer(ctx.meta, {
1462
1545
  output,
1463
1546
  config,
1464
1547
  file: {
@@ -1488,29 +1571,28 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1488
1571
  const { enum: enumOptions, optionalType, arrayType, syntaxType, group, output, printer } = ctx.options;
1489
1572
  const { adapter, config, resolver, root } = ctx;
1490
1573
  const params = caseParams(node.parameters, "camelcase");
1491
- const meta = { file: resolver.resolveFile({
1574
+ const meta = { file: resolver.file({
1492
1575
  name: node.operationId,
1493
1576
  extname: ".ts",
1494
1577
  tag: node.tags[0] ?? "default",
1495
- path: node.path
1496
- }, {
1578
+ path: node.path,
1497
1579
  root,
1498
1580
  output,
1499
1581
  group: group ?? void 0
1500
1582
  }) };
1501
1583
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1502
- 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);
1505
- }
1506
1584
  function renderSchemaType({ schema, name, keysToOmit }) {
1507
1585
  if (!schema) return null;
1508
1586
  const imports = adapter.getImports(schema, (schemaName) => ({
1509
- name: resolveImportName(schemaName),
1510
- path: resolver.resolveFile({
1587
+ name: resolveImportName({
1588
+ schemaName,
1589
+ enumOptions,
1590
+ enumSchemaNames,
1591
+ resolver
1592
+ }),
1593
+ path: resolver.file({
1511
1594
  name: schemaName,
1512
- extname: ".ts"
1513
- }, {
1595
+ extname: ".ts",
1514
1596
  root,
1515
1597
  output,
1516
1598
  group: group ?? void 0
@@ -1570,13 +1652,24 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1570
1652
  name: baseName
1571
1653
  })] });
1572
1654
  }
1573
- const paramTypes = params.map((param) => renderSchemaType({
1574
- schema: {
1575
- ...param.schema,
1576
- optional: !param.required
1577
- },
1578
- name: resolver.resolveParamName(node, param)
1579
- }));
1655
+ const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
1656
+ ...node,
1657
+ parameters: params
1658
+ }, { paramsCasing: "original" });
1659
+ const paramGroupTypes = [
1660
+ pathParams.length > 0 && renderSchemaType({
1661
+ schema: buildParams({ params: pathParams }),
1662
+ name: resolver.param.path(node, pathParams[0])
1663
+ }),
1664
+ queryParams.length > 0 && renderSchemaType({
1665
+ schema: buildParams({ params: queryParams }),
1666
+ name: resolver.param.query(node, queryParams[0])
1667
+ }),
1668
+ headerParams.length > 0 && renderSchemaType({
1669
+ schema: buildParams({ params: headerParams }),
1670
+ name: resolver.param.headers(node, headerParams[0])
1671
+ })
1672
+ ];
1580
1673
  const requestBodyContent = node.requestBody?.content ?? [];
1581
1674
  function buildRequestType() {
1582
1675
  if (requestBodyContent.length === 0) return null;
@@ -1588,11 +1681,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1588
1681
  ...entry.schema,
1589
1682
  description: node.requestBody.description ?? entry.schema.description
1590
1683
  },
1591
- name: resolver.resolveDataName(node),
1684
+ name: resolver.response.body(node),
1592
1685
  keysToOmit: entry.keysToOmit
1593
1686
  });
1594
1687
  }
1595
- return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
1688
+ return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
1596
1689
  ...schema,
1597
1690
  description: node.requestBody.description ?? schema.description
1598
1691
  }));
@@ -1600,32 +1693,37 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1600
1693
  const requestType = buildRequestType();
1601
1694
  const responseTypes = node.responses.map((res) => {
1602
1695
  const variants = (res.content ?? []).filter((entry) => entry.schema);
1603
- if (variants.length > 1) return buildContentTypeVariants(variants, resolver.resolveResponseStatusName(node, res.statusCode));
1696
+ if (variants.length > 1) return buildContentTypeVariants(variants, resolver.response.status(node, res.statusCode));
1604
1697
  const primary = variants[0] ?? res.content?.[0];
1605
1698
  return renderSchemaType({
1606
1699
  schema: primary?.schema ?? null,
1607
- name: resolver.resolveResponseStatusName(node, res.statusCode),
1700
+ name: resolver.response.status(node, res.statusCode),
1608
1701
  keysToOmit: primary?.keysToOmit
1609
1702
  });
1610
1703
  });
1611
- const dataType = renderSchemaType({
1612
- schema: buildData({
1704
+ const optionsType = renderSchemaType({
1705
+ schema: buildOptions({
1613
1706
  ...node,
1614
1707
  parameters: params
1615
1708
  }, { resolver }),
1616
- name: resolver.resolveRequestConfigName(node)
1709
+ name: resolver.response.options(node)
1617
1710
  });
1618
1711
  const responsesType = renderSchemaType({
1619
1712
  schema: buildResponses(node, { resolver }),
1620
- name: resolver.resolveResponsesName(node)
1713
+ name: resolver.response.responses(node)
1621
1714
  });
1622
1715
  function buildResponseType() {
1623
1716
  const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
1624
1717
  if (!node.responses.some(hasSchema)) return null;
1625
- const responseName = resolver.resolveResponseName(node);
1718
+ const responseName = resolver.response.response(node);
1626
1719
  const responsesWithSchema = node.responses.filter(hasSchema);
1627
1720
  if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
1628
- name: resolveImportName(schemaName),
1721
+ name: resolveImportName({
1722
+ schemaName,
1723
+ enumOptions,
1724
+ enumSchemaNames,
1725
+ resolver
1726
+ }),
1629
1727
  path: ""
1630
1728
  })).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseName)) return null;
1631
1729
  return renderSchemaType({
@@ -1641,7 +1739,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1641
1739
  baseName: meta.file.baseName,
1642
1740
  path: meta.file.path,
1643
1741
  meta: meta.file.meta,
1644
- banner: resolver.resolveBanner(ctx.meta, {
1742
+ banner: resolver.default.banner(ctx.meta, {
1645
1743
  output,
1646
1744
  config,
1647
1745
  file: {
@@ -1649,7 +1747,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1649
1747
  baseName: meta.file.baseName
1650
1748
  }
1651
1749
  }),
1652
- footer: resolver.resolveFooter(ctx.meta, {
1750
+ footer: resolver.default.footer(ctx.meta, {
1653
1751
  output,
1654
1752
  config,
1655
1753
  file: {
@@ -1658,10 +1756,10 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1658
1756
  }
1659
1757
  }),
1660
1758
  children: [
1661
- paramTypes,
1759
+ paramGroupTypes,
1662
1760
  responseTypes,
1663
1761
  requestType,
1664
- dataType,
1762
+ optionsType,
1665
1763
  responsesType,
1666
1764
  responseType
1667
1765
  ]
@@ -1676,64 +1774,61 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
1676
1774
  * to reference the exact names `plugin-ts` produces without duplicating the
1677
1775
  * casing/file-layout rules.
1678
1776
  *
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.
1777
+ * The `default` helpers are supplied by `createResolver`. This plugin overrides the top-level `name`
1778
+ * to use PascalCase for value and type names and `file` to write PascalCase file paths (dotted names
1779
+ * become `/`-joined), and groups the operation-specific naming under the `param`, `response`, and
1780
+ * `enum` namespaces.
1681
1781
  *
1682
1782
  * @example Resolve a type and file name
1683
1783
  * ```ts
1684
1784
  * import { resolverTs } from '@kubb/plugin-ts'
1685
1785
  *
1686
- * resolverTs.default('list pets', 'type') // 'ListPets'
1687
- * resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
1688
- * resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
1786
+ * resolverTs.name('list pets') // 'ListPets'
1787
+ * resolverTs.response.status(node, 200) // 'ListPetsStatus200'
1689
1788
  * ```
1690
1789
  */
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`);
1790
+ const resolverTs = (0, kubb_kit.createResolver)({
1791
+ pluginName: "plugin-ts",
1792
+ name(name) {
1793
+ return ensureValidVarName(pascalCase(name));
1794
+ },
1795
+ file: { baseName({ name, extname }) {
1796
+ return `${toFilePath(name, pascalCase)}${extname}`;
1797
+ } },
1798
+ param: {
1799
+ name(node, param) {
1800
+ return this.name(`${node.operationId} ${param.in} ${param.name}`);
1714
1801
  },
1715
- resolveRequestConfigName(node) {
1716
- return this.resolveTypeName(`${node.operationId} RequestConfig`);
1802
+ path(node) {
1803
+ return this.name(`${node.operationId} Path`);
1717
1804
  },
1718
- resolveResponsesName(node) {
1719
- return this.resolveTypeName(`${node.operationId} Responses`);
1805
+ query(node) {
1806
+ return this.name(`${node.operationId} Query`);
1720
1807
  },
1721
- resolveResponseName(node) {
1722
- return this.resolveTypeName(`${node.operationId} Response`);
1808
+ headers(node) {
1809
+ return this.name(`${node.operationId} Headers`);
1810
+ }
1811
+ },
1812
+ response: {
1813
+ status(node, statusCode) {
1814
+ return this.name(`${node.operationId} Status ${statusCode}`);
1723
1815
  },
1724
- resolveEnumKeyName(node, enumTypeSuffix = "key") {
1725
- return `${this.resolveTypeName(node.name ?? "")}${enumTypeSuffix}`;
1816
+ options(node) {
1817
+ return this.name(`${node.operationId} Options`);
1726
1818
  },
1727
- resolvePathParamsName(node, param) {
1728
- return this.resolveParamName(node, param);
1819
+ responses(node) {
1820
+ return this.name(`${node.operationId} Responses`);
1729
1821
  },
1730
- resolveQueryParamsName(node, param) {
1731
- return this.resolveParamName(node, param);
1822
+ response(node) {
1823
+ return this.name(`${node.operationId} Response`);
1732
1824
  },
1733
- resolveHeaderParamsName(node, param) {
1734
- return this.resolveParamName(node, param);
1825
+ body(node) {
1826
+ return this.name(`${node.operationId} Body`);
1735
1827
  }
1736
- };
1828
+ },
1829
+ enum: { keyName(node, enumTypeSuffix = "key") {
1830
+ return `${this.name(node.name ?? "")}${enumTypeSuffix}`;
1831
+ } }
1737
1832
  });
1738
1833
  //#endregion
1739
1834
  //#region src/plugin.ts
@@ -1794,10 +1889,7 @@ const pluginTs = (0, kubb_kit.definePlugin)((options) => {
1794
1889
  syntaxType,
1795
1890
  printer
1796
1891
  });
1797
- ctx.setResolver(userResolver ? {
1798
- ...resolverTs,
1799
- ...userResolver
1800
- } : resolverTs);
1892
+ ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverTs, userResolver) : resolverTs);
1801
1893
  if (userMacros?.length) ctx.setMacros(userMacros);
1802
1894
  ctx.addGenerator(typeGenerator);
1803
1895
  } }
@@ -2058,12 +2150,12 @@ function functionPrinter(options) {
2058
2150
  */
2059
2151
  function resolveParamType({ node, param, resolver }) {
2060
2152
  if (!resolver) return param.schema.primitive ?? "unknown";
2061
- const individualName = resolver.resolveParamName(node, param);
2153
+ const individualName = resolver.param.name(node, param);
2062
2154
  const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
2063
2155
  const groupResolvers = {
2064
- path: resolver.resolvePathParamsName,
2065
- query: resolver.resolveQueryParamsName,
2066
- header: resolver.resolveHeaderParamsName
2156
+ path: resolver.param.path,
2157
+ query: resolver.param.query,
2158
+ header: resolver.param.headers
2067
2159
  };
2068
2160
  const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
2069
2161
  if (groupName && groupName !== individualName) return createIndexedAccessType({
@@ -2081,8 +2173,8 @@ function resolveParamType({ node, param, resolver }) {
2081
2173
  function resolveGroupType({ node, params, group, resolver }) {
2082
2174
  if (!resolver || !params.length) return null;
2083
2175
  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;
2176
+ const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
2177
+ if (groupName === resolver.param.name(node, firstParam)) return null;
2086
2178
  return {
2087
2179
  type: groupName,
2088
2180
  optional: params.every((p) => !p.required)
@@ -2118,7 +2210,7 @@ function createOperationParams(node, options) {
2118
2210
  optional: !param.required
2119
2211
  });
2120
2212
  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;
2213
+ const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
2122
2214
  const bodyProperty = bodyType ? [{
2123
2215
  name: dataName,
2124
2216
  type: bodyType,
@@ -2162,7 +2254,7 @@ function createOperationParams(node, options) {
2162
2254
  }));
2163
2255
  } else {
2164
2256
  if (pathParamsType === "inlineSpread" && pathParams.length) {
2165
- const spreadType = resolver?.resolvePathParamsName(node, pathParams[0]);
2257
+ const spreadType = resolver?.param.path(node, pathParams[0]);
2166
2258
  params.push(createFunctionParameter({
2167
2259
  name: pathName,
2168
2260
  type: spreadType ? wrapType(spreadType) : void 0,
@@ -2232,6 +2324,7 @@ function buildTypeLiteral({ node, params, resolver }) {
2232
2324
  //#endregion
2233
2325
  exports.Enum = Enum;
2234
2326
  exports.Type = Type;
2327
+ exports.buildParams = buildParams;
2235
2328
  exports.createFunctionParameter = createFunctionParameter;
2236
2329
  exports.createFunctionParameters = createFunctionParameters;
2237
2330
  exports.createIndexedAccessType = createIndexedAccessType;