@kubb/plugin-ts 5.3.0-canary.20261025T193221 → 5.3.0

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
@@ -3,7 +3,7 @@ import { Resolver, addGenerator, ast, createResolver, defineExtension, defineGen
3
3
  import { generate } from "yuku-codegen";
4
4
  import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
5
5
  import { parserTs } from "@kubb/parser-ts";
6
- //#region \0rolldown/runtime.js
6
+ // \0rolldown/runtime.js
7
7
  var __defProp = Object.defineProperty;
8
8
  var __name = (target, value) => __defProp(target, "name", {
9
9
  value,
@@ -18,8 +18,7 @@ var __exportAll = (all, no_symbols) => {
18
18
  if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
19
19
  return target;
20
20
  };
21
- //#endregion
22
- //#region ../../internals/utils/src/casing.ts
21
+ // ../../internals/utils/src/casing.ts
23
22
  /**
24
23
  * Shared implementation for camelCase and PascalCase conversion.
25
24
  * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
@@ -92,8 +91,7 @@ function screamingSnakeCase(text, { prefix = "", suffix = "" } = {}) {
92
91
  suffix
93
92
  }).toUpperCase();
94
93
  }
95
- //#endregion
96
- //#region ../../internals/utils/src/reserved.ts
94
+ // ../../internals/utils/src/reserved.ts
97
95
  /**
98
96
  * JavaScript and Java reserved words.
99
97
  * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
@@ -101,6 +99,7 @@ function screamingSnakeCase(text, { prefix = "", suffix = "" } = {}) {
101
99
  const reservedWords = /* @__PURE__ */ new Set([
102
100
  "abstract",
103
101
  "arguments",
102
+ "await",
104
103
  "boolean",
105
104
  "break",
106
105
  "byte",
@@ -231,8 +230,7 @@ function ensureValidVarName(name) {
231
230
  function isIdentifier(name) {
232
231
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
233
232
  }
234
- //#endregion
235
- //#region ../../internals/utils/src/strings.ts
233
+ // ../../internals/utils/src/strings.ts
236
234
  /**
237
235
  * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
238
236
  * Returns the string unchanged when no balanced quote pair is found.
@@ -279,8 +277,7 @@ function stringify(value) {
279
277
  function jsDocEscape(input) {
280
278
  return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
281
279
  }
282
- //#endregion
283
- //#region ../../internals/utils/src/fs.ts
280
+ // ../../internals/utils/src/fs.ts
284
281
  /**
285
282
  * Builds a nested file path from a dotted name. Splits on dots that precede a letter
286
283
  * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
@@ -304,8 +301,7 @@ function toFilePath(name, caseLast = camelCase) {
304
301
  const parts = name.split(/\.(?=[a-zA-Z])/);
305
302
  return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
306
303
  }
307
- //#endregion
308
- //#region src/factory.ts
304
+ // src/factory.ts
309
305
  var factory_exports = /* @__PURE__ */ __exportAll({
310
306
  appendJSDocToNode: () => appendJSDocToNode,
311
307
  buildIndexSignatures: () => buildIndexSignatures,
@@ -696,11 +692,20 @@ function createUrlTemplateType(path) {
696
692
  };
697
693
  }
698
694
  /**
699
- * Converts a primitive const value to a TypeScript literal type.
695
+ * Converts a const value to a literal type, preserving nested arrays and objects.
700
696
  */
701
697
  function constToTypeNode(value, format) {
702
- if (format === "boolean") return createLiteralType(value === true);
703
- return createLiteralType(format === "number" && typeof value === "number" ? value : String(value));
698
+ if (value === null) return keywordTypeNodes.null;
699
+ if (Array.isArray(value)) return {
700
+ type: "TSTupleType",
701
+ elementTypes: value.map((item) => constToTypeNode(item))
702
+ };
703
+ if (typeof value === "object") return createTypeLiteralNode(Object.entries(value).map(([name, item]) => createPropertySignature({
704
+ name,
705
+ type: constToTypeNode(item)
706
+ })));
707
+ if ((format ?? typeof value) === "boolean") return createLiteralType(value === true);
708
+ return createLiteralType((format ?? typeof value) === "number" && typeof value === "number" ? value : String(value));
704
709
  }
705
710
  /**
706
711
  * Returns a `Date` reference type when `representation` is `'date'`, otherwise falls back to `string`.
@@ -794,8 +799,7 @@ function buildIndexSignatures(node, propertyCount, printNode) {
794
799
  accessibility: null
795
800
  }];
796
801
  }
797
- //#endregion
798
- //#region src/components/Enum.tsx
802
+ // src/components/Enum.tsx
799
803
  /**
800
804
  * Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
801
805
  *
@@ -809,7 +813,7 @@ function buildIndexSignatures(node, propertyCount, printNode) {
809
813
  function getEnumNames({ node, enum: enumOptions, resolver }) {
810
814
  const resolved = resolver.name(node.name);
811
815
  return {
812
- enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
816
+ enumName: enumOptions.constCasing === "pascalCase" ? resolved : ensureValidVarName(camelCase(node.name)),
813
817
  typeName: enumOptions.type === "asConst" ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
814
818
  };
815
819
  }
@@ -862,8 +866,7 @@ function Enum({ node, enum: enumOptions, resolver }) {
862
866
  children: typeNode
863
867
  })] });
864
868
  }
865
- //#endregion
866
- //#region ../../internals/shared/src/operation.ts
869
+ // ../../internals/shared/src/operation.ts
867
870
  /**
868
871
  * Maps a content type to the PascalCase suffix used to name per-content-type variants
869
872
  * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
@@ -946,7 +949,10 @@ function getOperationParameters(node) {
946
949
  * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod
947
950
  * printer to emit `z.object(…)` rather than a record.
948
951
  */
949
- function buildOptionsSchema(node, resolver) {
952
+ function hasRequestContentTypeChoice(node) {
953
+ return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
954
+ }
955
+ function buildOptionsSchema(node, resolver, { pairContentTypes = false } = {}) {
950
956
  const { path, query, header } = getOperationParameters(node);
951
957
  const hasBody = Boolean(node.requestBody?.content?.[0]?.schema);
952
958
  const createNever = () => ast.factory.createSchema({
@@ -971,29 +977,57 @@ function buildOptionsSchema(node, resolver) {
971
977
  resolve: resolver.param.headers
972
978
  }
973
979
  ];
974
- return ast.factory.createSchema({
980
+ const createOptions = (body, extra = []) => ast.factory.createSchema({
975
981
  type: "object",
976
982
  primitive: "object",
977
983
  deprecated: node.deprecated,
978
- properties: [ast.factory.createProperty({
979
- name: "body",
980
- required: hasBody,
981
- schema: hasBody ? ast.factory.createSchema({
982
- type: "ref",
983
- name: resolver.response.body(node)
984
- }) : createNever()
985
- }), ...groups.map(({ name, params, resolve }) => {
986
- const required = params.some((param) => param.required);
987
- return ast.factory.createProperty({
988
- name,
989
- required,
990
- schema: params.length > 0 ? ast.factory.createSchema({
991
- type: "ref",
992
- name: resolve.call(resolver.param, node, params[0]),
993
- optional: !required
994
- }) : createNever()
995
- });
996
- })]
984
+ properties: [
985
+ ast.factory.createProperty({
986
+ name: "body",
987
+ required: hasBody,
988
+ schema: body
989
+ }),
990
+ ...groups.map(({ name, params, resolve }) => {
991
+ const required = params.some((param) => param.required);
992
+ return ast.factory.createProperty({
993
+ name,
994
+ required,
995
+ schema: params.length > 0 ? ast.factory.createSchema({
996
+ type: "ref",
997
+ name: resolve.call(resolver.param, node, params[0]),
998
+ optional: !required
999
+ }) : createNever()
1000
+ });
1001
+ }),
1002
+ ...extra
1003
+ ]
1004
+ });
1005
+ const variants = pairContentTypes && hasRequestContentTypeChoice(node) ? resolveContentTypeVariants(node.requestBody?.content ?? [], resolver.response.body(node)) : [];
1006
+ if (variants.length < 2) return createOptions(hasBody ? ast.factory.createSchema({
1007
+ type: "ref",
1008
+ name: resolver.response.body(node)
1009
+ }) : createNever());
1010
+ return ast.factory.createSchema({
1011
+ type: "union",
1012
+ members: variants.map((variant, index) => createOptions(ast.factory.createSchema({
1013
+ type: "ref",
1014
+ name: variant.name
1015
+ }), [ast.factory.createProperty({
1016
+ name: "contentType",
1017
+ required: index > 0,
1018
+ schema: ast.factory.createSchema({
1019
+ type: "object",
1020
+ primitive: "object",
1021
+ properties: [ast.factory.createProperty({
1022
+ name: "request",
1023
+ required: true,
1024
+ schema: ast.factory.createSchema({
1025
+ type: "enum",
1026
+ enumValues: [variant.contentType]
1027
+ })
1028
+ })]
1029
+ })
1030
+ })]))
997
1031
  });
998
1032
  }
999
1033
  /**
@@ -1060,17 +1094,24 @@ function isSuccessStatusCode(statusCode) {
1060
1094
  const code = getStatusCodeNumber(statusCode);
1061
1095
  return code !== null && code >= 200 && code < 300;
1062
1096
  }
1063
- //#endregion
1064
- //#region ../../internals/shared/src/resolver.ts
1097
+ // ../../internals/shared/src/resolver.ts
1065
1098
  /**
1066
- * Resolves a single operation parameter name with the
1067
- * `<operationId> <in> <name>` template.
1099
+ * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
1100
+ * it is, so two of them never share an allocation even when a custom resolver gives both the same
1101
+ * name. Leave `scope` empty for the operation's own declaration.
1068
1102
  *
1069
1103
  * @example
1070
- * `operationParamName.call(resolver, node, param) // → 'DeletePetPathPetId'`
1104
+ * ```ts
1105
+ * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
1106
+ * ```
1071
1107
  */
1072
- function operationParamName(node, param) {
1073
- return this.name(`${node.operationId} ${param.in} ${param.name}`);
1108
+ function operationKey(node, ...scope) {
1109
+ return [
1110
+ "operation",
1111
+ node.method,
1112
+ node.path,
1113
+ ...scope.map(String)
1114
+ ];
1074
1115
  }
1075
1116
  /**
1076
1117
  * Builds the shared `param` namespace. Spread the result into `createResolver`
@@ -1083,15 +1124,33 @@ function operationParamName(node, param) {
1083
1124
  */
1084
1125
  function createOperationParamResolver() {
1085
1126
  return {
1086
- name: operationParamName,
1127
+ name(node, param) {
1128
+ const name = this.name(`${node.operationId} ${param.in} ${param.name}`);
1129
+ return this.resolveName({
1130
+ key: operationKey(node, "param", "name", param.in, param.name),
1131
+ name
1132
+ });
1133
+ },
1087
1134
  path(node) {
1088
- return this.name(`${node.operationId} Path`);
1135
+ const name = this.name(`${node.operationId} Path`);
1136
+ return this.resolveName({
1137
+ key: operationKey(node, "param", "path"),
1138
+ name
1139
+ });
1089
1140
  },
1090
1141
  query(node) {
1091
- return this.name(`${node.operationId} Query`);
1142
+ const name = this.name(`${node.operationId} Query`);
1143
+ return this.resolveName({
1144
+ key: operationKey(node, "param", "query"),
1145
+ name
1146
+ });
1092
1147
  },
1093
1148
  headers(node) {
1094
- return this.name(`${node.operationId} Headers`);
1149
+ const name = this.name(`${node.operationId} Headers`);
1150
+ return this.resolveName({
1151
+ key: operationKey(node, "param", "headers"),
1152
+ name
1153
+ });
1095
1154
  }
1096
1155
  };
1097
1156
  }
@@ -1108,16 +1167,32 @@ function createOperationParamResolver() {
1108
1167
  function createOperationResponseResolver() {
1109
1168
  return {
1110
1169
  status(node, statusCode) {
1111
- return this.name(`${node.operationId} Status ${statusCode}`);
1170
+ const name = this.name(`${node.operationId} Status ${statusCode}`);
1171
+ return this.resolveName({
1172
+ key: operationKey(node, "response", "status", statusCode),
1173
+ name
1174
+ });
1112
1175
  },
1113
1176
  body(node) {
1114
- return this.name(`${node.operationId} Body`);
1177
+ const name = this.name(`${node.operationId} Body`);
1178
+ return this.resolveName({
1179
+ key: operationKey(node, "response", "body"),
1180
+ name
1181
+ });
1115
1182
  },
1116
1183
  responses(node) {
1117
- return this.name(`${node.operationId} Responses`);
1184
+ const name = this.name(`${node.operationId} Responses`);
1185
+ return this.resolveName({
1186
+ key: operationKey(node, "response", "responses"),
1187
+ name
1188
+ });
1118
1189
  },
1119
1190
  response(node) {
1120
- return this.name(`${node.operationId} Response`);
1191
+ const name = this.name(`${node.operationId} Response`);
1192
+ return this.resolveName({
1193
+ key: operationKey(node, "response", "response"),
1194
+ name
1195
+ });
1121
1196
  }
1122
1197
  };
1123
1198
  }
@@ -1135,8 +1210,7 @@ function createCasedFile(caseLast) {
1135
1210
  return `${toFilePath(name, caseLast)}${extname}`;
1136
1211
  } };
1137
1212
  }
1138
- //#endregion
1139
- //#region ../../internals/shared/src/group.ts
1213
+ // ../../internals/shared/src/group.ts
1140
1214
  /**
1141
1215
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
1142
1216
  * shared default naming so every plugin groups output consistently:
@@ -1166,8 +1240,7 @@ function createGroupConfig(group) {
1166
1240
  name: group.name ? group.name : defaultName
1167
1241
  };
1168
1242
  }
1169
- //#endregion
1170
- //#region ../../internals/shared/src/schemaTraversal.ts
1243
+ // ../../internals/shared/src/schemaTraversal.ts
1171
1244
  /**
1172
1245
  * Maps each property of an object schema to its transformed output. Pairs every result with the
1173
1246
  * original property so the printer keeps full control over modifiers, getters, and key syntax.
@@ -1195,8 +1268,38 @@ function mapSchemaItems(node, transform) {
1195
1268
  output: transform(schema)
1196
1269
  }));
1197
1270
  }
1198
- //#endregion
1199
- //#region src/utils.ts
1271
+ // src/utils.ts
1272
+ /**
1273
+ * Renames inline enum declarations and their uses together.
1274
+ */
1275
+ function resolveInlineEnumNames({ node, owner, resolver, enumOptions }) {
1276
+ return ast.transform(node, { schema(child) {
1277
+ if (child === node || child.type !== "enum" || !child.name) return;
1278
+ const name = resolver.resolveName({
1279
+ key: [
1280
+ "enum",
1281
+ owner,
1282
+ child.pointer ?? child.name
1283
+ ],
1284
+ name: child.name,
1285
+ normalize: (value) => {
1286
+ const { enumName, typeName } = getEnumNames({
1287
+ node: {
1288
+ ...child,
1289
+ name: value
1290
+ },
1291
+ enum: enumOptions,
1292
+ resolver
1293
+ });
1294
+ return enumOptions.type === "literal" ? [typeName] : [enumName, typeName];
1295
+ }
1296
+ });
1297
+ return name === child.name ? void 0 : {
1298
+ ...child,
1299
+ name
1300
+ };
1301
+ } });
1302
+ }
1200
1303
  function enumTypeName({ resolver, name, enumOptions, isEnum }) {
1201
1304
  return isEnum && enumOptions?.type === "asConst" && enumOptions.typeSuffix ? resolver.enum.keyName({ name }, enumOptions.typeSuffix) : resolver.name(name);
1202
1305
  }
@@ -1229,6 +1332,7 @@ function formatExample(value) {
1229
1332
  function buildPropertyJSDocComments(schema, optional) {
1230
1333
  const meta = syncSchemaRef(schema);
1231
1334
  const isArray = meta?.primitive === "array";
1335
+ const isNumeric = meta?.primitive === "number" || meta?.primitive === "integer" || meta?.primitive === "bigint";
1232
1336
  const hasDescription = meta && "description" in meta && meta.description;
1233
1337
  const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
1234
1338
  const exampleValues = meta?.examples ?? [];
@@ -1236,8 +1340,8 @@ function buildPropertyJSDocComments(schema, optional) {
1236
1340
  hasDescription ? `@description ${jsDocEscape(meta.description)}` : null,
1237
1341
  ...formatComment,
1238
1342
  meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : null,
1239
- !isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
1240
- !isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
1343
+ !isArray && meta && "min" in meta && meta.min !== void 0 ? `@${isNumeric ? "minimum" : "minLength"} ${meta.min}` : null,
1344
+ !isArray && meta && "max" in meta && meta.max !== void 0 ? `@${isNumeric ? "maximum" : "maxLength"} ${meta.max}` : null,
1241
1345
  meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
1242
1346
  meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" && typeof meta.default === "string" ? stringify(meta.default) : formatExample(meta.default)}` : null,
1243
1347
  ...exampleValues.map((example) => `@example ${formatExample(example)}`)
@@ -1277,8 +1381,7 @@ function buildResponseUnion(node, { resolver }) {
1277
1381
  }))
1278
1382
  });
1279
1383
  }
1280
- //#endregion
1281
- //#region src/printers/printerTs.ts
1384
+ // src/printers/printerTs.ts
1282
1385
  const { isNonNullable } = factory_exports;
1283
1386
  /**
1284
1387
  * Adapts user overrides, which work in strings, to the node-based printer: `this.transform` hands them printed
@@ -1362,6 +1465,7 @@ const printerTs = ast.createPrinter((options) => {
1362
1465
  },
1363
1466
  enum(node) {
1364
1467
  const values = ast.getSchemaLiteralValues(node);
1468
+ if (values.some((value) => value !== null && typeof value === "object")) return createUnionDeclaration({ nodes: values.map((value) => constToTypeNode(value)) });
1365
1469
  if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({ nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable) });
1366
1470
  return createTypeReferenceNode(enumTypeName({
1367
1471
  resolver: this.options.resolver,
@@ -1396,6 +1500,12 @@ const printerTs = ast.createPrinter((options) => {
1396
1500
  },
1397
1501
  object(node) {
1398
1502
  const { transform, options } = this;
1503
+ const keySchema = node.propertyNames && syncSchemaRef(node.propertyNames);
1504
+ if (!node.properties.length && !Object.keys(node.patternProperties ?? {}).length && node.propertyNames && keySchema?.type === "enum" && node.additionalProperties !== false) {
1505
+ const keyType = transform(node.propertyNames) ?? keywordTypeNodes.string;
1506
+ const valueSchema = typeof node.additionalProperties === "object" ? node.additionalProperties : ast.factory.createSchema({ type: "unknown" });
1507
+ return createTypeReferenceNode("Partial", [createTypeReferenceNode("Record", [keyType, buildPropertyType(valueSchema, transform(valueSchema) ?? keywordTypeNodes.unknown, options.optionalType, false)])]);
1508
+ }
1399
1509
  const addsQuestionToken = options.optionalType === "questionToken" || options.optionalType === "questionTokenAndUndefined";
1400
1510
  const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
1401
1511
  const baseType = output ?? keywordTypeNodes.unknown;
@@ -1447,8 +1557,7 @@ const printerTs = ast.createPrinter((options) => {
1447
1557
  }
1448
1558
  };
1449
1559
  });
1450
- //#endregion
1451
- //#region src/components/Type.tsx
1560
+ // src/components/Type.tsx
1452
1561
  function Type({ name, node, printer, enum: enumOptions, resolver, inline }) {
1453
1562
  if (inline) {
1454
1563
  const withoutEnums = ast.transform(node, { schema: (n) => n.type === ast.schemaTypes.enum && n.name ? {
@@ -1500,8 +1609,7 @@ function Type({ name, node, printer, enum: enumOptions, resolver, inline }) {
1500
1609
  children: output
1501
1610
  })] });
1502
1611
  }
1503
- //#endregion
1504
- //#region src/generators/typeGenerator.tsx
1612
+ // src/generators/typeGenerator.tsx
1505
1613
  /**
1506
1614
  * Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
1507
1615
  * schema in the spec plus per-operation request, response, and parameter
@@ -1514,6 +1622,12 @@ const typeGenerator = defineGenerator({
1514
1622
  schema(node, ctx) {
1515
1623
  const { enum: enumOptions, syntaxType, optionalType, arrayType, output, group, printer } = ctx.options;
1516
1624
  const { config, resolver, root } = ctx;
1625
+ if (enumOptions.type !== "inlineLiteral") node = resolveInlineEnumNames({
1626
+ node,
1627
+ owner: node.name ?? "",
1628
+ resolver,
1629
+ enumOptions
1630
+ });
1517
1631
  if (!node.name) return;
1518
1632
  const enumSchemaNames = new Set(ctx.meta.enumNames);
1519
1633
  const importName = (schemaName) => enumTypeName({
@@ -1621,6 +1735,12 @@ const typeGenerator = defineGenerator({
1621
1735
  }) : null;
1622
1736
  function renderSchemaType({ schema, name, keysToOmit }) {
1623
1737
  if (!schema) return null;
1738
+ if (!inline && enumOptions.type !== "inlineLiteral") schema = resolveInlineEnumNames({
1739
+ node: schema,
1740
+ owner: node.operationId,
1741
+ resolver,
1742
+ enumOptions
1743
+ });
1624
1744
  const imports = resolver.imports({
1625
1745
  node: schema,
1626
1746
  root,
@@ -1730,13 +1850,13 @@ const typeGenerator = defineGenerator({
1730
1850
  schema: primary?.schema ? {
1731
1851
  ...primary.schema,
1732
1852
  pointer: res.pointer ?? primary.schema.pointer
1733
- } : null,
1853
+ } : ast.factory.createSchema({ type: "unknown" }),
1734
1854
  name: resolver.response.status(node, res.statusCode),
1735
1855
  keysToOmit: primary?.keysToOmit
1736
1856
  });
1737
1857
  });
1738
1858
  const optionsType = renderSchemaType({
1739
- schema: buildOptionsSchema(node, resolver),
1859
+ schema: buildOptionsSchema(node, resolver, { pairContentTypes: true }),
1740
1860
  name: resolver.response.options(node)
1741
1861
  });
1742
1862
  const responsesType = renderSchemaType({
@@ -1745,13 +1865,12 @@ const typeGenerator = defineGenerator({
1745
1865
  });
1746
1866
  function buildResponseType() {
1747
1867
  const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
1748
- if (!node.responses.some(hasSchema)) return null;
1749
1868
  const responseName = resolver.response.response(node);
1750
1869
  const responsesWithSchema = node.responses.filter(hasSchema);
1751
1870
  if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? ast.collectImportedRefNames(entry.schema).map(importName) : []))).has(responseName)) return null;
1752
1871
  return renderSchemaType({
1753
1872
  schema: {
1754
- ...buildResponseUnion(node, { resolver }),
1873
+ ...buildResponseUnion(node, { resolver }) ?? ast.factory.createSchema({ type: "unknown" }),
1755
1874
  description: "Union of all possible responses"
1756
1875
  },
1757
1876
  name: responseName
@@ -1789,22 +1908,18 @@ const typeGenerator = defineGenerator({
1789
1908
  });
1790
1909
  }
1791
1910
  });
1792
- //#endregion
1793
- //#region kubb-extension.json
1911
+ // kubb-extension.json
1794
1912
  var compatibility = {
1795
- "kubb": ">=5.14.0",
1913
+ "kubb": ">=5.14.6",
1796
1914
  "node": ">=22.22"
1797
1915
  };
1798
- //#endregion
1799
- //#region package.json
1800
- var version = "5.3.0-canary.20261025T193221";
1801
- //#endregion
1802
- //#region src/resolvers/resolverTs.ts
1916
+ // package.json
1917
+ var version = "5.3.0";
1918
+ // src/resolvers/resolverTs.ts
1803
1919
  /**
1804
1920
  * Default resolver used by `@kubb/plugin-ts`. Decides the names and file paths
1805
- * for every generated TypeScript type. Import this in other plugins that need
1806
- * to reference the exact names `plugin-ts` produces without duplicating the
1807
- * casing/file-layout rules.
1921
+ * for generated TypeScript types. Other plugins should read the build's resolver
1922
+ * through `driver.getResolver(pluginTsName)` to share its name allocations.
1808
1923
  *
1809
1924
  * The `default` helpers are supplied by `createResolver`. This plugin overrides the top-level `name`
1810
1925
  * to use PascalCase for value and type names and `file` to write PascalCase file paths (dotted names
@@ -1829,15 +1944,18 @@ const resolverTs = createResolver({
1829
1944
  response: {
1830
1945
  ...createOperationResponseResolver(),
1831
1946
  options(node) {
1832
- return this.name(`${node.operationId} Options`);
1947
+ const name = this.name(`${node.operationId} Options`);
1948
+ return this.resolveName({
1949
+ key: operationKey(node, "response", "options"),
1950
+ name
1951
+ });
1833
1952
  }
1834
1953
  },
1835
1954
  enum: { keyName(node, enumTypeSuffix = "key") {
1836
1955
  return `${this.name(node.name ?? "")}${enumTypeSuffix}`;
1837
1956
  } }
1838
1957
  });
1839
- //#endregion
1840
- //#region src/plugin.ts
1958
+ // src/plugin.ts
1841
1959
  /**
1842
1960
  * Canonical plugin name for `@kubb/plugin-ts`. Used for driver lookups and
1843
1961
  * cross-plugin dependency references.
@@ -1903,8 +2021,7 @@ const pluginTs = defineExtension({
1903
2021
  };
1904
2022
  }
1905
2023
  });
1906
- //#endregion
1907
- //#region src/printers/functionParams.ts
2024
+ // src/printers/functionParams.ts
1908
2025
  /**
1909
2026
  * Narrows a {@link TypeExpression} to a {@link TypeLiteralNode}.
1910
2027
  */
@@ -2013,8 +2130,7 @@ function createFunctionParameters(props = {}) {
2013
2130
  ...props
2014
2131
  };
2015
2132
  }
2016
- //#endregion
2017
- //#region src/printers/functionPrinter.ts
2133
+ // src/printers/functionPrinter.ts
2018
2134
  /**
2019
2135
  * Ordering priority for function parameters: lower = sorted earlier.
2020
2136
  */
@@ -2157,7 +2273,6 @@ function functionPrinter(options) {
2157
2273
  }
2158
2274
  };
2159
2275
  }
2160
- //#endregion
2161
2276
  export { Enum, Type, buildParams, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createTypeLiteral, pluginTs as default, pluginTs, enumTypeName, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
2162
2277
 
2163
2278
  //# sourceMappingURL=index.js.map