@kubb/plugin-ts 5.0.0-alpha.22 → 5.0.0-alpha.24

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.
Files changed (66) hide show
  1. package/dist/index.cjs +1680 -49
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +529 -4
  4. package/dist/index.js +1653 -52
  5. package/dist/index.js.map +1 -1
  6. package/package.json +3 -42
  7. package/src/components/Enum.tsx +2 -7
  8. package/src/components/Type.tsx +11 -5
  9. package/src/generators/typeGenerator.tsx +36 -24
  10. package/src/generators/typeGeneratorLegacy.tsx +28 -38
  11. package/src/index.ts +13 -1
  12. package/src/plugin.ts +42 -23
  13. package/src/presets.ts +16 -34
  14. package/src/printers/functionPrinter.ts +194 -0
  15. package/src/printers/printerTs.ts +23 -7
  16. package/src/resolvers/resolverTs.ts +10 -47
  17. package/src/resolvers/resolverTsLegacy.ts +4 -31
  18. package/src/types.ts +169 -254
  19. package/src/utils.ts +103 -0
  20. package/dist/Type-Bf8raoQX.cjs +0 -124
  21. package/dist/Type-Bf8raoQX.cjs.map +0 -1
  22. package/dist/Type-BpXxT4l_.js +0 -113
  23. package/dist/Type-BpXxT4l_.js.map +0 -1
  24. package/dist/builderTs-COUg3xtQ.cjs +0 -135
  25. package/dist/builderTs-COUg3xtQ.cjs.map +0 -1
  26. package/dist/builderTs-DPpkJKd1.js +0 -131
  27. package/dist/builderTs-DPpkJKd1.js.map +0 -1
  28. package/dist/builders.cjs +0 -3
  29. package/dist/builders.d.ts +0 -23
  30. package/dist/builders.js +0 -2
  31. package/dist/casing-BJHFg-zZ.js +0 -84
  32. package/dist/casing-BJHFg-zZ.js.map +0 -1
  33. package/dist/casing-DHfdqpLi.cjs +0 -107
  34. package/dist/casing-DHfdqpLi.cjs.map +0 -1
  35. package/dist/chunk-ByKO4r7w.cjs +0 -38
  36. package/dist/components.cjs +0 -4
  37. package/dist/components.d.ts +0 -71
  38. package/dist/components.js +0 -2
  39. package/dist/generators-DFDut8o-.js +0 -555
  40. package/dist/generators-DFDut8o-.js.map +0 -1
  41. package/dist/generators-DKd7MYbx.cjs +0 -567
  42. package/dist/generators-DKd7MYbx.cjs.map +0 -1
  43. package/dist/generators.cjs +0 -4
  44. package/dist/generators.d.ts +0 -12
  45. package/dist/generators.js +0 -2
  46. package/dist/printerTs-BcHudagv.cjs +0 -594
  47. package/dist/printerTs-BcHudagv.cjs.map +0 -1
  48. package/dist/printerTs-CMBCOuqd.js +0 -558
  49. package/dist/printerTs-CMBCOuqd.js.map +0 -1
  50. package/dist/printers.cjs +0 -3
  51. package/dist/printers.d.ts +0 -81
  52. package/dist/printers.js +0 -2
  53. package/dist/resolverTsLegacy-CPiqqsO6.js +0 -185
  54. package/dist/resolverTsLegacy-CPiqqsO6.js.map +0 -1
  55. package/dist/resolverTsLegacy-CuR9XbKk.cjs +0 -196
  56. package/dist/resolverTsLegacy-CuR9XbKk.cjs.map +0 -1
  57. package/dist/resolvers.cjs +0 -4
  58. package/dist/resolvers.d.ts +0 -52
  59. package/dist/resolvers.js +0 -2
  60. package/dist/types-CRtcZOCz.d.ts +0 -374
  61. package/src/builders/builderTs.ts +0 -107
  62. package/src/builders/index.ts +0 -1
  63. package/src/components/index.ts +0 -2
  64. package/src/generators/index.ts +0 -2
  65. package/src/printers/index.ts +0 -1
  66. package/src/resolvers/index.ts +0 -2
package/dist/index.cjs CHANGED
@@ -1,48 +1,1551 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_chunk = require("./chunk-ByKO4r7w.cjs");
3
- const require_generators = require("./generators-DKd7MYbx.cjs");
4
- const require_resolverTsLegacy = require("./resolverTsLegacy-CuR9XbKk.cjs");
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
5
24
  let node_path = require("node:path");
6
- node_path = require_chunk.__toESM(node_path);
25
+ node_path = __toESM(node_path);
26
+ let _kubb_fabric_core_parsers_typescript = require("@kubb/fabric-core/parsers/typescript");
27
+ let _kubb_react_fabric = require("@kubb/react-fabric");
28
+ let remeda = require("remeda");
29
+ let typescript = require("typescript");
30
+ typescript = __toESM(typescript);
31
+ let _kubb_react_fabric_jsx_runtime = require("@kubb/react-fabric/jsx-runtime");
7
32
  let _kubb_ast = require("@kubb/ast");
8
33
  let _kubb_core = require("@kubb/core");
9
- //#region src/presets.ts
34
+ //#region ../../internals/utils/src/casing.ts
10
35
  /**
11
- * Built-in preset registry for `@kubb/plugin-ts`.
36
+ * Shared implementation for camelCase and PascalCase conversion.
37
+ * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
38
+ * and capitalizes each word according to `pascal`.
12
39
  *
13
- * - `default` uses `resolverTs` and `typeGenerator` (current naming conventions).
14
- * - `kubbV4` — uses `resolverTsLegacy` and `typeGeneratorLegacy` (Kubb v4 naming conventions).
40
+ * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
15
41
  */
16
- const presets = (0, _kubb_core.definePresets)({
17
- default: (0, _kubb_core.definePreset)("default", {
18
- resolvers: [require_resolverTsLegacy.resolverTs],
19
- generators: [require_generators.typeGenerator]
20
- }),
21
- kubbV4: (0, _kubb_core.definePreset)("kubbV4", {
22
- resolvers: [require_resolverTsLegacy.resolverTsLegacy],
23
- generators: [require_generators.typeGeneratorLegacy]
24
- })
42
+ function toCamelOrPascal(text, pascal) {
43
+ return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
44
+ if (word.length > 1 && word === word.toUpperCase()) return word;
45
+ if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
46
+ return word.charAt(0).toUpperCase() + word.slice(1);
47
+ }).join("").replace(/[^a-zA-Z0-9]/g, "");
48
+ }
49
+ /**
50
+ * Splits `text` on `.` and applies `transformPart` to each segment.
51
+ * The last segment receives `isLast = true`, all earlier segments receive `false`.
52
+ * Segments are joined with `/` to form a file path.
53
+ *
54
+ * Only splits on dots followed by a letter so that version numbers
55
+ * embedded in operationIds (e.g. `v2025.0`) are kept intact.
56
+ */
57
+ function applyToFileParts(text, transformPart) {
58
+ const parts = text.split(/\.(?=[a-zA-Z])/);
59
+ return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
60
+ }
61
+ /**
62
+ * Converts `text` to camelCase.
63
+ * When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
64
+ *
65
+ * @example
66
+ * camelCase('hello-world') // 'helloWorld'
67
+ * camelCase('pet.petId', { isFile: true }) // 'pet/petId'
68
+ */
69
+ function camelCase(text, { isFile, prefix = "", suffix = "" } = {}) {
70
+ if (isFile) return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? {
71
+ prefix,
72
+ suffix
73
+ } : {}));
74
+ return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
75
+ }
76
+ /**
77
+ * Converts `text` to PascalCase.
78
+ * When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.
79
+ *
80
+ * @example
81
+ * pascalCase('hello-world') // 'HelloWorld'
82
+ * pascalCase('pet.petId', { isFile: true }) // 'pet/PetId'
83
+ */
84
+ function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
85
+ if (isFile) return applyToFileParts(text, (part, isLast) => isLast ? pascalCase(part, {
86
+ prefix,
87
+ suffix
88
+ }) : camelCase(part));
89
+ return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
90
+ }
91
+ /**
92
+ * Converts `text` to snake_case.
93
+ *
94
+ * @example
95
+ * snakeCase('helloWorld') // 'hello_world'
96
+ * snakeCase('Hello-World') // 'hello_world'
97
+ */
98
+ function snakeCase(text, { prefix = "", suffix = "" } = {}) {
99
+ return `${prefix} ${text} ${suffix}`.trim().replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s\-.]+/g, "_").replace(/[^a-zA-Z0-9_]/g, "").toLowerCase().split("_").filter(Boolean).join("_");
100
+ }
101
+ /**
102
+ * Converts `text` to SCREAMING_SNAKE_CASE.
103
+ *
104
+ * @example
105
+ * screamingSnakeCase('helloWorld') // 'HELLO_WORLD'
106
+ */
107
+ function screamingSnakeCase(text, { prefix = "", suffix = "" } = {}) {
108
+ return snakeCase(text, {
109
+ prefix,
110
+ suffix
111
+ }).toUpperCase();
112
+ }
113
+ //#endregion
114
+ //#region ../../internals/utils/src/string.ts
115
+ /**
116
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
117
+ * Returns the string unchanged when no balanced quote pair is found.
118
+ *
119
+ * @example
120
+ * trimQuotes('"hello"') // 'hello'
121
+ * trimQuotes('hello') // 'hello'
122
+ */
123
+ function trimQuotes(text) {
124
+ if (text.length >= 2) {
125
+ const first = text[0];
126
+ const last = text[text.length - 1];
127
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
128
+ }
129
+ return text;
130
+ }
131
+ /**
132
+ * Escapes characters that are not allowed inside JS string literals.
133
+ * Handles quotes, backslashes, and Unicode line terminators (U+2028 / U+2029).
134
+ *
135
+ * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
140
+ * ```
141
+ */
142
+ function jsStringEscape(input) {
143
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
144
+ switch (character) {
145
+ case "\"":
146
+ case "'":
147
+ case "\\": return `\\${character}`;
148
+ case "\n": return "\\n";
149
+ case "\r": return "\\r";
150
+ case "\u2028": return "\\u2028";
151
+ case "\u2029": return "\\u2029";
152
+ default: return "";
153
+ }
154
+ });
155
+ }
156
+ //#endregion
157
+ //#region ../../internals/utils/src/object.ts
158
+ /**
159
+ * Serializes a primitive value to a JSON string literal, stripping any surrounding quote characters first.
160
+ *
161
+ * @example
162
+ * stringify('hello') // '"hello"'
163
+ * stringify('"hello"') // '"hello"'
164
+ */
165
+ function stringify(value) {
166
+ if (value === void 0 || value === null) return "\"\"";
167
+ return JSON.stringify(trimQuotes(value.toString()));
168
+ }
169
+ //#endregion
170
+ //#region src/constants.ts
171
+ /**
172
+ * `optionalType` values that cause a property's type to include `| undefined`.
173
+ */
174
+ const OPTIONAL_ADDS_UNDEFINED = new Set(["undefined", "questionTokenAndUndefined"]);
175
+ /**
176
+ * `optionalType` values that render the property key with a `?` token.
177
+ */
178
+ const OPTIONAL_ADDS_QUESTION_TOKEN = new Set(["questionToken", "questionTokenAndUndefined"]);
179
+ /**
180
+ * `enumType` values that append a `Key` suffix to the generated enum type alias.
181
+ */
182
+ const ENUM_TYPES_WITH_KEY_SUFFIX = new Set(["asConst", "asPascalConst"]);
183
+ /**
184
+ * `enumType` values that require a runtime value declaration (object, enum, or literal).
185
+ */
186
+ const ENUM_TYPES_WITH_RUNTIME_VALUE = new Set([
187
+ "enum",
188
+ "asConst",
189
+ "asPascalConst",
190
+ "constEnum",
191
+ "literal",
192
+ void 0
193
+ ]);
194
+ /**
195
+ * `enumType` values whose type declaration is type-only (no runtime value emitted for the type alias).
196
+ */
197
+ const ENUM_TYPES_WITH_TYPE_ONLY = new Set([
198
+ "asConst",
199
+ "asPascalConst",
200
+ "literal",
201
+ void 0
202
+ ]);
203
+ //#endregion
204
+ //#region src/factory.ts
205
+ const { SyntaxKind, factory } = typescript.default;
206
+ const modifiers = {
207
+ async: factory.createModifier(typescript.default.SyntaxKind.AsyncKeyword),
208
+ export: factory.createModifier(typescript.default.SyntaxKind.ExportKeyword),
209
+ const: factory.createModifier(typescript.default.SyntaxKind.ConstKeyword),
210
+ static: factory.createModifier(typescript.default.SyntaxKind.StaticKeyword)
211
+ };
212
+ const syntaxKind = {
213
+ union: SyntaxKind.UnionType,
214
+ literalType: SyntaxKind.LiteralType,
215
+ stringLiteral: SyntaxKind.StringLiteral
216
+ };
217
+ function isValidIdentifier(str) {
218
+ if (!str.length || str.trim() !== str) return false;
219
+ const node = typescript.default.parseIsolatedEntityName(str, typescript.default.ScriptTarget.Latest);
220
+ return !!node && node.kind === typescript.default.SyntaxKind.Identifier && typescript.default.identifierToKeywordKind(node.kind) === void 0;
221
+ }
222
+ function propertyName(name) {
223
+ if (typeof name === "string") return isValidIdentifier(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
224
+ return name;
225
+ }
226
+ const questionToken = factory.createToken(typescript.default.SyntaxKind.QuestionToken);
227
+ function createQuestionToken(token) {
228
+ if (!token) return;
229
+ if (token === true) return questionToken;
230
+ return token;
231
+ }
232
+ function createIntersectionDeclaration({ nodes, withParentheses }) {
233
+ if (!nodes.length) return null;
234
+ if (nodes.length === 1) return nodes[0] || null;
235
+ const node = factory.createIntersectionTypeNode(nodes);
236
+ if (withParentheses) return factory.createParenthesizedType(node);
237
+ return node;
238
+ }
239
+ function createArrayDeclaration({ nodes, arrayType = "array" }) {
240
+ if (!nodes.length) return factory.createTupleTypeNode([]);
241
+ if (nodes.length === 1) {
242
+ const node = nodes[0];
243
+ if (!node) return null;
244
+ if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [node]);
245
+ return factory.createArrayTypeNode(node);
246
+ }
247
+ const unionType = factory.createUnionTypeNode(nodes);
248
+ if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [unionType]);
249
+ return factory.createArrayTypeNode(factory.createParenthesizedType(unionType));
250
+ }
251
+ /**
252
+ * Minimum nodes length of 2
253
+ * @example `string | number`
254
+ */
255
+ function createUnionDeclaration({ nodes, withParentheses }) {
256
+ if (!nodes.length) return keywordTypeNodes.any;
257
+ if (nodes.length === 1) return nodes[0];
258
+ const node = factory.createUnionTypeNode(nodes);
259
+ if (withParentheses) return factory.createParenthesizedType(node);
260
+ return node;
261
+ }
262
+ function createPropertySignature({ readOnly, modifiers = [], name, questionToken, type }) {
263
+ return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.default.SyntaxKind.ReadonlyKeyword) : void 0].filter(Boolean), propertyName(name), createQuestionToken(questionToken), type);
264
+ }
265
+ function createParameterSignature(name, { modifiers, dotDotDotToken, questionToken, type, initializer }) {
266
+ return factory.createParameterDeclaration(modifiers, dotDotDotToken, name, createQuestionToken(questionToken), type, initializer);
267
+ }
268
+ /**
269
+ * @link https://github.com/microsoft/TypeScript/issues/44151
270
+ */
271
+ function appendJSDocToNode({ node, comments }) {
272
+ const filteredComments = comments.filter(Boolean);
273
+ if (!filteredComments.length) return node;
274
+ const text = filteredComments.reduce((acc = "", comment = "") => {
275
+ return `${acc}\n * ${comment.replaceAll("*/", "*\\/")}`;
276
+ }, "*");
277
+ return typescript.default.addSyntheticLeadingComment(node, typescript.default.SyntaxKind.MultiLineCommentTrivia, `${text || "*"}\n`, true);
278
+ }
279
+ function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(typescript.default.SyntaxKind.StringKeyword) } = {}) {
280
+ return factory.createIndexSignature(modifiers, [createParameterSignature(indexName, { type: indexType })], type);
281
+ }
282
+ function createTypeAliasDeclaration({ modifiers, name, typeParameters, type }) {
283
+ return factory.createTypeAliasDeclaration(modifiers, name, typeParameters, type);
284
+ }
285
+ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }) {
286
+ return factory.createInterfaceDeclaration(modifiers, name, typeParameters, void 0, members);
287
+ }
288
+ function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
289
+ if (syntax === "interface" && "members" in type) return appendJSDocToNode({
290
+ node: createInterfaceDeclaration({
291
+ members: type.members,
292
+ modifiers: isExportable ? [modifiers.export] : [],
293
+ name,
294
+ typeParameters: void 0
295
+ }),
296
+ comments
297
+ });
298
+ return appendJSDocToNode({
299
+ node: createTypeAliasDeclaration({
300
+ type,
301
+ modifiers: isExportable ? [modifiers.export] : [],
302
+ name,
303
+ typeParameters: void 0
304
+ }),
305
+ comments
306
+ });
307
+ }
308
+ /**
309
+ * Apply casing transformation to enum keys
310
+ */
311
+ function applyEnumKeyCasing(key, casing = "none") {
312
+ if (casing === "none") return key;
313
+ if (casing === "screamingSnakeCase") return screamingSnakeCase(key);
314
+ if (casing === "snakeCase") return snakeCase(key);
315
+ if (casing === "pascalCase") return pascalCase(key);
316
+ if (casing === "camelCase") return camelCase(key);
317
+ return key;
318
+ }
319
+ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCasing = "none" }) {
320
+ if (type === "literal" || type === "inlineLiteral") return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.default.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createUnionTypeNode(enums.map(([_key, value]) => {
321
+ if ((0, remeda.isNumber)(value)) {
322
+ if (value < 0) return factory.createLiteralTypeNode(factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))));
323
+ return factory.createLiteralTypeNode(factory.createNumericLiteral(value?.toString()));
324
+ }
325
+ if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
326
+ if (value) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
327
+ }).filter(Boolean)))];
328
+ if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(typescript.default.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(typescript.default.SyntaxKind.ConstKeyword) : void 0].filter(Boolean), factory.createIdentifier(typeName), enums.map(([key, value]) => {
329
+ let initializer = factory.createStringLiteral(value?.toString());
330
+ if (Number.parseInt(value.toString(), 10) === value && (0, remeda.isNumber)(Number.parseInt(value.toString(), 10))) if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
331
+ else initializer = factory.createNumericLiteral(value);
332
+ if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
333
+ if ((0, remeda.isNumber)(Number.parseInt(key.toString(), 10))) {
334
+ const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
335
+ return factory.createEnumMember(propertyName(casingKey), initializer);
336
+ }
337
+ if (key) {
338
+ const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
339
+ return factory.createEnumMember(propertyName(casingKey), initializer);
340
+ }
341
+ }).filter(Boolean))];
342
+ const identifierName = name;
343
+ if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.default.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(typescript.default.SyntaxKind.NeverKeyword))];
344
+ return [factory.createVariableStatement([factory.createToken(typescript.default.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier(identifierName), void 0, void 0, factory.createAsExpression(factory.createObjectLiteralExpression(enums.map(([key, value]) => {
345
+ let initializer = factory.createStringLiteral(value?.toString());
346
+ if ((0, remeda.isNumber)(value)) if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
347
+ else initializer = factory.createNumericLiteral(value);
348
+ if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
349
+ if (key) {
350
+ const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
351
+ return factory.createPropertyAssignment(propertyName(casingKey), initializer);
352
+ }
353
+ }).filter(Boolean), true), factory.createTypeReferenceNode(factory.createIdentifier("const"), void 0)))], typescript.default.NodeFlags.Const)), factory.createTypeAliasDeclaration([factory.createToken(typescript.default.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createIndexedAccessTypeNode(factory.createParenthesizedType(factory.createTypeQueryNode(factory.createIdentifier(identifierName), void 0)), factory.createTypeOperatorNode(typescript.default.SyntaxKind.KeyOfKeyword, factory.createTypeQueryNode(factory.createIdentifier(identifierName), void 0))))];
354
+ }
355
+ function createOmitDeclaration({ keys, type, nonNullable }) {
356
+ const node = nonNullable ? factory.createTypeReferenceNode(factory.createIdentifier("NonNullable"), [type]) : type;
357
+ if (Array.isArray(keys)) return factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [node, factory.createUnionTypeNode(keys.map((key) => {
358
+ return factory.createLiteralTypeNode(factory.createStringLiteral(key));
359
+ }))]);
360
+ return factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [node, factory.createLiteralTypeNode(factory.createStringLiteral(keys))]);
361
+ }
362
+ const keywordTypeNodes = {
363
+ any: factory.createKeywordTypeNode(typescript.default.SyntaxKind.AnyKeyword),
364
+ unknown: factory.createKeywordTypeNode(typescript.default.SyntaxKind.UnknownKeyword),
365
+ void: factory.createKeywordTypeNode(typescript.default.SyntaxKind.VoidKeyword),
366
+ number: factory.createKeywordTypeNode(typescript.default.SyntaxKind.NumberKeyword),
367
+ integer: factory.createKeywordTypeNode(typescript.default.SyntaxKind.NumberKeyword),
368
+ bigint: factory.createKeywordTypeNode(typescript.default.SyntaxKind.BigIntKeyword),
369
+ object: factory.createKeywordTypeNode(typescript.default.SyntaxKind.ObjectKeyword),
370
+ string: factory.createKeywordTypeNode(typescript.default.SyntaxKind.StringKeyword),
371
+ boolean: factory.createKeywordTypeNode(typescript.default.SyntaxKind.BooleanKeyword),
372
+ undefined: factory.createKeywordTypeNode(typescript.default.SyntaxKind.UndefinedKeyword),
373
+ null: factory.createLiteralTypeNode(factory.createToken(typescript.default.SyntaxKind.NullKeyword)),
374
+ never: factory.createKeywordTypeNode(typescript.default.SyntaxKind.NeverKeyword)
375
+ };
376
+ /**
377
+ * Converts a path like '/pet/{petId}/uploadImage' to a template literal type
378
+ * like `/pet/${string}/uploadImage`
379
+ */
380
+ /**
381
+ * Converts an OAS-style path (e.g. `/pets/{petId}`) or an Express-style path
382
+ * (e.g. `/pets/:petId`) to a TypeScript template literal type
383
+ * like `` `/pets/${string}` ``.
384
+ */
385
+ function createUrlTemplateType(path) {
386
+ const normalized = path.replace(/:([^/]+)/g, "{$1}");
387
+ if (!normalized.includes("{")) return factory.createLiteralTypeNode(factory.createStringLiteral(normalized));
388
+ const segments = normalized.split(/(\{[^}]+\})/);
389
+ const parts = [];
390
+ const parameterIndices = [];
391
+ segments.forEach((segment) => {
392
+ if (segment.startsWith("{") && segment.endsWith("}")) {
393
+ parameterIndices.push(parts.length);
394
+ parts.push(segment);
395
+ } else if (segment) parts.push(segment);
396
+ });
397
+ const head = typescript.default.factory.createTemplateHead(parts[0] || "");
398
+ const templateSpans = [];
399
+ parameterIndices.forEach((paramIndex, i) => {
400
+ const isLast = i === parameterIndices.length - 1;
401
+ const nextPart = parts[paramIndex + 1] || "";
402
+ const literal = isLast ? typescript.default.factory.createTemplateTail(nextPart) : typescript.default.factory.createTemplateMiddle(nextPart);
403
+ templateSpans.push(typescript.default.factory.createTemplateLiteralTypeSpan(keywordTypeNodes.string, literal));
404
+ });
405
+ return typescript.default.factory.createTemplateLiteralType(head, templateSpans);
406
+ }
407
+ const createTypeLiteralNode = factory.createTypeLiteralNode;
408
+ const createTypeReferenceNode = factory.createTypeReferenceNode;
409
+ const createNumericLiteral = factory.createNumericLiteral;
410
+ const createStringLiteral = factory.createStringLiteral;
411
+ const createArrayTypeNode = factory.createArrayTypeNode;
412
+ factory.createParenthesizedType;
413
+ const createLiteralTypeNode = factory.createLiteralTypeNode;
414
+ factory.createNull;
415
+ const createIdentifier = factory.createIdentifier;
416
+ const createOptionalTypeNode = factory.createOptionalTypeNode;
417
+ const createTupleTypeNode = factory.createTupleTypeNode;
418
+ const createRestTypeNode = factory.createRestTypeNode;
419
+ const createTrue = factory.createTrue;
420
+ const createFalse = factory.createFalse;
421
+ factory.createIndexedAccessTypeNode;
422
+ factory.createTypeOperatorNode;
423
+ const createPrefixUnaryExpression = factory.createPrefixUnaryExpression;
424
+ //#endregion
425
+ //#region src/components/Enum.tsx
426
+ /**
427
+ * Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
428
+ *
429
+ * The raw `node.name` may be a YAML key such as `"enumNames.Type"` which is not a
430
+ * valid TypeScript identifier. The resolver normalizes it; for inline enum
431
+ * properties the adapter already emits a PascalCase+suffix name so resolution is typically a no-op.
432
+ */
433
+ function getEnumNames({ node, enumType, enumTypeSuffix, resolver }) {
434
+ const resolved = resolver.default(node.name, "type");
435
+ return {
436
+ enumName: enumType === "asPascalConst" ? resolved : camelCase(node.name),
437
+ typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolved
438
+ };
439
+ }
440
+ /**
441
+ * Renders the enum declaration(s) for a single named `EnumSchemaNode`.
442
+ *
443
+ * Depending on `enumType` this may emit:
444
+ * - A runtime object (`asConst` / `asPascalConst`) plus a `typeof` type alias
445
+ * - A `const enum` or plain `enum` declaration (`constEnum` / `enum`)
446
+ * - A union literal type alias (`literal`)
447
+ *
448
+ * The emitted `File.Source` nodes carry the resolved names so that the barrel
449
+ * index picks up the correct export identifiers.
450
+ */
451
+ function Enum({ node, enumType, enumTypeSuffix, enumKeyCasing, resolver }) {
452
+ const { enumName, typeName } = getEnumNames({
453
+ node,
454
+ enumType,
455
+ enumTypeSuffix,
456
+ resolver
457
+ });
458
+ const [nameNode, typeNode] = createEnumDeclaration({
459
+ name: enumName,
460
+ typeName,
461
+ enums: node.namedEnumValues?.map((v) => [trimQuotes(v.name.toString()), v.value]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
462
+ type: enumType,
463
+ enumKeyCasing
464
+ });
465
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [nameNode && /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
466
+ name: enumName,
467
+ isExportable: true,
468
+ isIndexable: true,
469
+ isTypeOnly: false,
470
+ children: (0, _kubb_fabric_core_parsers_typescript.safePrint)(nameNode)
471
+ }), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
472
+ name: typeName,
473
+ isIndexable: true,
474
+ isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
475
+ isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
476
+ children: (0, _kubb_fabric_core_parsers_typescript.safePrint)(typeNode)
477
+ })] });
478
+ }
479
+ //#endregion
480
+ //#region src/printers/printerTs.ts
481
+ /**
482
+ * Converts a primitive const value to a TypeScript literal type node.
483
+ * Handles negative numbers via a prefix unary expression.
484
+ */
485
+ function constToTypeNode(value, format) {
486
+ if (format === "boolean") return createLiteralTypeNode(value === true ? createTrue() : createFalse());
487
+ if (format === "number" && typeof value === "number") {
488
+ if (value < 0) return createLiteralTypeNode(createPrefixUnaryExpression(SyntaxKind.MinusToken, createNumericLiteral(Math.abs(value))));
489
+ return createLiteralTypeNode(createNumericLiteral(value));
490
+ }
491
+ return createLiteralTypeNode(createStringLiteral(String(value)));
492
+ }
493
+ /**
494
+ * Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
495
+ */
496
+ function dateOrStringNode(node) {
497
+ return node.representation === "date" ? createTypeReferenceNode(createIdentifier("Date")) : keywordTypeNodes.string;
498
+ }
499
+ /**
500
+ * Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
501
+ */
502
+ function buildMemberNodes(members, print) {
503
+ return (members ?? []).map(print).filter(Boolean);
504
+ }
505
+ /**
506
+ * Builds a TypeScript tuple type node from an array schema's `items`,
507
+ * applying min/max slice and optional/rest element rules.
508
+ */
509
+ function buildTupleNode(node, print) {
510
+ let items = (node.items ?? []).map(print).filter(Boolean);
511
+ const restNode = node.rest ? print(node.rest) ?? void 0 : void 0;
512
+ const { min, max } = node;
513
+ if (max !== void 0) {
514
+ items = items.slice(0, max);
515
+ if (items.length < max && restNode) items = [...items, ...Array(max - items.length).fill(restNode)];
516
+ }
517
+ if (min !== void 0) items = items.map((item, i) => i >= min ? createOptionalTypeNode(item) : item);
518
+ if (max === void 0 && restNode) items.push(createRestTypeNode(createArrayTypeNode(restNode)));
519
+ return createTupleTypeNode(items);
520
+ }
521
+ /**
522
+ * Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
523
+ */
524
+ function buildPropertyType(schema, baseType, optionalType) {
525
+ const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
526
+ let type = baseType;
527
+ if (schema.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
528
+ if ((schema.nullish || schema.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
529
+ return type;
530
+ }
531
+ /**
532
+ * Collects JSDoc annotation strings (description, deprecated, min/max, pattern, default, example, type) for a schema node.
533
+ */
534
+ function buildPropertyJSDocComments(schema) {
535
+ const isArray = schema.type === "array";
536
+ return [
537
+ "description" in schema && schema.description ? `@description ${jsStringEscape(schema.description)}` : void 0,
538
+ "deprecated" in schema && schema.deprecated ? "@deprecated" : void 0,
539
+ !isArray && "min" in schema && schema.min !== void 0 ? `@minLength ${schema.min}` : void 0,
540
+ !isArray && "max" in schema && schema.max !== void 0 ? `@maxLength ${schema.max}` : void 0,
541
+ "pattern" in schema && schema.pattern ? `@pattern ${schema.pattern}` : void 0,
542
+ "default" in schema && schema.default !== void 0 ? `@default ${"primitive" in schema && schema.primitive === "string" ? stringify(schema.default) : schema.default}` : void 0,
543
+ "example" in schema && schema.example !== void 0 ? `@example ${schema.example}` : void 0,
544
+ "primitive" in schema && schema.primitive ? [`@type ${schema.primitive || "unknown"}`, "optional" in schema && schema.optional ? " | undefined" : void 0].filter(Boolean).join("") : void 0
545
+ ];
546
+ }
547
+ /**
548
+ * Creates TypeScript index signatures for `additionalProperties` and `patternProperties` on an object schema node.
549
+ */
550
+ function buildIndexSignatures(node, propertyCount, print) {
551
+ const elements = [];
552
+ if (node.additionalProperties && node.additionalProperties !== true) {
553
+ const additionalType = print(node.additionalProperties) ?? keywordTypeNodes.unknown;
554
+ elements.push(createIndexSignature(propertyCount > 0 ? keywordTypeNodes.unknown : additionalType));
555
+ } else if (node.additionalProperties === true) elements.push(createIndexSignature(keywordTypeNodes.unknown));
556
+ if (node.patternProperties) {
557
+ const first = Object.values(node.patternProperties)[0];
558
+ if (first) {
559
+ let patternType = print(first) ?? keywordTypeNodes.unknown;
560
+ if (first.nullable) patternType = createUnionDeclaration({ nodes: [patternType, keywordTypeNodes.null] });
561
+ elements.push(createIndexSignature(patternType));
562
+ }
563
+ }
564
+ return elements;
565
+ }
566
+ /**
567
+ * TypeScript type printer built with `definePrinter`.
568
+ *
569
+ * Converts a `SchemaNode` AST node into a TypeScript AST node:
570
+ * - **`printer.print(node)`** — when `options.typeName` is set, returns a full
571
+ * `type Name = …` or `interface Name { … }` declaration (`ts.Node`).
572
+ * Without `typeName`, returns the raw `ts.TypeNode` for the schema.
573
+ *
574
+ * Dispatches on `node.type` to the appropriate handler in `nodes`. Options are closed
575
+ * over per printer instance, so each call to `printerTs(options)` produces an independent printer.
576
+ *
577
+ * @example Raw type node (no `typeName`)
578
+ * ```ts
579
+ * const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral' })
580
+ * const typeNode = printer.print(schemaNode) // ts.TypeNode
581
+ * ```
582
+ *
583
+ * @example Full declaration (with `typeName`)
584
+ * ```ts
585
+ * const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral', typeName: 'MyType' })
586
+ * const declaration = printer.print(schemaNode) // ts.TypeAliasDeclaration | ts.InterfaceDeclaration
587
+ * ```
588
+ */
589
+ const printerTs = (0, _kubb_core.definePrinter)((options) => {
590
+ const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(options.optionalType);
591
+ return {
592
+ name: "typescript",
593
+ options,
594
+ nodes: {
595
+ any: () => keywordTypeNodes.any,
596
+ unknown: () => keywordTypeNodes.unknown,
597
+ void: () => keywordTypeNodes.void,
598
+ never: () => keywordTypeNodes.never,
599
+ boolean: () => keywordTypeNodes.boolean,
600
+ null: () => keywordTypeNodes.null,
601
+ blob: () => createTypeReferenceNode("Blob", []),
602
+ string: () => keywordTypeNodes.string,
603
+ uuid: () => keywordTypeNodes.string,
604
+ email: () => keywordTypeNodes.string,
605
+ url: (node) => {
606
+ if (node.path) return createUrlTemplateType(node.path);
607
+ return keywordTypeNodes.string;
608
+ },
609
+ datetime: () => keywordTypeNodes.string,
610
+ number: () => keywordTypeNodes.number,
611
+ integer: () => keywordTypeNodes.number,
612
+ bigint: () => keywordTypeNodes.bigint,
613
+ date: dateOrStringNode,
614
+ time: dateOrStringNode,
615
+ ref(node) {
616
+ if (!node.name) return;
617
+ const refName = node.ref ? node.ref.split("/").at(-1) ?? node.name : node.name;
618
+ return createTypeReferenceNode(node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) && this.options.enumTypeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.resolveEnumKeyName({ name: refName }, this.options.enumTypeSuffix) : node.ref ? this.options.resolver.default(refName, "type") : refName, void 0);
619
+ },
620
+ enum(node) {
621
+ const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
622
+ if (this.options.enumType === "inlineLiteral" || !node.name) return createUnionDeclaration({
623
+ withParentheses: true,
624
+ nodes: values.filter((v) => v !== null).map((value) => constToTypeNode(value, typeof value)).filter(Boolean)
625
+ }) ?? void 0;
626
+ return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) && this.options.enumTypeSuffix ? this.options.resolver.resolveEnumKeyName(node, this.options.enumTypeSuffix) : this.options.resolver.default(node.name, "type"), void 0);
627
+ },
628
+ union(node) {
629
+ const members = node.members ?? [];
630
+ const hasStringLiteral = members.some((m) => {
631
+ return (0, _kubb_ast.narrowSchema)(m, _kubb_ast.schemaTypes.enum)?.primitive === "string";
632
+ });
633
+ const hasPlainString = members.some((m) => (0, _kubb_ast.isStringType)(m));
634
+ if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
635
+ withParentheses: true,
636
+ nodes: members.map((m) => {
637
+ if ((0, _kubb_ast.isStringType)(m)) return createIntersectionDeclaration({
638
+ nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
639
+ withParentheses: true
640
+ });
641
+ return this.transform(m);
642
+ }).filter(Boolean)
643
+ }) ?? void 0;
644
+ return createUnionDeclaration({
645
+ withParentheses: true,
646
+ nodes: buildMemberNodes(members, this.transform)
647
+ }) ?? void 0;
648
+ },
649
+ intersection(node) {
650
+ return createIntersectionDeclaration({
651
+ withParentheses: true,
652
+ nodes: buildMemberNodes(node.members, this.transform)
653
+ }) ?? void 0;
654
+ },
655
+ array(node) {
656
+ return createArrayDeclaration({
657
+ nodes: (node.items ?? []).map((item) => this.transform(item)).filter(Boolean),
658
+ arrayType: this.options.arrayType
659
+ }) ?? void 0;
660
+ },
661
+ tuple(node) {
662
+ return buildTupleNode(node, this.transform);
663
+ },
664
+ object(node) {
665
+ const { transform, options } = this;
666
+ const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
667
+ const propertyNodes = node.properties.map((prop) => {
668
+ const baseType = transform(prop.schema) ?? keywordTypeNodes.unknown;
669
+ const type = buildPropertyType(prop.schema, baseType, options.optionalType);
670
+ return appendJSDocToNode({
671
+ node: createPropertySignature({
672
+ questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
673
+ name: prop.name,
674
+ type,
675
+ readOnly: prop.schema.readOnly
676
+ }),
677
+ comments: buildPropertyJSDocComments(prop.schema)
678
+ });
679
+ });
680
+ const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, transform)];
681
+ if (!allElements.length) return keywordTypeNodes.object;
682
+ return createTypeLiteralNode(allElements);
683
+ }
684
+ },
685
+ print(node) {
686
+ let type = this.transform(node);
687
+ if (!type) return null;
688
+ if (node.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
689
+ if ((node.nullish || node.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
690
+ const { name, syntaxType = "type", description, keysToOmit } = this.options;
691
+ if (!name) return (0, _kubb_fabric_core_parsers_typescript.safePrint)(type);
692
+ const useTypeGeneration = syntaxType === "type" || type.kind === syntaxKind.union || !!keysToOmit?.length;
693
+ return (0, _kubb_fabric_core_parsers_typescript.safePrint)(createTypeDeclaration({
694
+ name,
695
+ isExportable: true,
696
+ type: keysToOmit?.length ? createOmitDeclaration({
697
+ keys: keysToOmit,
698
+ type,
699
+ nonNullable: true
700
+ }) : type,
701
+ syntax: useTypeGeneration ? "type" : "interface",
702
+ comments: [
703
+ node?.title ? jsStringEscape(node.title) : void 0,
704
+ description ? `@description ${jsStringEscape(description)}` : void 0,
705
+ node?.deprecated ? "@deprecated" : void 0,
706
+ node && "min" in node && node.min !== void 0 ? `@minLength ${node.min}` : void 0,
707
+ node && "max" in node && node.max !== void 0 ? `@maxLength ${node.max}` : void 0,
708
+ node && "pattern" in node && node.pattern ? `@pattern ${node.pattern}` : void 0,
709
+ node?.default ? `@default ${node.default}` : void 0,
710
+ node?.example ? `@example ${node.example}` : void 0
711
+ ]
712
+ }));
713
+ }
714
+ };
25
715
  });
716
+ //#endregion
717
+ //#region src/components/Type.tsx
718
+ function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumTypeSuffix, enumKeyCasing, description, resolver, enumSchemaNames }) {
719
+ const resolvedDescription = description || node?.description;
720
+ const enumSchemaNodes = (0, _kubb_ast.collect)(node, { schema(n) {
721
+ const enumNode = (0, _kubb_ast.narrowSchema)(n, _kubb_ast.schemaTypes.enum);
722
+ if (enumNode?.name) return enumNode;
723
+ } });
724
+ const output = printerTs({
725
+ optionalType,
726
+ arrayType,
727
+ enumType,
728
+ enumTypeSuffix,
729
+ name,
730
+ syntaxType,
731
+ description: resolvedDescription,
732
+ keysToOmit,
733
+ resolver,
734
+ enumSchemaNames
735
+ }).print(node);
736
+ if (!output) return;
737
+ const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
738
+ return {
739
+ node,
740
+ ...getEnumNames({
741
+ node,
742
+ enumType,
743
+ enumTypeSuffix,
744
+ resolver
745
+ })
746
+ };
747
+ });
748
+ const shouldExportEnums = enumType !== "inlineLiteral";
749
+ const shouldExportType = enumType === "inlineLiteral" || enums.every((item) => item.typeName !== name);
750
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [shouldExportEnums && enums.map(({ node }) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Enum, {
751
+ node,
752
+ enumType,
753
+ enumTypeSuffix,
754
+ enumKeyCasing,
755
+ resolver
756
+ })), shouldExportType && /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Source, {
757
+ name,
758
+ isTypeOnly: true,
759
+ isExportable: true,
760
+ isIndexable: true,
761
+ children: output
762
+ })] });
763
+ }
764
+ //#endregion
765
+ //#region src/utils.ts
766
+ function buildParams({ params, node, resolver }) {
767
+ return (0, _kubb_ast.createSchema)({
768
+ type: "object",
769
+ properties: params.map((param) => (0, _kubb_ast.createProperty)({
770
+ name: param.name,
771
+ required: param.required,
772
+ schema: (0, _kubb_ast.createSchema)({
773
+ type: "ref",
774
+ name: resolver.resolveParamName(node, param)
775
+ })
776
+ }))
777
+ });
778
+ }
779
+ function buildData({ node, resolver }) {
780
+ const pathParams = node.parameters.filter((p) => p.in === "path");
781
+ const queryParams = node.parameters.filter((p) => p.in === "query");
782
+ const headerParams = node.parameters.filter((p) => p.in === "header");
783
+ return (0, _kubb_ast.createSchema)({
784
+ type: "object",
785
+ deprecated: node.deprecated,
786
+ properties: [
787
+ (0, _kubb_ast.createProperty)({
788
+ name: "data",
789
+ schema: node.requestBody?.schema ? (0, _kubb_ast.createSchema)({
790
+ type: "ref",
791
+ name: resolver.resolveDataName(node),
792
+ optional: true
793
+ }) : (0, _kubb_ast.createSchema)({
794
+ type: "never",
795
+ optional: true
796
+ })
797
+ }),
798
+ (0, _kubb_ast.createProperty)({
799
+ name: "pathParams",
800
+ required: pathParams.length > 0,
801
+ schema: pathParams.length > 0 ? buildParams({
802
+ params: pathParams,
803
+ node,
804
+ resolver
805
+ }) : (0, _kubb_ast.createSchema)({ type: "never" })
806
+ }),
807
+ (0, _kubb_ast.createProperty)({
808
+ name: "queryParams",
809
+ schema: queryParams.length > 0 ? (0, _kubb_ast.createSchema)({
810
+ ...buildParams({
811
+ params: queryParams,
812
+ node,
813
+ resolver
814
+ }),
815
+ optional: true
816
+ }) : (0, _kubb_ast.createSchema)({
817
+ type: "never",
818
+ optional: true
819
+ })
820
+ }),
821
+ (0, _kubb_ast.createProperty)({
822
+ name: "headerParams",
823
+ schema: headerParams.length > 0 ? (0, _kubb_ast.createSchema)({
824
+ ...buildParams({
825
+ params: headerParams,
826
+ node,
827
+ resolver
828
+ }),
829
+ optional: true
830
+ }) : (0, _kubb_ast.createSchema)({
831
+ type: "never",
832
+ optional: true
833
+ })
834
+ }),
835
+ (0, _kubb_ast.createProperty)({
836
+ name: "url",
837
+ required: true,
838
+ schema: (0, _kubb_ast.createSchema)({
839
+ type: "url",
840
+ path: node.path
841
+ })
842
+ })
843
+ ]
844
+ });
845
+ }
846
+ function buildResponses({ node, resolver }) {
847
+ if (node.responses.length === 0) return null;
848
+ return (0, _kubb_ast.createSchema)({
849
+ type: "object",
850
+ properties: node.responses.map((res) => (0, _kubb_ast.createProperty)({
851
+ name: String(res.statusCode),
852
+ required: true,
853
+ schema: (0, _kubb_ast.createSchema)({
854
+ type: "ref",
855
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
856
+ })
857
+ }))
858
+ });
859
+ }
860
+ function buildResponseUnion({ node, resolver }) {
861
+ const responsesWithSchema = node.responses.filter((res) => res.schema);
862
+ if (responsesWithSchema.length === 0) return null;
863
+ return (0, _kubb_ast.createSchema)({
864
+ type: "union",
865
+ members: responsesWithSchema.map((res) => (0, _kubb_ast.createSchema)({
866
+ type: "ref",
867
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
868
+ }))
869
+ });
870
+ }
871
+ //#endregion
872
+ //#region src/generators/typeGenerator.tsx
873
+ const typeGenerator = (0, _kubb_core.defineGenerator)({
874
+ name: "typescript",
875
+ type: "react",
876
+ Operation({ node, adapter, options, config, resolver }) {
877
+ const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, transformers = [] } = options;
878
+ const root = node_path.default.resolve(config.root, config.output.path);
879
+ const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
880
+ const file = resolver.resolveFile({
881
+ name: node.operationId,
882
+ extname: ".ts",
883
+ tag: node.tags[0] ?? "default",
884
+ path: node.path
885
+ }, {
886
+ root,
887
+ output,
888
+ group
889
+ });
890
+ const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
891
+ const enumSchemaNames = new Set((adapter.rootNode?.schemas ?? []).filter((s) => (0, _kubb_ast.narrowSchema)(s, _kubb_ast.schemaTypes.enum) && s.name).map((s) => s.name));
892
+ function resolveImportName(schemaName) {
893
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
894
+ return resolver.default(schemaName, "type");
895
+ }
896
+ function renderSchemaType({ node: schemaNode, name, description, keysToOmit }) {
897
+ if (!schemaNode) return null;
898
+ const transformedNode = (0, _kubb_ast.transform)(schemaNode, (0, _kubb_ast.composeTransformers)(...transformers));
899
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
900
+ name: resolveImportName(schemaName),
901
+ path: resolver.resolveFile({
902
+ name: schemaName,
903
+ extname: ".ts"
904
+ }, {
905
+ root,
906
+ output,
907
+ group
908
+ }).path
909
+ }));
910
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
911
+ root: file.path,
912
+ path: imp.path,
913
+ name: imp.name,
914
+ isTypeOnly: true
915
+ }, [
916
+ name,
917
+ imp.path,
918
+ imp.isTypeOnly
919
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
920
+ name,
921
+ node: transformedNode,
922
+ description,
923
+ enumType,
924
+ enumTypeSuffix,
925
+ enumKeyCasing,
926
+ optionalType,
927
+ arrayType,
928
+ syntaxType,
929
+ resolver,
930
+ keysToOmit,
931
+ enumSchemaNames
932
+ })] });
933
+ }
934
+ const paramTypes = params.map((param) => renderSchemaType({
935
+ node: param.schema,
936
+ name: resolver.resolveParamName(node, param)
937
+ }));
938
+ const requestType = node.requestBody?.schema ? renderSchemaType({
939
+ node: node.requestBody.schema,
940
+ name: resolver.resolveDataName(node),
941
+ description: node.requestBody.description ?? node.requestBody.schema.description,
942
+ keysToOmit: node.requestBody.keysToOmit
943
+ }) : null;
944
+ const responseTypes = node.responses.map((res) => renderSchemaType({
945
+ node: res.schema,
946
+ name: resolver.resolveResponseStatusName(node, res.statusCode),
947
+ description: res.description,
948
+ keysToOmit: res.keysToOmit
949
+ }));
950
+ const dataType = renderSchemaType({
951
+ node: buildData({
952
+ node: {
953
+ ...node,
954
+ parameters: params
955
+ },
956
+ resolver
957
+ }),
958
+ name: resolver.resolveRequestConfigName(node)
959
+ });
960
+ const responsesType = renderSchemaType({
961
+ node: buildResponses({
962
+ node,
963
+ resolver
964
+ }),
965
+ name: resolver.resolveResponsesName(node)
966
+ });
967
+ const responseType = renderSchemaType({
968
+ node: buildResponseUnion({
969
+ node,
970
+ resolver
971
+ }),
972
+ name: resolver.resolveResponseName(node),
973
+ description: "Union of all possible responses"
974
+ });
975
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
976
+ baseName: file.baseName,
977
+ path: file.path,
978
+ meta: file.meta,
979
+ banner: resolver.resolveBanner(adapter.rootNode, {
980
+ output,
981
+ config
982
+ }),
983
+ footer: resolver.resolveFooter(adapter.rootNode, {
984
+ output,
985
+ config
986
+ }),
987
+ children: [
988
+ paramTypes,
989
+ responseTypes,
990
+ requestType,
991
+ dataType,
992
+ responsesType,
993
+ responseType
994
+ ]
995
+ });
996
+ },
997
+ Schema({ node, adapter, options, config, resolver }) {
998
+ const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options;
999
+ const root = node_path.default.resolve(config.root, config.output.path);
1000
+ const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
1001
+ if (!node.name) return;
1002
+ const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
1003
+ const enumSchemaNames = new Set((adapter.rootNode?.schemas ?? []).filter((s) => (0, _kubb_ast.narrowSchema)(s, _kubb_ast.schemaTypes.enum) && s.name).map((s) => s.name));
1004
+ function resolveImportName(schemaName) {
1005
+ if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
1006
+ return resolver.default(schemaName, "type");
1007
+ }
1008
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
1009
+ name: resolveImportName(schemaName),
1010
+ path: resolver.resolveFile({
1011
+ name: schemaName,
1012
+ extname: ".ts"
1013
+ }, {
1014
+ root,
1015
+ output,
1016
+ group
1017
+ }).path
1018
+ }));
1019
+ const isEnumSchema = !!(0, _kubb_ast.narrowSchema)(node, _kubb_ast.schemaTypes.enum);
1020
+ const type = {
1021
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolver.resolveName(node.name),
1022
+ file: resolver.resolveFile({
1023
+ name: node.name,
1024
+ extname: ".ts"
1025
+ }, {
1026
+ root,
1027
+ output,
1028
+ group
1029
+ })
1030
+ };
1031
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1032
+ baseName: type.file.baseName,
1033
+ path: type.file.path,
1034
+ meta: type.file.meta,
1035
+ banner: resolver.resolveBanner(adapter.rootNode, {
1036
+ output,
1037
+ config
1038
+ }),
1039
+ footer: resolver.resolveFooter(adapter.rootNode, {
1040
+ output,
1041
+ config
1042
+ }),
1043
+ children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1044
+ root: type.file.path,
1045
+ path: imp.path,
1046
+ name: imp.name,
1047
+ isTypeOnly: true
1048
+ }, [
1049
+ node.name,
1050
+ imp.path,
1051
+ imp.isTypeOnly
1052
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1053
+ name: type.name,
1054
+ node: transformedNode,
1055
+ enumType,
1056
+ enumTypeSuffix,
1057
+ enumKeyCasing,
1058
+ optionalType,
1059
+ arrayType,
1060
+ syntaxType,
1061
+ resolver,
1062
+ enumSchemaNames
1063
+ })]
1064
+ });
1065
+ }
1066
+ });
1067
+ //#endregion
1068
+ //#region src/resolvers/resolverTs.ts
1069
+ function resolveName(name, type) {
1070
+ return pascalCase(name, { isFile: type === "file" });
1071
+ }
26
1072
  /**
27
- * Resolves a compatibility preset for `plugin-ts`, merging user-supplied resolvers,
28
- * transformers, and generators on top of the built-in preset defaults.
1073
+ * Resolver for `@kubb/plugin-ts` that provides the default naming and path-resolution
1074
+ * helpers used by the plugin. Import this in other plugins to resolve the exact names and
1075
+ * paths that `plugin-ts` generates without hardcoding the conventions.
29
1076
  *
30
- * `resolverTs` is always prepended to the resolver list as the baseline.
1077
+ * The `default` method is automatically injected by `defineResolver` it uses `camelCase`
1078
+ * for identifiers/files and `pascalCase` for type names.
31
1079
  *
32
1080
  * @example
33
1081
  * ```ts
34
- * const preset = getPreset('kubbV4', { resolvers: [], transformers: [], generators: [] })
1082
+ * import { resolver } from '@kubb/plugin-ts'
1083
+ *
1084
+ * resolver.default('list pets', 'type') // → 'ListPets'
1085
+ * resolver.resolveName('list pets status 200') // → 'ListPetsStatus200'
1086
+ * resolver.resolvePathName('list pets', 'file') // → 'listPets'
35
1087
  * ```
36
1088
  */
37
- function getPreset(preset, { resolvers, transformers, generators }) {
38
- return (0, _kubb_core.getPreset)({
39
- preset,
40
- presets,
41
- resolvers: [require_resolverTsLegacy.resolverTs, ...resolvers ?? []],
42
- transformers,
43
- generators
1089
+ const resolverTs = (0, _kubb_core.defineResolver)(() => {
1090
+ return {
1091
+ name: "default",
1092
+ pluginName: "plugin-ts",
1093
+ default(name, type) {
1094
+ return resolveName(name, type);
1095
+ },
1096
+ resolveName(name) {
1097
+ return this.default(name, "function");
1098
+ },
1099
+ resolvePathName(name, type) {
1100
+ return this.default(name, type);
1101
+ },
1102
+ resolveParamName(node, param) {
1103
+ return this.resolveName(`${node.operationId} ${param.in} ${param.name}`);
1104
+ },
1105
+ resolveResponseStatusName(node, statusCode) {
1106
+ return this.resolveName(`${node.operationId} Status ${statusCode}`);
1107
+ },
1108
+ resolveDataName(node) {
1109
+ return this.resolveName(`${node.operationId} Data`);
1110
+ },
1111
+ resolveRequestConfigName(node) {
1112
+ return this.resolveName(`${node.operationId} RequestConfig`);
1113
+ },
1114
+ resolveResponsesName(node) {
1115
+ return this.resolveName(`${node.operationId} Responses`);
1116
+ },
1117
+ resolveResponseName(node) {
1118
+ return this.resolveName(`${node.operationId} Response`);
1119
+ },
1120
+ resolveEnumKeyName(node, enumTypeSuffix = "key") {
1121
+ return `${this.resolveName(node.name ?? "")}${enumTypeSuffix}`;
1122
+ },
1123
+ resolvePathParamsName(node, param) {
1124
+ return this.resolveParamName(node, param);
1125
+ },
1126
+ resolveQueryParamsName(node, param) {
1127
+ return this.resolveParamName(node, param);
1128
+ },
1129
+ resolveHeaderParamsName(node, param) {
1130
+ return this.resolveParamName(node, param);
1131
+ }
1132
+ };
1133
+ });
1134
+ //#endregion
1135
+ //#region src/resolvers/resolverTsLegacy.ts
1136
+ /**
1137
+ * Legacy resolver for `@kubb/plugin-ts` that reproduces the naming conventions
1138
+ * used before the v2 resolver refactor. Enable via `compatibilityPreset: 'kubbV4'`
1139
+ * (or by composing this resolver manually).
1140
+ *
1141
+ * Key differences from the default resolver:
1142
+ * - Response status types: `<OperationId><StatusCode>` (e.g. `CreatePets201`) instead of `<OperationId>Status201`
1143
+ * - Default/error responses: `<OperationId>Error` instead of `<OperationId>StatusDefault`
1144
+ * - Request body: `<OperationId>MutationRequest` (non-GET) / `<OperationId>QueryRequest` (GET)
1145
+ * - Combined responses type: `<OperationId>Mutation` / `<OperationId>Query`
1146
+ * - Response union: `<OperationId>MutationResponse` / `<OperationId>QueryResponse`
1147
+ *
1148
+ * @example
1149
+ * ```ts
1150
+ * import { resolverTsLegacy } from '@kubb/plugin-ts'
1151
+ *
1152
+ * resolverTsLegacy.resolveResponseStatusTypedName(node, 201) // → 'CreatePets201'
1153
+ * resolverTsLegacy.resolveResponseStatusTypedName(node, 'default') // → 'CreatePetsError'
1154
+ * resolverTsLegacy.resolveDataTypedName(node) // → 'CreatePetsMutationRequest' (POST)
1155
+ * resolverTsLegacy.resolveResponsesTypedName(node) // → 'CreatePetsMutation' (POST)
1156
+ * resolverTsLegacy.resolveResponseTypedName(node) // → 'CreatePetsMutationResponse' (POST)
1157
+ * ```
1158
+ */
1159
+ const resolverTsLegacy = (0, _kubb_core.defineResolver)(() => {
1160
+ return {
1161
+ ...resolverTs,
1162
+ pluginName: "plugin-ts",
1163
+ resolveResponseStatusName(node, statusCode) {
1164
+ if (statusCode === "default") return this.resolveName(`${node.operationId} Error`);
1165
+ return this.resolveName(`${node.operationId} ${statusCode}`);
1166
+ },
1167
+ resolveDataName(node) {
1168
+ const suffix = node.method === "GET" ? "QueryRequest" : "MutationRequest";
1169
+ return this.resolveName(`${node.operationId} ${suffix}`);
1170
+ },
1171
+ resolveResponsesName(node) {
1172
+ const suffix = node.method === "GET" ? "Query" : "Mutation";
1173
+ return this.resolveName(`${node.operationId} ${suffix}`);
1174
+ },
1175
+ resolveResponseName(node) {
1176
+ const suffix = node.method === "GET" ? "QueryResponse" : "MutationResponse";
1177
+ return this.resolveName(`${node.operationId} ${suffix}`);
1178
+ },
1179
+ resolvePathParamsName(node, _param) {
1180
+ return this.resolveName(`${node.operationId} PathParams`);
1181
+ },
1182
+ resolveQueryParamsName(node, _param) {
1183
+ return this.resolveName(`${node.operationId} QueryParams`);
1184
+ },
1185
+ resolveHeaderParamsName(node, _param) {
1186
+ return this.resolveName(`${node.operationId} HeaderParams`);
1187
+ }
1188
+ };
1189
+ });
1190
+ //#endregion
1191
+ //#region src/generators/typeGeneratorLegacy.tsx
1192
+ function buildGroupedParamsSchema({ params, parentName }) {
1193
+ return (0, _kubb_ast.createSchema)({
1194
+ type: "object",
1195
+ properties: params.map((param) => {
1196
+ let schema = param.schema;
1197
+ if ((0, _kubb_ast.narrowSchema)(schema, "enum") && !schema.name && parentName) schema = {
1198
+ ...schema,
1199
+ name: pascalCase([
1200
+ parentName,
1201
+ param.name,
1202
+ "enum"
1203
+ ].join(" "))
1204
+ };
1205
+ return (0, _kubb_ast.createProperty)({
1206
+ name: param.name,
1207
+ required: param.required,
1208
+ schema
1209
+ });
1210
+ })
44
1211
  });
45
1212
  }
1213
+ function buildLegacyResponsesSchemaNode({ node, resolver }) {
1214
+ const isGet = node.method.toLowerCase() === "get";
1215
+ const successResponses = node.responses.filter((res) => {
1216
+ const code = Number(res.statusCode);
1217
+ return !Number.isNaN(code) && code >= 200 && code < 300;
1218
+ });
1219
+ const errorResponses = node.responses.filter((res) => res.statusCode === "default" || Number(res.statusCode) >= 400);
1220
+ const responseSchema = successResponses.length > 0 ? successResponses.length === 1 ? (0, _kubb_ast.createSchema)({
1221
+ type: "ref",
1222
+ name: resolver.resolveResponseStatusName(node, successResponses[0].statusCode)
1223
+ }) : (0, _kubb_ast.createSchema)({
1224
+ type: "union",
1225
+ members: successResponses.map((res) => (0, _kubb_ast.createSchema)({
1226
+ type: "ref",
1227
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
1228
+ }))
1229
+ }) : (0, _kubb_ast.createSchema)({ type: "any" });
1230
+ const errorsSchema = errorResponses.length > 0 ? errorResponses.length === 1 ? (0, _kubb_ast.createSchema)({
1231
+ type: "ref",
1232
+ name: resolver.resolveResponseStatusName(node, errorResponses[0].statusCode)
1233
+ }) : (0, _kubb_ast.createSchema)({
1234
+ type: "union",
1235
+ members: errorResponses.map((res) => (0, _kubb_ast.createSchema)({
1236
+ type: "ref",
1237
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
1238
+ }))
1239
+ }) : (0, _kubb_ast.createSchema)({ type: "any" });
1240
+ const properties = [(0, _kubb_ast.createProperty)({
1241
+ name: "Response",
1242
+ required: true,
1243
+ schema: responseSchema
1244
+ })];
1245
+ if (!isGet && node.requestBody?.schema) properties.push((0, _kubb_ast.createProperty)({
1246
+ name: "Request",
1247
+ required: true,
1248
+ schema: (0, _kubb_ast.createSchema)({
1249
+ type: "ref",
1250
+ name: resolver.resolveDataName(node)
1251
+ })
1252
+ }));
1253
+ const queryParam = node.parameters.find((p) => p.in === "query");
1254
+ if (queryParam) properties.push((0, _kubb_ast.createProperty)({
1255
+ name: "QueryParams",
1256
+ required: true,
1257
+ schema: (0, _kubb_ast.createSchema)({
1258
+ type: "ref",
1259
+ name: resolver.resolveQueryParamsName(node, queryParam)
1260
+ })
1261
+ }));
1262
+ const pathParam = node.parameters.find((p) => p.in === "path");
1263
+ if (pathParam) properties.push((0, _kubb_ast.createProperty)({
1264
+ name: "PathParams",
1265
+ required: true,
1266
+ schema: (0, _kubb_ast.createSchema)({
1267
+ type: "ref",
1268
+ name: resolver.resolvePathParamsName(node, pathParam)
1269
+ })
1270
+ }));
1271
+ const headerParam = node.parameters.find((p) => p.in === "header");
1272
+ if (headerParam) properties.push((0, _kubb_ast.createProperty)({
1273
+ name: "HeaderParams",
1274
+ required: true,
1275
+ schema: (0, _kubb_ast.createSchema)({
1276
+ type: "ref",
1277
+ name: resolver.resolveHeaderParamsName(node, headerParam)
1278
+ })
1279
+ }));
1280
+ properties.push((0, _kubb_ast.createProperty)({
1281
+ name: "Errors",
1282
+ required: true,
1283
+ schema: errorsSchema
1284
+ }));
1285
+ return (0, _kubb_ast.createSchema)({
1286
+ type: "object",
1287
+ properties
1288
+ });
1289
+ }
1290
+ function buildLegacyResponseUnionSchemaNode({ node, resolver }) {
1291
+ const successResponses = node.responses.filter((res) => {
1292
+ const code = Number(res.statusCode);
1293
+ return !Number.isNaN(code) && code >= 200 && code < 300;
1294
+ });
1295
+ if (successResponses.length === 0) return (0, _kubb_ast.createSchema)({ type: "any" });
1296
+ if (successResponses.length === 1) return (0, _kubb_ast.createSchema)({
1297
+ type: "ref",
1298
+ name: resolver.resolveResponseStatusName(node, successResponses[0].statusCode)
1299
+ });
1300
+ return (0, _kubb_ast.createSchema)({
1301
+ type: "union",
1302
+ members: successResponses.map((res) => (0, _kubb_ast.createSchema)({
1303
+ type: "ref",
1304
+ name: resolver.resolveResponseStatusName(node, res.statusCode)
1305
+ }))
1306
+ });
1307
+ }
1308
+ function nameUnnamedEnums(node, parentName) {
1309
+ return (0, _kubb_ast.transform)(node, {
1310
+ schema(n) {
1311
+ const enumNode = (0, _kubb_ast.narrowSchema)(n, "enum");
1312
+ if (enumNode && !enumNode.name) return {
1313
+ ...enumNode,
1314
+ name: pascalCase([parentName, "enum"].join(" "))
1315
+ };
1316
+ },
1317
+ property(p) {
1318
+ const enumNode = (0, _kubb_ast.narrowSchema)(p.schema, "enum");
1319
+ if (enumNode && !enumNode.name) return {
1320
+ ...p,
1321
+ schema: {
1322
+ ...enumNode,
1323
+ name: pascalCase([
1324
+ parentName,
1325
+ p.name,
1326
+ "enum"
1327
+ ].join(" "))
1328
+ }
1329
+ };
1330
+ }
1331
+ });
1332
+ }
1333
+ const typeGeneratorLegacy = (0, _kubb_core.defineGenerator)({
1334
+ name: "typescript-legacy",
1335
+ type: "react",
1336
+ Operation({ node, adapter, options, config, resolver }) {
1337
+ const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, transformers = [] } = options;
1338
+ const root = node_path.default.resolve(config.root, config.output.path);
1339
+ const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
1340
+ const file = resolver.resolveFile({
1341
+ name: node.operationId,
1342
+ extname: ".ts",
1343
+ tag: node.tags[0] ?? "default",
1344
+ path: node.path
1345
+ }, {
1346
+ root,
1347
+ output,
1348
+ group
1349
+ });
1350
+ const params = (0, _kubb_ast.caseParams)(node.parameters, paramsCasing);
1351
+ function renderSchemaType({ node: schemaNode, name, description, keysToOmit }) {
1352
+ if (!schemaNode) return null;
1353
+ const transformedNode = (0, _kubb_ast.transform)(schemaNode, (0, _kubb_ast.composeTransformers)(...transformers));
1354
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
1355
+ name: resolver.default(schemaName, "type"),
1356
+ path: resolver.resolveFile({
1357
+ name: schemaName,
1358
+ extname: ".ts"
1359
+ }, {
1360
+ root,
1361
+ output,
1362
+ group
1363
+ }).path
1364
+ }));
1365
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric_jsx_runtime.Fragment, { children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1366
+ root: file.path,
1367
+ path: imp.path,
1368
+ name: imp.name,
1369
+ isTypeOnly: true
1370
+ }, [
1371
+ name,
1372
+ imp.path,
1373
+ imp.isTypeOnly
1374
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1375
+ name,
1376
+ node: transformedNode,
1377
+ description,
1378
+ enumType,
1379
+ enumTypeSuffix,
1380
+ enumKeyCasing,
1381
+ optionalType,
1382
+ arrayType,
1383
+ syntaxType,
1384
+ resolver,
1385
+ keysToOmit
1386
+ })] });
1387
+ }
1388
+ const pathParams = params.filter((p) => p.in === "path");
1389
+ const queryParams = params.filter((p) => p.in === "query");
1390
+ const headerParams = params.filter((p) => p.in === "header");
1391
+ const responseTypes = node.responses.map((res) => {
1392
+ const responseName = resolver.resolveResponseStatusName(node, res.statusCode);
1393
+ const baseResponseName = resolverTsLegacy.resolveResponseStatusName(node, res.statusCode);
1394
+ return renderSchemaType({
1395
+ node: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
1396
+ name: responseName,
1397
+ description: res.description,
1398
+ keysToOmit: res.keysToOmit
1399
+ });
1400
+ });
1401
+ const requestType = node.requestBody?.schema ? renderSchemaType({
1402
+ node: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
1403
+ name: resolver.resolveDataName(node),
1404
+ description: node.requestBody.description ?? node.requestBody.schema.description,
1405
+ keysToOmit: node.requestBody.keysToOmit
1406
+ }) : null;
1407
+ const legacyParamTypes = [
1408
+ pathParams.length > 0 ? renderSchemaType({
1409
+ node: buildGroupedParamsSchema({
1410
+ params: pathParams,
1411
+ parentName: resolverTsLegacy.resolvePathParamsName(node, pathParams[0])
1412
+ }),
1413
+ name: resolver.resolvePathParamsName(node, pathParams[0])
1414
+ }) : null,
1415
+ queryParams.length > 0 ? renderSchemaType({
1416
+ node: buildGroupedParamsSchema({
1417
+ params: queryParams,
1418
+ parentName: resolverTsLegacy.resolveQueryParamsName(node, queryParams[0])
1419
+ }),
1420
+ name: resolver.resolveQueryParamsName(node, queryParams[0])
1421
+ }) : null,
1422
+ headerParams.length > 0 ? renderSchemaType({
1423
+ node: buildGroupedParamsSchema({
1424
+ params: headerParams,
1425
+ parentName: resolverTsLegacy.resolveHeaderParamsName(node, headerParams[0])
1426
+ }),
1427
+ name: resolver.resolveHeaderParamsName(node, headerParams[0])
1428
+ }) : null
1429
+ ];
1430
+ const legacyResponsesType = renderSchemaType({
1431
+ node: buildLegacyResponsesSchemaNode({
1432
+ node,
1433
+ resolver
1434
+ }),
1435
+ name: resolver.resolveResponsesName(node)
1436
+ });
1437
+ const legacyResponseType = renderSchemaType({
1438
+ node: buildLegacyResponseUnionSchemaNode({
1439
+ node,
1440
+ resolver
1441
+ }),
1442
+ name: resolver.resolveResponseName(node)
1443
+ });
1444
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1445
+ baseName: file.baseName,
1446
+ path: file.path,
1447
+ meta: file.meta,
1448
+ banner: resolver.resolveBanner(adapter.rootNode, {
1449
+ output,
1450
+ config
1451
+ }),
1452
+ footer: resolver.resolveFooter(adapter.rootNode, {
1453
+ output,
1454
+ config
1455
+ }),
1456
+ children: [
1457
+ legacyParamTypes,
1458
+ responseTypes,
1459
+ requestType,
1460
+ legacyResponseType,
1461
+ legacyResponsesType
1462
+ ]
1463
+ });
1464
+ },
1465
+ Schema({ node, adapter, options, config, resolver }) {
1466
+ const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options;
1467
+ const root = node_path.default.resolve(config.root, config.output.path);
1468
+ const mode = (0, _kubb_core.getMode)(node_path.default.resolve(root, output.path));
1469
+ if (!node.name) return;
1470
+ const transformedNode = (0, _kubb_ast.transform)(node, (0, _kubb_ast.composeTransformers)(...transformers));
1471
+ const imports = adapter.getImports(transformedNode, (schemaName) => ({
1472
+ name: resolver.default(schemaName, "type"),
1473
+ path: resolver.resolveFile({
1474
+ name: schemaName,
1475
+ extname: ".ts"
1476
+ }, {
1477
+ root,
1478
+ output,
1479
+ group
1480
+ }).path
1481
+ }));
1482
+ const isEnumSchema = !!(0, _kubb_ast.narrowSchema)(node, _kubb_ast.schemaTypes.enum);
1483
+ const type = {
1484
+ name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolver.resolveName(node.name),
1485
+ file: resolver.resolveFile({
1486
+ name: node.name,
1487
+ extname: ".ts"
1488
+ }, {
1489
+ root,
1490
+ output,
1491
+ group
1492
+ })
1493
+ };
1494
+ return /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsxs)(_kubb_react_fabric.File, {
1495
+ baseName: type.file.baseName,
1496
+ path: type.file.path,
1497
+ meta: type.file.meta,
1498
+ banner: resolver.resolveBanner(adapter.rootNode, {
1499
+ output,
1500
+ config
1501
+ }),
1502
+ footer: resolver.resolveFooter(adapter.rootNode, {
1503
+ output,
1504
+ config
1505
+ }),
1506
+ children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.File.Import, {
1507
+ root: type.file.path,
1508
+ path: imp.path,
1509
+ name: imp.name,
1510
+ isTypeOnly: true
1511
+ }, [
1512
+ node.name,
1513
+ imp.path,
1514
+ imp.isTypeOnly
1515
+ ].join("-"))), /* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(Type, {
1516
+ name: type.name,
1517
+ node: transformedNode,
1518
+ enumType,
1519
+ enumTypeSuffix,
1520
+ enumKeyCasing,
1521
+ optionalType,
1522
+ arrayType,
1523
+ syntaxType,
1524
+ resolver
1525
+ })]
1526
+ });
1527
+ }
1528
+ });
1529
+ //#endregion
1530
+ //#region src/presets.ts
1531
+ /**
1532
+ * Built-in preset registry for `@kubb/plugin-ts`.
1533
+ *
1534
+ * - `default` — uses `resolverTs` and `typeGenerator` (current naming conventions).
1535
+ * - `kubbV4` — uses `resolverTsLegacy` and `typeGeneratorLegacy` (Kubb v4 naming conventions).
1536
+ */
1537
+ const presets = (0, _kubb_core.definePresets)({
1538
+ default: {
1539
+ name: "default",
1540
+ resolvers: [resolverTs],
1541
+ generators: [typeGenerator]
1542
+ },
1543
+ kubbV4: {
1544
+ name: "kubbV4",
1545
+ resolvers: [resolverTsLegacy],
1546
+ generators: [typeGeneratorLegacy]
1547
+ }
1548
+ });
46
1549
  //#endregion
47
1550
  //#region src/plugin.ts
48
1551
  /**
@@ -70,7 +1573,9 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
70
1573
  path: "types",
71
1574
  barrelType: "named"
72
1575
  }, group, exclude = [], include, override = [], enumType = "asConst", enumTypeSuffix = "Key", enumKeyCasing = "none", optionalType = "questionToken", arrayType = "array", syntaxType = "type", paramsCasing, compatibilityPreset = "default", resolvers: userResolvers = [], transformers: userTransformers = [], generators: userGenerators = [] } = options;
73
- const { resolver, transformers, generators } = getPreset(compatibilityPreset, {
1576
+ const preset = (0, _kubb_core.getPreset)({
1577
+ preset: compatibilityPreset,
1578
+ presets,
74
1579
  resolvers: userResolvers,
75
1580
  transformers: userTransformers,
76
1581
  generators: userGenerators
@@ -79,25 +1584,35 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
79
1584
  let resolvePathWarning = false;
80
1585
  return {
81
1586
  name: pluginTsName,
82
- options: {
83
- output,
84
- optionalType,
85
- group,
86
- arrayType,
87
- enumType,
88
- enumTypeSuffix,
89
- enumKeyCasing,
90
- syntaxType,
91
- paramsCasing,
92
- resolver,
93
- transformers
1587
+ get resolver() {
1588
+ return preset.resolver;
1589
+ },
1590
+ get options() {
1591
+ return {
1592
+ output,
1593
+ optionalType,
1594
+ group: group ? {
1595
+ ...options.group,
1596
+ name: (ctx) => {
1597
+ if (options.group?.type === "path") return `${ctx.group.split("/")[1]}`;
1598
+ return `${camelCase(ctx.group)}Controller`;
1599
+ }
1600
+ } : void 0,
1601
+ arrayType,
1602
+ enumType,
1603
+ enumTypeSuffix,
1604
+ enumKeyCasing,
1605
+ syntaxType,
1606
+ paramsCasing,
1607
+ transformers: preset.transformers
1608
+ };
94
1609
  },
95
1610
  resolvePath(baseName, pathMode, options) {
96
1611
  if (!resolvePathWarning) {
97
- this.driver.events.emit("warn", "Do not use resolvePath for pluginTs, use resolverTs.resolvePath instead");
1612
+ this.events.emit("warn", "Do not use resolvePath for pluginTs, use resolverTs.resolvePath instead");
98
1613
  resolvePathWarning = true;
99
1614
  }
100
- return resolver.resolvePath({
1615
+ return this.plugin.resolver.resolvePath({
101
1616
  baseName,
102
1617
  pathMode,
103
1618
  tag: options?.group?.tag,
@@ -105,25 +1620,25 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
105
1620
  }, {
106
1621
  root: node_path.default.resolve(this.config.root, this.config.output.path),
107
1622
  output,
108
- group
1623
+ group: this.plugin.options.group
109
1624
  });
110
1625
  },
111
1626
  resolveName(name, type) {
112
1627
  if (!resolveNameWarning) {
113
- this.driver.events.emit("warn", "Do not use resolveName for pluginTs, use resolverTs.default instead");
1628
+ this.events.emit("warn", "Do not use resolveName for pluginTs, use resolverTs.default instead");
114
1629
  resolveNameWarning = true;
115
1630
  }
116
- return resolver.default(name, type);
1631
+ return this.plugin.resolver.default(name, type);
117
1632
  },
118
1633
  async install() {
119
- const { config, fabric, plugin, adapter, rootNode, driver, openInStudio } = this;
1634
+ const { config, fabric, plugin, adapter, rootNode, driver, openInStudio, resolver } = this;
120
1635
  const root = node_path.default.resolve(config.root, config.output.path);
121
1636
  if (!adapter) throw new Error("Plugin cannot work without adapter being set");
122
1637
  await openInStudio({ ast: true });
123
1638
  await (0, _kubb_ast.walk)(rootNode, {
124
1639
  depth: "shallow",
125
1640
  async schema(schemaNode) {
126
- const writeTasks = generators.map(async (generator) => {
1641
+ const writeTasks = preset.generators.map(async (generator) => {
127
1642
  if (generator.type === "react" && generator.version === "2") {
128
1643
  const options = resolver.resolveOptions(schemaNode, {
129
1644
  options: plugin.options,
@@ -134,6 +1649,7 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
134
1649
  if (options === null) return;
135
1650
  await (0, _kubb_core.renderSchema)(schemaNode, {
136
1651
  options,
1652
+ resolver,
137
1653
  adapter,
138
1654
  config,
139
1655
  fabric,
@@ -146,7 +1662,7 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
146
1662
  await Promise.all(writeTasks);
147
1663
  },
148
1664
  async operation(operationNode) {
149
- const writeTasks = generators.map(async (generator) => {
1665
+ const writeTasks = preset.generators.map(async (generator) => {
150
1666
  if (generator.type === "react" && generator.version === "2") {
151
1667
  const options = resolver.resolveOptions(operationNode, {
152
1668
  options: plugin.options,
@@ -157,6 +1673,7 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
157
1673
  if (options === null) return;
158
1674
  await (0, _kubb_core.renderOperation)(operationNode, {
159
1675
  options,
1676
+ resolver,
160
1677
  adapter,
161
1678
  config,
162
1679
  fabric,
@@ -180,7 +1697,121 @@ const pluginTs = (0, _kubb_core.createPlugin)((options) => {
180
1697
  };
181
1698
  });
182
1699
  //#endregion
1700
+ //#region src/printers/functionPrinter.ts
1701
+ const kindToHandlerKey = {
1702
+ FunctionParameter: "functionParameter",
1703
+ ParameterGroup: "parameterGroup",
1704
+ FunctionParameters: "functionParameters",
1705
+ Type: "type"
1706
+ };
1707
+ /**
1708
+ * Creates a function-parameter printer factory.
1709
+ *
1710
+ * Uses `createPrinterFactory` and dispatches handlers by `node.kind`
1711
+ * (for function nodes) rather than by `node.type` (for schema nodes).
1712
+ */
1713
+ const defineFunctionPrinter = (0, _kubb_ast.createPrinterFactory)((node) => kindToHandlerKey[node.kind]);
1714
+ function rank(param) {
1715
+ if (param.kind === "ParameterGroup") {
1716
+ if (param.default) return 2;
1717
+ return param.optional ?? param.properties.every((p) => p.optional || p.default !== void 0) ? 1 : 0;
1718
+ }
1719
+ if (param.rest) return 3;
1720
+ if (param.default) return 2;
1721
+ return param.optional ? 1 : 0;
1722
+ }
1723
+ function sortParams(params) {
1724
+ return [...params].sort((a, b) => rank(a) - rank(b));
1725
+ }
1726
+ function sortChildParams(params) {
1727
+ return [...params].sort((a, b) => rank(a) - rank(b));
1728
+ }
1729
+ /**
1730
+ * Default function-signature printer.
1731
+ * Covers the four standard output modes used across Kubb plugins.
1732
+ *
1733
+ * @example
1734
+ * ```ts
1735
+ * const printer = functionPrinter({ mode: 'declaration' })
1736
+ *
1737
+ * const sig = createFunctionParameters({
1738
+ * params: [
1739
+ * createFunctionParameter({ name: 'petId', type: 'string', optional: false }),
1740
+ * createFunctionParameter({ name: 'config', type: 'Config', optional: false, default: '{}' }),
1741
+ * ],
1742
+ * })
1743
+ *
1744
+ * printer.print(sig) // → "petId: string, config: Config = {}"
1745
+ * ```
1746
+ */
1747
+ const functionPrinter = defineFunctionPrinter((options) => ({
1748
+ name: "functionParameters",
1749
+ options,
1750
+ nodes: {
1751
+ type(node) {
1752
+ if (node.variant === "member") return `${node.base}['${node.key}']`;
1753
+ if (node.variant === "struct") return `{ ${node.properties.map((p) => {
1754
+ const typeStr = this.transform(p.type);
1755
+ return p.optional ? `${p.name}?: ${typeStr}` : `${p.name}: ${typeStr}`;
1756
+ }).join("; ")} }`;
1757
+ if (node.variant === "reference") return node.name;
1758
+ return null;
1759
+ },
1760
+ functionParameter(node) {
1761
+ const { mode, transformName, transformType } = this.options;
1762
+ const name = transformName ? transformName(node.name) : node.name;
1763
+ const rawType = node.type ? this.transform(node.type) : void 0;
1764
+ const type = rawType != null && transformType ? transformType(rawType) : rawType;
1765
+ if (mode === "keys" || mode === "values") return node.rest ? `...${name}` : name;
1766
+ if (mode === "call") return node.rest ? `...${name}` : name;
1767
+ if (node.rest) return type ? `...${name}: ${type}` : `...${name}`;
1768
+ if (type) {
1769
+ if (node.optional) return `${name}?: ${type}`;
1770
+ return node.default ? `${name}: ${type} = ${node.default}` : `${name}: ${type}`;
1771
+ }
1772
+ return node.default ? `${name} = ${node.default}` : name;
1773
+ },
1774
+ parameterGroup(node) {
1775
+ const { mode, transformName, transformType } = this.options;
1776
+ const sorted = sortChildParams(node.properties);
1777
+ const isOptional = node.optional ?? sorted.every((p) => p.optional || p.default !== void 0);
1778
+ if (node.inline) return sorted.map((p) => this.transform(p)).filter(Boolean).join(", ");
1779
+ if (mode === "keys" || mode === "values") return `{ ${sorted.map((p) => p.name).join(", ")} }`;
1780
+ if (mode === "call") return `{ ${sorted.map((p) => p.name).join(", ")} }`;
1781
+ const names = sorted.map((p) => {
1782
+ return transformName ? transformName(p.name) : p.name;
1783
+ });
1784
+ const nameStr = names.length ? `{ ${names.join(", ")} }` : void 0;
1785
+ if (!nameStr) return null;
1786
+ let typeAnnotation = node.type ? this.transform(node.type) ?? void 0 : void 0;
1787
+ if (!typeAnnotation) {
1788
+ const typeParts = sorted.filter((p) => p.type).map((p) => {
1789
+ const rawT = p.type ? this.transform(p.type) : void 0;
1790
+ const t = rawT != null && transformType ? transformType(rawT) : rawT;
1791
+ return p.optional || p.default !== void 0 ? `${p.name}?: ${t}` : `${p.name}: ${t}`;
1792
+ });
1793
+ typeAnnotation = typeParts.length ? `{ ${typeParts.join("; ")} }` : void 0;
1794
+ }
1795
+ if (typeAnnotation) {
1796
+ if (isOptional) return `${nameStr}: ${typeAnnotation} = ${node.default ?? "{}"}`;
1797
+ return node.default ? `${nameStr}: ${typeAnnotation} = ${node.default}` : `${nameStr}: ${typeAnnotation}`;
1798
+ }
1799
+ return node.default ? `${nameStr} = ${node.default}` : nameStr;
1800
+ },
1801
+ functionParameters(node) {
1802
+ return sortParams(node.params).map((p) => this.transform(p)).filter(Boolean).join(", ");
1803
+ }
1804
+ }
1805
+ }));
1806
+ //#endregion
1807
+ exports.Enum = Enum;
1808
+ exports.Type = Type;
1809
+ exports.functionPrinter = functionPrinter;
183
1810
  exports.pluginTs = pluginTs;
184
1811
  exports.pluginTsName = pluginTsName;
1812
+ exports.printerTs = printerTs;
1813
+ exports.resolverTs = resolverTs;
1814
+ exports.resolverTsLegacy = resolverTsLegacy;
1815
+ exports.typeGenerator = typeGenerator;
185
1816
 
186
1817
  //# sourceMappingURL=index.cjs.map