@kubb/plugin-ts 5.0.0-beta.4 → 5.0.0-beta.42
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/README.md +39 -22
- package/dist/index.cjs +432 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +84 -62
- package/dist/index.js +427 -125
- package/dist/index.js.map +1 -1
- package/extension.yaml +713 -265
- package/package.json +10 -12
- package/src/components/Enum.tsx +3 -3
- package/src/factory.ts +54 -25
- package/src/generators/typeGenerator.tsx +100 -39
- package/src/plugin.ts +20 -21
- package/src/printers/functionPrinter.ts +2 -2
- package/src/printers/printerTs.ts +31 -30
- package/src/resolvers/resolverTs.ts +28 -25
- package/src/types.ts +44 -37
- package/src/utils.ts +23 -13
- /package/dist/{chunk--u3MIqq1.js → chunk-C0LytTxp.js} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,10 @@ Object.defineProperties(exports, {
|
|
|
5
5
|
//#region \0rolldown/runtime.js
|
|
6
6
|
var __create = Object.create;
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", {
|
|
9
|
+
value,
|
|
10
|
+
configurable: true
|
|
11
|
+
});
|
|
8
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
14
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -27,7 +31,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
31
|
let _kubb_parser_ts = require("@kubb/parser-ts");
|
|
28
32
|
let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
|
|
29
33
|
let _kubb_core = require("@kubb/core");
|
|
30
|
-
let remeda = require("remeda");
|
|
31
34
|
let typescript = require("typescript");
|
|
32
35
|
typescript = __toESM(typescript, 1);
|
|
33
36
|
let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
|
|
@@ -167,6 +170,129 @@ function stringify(value) {
|
|
|
167
170
|
return JSON.stringify(trimQuotes(value.toString()));
|
|
168
171
|
}
|
|
169
172
|
//#endregion
|
|
173
|
+
//#region ../../internals/utils/src/reserved.ts
|
|
174
|
+
/**
|
|
175
|
+
* JavaScript and Java reserved words.
|
|
176
|
+
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
177
|
+
*/
|
|
178
|
+
const reservedWords = new Set([
|
|
179
|
+
"abstract",
|
|
180
|
+
"arguments",
|
|
181
|
+
"boolean",
|
|
182
|
+
"break",
|
|
183
|
+
"byte",
|
|
184
|
+
"case",
|
|
185
|
+
"catch",
|
|
186
|
+
"char",
|
|
187
|
+
"class",
|
|
188
|
+
"const",
|
|
189
|
+
"continue",
|
|
190
|
+
"debugger",
|
|
191
|
+
"default",
|
|
192
|
+
"delete",
|
|
193
|
+
"do",
|
|
194
|
+
"double",
|
|
195
|
+
"else",
|
|
196
|
+
"enum",
|
|
197
|
+
"eval",
|
|
198
|
+
"export",
|
|
199
|
+
"extends",
|
|
200
|
+
"false",
|
|
201
|
+
"final",
|
|
202
|
+
"finally",
|
|
203
|
+
"float",
|
|
204
|
+
"for",
|
|
205
|
+
"function",
|
|
206
|
+
"goto",
|
|
207
|
+
"if",
|
|
208
|
+
"implements",
|
|
209
|
+
"import",
|
|
210
|
+
"in",
|
|
211
|
+
"instanceof",
|
|
212
|
+
"int",
|
|
213
|
+
"interface",
|
|
214
|
+
"let",
|
|
215
|
+
"long",
|
|
216
|
+
"native",
|
|
217
|
+
"new",
|
|
218
|
+
"null",
|
|
219
|
+
"package",
|
|
220
|
+
"private",
|
|
221
|
+
"protected",
|
|
222
|
+
"public",
|
|
223
|
+
"return",
|
|
224
|
+
"short",
|
|
225
|
+
"static",
|
|
226
|
+
"super",
|
|
227
|
+
"switch",
|
|
228
|
+
"synchronized",
|
|
229
|
+
"this",
|
|
230
|
+
"throw",
|
|
231
|
+
"throws",
|
|
232
|
+
"transient",
|
|
233
|
+
"true",
|
|
234
|
+
"try",
|
|
235
|
+
"typeof",
|
|
236
|
+
"var",
|
|
237
|
+
"void",
|
|
238
|
+
"volatile",
|
|
239
|
+
"while",
|
|
240
|
+
"with",
|
|
241
|
+
"yield",
|
|
242
|
+
"Array",
|
|
243
|
+
"Date",
|
|
244
|
+
"hasOwnProperty",
|
|
245
|
+
"Infinity",
|
|
246
|
+
"isFinite",
|
|
247
|
+
"isNaN",
|
|
248
|
+
"isPrototypeOf",
|
|
249
|
+
"length",
|
|
250
|
+
"Math",
|
|
251
|
+
"name",
|
|
252
|
+
"NaN",
|
|
253
|
+
"Number",
|
|
254
|
+
"Object",
|
|
255
|
+
"prototype",
|
|
256
|
+
"String",
|
|
257
|
+
"toString",
|
|
258
|
+
"undefined",
|
|
259
|
+
"valueOf"
|
|
260
|
+
]);
|
|
261
|
+
/**
|
|
262
|
+
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* isValidVarName('status') // true
|
|
267
|
+
* isValidVarName('class') // false (reserved word)
|
|
268
|
+
* isValidVarName('42foo') // false (starts with digit)
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
function isValidVarName(name) {
|
|
272
|
+
if (!name || reservedWords.has(name)) return false;
|
|
273
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Returns `name` when it's a syntactically valid JavaScript variable name,
|
|
277
|
+
* otherwise prefixes it with `_` so the result is a valid identifier.
|
|
278
|
+
*
|
|
279
|
+
* Useful for sanitizing OpenAPI schema names or operation IDs that start with
|
|
280
|
+
* a digit (e.g. `409`, `504AccountCancel`) before using them as exported
|
|
281
|
+
* variable, type, or function names.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```ts
|
|
285
|
+
* ensureValidVarName('409') // '_409'
|
|
286
|
+
* ensureValidVarName('504AccountCancel') // '_504AccountCancel'
|
|
287
|
+
* ensureValidVarName('Pet') // 'Pet'
|
|
288
|
+
* ensureValidVarName('class') // '_class'
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
function ensureValidVarName(name) {
|
|
292
|
+
if (!name || isValidVarName(name)) return name;
|
|
293
|
+
return `_${name}`;
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
170
296
|
//#region src/constants.ts
|
|
171
297
|
/**
|
|
172
298
|
* `optionalType` values that cause a property's type to include `| undefined`.
|
|
@@ -212,6 +338,9 @@ const PARAM_RANK = {
|
|
|
212
338
|
//#endregion
|
|
213
339
|
//#region src/factory.ts
|
|
214
340
|
const { SyntaxKind, factory } = typescript.default;
|
|
341
|
+
function isNumber(value) {
|
|
342
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
343
|
+
}
|
|
215
344
|
/**
|
|
216
345
|
* TypeScript AST modifiers for common keywords (async, export, const, static).
|
|
217
346
|
*/
|
|
@@ -229,10 +358,19 @@ const syntaxKind = {
|
|
|
229
358
|
literalType: SyntaxKind.LiteralType,
|
|
230
359
|
stringLiteral: SyntaxKind.StringLiteral
|
|
231
360
|
};
|
|
361
|
+
function isNonNullable$1(value) {
|
|
362
|
+
return value !== null && value !== void 0;
|
|
363
|
+
}
|
|
364
|
+
__name(isNonNullable$1, "isNonNullable");
|
|
232
365
|
function isValidIdentifier(str) {
|
|
233
366
|
if (!str.length || str.trim() !== str) return false;
|
|
234
|
-
|
|
235
|
-
|
|
367
|
+
let ch = str.codePointAt(0);
|
|
368
|
+
if (!typescript.default.isIdentifierStart(ch, typescript.default.ScriptTarget.Latest)) return false;
|
|
369
|
+
for (let i = ch > 65535 ? 2 : 1; i < str.length; i += ch > 65535 ? 2 : 1) {
|
|
370
|
+
ch = str.codePointAt(i);
|
|
371
|
+
if (!typescript.default.isIdentifierPart(ch, typescript.default.ScriptTarget.Latest)) return false;
|
|
372
|
+
}
|
|
373
|
+
return true;
|
|
236
374
|
}
|
|
237
375
|
function propertyName(name) {
|
|
238
376
|
if (typeof name === "string") return isValidIdentifier(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
|
|
@@ -298,7 +436,7 @@ function createUnionDeclaration({ nodes, withParentheses }) {
|
|
|
298
436
|
* Supports optional markers, readonly modifiers, and type annotations.
|
|
299
437
|
*/
|
|
300
438
|
function createPropertySignature({ readOnly, modifiers = [], name, questionToken, type }) {
|
|
301
|
-
return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.default.SyntaxKind.ReadonlyKeyword) : void 0].filter(
|
|
439
|
+
return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.default.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
|
|
302
440
|
}
|
|
303
441
|
/**
|
|
304
442
|
* Creates a function parameter declaration with optional markers, rest parameters, and type annotations.
|
|
@@ -390,19 +528,19 @@ function applyEnumKeyCasing(key, casing = "none") {
|
|
|
390
528
|
*/
|
|
391
529
|
function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCasing = "none" }) {
|
|
392
530
|
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]) => {
|
|
393
|
-
if (
|
|
531
|
+
if (isNumber(value)) {
|
|
394
532
|
if (value < 0) return factory.createLiteralTypeNode(factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))));
|
|
395
533
|
return factory.createLiteralTypeNode(factory.createNumericLiteral(value?.toString()));
|
|
396
534
|
}
|
|
397
535
|
if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
|
|
398
536
|
if (value) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
|
|
399
|
-
}).filter(
|
|
400
|
-
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(
|
|
537
|
+
}).filter((node) => node !== void 0)))];
|
|
538
|
+
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((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value]) => {
|
|
401
539
|
let initializer = factory.createStringLiteral(value?.toString());
|
|
402
|
-
if (Number.parseInt(value.toString(), 10) === value &&
|
|
540
|
+
if (Number.parseInt(value.toString(), 10) === value && isNumber(Number.parseInt(value.toString(), 10))) if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
|
|
403
541
|
else initializer = factory.createNumericLiteral(value);
|
|
404
542
|
if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
|
|
405
|
-
if (
|
|
543
|
+
if (isNumber(Number.parseInt(key.toString(), 10))) {
|
|
406
544
|
const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
|
|
407
545
|
return factory.createEnumMember(propertyName(casingKey), initializer);
|
|
408
546
|
}
|
|
@@ -410,19 +548,19 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
410
548
|
const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
|
|
411
549
|
return factory.createEnumMember(propertyName(casingKey), initializer);
|
|
412
550
|
}
|
|
413
|
-
}).filter(
|
|
551
|
+
}).filter((member) => member !== void 0))];
|
|
414
552
|
const identifierName = name;
|
|
415
553
|
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))];
|
|
416
554
|
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]) => {
|
|
417
555
|
let initializer = factory.createStringLiteral(value?.toString());
|
|
418
|
-
if (
|
|
556
|
+
if (isNumber(value)) if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
|
|
419
557
|
else initializer = factory.createNumericLiteral(value);
|
|
420
558
|
if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
|
|
421
559
|
if (key) {
|
|
422
560
|
const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
|
|
423
561
|
return factory.createPropertyAssignment(propertyName(casingKey), initializer);
|
|
424
562
|
}
|
|
425
|
-
}).filter(
|
|
563
|
+
}).filter((property) => property !== void 0), 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))))];
|
|
426
564
|
}
|
|
427
565
|
/**
|
|
428
566
|
* Creates a TypeScript `Omit<T, Keys>` type reference node.
|
|
@@ -562,14 +700,14 @@ function dateOrStringNode(node) {
|
|
|
562
700
|
* Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
|
|
563
701
|
*/
|
|
564
702
|
function buildMemberNodes(members, print) {
|
|
565
|
-
return (members ?? []).map(print).filter(
|
|
703
|
+
return (members ?? []).map(print).filter(isNonNullable$1);
|
|
566
704
|
}
|
|
567
705
|
/**
|
|
568
706
|
* Builds a TypeScript tuple type node from an array schema's `items`,
|
|
569
707
|
* applying min/max slice and optional/rest element rules.
|
|
570
708
|
*/
|
|
571
709
|
function buildTupleNode(node, print) {
|
|
572
|
-
let items = (node.items ?? []).map(print).filter(
|
|
710
|
+
let items = (node.items ?? []).map(print).filter(isNonNullable$1);
|
|
573
711
|
const restNode = node.rest ? print(node.rest) ?? void 0 : void 0;
|
|
574
712
|
const { min, max } = node;
|
|
575
713
|
if (max !== void 0) {
|
|
@@ -656,13 +794,13 @@ function Enum({ node, enumType, enumTypeSuffix, enumKeyCasing, resolver }) {
|
|
|
656
794
|
isExportable: true,
|
|
657
795
|
isIndexable: true,
|
|
658
796
|
isTypeOnly: false,
|
|
659
|
-
children:
|
|
797
|
+
children: _kubb_parser_ts.parserTs.print(nameNode)
|
|
660
798
|
}), /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
661
799
|
name: typeName,
|
|
662
800
|
isIndexable: true,
|
|
663
801
|
isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
|
|
664
802
|
isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
|
|
665
|
-
children:
|
|
803
|
+
children: _kubb_parser_ts.parserTs.print(typeNode)
|
|
666
804
|
})] });
|
|
667
805
|
}
|
|
668
806
|
//#endregion
|
|
@@ -702,6 +840,98 @@ function Type({ name, node, printer, enumType, enumTypeSuffix, enumKeyCasing, re
|
|
|
702
840
|
})] });
|
|
703
841
|
}
|
|
704
842
|
//#endregion
|
|
843
|
+
//#region ../../internals/shared/src/operation.ts
|
|
844
|
+
/**
|
|
845
|
+
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
846
|
+
* (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
|
|
847
|
+
*/
|
|
848
|
+
function getContentTypeSuffix(contentType) {
|
|
849
|
+
const baseType = contentType.split(";")[0].trim();
|
|
850
|
+
if (baseType === "application/json") return "Json";
|
|
851
|
+
if (baseType === "multipart/form-data") return "FormData";
|
|
852
|
+
if (baseType === "application/x-www-form-urlencoded") return "FormUrlEncoded";
|
|
853
|
+
const parts = (baseType.split("/").pop() ?? baseType).split(/[^a-zA-Z0-9]+/).filter(Boolean);
|
|
854
|
+
if (parts.length === 0) return "Unknown";
|
|
855
|
+
return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* Appends a content-type suffix to a base name, keeping a trailing `Data` segment last
|
|
859
|
+
* (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).
|
|
860
|
+
*/
|
|
861
|
+
function getPerContentTypeName(baseName, suffix) {
|
|
862
|
+
if (baseName.endsWith("Data")) return suffix.endsWith("Data") ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`;
|
|
863
|
+
return baseName + suffix;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Resolves per-content-type variant names for a set of content entries, deduplicating suffix
|
|
867
|
+
* collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is
|
|
868
|
+
* the final (possibly counter-augmented) value, so callers can derive parallel names in another
|
|
869
|
+
* namespace (e.g. plugin-faker deriving the matching plugin-ts type name).
|
|
870
|
+
*/
|
|
871
|
+
function resolveContentTypeVariants(entries, baseName) {
|
|
872
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
873
|
+
return entries.filter((entry) => entry.schema).map((entry) => {
|
|
874
|
+
const baseSuffix = getContentTypeSuffix(entry.contentType);
|
|
875
|
+
let suffix = baseSuffix;
|
|
876
|
+
let name = getPerContentTypeName(baseName, suffix);
|
|
877
|
+
let counter = 2;
|
|
878
|
+
while (usedNames.has(name)) {
|
|
879
|
+
suffix = `${baseSuffix}${counter++}`;
|
|
880
|
+
name = getPerContentTypeName(baseName, suffix);
|
|
881
|
+
}
|
|
882
|
+
usedNames.add(name);
|
|
883
|
+
return {
|
|
884
|
+
name,
|
|
885
|
+
suffix,
|
|
886
|
+
schema: entry.schema,
|
|
887
|
+
keysToOmit: entry.keysToOmit,
|
|
888
|
+
contentType: entry.contentType
|
|
889
|
+
};
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
function getOperationParameters(node, options = {}) {
|
|
893
|
+
const params = _kubb_core.ast.caseParams(node.parameters, options.paramsCasing);
|
|
894
|
+
return {
|
|
895
|
+
path: params.filter((param) => param.in === "path"),
|
|
896
|
+
query: params.filter((param) => param.in === "query"),
|
|
897
|
+
header: params.filter((param) => param.in === "header"),
|
|
898
|
+
cookie: params.filter((param) => param.in === "cookie")
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
//#endregion
|
|
902
|
+
//#region ../../internals/shared/src/group.ts
|
|
903
|
+
/**
|
|
904
|
+
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
905
|
+
* shared default naming so every plugin groups output consistently:
|
|
906
|
+
*
|
|
907
|
+
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
908
|
+
* - other groups use `${camelCase(group)}${suffix}` (e.g. `petController`).
|
|
909
|
+
*
|
|
910
|
+
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
911
|
+
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
912
|
+
* per-plugin convention.
|
|
913
|
+
*
|
|
914
|
+
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
915
|
+
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
916
|
+
*
|
|
917
|
+
* @example
|
|
918
|
+
* ```ts
|
|
919
|
+
* createGroupConfig(group, { suffix: 'Controller' }) // plugin-ts, plugin-client, …
|
|
920
|
+
* createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
|
|
921
|
+
* ```
|
|
922
|
+
*/
|
|
923
|
+
function createGroupConfig(group, options) {
|
|
924
|
+
if (!group) return null;
|
|
925
|
+
const defaultName = (ctx) => {
|
|
926
|
+
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
927
|
+
return `${camelCase(ctx.group)}${options.suffix}`;
|
|
928
|
+
};
|
|
929
|
+
return {
|
|
930
|
+
...group,
|
|
931
|
+
name: group.name ? group.name : defaultName
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
//#endregion
|
|
705
935
|
//#region src/utils.ts
|
|
706
936
|
/**
|
|
707
937
|
* Collects JSDoc annotation strings for a schema node.
|
|
@@ -713,15 +943,18 @@ function Type({ name, node, printer, enumType, enumTypeSuffix, enumKeyCasing, re
|
|
|
713
943
|
function buildPropertyJSDocComments(schema) {
|
|
714
944
|
const meta = _kubb_core.ast.syncSchemaRef(schema);
|
|
715
945
|
const isArray = meta?.primitive === "array";
|
|
946
|
+
const hasDescription = meta && "description" in meta && meta.description;
|
|
947
|
+
const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
|
|
716
948
|
return [
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
!isArray && meta && "
|
|
721
|
-
meta && "
|
|
722
|
-
meta && "
|
|
723
|
-
meta && "
|
|
724
|
-
meta && "
|
|
949
|
+
hasDescription ? `@description ${jsStringEscape(meta.description)}` : null,
|
|
950
|
+
...formatComment,
|
|
951
|
+
meta && "deprecated" in meta && meta.deprecated ? "@deprecated" : null,
|
|
952
|
+
!isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
|
|
953
|
+
!isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
|
|
954
|
+
meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
|
|
955
|
+
meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
|
|
956
|
+
meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` : null,
|
|
957
|
+
meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, "optional" in schema && schema.optional ? " | undefined" : null].filter(Boolean).join("") : null
|
|
725
958
|
].filter(Boolean);
|
|
726
959
|
}
|
|
727
960
|
function buildParams(node, { params, resolver }) {
|
|
@@ -738,9 +971,7 @@ function buildParams(node, { params, resolver }) {
|
|
|
738
971
|
});
|
|
739
972
|
}
|
|
740
973
|
function buildData(node, { resolver }) {
|
|
741
|
-
const pathParams
|
|
742
|
-
const queryParams = node.parameters.filter((p) => p.in === "query");
|
|
743
|
-
const headerParams = node.parameters.filter((p) => p.in === "header");
|
|
974
|
+
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
|
|
744
975
|
return _kubb_core.ast.createSchema({
|
|
745
976
|
type: "object",
|
|
746
977
|
deprecated: node.deprecated,
|
|
@@ -822,7 +1053,7 @@ function buildResponses(node, { resolver }) {
|
|
|
822
1053
|
});
|
|
823
1054
|
}
|
|
824
1055
|
function buildResponseUnion(node, { resolver }) {
|
|
825
|
-
const responsesWithSchema = node.responses.filter((res) => res.schema);
|
|
1056
|
+
const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
|
|
826
1057
|
if (responsesWithSchema.length === 0) return null;
|
|
827
1058
|
return _kubb_core.ast.createSchema({
|
|
828
1059
|
type: "union",
|
|
@@ -834,6 +1065,9 @@ function buildResponseUnion(node, { resolver }) {
|
|
|
834
1065
|
}
|
|
835
1066
|
//#endregion
|
|
836
1067
|
//#region src/printers/printerTs.ts
|
|
1068
|
+
function isNonNullable(value) {
|
|
1069
|
+
return value !== null && value !== void 0;
|
|
1070
|
+
}
|
|
837
1071
|
/**
|
|
838
1072
|
* TypeScript type printer built with `definePrinter`.
|
|
839
1073
|
*
|
|
@@ -886,7 +1120,7 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
|
|
|
886
1120
|
date: dateOrStringNode,
|
|
887
1121
|
time: dateOrStringNode,
|
|
888
1122
|
ref(node) {
|
|
889
|
-
if (!node.name) return;
|
|
1123
|
+
if (!node.name) return null;
|
|
890
1124
|
const refName = node.ref ? _kubb_core.ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
891
1125
|
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);
|
|
892
1126
|
},
|
|
@@ -894,7 +1128,7 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
|
|
|
894
1128
|
const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
|
|
895
1129
|
if (this.options.enumType === "inlineLiteral" || !node.name) return createUnionDeclaration({
|
|
896
1130
|
withParentheses: true,
|
|
897
|
-
nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(
|
|
1131
|
+
nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
|
|
898
1132
|
}) ?? void 0;
|
|
899
1133
|
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);
|
|
900
1134
|
},
|
|
@@ -912,7 +1146,7 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
|
|
|
912
1146
|
withParentheses: true
|
|
913
1147
|
});
|
|
914
1148
|
return this.transform(m);
|
|
915
|
-
}).filter(
|
|
1149
|
+
}).filter(isNonNullable)
|
|
916
1150
|
}) ?? void 0;
|
|
917
1151
|
return createUnionDeclaration({
|
|
918
1152
|
withParentheses: true,
|
|
@@ -923,16 +1157,16 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
|
|
|
923
1157
|
return createIntersectionDeclaration({
|
|
924
1158
|
withParentheses: true,
|
|
925
1159
|
nodes: buildMemberNodes(node.members, this.transform)
|
|
926
|
-
}) ??
|
|
1160
|
+
}) ?? null;
|
|
927
1161
|
},
|
|
928
1162
|
array(node) {
|
|
929
1163
|
return createArrayDeclaration({
|
|
930
|
-
nodes: (node.items ?? []).map((item) => this.transform(item)).filter(
|
|
1164
|
+
nodes: (node.items ?? []).map((item) => this.transform(item)).filter(isNonNullable),
|
|
931
1165
|
arrayType: this.options.arrayType
|
|
932
|
-
}) ??
|
|
1166
|
+
}) ?? null;
|
|
933
1167
|
},
|
|
934
1168
|
tuple(node) {
|
|
935
|
-
return buildTupleNode(node, this.transform);
|
|
1169
|
+
return buildTupleNode(node, this.transform) ?? null;
|
|
936
1170
|
},
|
|
937
1171
|
object(node) {
|
|
938
1172
|
const { transform, options } = this;
|
|
@@ -959,46 +1193,54 @@ const printerTs = _kubb_core.ast.definePrinter((options) => {
|
|
|
959
1193
|
},
|
|
960
1194
|
print(node) {
|
|
961
1195
|
const { name, syntaxType = "type", description, keysToOmit } = this.options;
|
|
962
|
-
|
|
963
|
-
if (!
|
|
1196
|
+
const transformed = this.transform(node);
|
|
1197
|
+
if (!transformed) return null;
|
|
964
1198
|
const meta = _kubb_core.ast.syncSchemaRef(node);
|
|
965
1199
|
if (!name) {
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
return
|
|
1200
|
+
const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
|
|
1201
|
+
const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
1202
|
+
return _kubb_parser_ts.parserTs.print(result);
|
|
969
1203
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1204
|
+
const inner = (() => {
|
|
1205
|
+
const omitted = keysToOmit?.length ? createOmitDeclaration({
|
|
1206
|
+
keys: keysToOmit,
|
|
1207
|
+
type: transformed,
|
|
1208
|
+
nonNullable: true
|
|
1209
|
+
}) : transformed;
|
|
1210
|
+
const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [omitted, keywordTypeNodes.null] }) : omitted;
|
|
1211
|
+
return meta.nullish || meta.optional ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
1212
|
+
})();
|
|
1213
|
+
const typeNode = createTypeDeclaration({
|
|
979
1214
|
name,
|
|
980
1215
|
isExportable: true,
|
|
981
1216
|
type: inner,
|
|
982
|
-
syntax:
|
|
1217
|
+
syntax: syntaxType === "type" || inner.kind === syntaxKind.union || !!keysToOmit?.length ? "type" : "interface",
|
|
983
1218
|
comments: buildPropertyJSDocComments({
|
|
984
1219
|
...meta,
|
|
985
1220
|
description
|
|
986
1221
|
})
|
|
987
|
-
})
|
|
1222
|
+
});
|
|
1223
|
+
return _kubb_parser_ts.parserTs.print(typeNode);
|
|
988
1224
|
}
|
|
989
1225
|
};
|
|
990
1226
|
});
|
|
991
1227
|
//#endregion
|
|
992
1228
|
//#region src/generators/typeGenerator.tsx
|
|
1229
|
+
/**
|
|
1230
|
+
* Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
|
|
1231
|
+
* schema in the spec plus per-operation request, response, and parameter
|
|
1232
|
+
* types. Drop-replace with a custom `Generator<PluginTs>` to change how
|
|
1233
|
+
* TypeScript output is produced.
|
|
1234
|
+
*/
|
|
993
1235
|
const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
994
1236
|
name: "typescript",
|
|
995
|
-
renderer: _kubb_renderer_jsx.
|
|
1237
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
996
1238
|
schema(node, ctx) {
|
|
997
1239
|
const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, printer } = ctx.options;
|
|
998
1240
|
const { adapter, config, resolver, root } = ctx;
|
|
999
1241
|
if (!node.name) return;
|
|
1000
1242
|
const mode = ctx.getMode(output);
|
|
1001
|
-
const enumSchemaNames = new Set(
|
|
1243
|
+
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1002
1244
|
function resolveImportName(schemaName) {
|
|
1003
1245
|
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
|
|
1004
1246
|
return resolver.resolveTypeName(schemaName);
|
|
@@ -1011,7 +1253,7 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1011
1253
|
}, {
|
|
1012
1254
|
root,
|
|
1013
1255
|
output,
|
|
1014
|
-
group
|
|
1256
|
+
group: group ?? void 0
|
|
1015
1257
|
}).path
|
|
1016
1258
|
}));
|
|
1017
1259
|
const isEnumSchema = !!_kubb_core.ast.narrowSchema(node, _kubb_core.ast.schemaTypes.enum);
|
|
@@ -1023,7 +1265,7 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1023
1265
|
}, {
|
|
1024
1266
|
root,
|
|
1025
1267
|
output,
|
|
1026
|
-
group
|
|
1268
|
+
group: group ?? void 0
|
|
1027
1269
|
})
|
|
1028
1270
|
};
|
|
1029
1271
|
const schemaPrinter = printerTs({
|
|
@@ -1042,13 +1284,21 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1042
1284
|
baseName: meta.file.baseName,
|
|
1043
1285
|
path: meta.file.path,
|
|
1044
1286
|
meta: meta.file.meta,
|
|
1045
|
-
banner: resolver.resolveBanner(
|
|
1287
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1046
1288
|
output,
|
|
1047
|
-
config
|
|
1289
|
+
config,
|
|
1290
|
+
file: {
|
|
1291
|
+
path: meta.file.path,
|
|
1292
|
+
baseName: meta.file.baseName
|
|
1293
|
+
}
|
|
1048
1294
|
}),
|
|
1049
|
-
footer: resolver.resolveFooter(
|
|
1295
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1050
1296
|
output,
|
|
1051
|
-
config
|
|
1297
|
+
config,
|
|
1298
|
+
file: {
|
|
1299
|
+
path: meta.file.path,
|
|
1300
|
+
baseName: meta.file.baseName
|
|
1301
|
+
}
|
|
1052
1302
|
}),
|
|
1053
1303
|
children: [mode === "split" && imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1054
1304
|
root: meta.file.path,
|
|
@@ -1083,9 +1333,9 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1083
1333
|
}, {
|
|
1084
1334
|
root,
|
|
1085
1335
|
output,
|
|
1086
|
-
group
|
|
1336
|
+
group: group ?? void 0
|
|
1087
1337
|
}) };
|
|
1088
|
-
const enumSchemaNames = new Set(
|
|
1338
|
+
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1089
1339
|
function resolveImportName(schemaName) {
|
|
1090
1340
|
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
|
|
1091
1341
|
return resolver.resolveTypeName(schemaName);
|
|
@@ -1100,7 +1350,7 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1100
1350
|
}, {
|
|
1101
1351
|
root,
|
|
1102
1352
|
output,
|
|
1103
|
-
group
|
|
1353
|
+
group: group ?? void 0
|
|
1104
1354
|
}).path
|
|
1105
1355
|
}));
|
|
1106
1356
|
const schemaPrinter = printerTs({
|
|
@@ -1135,23 +1385,63 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1135
1385
|
printer: schemaPrinter
|
|
1136
1386
|
})] });
|
|
1137
1387
|
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Emits an individual type per content type plus a union alias under `baseName`.
|
|
1390
|
+
* Shared by the request body and multi-content-type responses.
|
|
1391
|
+
*/
|
|
1392
|
+
function buildContentTypeVariants(entries, baseName, decorate) {
|
|
1393
|
+
const variants = resolveContentTypeVariants(entries, baseName);
|
|
1394
|
+
const unionSchema = _kubb_core.ast.createSchema({
|
|
1395
|
+
type: "union",
|
|
1396
|
+
members: variants.map((variant) => _kubb_core.ast.createSchema({
|
|
1397
|
+
type: "ref",
|
|
1398
|
+
name: variant.name
|
|
1399
|
+
}))
|
|
1400
|
+
});
|
|
1401
|
+
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [variants.map((variant) => renderSchemaType({
|
|
1402
|
+
schema: decorate ? decorate(variant.schema) : variant.schema,
|
|
1403
|
+
name: variant.name,
|
|
1404
|
+
keysToOmit: variant.keysToOmit
|
|
1405
|
+
})), renderSchemaType({
|
|
1406
|
+
schema: unionSchema,
|
|
1407
|
+
name: baseName
|
|
1408
|
+
})] });
|
|
1409
|
+
}
|
|
1138
1410
|
const paramTypes = params.map((param) => renderSchemaType({
|
|
1139
1411
|
schema: param.schema,
|
|
1140
1412
|
name: resolver.resolveParamName(node, param)
|
|
1141
1413
|
}));
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1414
|
+
const requestBodyContent = node.requestBody?.content ?? [];
|
|
1415
|
+
function buildRequestType() {
|
|
1416
|
+
if (requestBodyContent.length === 0) return null;
|
|
1417
|
+
if (requestBodyContent.length === 1) {
|
|
1418
|
+
const entry = requestBodyContent[0];
|
|
1419
|
+
if (!entry.schema) return null;
|
|
1420
|
+
return renderSchemaType({
|
|
1421
|
+
schema: {
|
|
1422
|
+
...entry.schema,
|
|
1423
|
+
description: node.requestBody.description ?? entry.schema.description
|
|
1424
|
+
},
|
|
1425
|
+
name: resolver.resolveDataName(node),
|
|
1426
|
+
keysToOmit: entry.keysToOmit
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
return buildContentTypeVariants(requestBodyContent, resolver.resolveDataName(node), (schema) => ({
|
|
1430
|
+
...schema,
|
|
1431
|
+
description: node.requestBody.description ?? schema.description
|
|
1432
|
+
}));
|
|
1433
|
+
}
|
|
1434
|
+
const requestType = buildRequestType();
|
|
1435
|
+
const responseTypes = node.responses.map((res) => {
|
|
1436
|
+
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
1437
|
+
if (variants.length > 1) return buildContentTypeVariants(variants, resolver.resolveResponseStatusName(node, res.statusCode));
|
|
1438
|
+
const primary = variants[0] ?? res.content?.[0];
|
|
1439
|
+
return renderSchemaType({
|
|
1440
|
+
schema: primary?.schema ?? null,
|
|
1441
|
+
name: resolver.resolveResponseStatusName(node, res.statusCode),
|
|
1442
|
+
keysToOmit: primary?.keysToOmit
|
|
1443
|
+
});
|
|
1444
|
+
});
|
|
1155
1445
|
const dataType = renderSchemaType({
|
|
1156
1446
|
schema: buildData({
|
|
1157
1447
|
...node,
|
|
@@ -1163,14 +1453,15 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1163
1453
|
schema: buildResponses(node, { resolver }),
|
|
1164
1454
|
name: resolver.resolveResponsesName(node)
|
|
1165
1455
|
});
|
|
1166
|
-
|
|
1167
|
-
|
|
1456
|
+
function buildResponseType() {
|
|
1457
|
+
const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
|
|
1458
|
+
if (!node.responses.some(hasSchema)) return null;
|
|
1168
1459
|
const responseName = resolver.resolveResponseName(node);
|
|
1169
|
-
const responsesWithSchema = node.responses.filter(
|
|
1170
|
-
if (new Set(responsesWithSchema.flatMap((res) => res.schema ? adapter.getImports(
|
|
1460
|
+
const responsesWithSchema = node.responses.filter(hasSchema);
|
|
1461
|
+
if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1171
1462
|
name: resolveImportName(schemaName),
|
|
1172
1463
|
path: ""
|
|
1173
|
-
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : [])).has(responseName)) return null;
|
|
1464
|
+
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseName)) return null;
|
|
1174
1465
|
return renderSchemaType({
|
|
1175
1466
|
schema: {
|
|
1176
1467
|
...buildResponseUnion(node, { resolver }),
|
|
@@ -1178,18 +1469,27 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1178
1469
|
},
|
|
1179
1470
|
name: responseName
|
|
1180
1471
|
});
|
|
1181
|
-
}
|
|
1472
|
+
}
|
|
1473
|
+
const responseType = buildResponseType();
|
|
1182
1474
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
1183
1475
|
baseName: meta.file.baseName,
|
|
1184
1476
|
path: meta.file.path,
|
|
1185
1477
|
meta: meta.file.meta,
|
|
1186
|
-
banner: resolver.resolveBanner(
|
|
1478
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1187
1479
|
output,
|
|
1188
|
-
config
|
|
1480
|
+
config,
|
|
1481
|
+
file: {
|
|
1482
|
+
path: meta.file.path,
|
|
1483
|
+
baseName: meta.file.baseName
|
|
1484
|
+
}
|
|
1189
1485
|
}),
|
|
1190
|
-
footer: resolver.resolveFooter(
|
|
1486
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1191
1487
|
output,
|
|
1192
|
-
config
|
|
1488
|
+
config,
|
|
1489
|
+
file: {
|
|
1490
|
+
path: meta.file.path,
|
|
1491
|
+
baseName: meta.file.baseName
|
|
1492
|
+
}
|
|
1193
1493
|
}),
|
|
1194
1494
|
children: [
|
|
1195
1495
|
paramTypes,
|
|
@@ -1205,86 +1505,98 @@ const typeGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1205
1505
|
//#endregion
|
|
1206
1506
|
//#region src/resolvers/resolverTs.ts
|
|
1207
1507
|
/**
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1508
|
+
* Default resolver used by `@kubb/plugin-ts`. Decides the names and file paths
|
|
1509
|
+
* for every generated TypeScript type. Import this in other plugins that need
|
|
1510
|
+
* to reference the exact names `plugin-ts` produces without duplicating the
|
|
1511
|
+
* casing/file-layout rules.
|
|
1211
1512
|
*
|
|
1212
|
-
* The `default` method is
|
|
1213
|
-
*
|
|
1513
|
+
* The `default` method is supplied by `defineResolver`. It uses PascalCase for
|
|
1514
|
+
* type names and PascalCase-with-isFile for files.
|
|
1214
1515
|
*
|
|
1215
|
-
* @example
|
|
1516
|
+
* @example Resolve a type and file name
|
|
1216
1517
|
* ```ts
|
|
1217
|
-
* import {
|
|
1518
|
+
* import { resolverTs } from '@kubb/plugin-ts'
|
|
1218
1519
|
*
|
|
1219
|
-
*
|
|
1220
|
-
*
|
|
1221
|
-
*
|
|
1520
|
+
* resolverTs.default('list pets', 'type') // 'ListPets'
|
|
1521
|
+
* resolverTs.resolvePathName('list pets', 'file') // 'ListPets'
|
|
1522
|
+
* resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
|
|
1222
1523
|
* ```
|
|
1223
1524
|
*/
|
|
1224
|
-
const resolverTs = (0, _kubb_core.defineResolver)((
|
|
1525
|
+
const resolverTs = (0, _kubb_core.defineResolver)(() => {
|
|
1225
1526
|
return {
|
|
1226
1527
|
name: "default",
|
|
1227
1528
|
pluginName: "plugin-ts",
|
|
1228
1529
|
default(name, type) {
|
|
1229
|
-
|
|
1530
|
+
const resolved = pascalCase(name, { isFile: type === "file" });
|
|
1531
|
+
return type === "file" ? resolved : ensureValidVarName(resolved);
|
|
1230
1532
|
},
|
|
1231
1533
|
resolveTypeName(name) {
|
|
1232
|
-
return pascalCase(name);
|
|
1534
|
+
return ensureValidVarName(pascalCase(name));
|
|
1233
1535
|
},
|
|
1234
1536
|
resolvePathName(name, type) {
|
|
1235
|
-
|
|
1537
|
+
const resolved = pascalCase(name, { isFile: type === "file" });
|
|
1538
|
+
return type === "file" ? resolved : ensureValidVarName(resolved);
|
|
1236
1539
|
},
|
|
1237
1540
|
resolveParamName(node, param) {
|
|
1238
|
-
return
|
|
1541
|
+
return this.resolveTypeName(`${node.operationId} ${param.in} ${param.name}`);
|
|
1239
1542
|
},
|
|
1240
1543
|
resolveResponseStatusName(node, statusCode) {
|
|
1241
|
-
return
|
|
1544
|
+
return this.resolveTypeName(`${node.operationId} Status ${statusCode}`);
|
|
1242
1545
|
},
|
|
1243
1546
|
resolveDataName(node) {
|
|
1244
|
-
return
|
|
1547
|
+
return this.resolveTypeName(`${node.operationId} Data`);
|
|
1245
1548
|
},
|
|
1246
1549
|
resolveRequestConfigName(node) {
|
|
1247
|
-
return
|
|
1550
|
+
return this.resolveTypeName(`${node.operationId} RequestConfig`);
|
|
1248
1551
|
},
|
|
1249
1552
|
resolveResponsesName(node) {
|
|
1250
|
-
return
|
|
1553
|
+
return this.resolveTypeName(`${node.operationId} Responses`);
|
|
1251
1554
|
},
|
|
1252
1555
|
resolveResponseName(node) {
|
|
1253
|
-
return
|
|
1556
|
+
return this.resolveTypeName(`${node.operationId} Response`);
|
|
1254
1557
|
},
|
|
1255
1558
|
resolveEnumKeyName(node, enumTypeSuffix = "key") {
|
|
1256
|
-
return `${
|
|
1559
|
+
return `${this.resolveTypeName(node.name ?? "")}${enumTypeSuffix}`;
|
|
1257
1560
|
},
|
|
1258
1561
|
resolvePathParamsName(node, param) {
|
|
1259
|
-
return
|
|
1562
|
+
return this.resolveParamName(node, param);
|
|
1260
1563
|
},
|
|
1261
1564
|
resolveQueryParamsName(node, param) {
|
|
1262
|
-
return
|
|
1565
|
+
return this.resolveParamName(node, param);
|
|
1263
1566
|
},
|
|
1264
1567
|
resolveHeaderParamsName(node, param) {
|
|
1265
|
-
return
|
|
1568
|
+
return this.resolveParamName(node, param);
|
|
1266
1569
|
}
|
|
1267
1570
|
};
|
|
1268
1571
|
});
|
|
1269
1572
|
//#endregion
|
|
1270
1573
|
//#region src/plugin.ts
|
|
1271
1574
|
/**
|
|
1272
|
-
* Canonical plugin name for `@kubb/plugin-ts
|
|
1575
|
+
* Canonical plugin name for `@kubb/plugin-ts`. Used for driver lookups and
|
|
1576
|
+
* cross-plugin dependency references.
|
|
1273
1577
|
*/
|
|
1274
1578
|
const pluginTsName = "plugin-ts";
|
|
1275
1579
|
/**
|
|
1276
|
-
*
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
* and writes barrel files based on `output.barrelType`.
|
|
1580
|
+
* Generates TypeScript `type` aliases and `interface` declarations from an
|
|
1581
|
+
* OpenAPI spec. The foundation that every other Kubb plugin builds on:
|
|
1582
|
+
* clients, query hooks, mocks, and validators all reference the names this
|
|
1583
|
+
* plugin produces.
|
|
1281
1584
|
*
|
|
1282
1585
|
* @example
|
|
1283
1586
|
* ```ts
|
|
1284
|
-
* import
|
|
1587
|
+
* import { defineConfig } from 'kubb'
|
|
1588
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1285
1589
|
*
|
|
1286
1590
|
* export default defineConfig({
|
|
1287
|
-
*
|
|
1591
|
+
* input: { path: './petStore.yaml' },
|
|
1592
|
+
* output: { path: './src/gen' },
|
|
1593
|
+
* plugins: [
|
|
1594
|
+
* pluginTs({
|
|
1595
|
+
* output: { path: './types' },
|
|
1596
|
+
* enumType: 'asConst',
|
|
1597
|
+
* optionalType: 'questionTokenAndUndefined',
|
|
1598
|
+
* }),
|
|
1599
|
+
* ],
|
|
1288
1600
|
* })
|
|
1289
1601
|
* ```
|
|
1290
1602
|
*/
|
|
@@ -1293,13 +1605,7 @@ const pluginTs = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1293
1605
|
path: "types",
|
|
1294
1606
|
barrelType: "named"
|
|
1295
1607
|
}, group, exclude = [], include, override = [], enumType = "asConst", enumTypeSuffix = "Key", enumKeyCasing = "none", optionalType = "questionToken", arrayType = "array", syntaxType = "type", paramsCasing, printer, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
|
|
1296
|
-
const groupConfig = group
|
|
1297
|
-
...group,
|
|
1298
|
-
name: (ctx) => {
|
|
1299
|
-
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
1300
|
-
return `${camelCase(ctx.group)}Controller`;
|
|
1301
|
-
}
|
|
1302
|
-
} : void 0;
|
|
1608
|
+
const groupConfig = createGroupConfig(group, { suffix: "Controller" });
|
|
1303
1609
|
return {
|
|
1304
1610
|
name: pluginTsName,
|
|
1305
1611
|
options,
|
|
@@ -1354,10 +1660,10 @@ function rank(param) {
|
|
|
1354
1660
|
return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
1355
1661
|
}
|
|
1356
1662
|
function sortParams(params) {
|
|
1357
|
-
return
|
|
1663
|
+
return params.toSorted((a, b) => rank(a) - rank(b));
|
|
1358
1664
|
}
|
|
1359
1665
|
function sortChildParams(params) {
|
|
1360
|
-
return
|
|
1666
|
+
return params.toSorted((a, b) => rank(a) - rank(b));
|
|
1361
1667
|
}
|
|
1362
1668
|
/**
|
|
1363
1669
|
* Default function-signature printer.
|