@kubb/plugin-ts 5.0.10 → 5.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +113 -495
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -147
- package/dist/index.js +113 -495
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -311,47 +311,6 @@ function toFilePath(name, caseLast = camelCase) {
|
|
|
311
311
|
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
312
312
|
}
|
|
313
313
|
//#endregion
|
|
314
|
-
//#region src/constants.ts
|
|
315
|
-
/**
|
|
316
|
-
* `optionalType` values that cause a property's type to include `| undefined`.
|
|
317
|
-
*/
|
|
318
|
-
const OPTIONAL_ADDS_UNDEFINED = /* @__PURE__ */ new Set(["undefined", "questionTokenAndUndefined"]);
|
|
319
|
-
/**
|
|
320
|
-
* `optionalType` values that render the property key with a `?` token.
|
|
321
|
-
*/
|
|
322
|
-
const OPTIONAL_ADDS_QUESTION_TOKEN = /* @__PURE__ */ new Set(["questionToken", "questionTokenAndUndefined"]);
|
|
323
|
-
/**
|
|
324
|
-
* `enum.type` values that append a `typeSuffix` to the generated enum type alias.
|
|
325
|
-
*/
|
|
326
|
-
const ENUM_TYPES_WITH_KEY_SUFFIX = /* @__PURE__ */ new Set(["asConst"]);
|
|
327
|
-
/**
|
|
328
|
-
* `enum.type` values that require a runtime value declaration (object, enum, or literal).
|
|
329
|
-
*/
|
|
330
|
-
const ENUM_TYPES_WITH_RUNTIME_VALUE = /* @__PURE__ */ new Set([
|
|
331
|
-
"enum",
|
|
332
|
-
"asConst",
|
|
333
|
-
"constEnum",
|
|
334
|
-
"literal",
|
|
335
|
-
void 0
|
|
336
|
-
]);
|
|
337
|
-
/**
|
|
338
|
-
* `enum.type` values whose type declaration is type-only (no runtime value emitted for the type alias).
|
|
339
|
-
*/
|
|
340
|
-
const ENUM_TYPES_WITH_TYPE_ONLY = /* @__PURE__ */ new Set([
|
|
341
|
-
"asConst",
|
|
342
|
-
"literal",
|
|
343
|
-
void 0
|
|
344
|
-
]);
|
|
345
|
-
/**
|
|
346
|
-
* Ordering priority for function parameters: lower = sorted earlier.
|
|
347
|
-
*/
|
|
348
|
-
const PARAM_RANK = {
|
|
349
|
-
required: 0,
|
|
350
|
-
optional: 1,
|
|
351
|
-
withDefault: 2,
|
|
352
|
-
rest: 3
|
|
353
|
-
};
|
|
354
|
-
//#endregion
|
|
355
314
|
//#region src/factory.ts
|
|
356
315
|
var factory_exports = /* @__PURE__ */ __exportAll({
|
|
357
316
|
appendJSDocToNode: () => appendJSDocToNode,
|
|
@@ -362,14 +321,9 @@ var factory_exports = /* @__PURE__ */ __exportAll({
|
|
|
362
321
|
constToTypeNode: () => constToTypeNode,
|
|
363
322
|
createArrayDeclaration: () => createArrayDeclaration,
|
|
364
323
|
createEnumDeclaration: () => createEnumDeclaration,
|
|
365
|
-
createExportDeclaration: () => createExportDeclaration,
|
|
366
|
-
createImportDeclaration: () => createImportDeclaration,
|
|
367
324
|
createIntersectionDeclaration: () => createIntersectionDeclaration,
|
|
368
|
-
createJSDoc: () => createJSDoc,
|
|
369
325
|
createOmitDeclaration: () => createOmitDeclaration,
|
|
370
|
-
createParameterSignature: () => createParameterSignature,
|
|
371
326
|
createPropertySignature: () => createPropertySignature,
|
|
372
|
-
createQuestionToken: () => createQuestionToken,
|
|
373
327
|
createTypeDeclaration: () => createTypeDeclaration,
|
|
374
328
|
createTypeLiteralNode: () => createTypeLiteralNode,
|
|
375
329
|
createTypeReferenceNode: () => createTypeReferenceNode,
|
|
@@ -377,9 +331,10 @@ var factory_exports = /* @__PURE__ */ __exportAll({
|
|
|
377
331
|
createUrlTemplateType: () => createUrlTemplateType,
|
|
378
332
|
dateOrStringNode: () => dateOrStringNode,
|
|
379
333
|
isNonNullable: () => isNonNullable$1,
|
|
334
|
+
isUnionTypeNode: () => isUnionTypeNode,
|
|
380
335
|
keywordTypeNodes: () => keywordTypeNodes,
|
|
381
336
|
modifiers: () => modifiers,
|
|
382
|
-
|
|
337
|
+
wrapNullableOptional: () => wrapNullableOptional
|
|
383
338
|
});
|
|
384
339
|
/**
|
|
385
340
|
* Loaded with `require`, not `import`. When ESM imports a CommonJS package, Node keeps a second
|
|
@@ -387,35 +342,14 @@ var factory_exports = /* @__PURE__ */ __exportAll({
|
|
|
387
342
|
*/
|
|
388
343
|
const typescript = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("typescript");
|
|
389
344
|
const { SyntaxKind, factory } = typescript;
|
|
390
|
-
/**
|
|
391
|
-
* Compares two strings by UTF-16 code unit, keeping sorted output identical across platforms
|
|
392
|
-
* regardless of locale.
|
|
393
|
-
*/
|
|
394
|
-
function compareStrings(a, b) {
|
|
395
|
-
if (a < b) return -1;
|
|
396
|
-
if (a > b) return 1;
|
|
397
|
-
return 0;
|
|
398
|
-
}
|
|
399
345
|
function isNumber(value) {
|
|
400
346
|
return typeof value === "number" && !Number.isNaN(value);
|
|
401
347
|
}
|
|
402
348
|
/**
|
|
403
|
-
* TypeScript AST modifiers for
|
|
349
|
+
* TypeScript AST modifiers for the `export` keyword.
|
|
404
350
|
*/
|
|
405
|
-
const modifiers = {
|
|
406
|
-
|
|
407
|
-
export: factory.createModifier(typescript.SyntaxKind.ExportKeyword),
|
|
408
|
-
const: factory.createModifier(typescript.SyntaxKind.ConstKeyword),
|
|
409
|
-
static: factory.createModifier(typescript.SyntaxKind.StaticKeyword)
|
|
410
|
-
};
|
|
411
|
-
/**
|
|
412
|
-
* TypeScript syntax kind constants for union, literal, and string types.
|
|
413
|
-
*/
|
|
414
|
-
const syntaxKind = {
|
|
415
|
-
union: SyntaxKind.UnionType,
|
|
416
|
-
literalType: SyntaxKind.LiteralType,
|
|
417
|
-
stringLiteral: SyntaxKind.StringLiteral
|
|
418
|
-
};
|
|
351
|
+
const modifiers = { export: factory.createModifier(typescript.SyntaxKind.ExportKeyword) };
|
|
352
|
+
const isUnionTypeNode = typescript.isUnionTypeNode;
|
|
419
353
|
function isNonNullable$1(value) {
|
|
420
354
|
return value !== null && value !== void 0;
|
|
421
355
|
}
|
|
@@ -469,7 +403,6 @@ function createArrayDeclaration({ nodes, arrayType = "array" }) {
|
|
|
469
403
|
if (!nodes.length) return factory.createTupleTypeNode([]);
|
|
470
404
|
if (nodes.length === 1) {
|
|
471
405
|
const node = nodes[0];
|
|
472
|
-
if (!node) return null;
|
|
473
406
|
if (arrayType === "generic") return factory.createTypeReferenceNode(factory.createIdentifier("Array"), [node]);
|
|
474
407
|
return factory.createArrayTypeNode(node);
|
|
475
408
|
}
|
|
@@ -497,23 +430,6 @@ function createPropertySignature({ readOnly, modifiers = [], name, questionToken
|
|
|
497
430
|
return factory.createPropertySignature([...modifiers, readOnly ? factory.createToken(typescript.SyntaxKind.ReadonlyKeyword) : void 0].filter((modifier) => modifier !== void 0), propertyName(name), createQuestionToken(questionToken), type);
|
|
498
431
|
}
|
|
499
432
|
/**
|
|
500
|
-
* Creates a function parameter declaration with optional markers, rest parameters, and type annotations.
|
|
501
|
-
*/
|
|
502
|
-
function createParameterSignature(name, { modifiers, dotDotDotToken, questionToken, type, initializer }) {
|
|
503
|
-
return factory.createParameterDeclaration(modifiers, dotDotDotToken, name, createQuestionToken(questionToken), type, initializer);
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Creates a JSDoc comment node from an array of comment strings.
|
|
507
|
-
* Returns null if no comments are provided.
|
|
508
|
-
*/
|
|
509
|
-
function createJSDoc({ comments }) {
|
|
510
|
-
if (!comments.length) return null;
|
|
511
|
-
return factory.createJSDocComment(factory.createNodeArray(comments.map((comment, i) => {
|
|
512
|
-
if (i === comments.length - 1) return factory.createJSDocText(comment);
|
|
513
|
-
return factory.createJSDocText(`${comment}\n`);
|
|
514
|
-
})));
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
433
|
* Attaches JSDoc comments to an AST node as synthetic leading comments.
|
|
518
434
|
* Filters out undefined comments before attaching.
|
|
519
435
|
*
|
|
@@ -532,19 +448,7 @@ function appendJSDocToNode({ node, comments }) {
|
|
|
532
448
|
* Defines the key type (default: `string`) and value type on an object.
|
|
533
449
|
*/
|
|
534
450
|
function createIndexSignature(type, { modifiers, indexName = "key", indexType = factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword) } = {}) {
|
|
535
|
-
return factory.createIndexSignature(modifiers, [
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Creates a TypeScript type alias declaration with optional modifiers and type parameters.
|
|
539
|
-
*/
|
|
540
|
-
function createTypeAliasDeclaration({ modifiers, name, typeParameters, type }) {
|
|
541
|
-
return factory.createTypeAliasDeclaration(modifiers, name, typeParameters, type);
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Creates a TypeScript interface declaration with optional modifiers, type parameters, and members.
|
|
545
|
-
*/
|
|
546
|
-
function createInterfaceDeclaration({ modifiers, name, typeParameters, members }) {
|
|
547
|
-
return factory.createInterfaceDeclaration(modifiers, name, typeParameters, void 0, members);
|
|
451
|
+
return factory.createIndexSignature(modifiers, [factory.createParameterDeclaration(void 0, void 0, indexName, void 0, indexType)], type);
|
|
548
452
|
}
|
|
549
453
|
/**
|
|
550
454
|
* Creates a TypeScript type declaration as either a type alias or interface.
|
|
@@ -552,67 +456,22 @@ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }
|
|
|
552
456
|
*/
|
|
553
457
|
function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
|
|
554
458
|
if (syntax === "interface" && typescript.isTypeLiteralNode(type)) return appendJSDocToNode({
|
|
555
|
-
node: createInterfaceDeclaration(
|
|
556
|
-
members: [...type.members],
|
|
557
|
-
modifiers: isExportable ? [modifiers.export] : [],
|
|
558
|
-
name,
|
|
559
|
-
typeParameters: void 0
|
|
560
|
-
}),
|
|
459
|
+
node: factory.createInterfaceDeclaration(isExportable ? [modifiers.export] : [], name, void 0, void 0, [...type.members]),
|
|
561
460
|
comments
|
|
562
461
|
});
|
|
563
462
|
return appendJSDocToNode({
|
|
564
|
-
node: createTypeAliasDeclaration(
|
|
565
|
-
type,
|
|
566
|
-
modifiers: isExportable ? [modifiers.export] : [],
|
|
567
|
-
name,
|
|
568
|
-
typeParameters: void 0
|
|
569
|
-
}),
|
|
463
|
+
node: factory.createTypeAliasDeclaration(isExportable ? [modifiers.export] : [], name, void 0, type),
|
|
570
464
|
comments
|
|
571
465
|
});
|
|
572
466
|
}
|
|
573
467
|
/**
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
* @example Default import
|
|
578
|
-
* `import Pet from './Pet'`
|
|
579
|
-
*
|
|
580
|
-
* @example Named imports with rename
|
|
581
|
-
* `import { Pet as Cat } from './Pet'`
|
|
582
|
-
*
|
|
583
|
-
* @example Namespace import
|
|
584
|
-
* `import * as Pet from './Pet'`
|
|
585
|
-
*/
|
|
586
|
-
function createImportDeclaration({ name, path, isTypeOnly = false, isNameSpace = false }) {
|
|
587
|
-
if (!Array.isArray(name)) {
|
|
588
|
-
const importPropertyName = isNameSpace ? void 0 : factory.createIdentifier(name);
|
|
589
|
-
const importName = isNameSpace ? factory.createNamespaceImport(factory.createIdentifier(name)) : void 0;
|
|
590
|
-
return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, importPropertyName, importName), factory.createStringLiteral(path), void 0);
|
|
591
|
-
}
|
|
592
|
-
const sortedName = name.toSorted((a, b) => compareStrings(typeof a === "object" ? a.propertyName : a, typeof b === "object" ? b.propertyName : b));
|
|
593
|
-
return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(sortedName.map((item) => {
|
|
594
|
-
if (typeof item === "object") {
|
|
595
|
-
const obj = item;
|
|
596
|
-
if (obj.name) return factory.createImportSpecifier(false, factory.createIdentifier(obj.propertyName), factory.createIdentifier(obj.name));
|
|
597
|
-
return factory.createImportSpecifier(false, void 0, factory.createIdentifier(obj.propertyName));
|
|
598
|
-
}
|
|
599
|
-
return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
|
|
600
|
-
}))), factory.createStringLiteral(path), void 0);
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Creates an export declaration with support for named exports, namespace exports, and type-only exports.
|
|
604
|
-
* Sorts export names alphabetically for consistent output across platforms.
|
|
468
|
+
* Converts an enum member value to a literal expression. Numbers become numeric literals (negatives use a prefix
|
|
469
|
+
* minus, as `createNumericLiteral` rejects them) unless `asNumber` is `false`, which emits the string form.
|
|
605
470
|
*/
|
|
606
|
-
function
|
|
607
|
-
if (
|
|
608
|
-
if (
|
|
609
|
-
|
|
610
|
-
return factory.createExportDeclaration(void 0, isTypeOnly, asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : void 0, factory.createStringLiteral(path), void 0);
|
|
611
|
-
}
|
|
612
|
-
const sortedName = name.toSorted((a, b) => compareStrings(typeof a === "string" ? a : a.text, typeof b === "string" ? b : b.text));
|
|
613
|
-
return factory.createExportDeclaration(void 0, isTypeOnly, factory.createNamedExports(sortedName.map((propertyName) => {
|
|
614
|
-
return factory.createExportSpecifier(false, void 0, typeof propertyName === "string" ? factory.createIdentifier(propertyName) : propertyName);
|
|
615
|
-
})), factory.createStringLiteral(path), void 0);
|
|
471
|
+
function valueToExpression(value, asNumber = isNumber(value)) {
|
|
472
|
+
if (typeof value === "boolean") return value ? factory.createTrue() : factory.createFalse();
|
|
473
|
+
if (asNumber && isNumber(value)) return value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value))) : factory.createNumericLiteral(value);
|
|
474
|
+
return factory.createStringLiteral(value.toString());
|
|
616
475
|
}
|
|
617
476
|
/**
|
|
618
477
|
* Apply casing transformation to enum keys
|
|
@@ -649,12 +508,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
649
508
|
if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
|
|
650
509
|
}).filter((node) => node !== void 0)))];
|
|
651
510
|
if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(typescript.SyntaxKind.ConstKeyword) : void 0].filter((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value, description]) => {
|
|
652
|
-
|
|
653
|
-
if (Number.parseInt(value.toString(), 10) === value && isNumber(value)) {
|
|
654
|
-
if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
|
|
655
|
-
else initializer = factory.createNumericLiteral(value);
|
|
656
|
-
}
|
|
657
|
-
if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
|
|
511
|
+
const initializer = valueToExpression(value, Number.parseInt(value.toString(), 10) === value);
|
|
658
512
|
if (isNumber(Number.parseInt(key.toString(), 10))) {
|
|
659
513
|
const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
|
|
660
514
|
return appendJSDocToNode({
|
|
@@ -673,12 +527,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
673
527
|
const identifierName = name;
|
|
674
528
|
if (enums.length === 0) return [void 0, factory.createTypeAliasDeclaration([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createIdentifier(typeName), void 0, factory.createKeywordTypeNode(typescript.SyntaxKind.NeverKeyword))];
|
|
675
529
|
return [factory.createVariableStatement([factory.createToken(typescript.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier(identifierName), void 0, void 0, factory.createAsExpression(factory.createObjectLiteralExpression(enums.map(([key, value, description]) => {
|
|
676
|
-
|
|
677
|
-
if (isNumber(value)) {
|
|
678
|
-
if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
|
|
679
|
-
else initializer = factory.createNumericLiteral(value);
|
|
680
|
-
}
|
|
681
|
-
if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
|
|
530
|
+
const initializer = valueToExpression(value);
|
|
682
531
|
if (key !== null && key !== void 0) {
|
|
683
532
|
const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
|
|
684
533
|
return appendJSDocToNode({
|
|
@@ -757,66 +606,19 @@ const createTypeLiteralNode = factory.createTypeLiteralNode;
|
|
|
757
606
|
*/
|
|
758
607
|
const createTypeReferenceNode = factory.createTypeReferenceNode;
|
|
759
608
|
/**
|
|
760
|
-
* Creates a numeric literal type node.
|
|
761
|
-
*/
|
|
762
|
-
const createNumericLiteral = factory.createNumericLiteral;
|
|
763
|
-
/**
|
|
764
|
-
* Creates a string literal type node.
|
|
765
|
-
*/
|
|
766
|
-
const createStringLiteral = factory.createStringLiteral;
|
|
767
|
-
/**
|
|
768
|
-
* Creates an array type node (e.g., `T[]`).
|
|
769
|
-
*/
|
|
770
|
-
const createArrayTypeNode = factory.createArrayTypeNode;
|
|
771
|
-
/**
|
|
772
|
-
* Creates a literal type node (e.g., `'hello'`, `42`, `true`).
|
|
773
|
-
*/
|
|
774
|
-
const createLiteralTypeNode = factory.createLiteralTypeNode;
|
|
775
|
-
/**
|
|
776
|
-
* Creates an identifier node.
|
|
777
|
-
*/
|
|
778
|
-
const createIdentifier = factory.createIdentifier;
|
|
779
|
-
/**
|
|
780
|
-
* Creates an optional type node (e.g., `T | undefined`).
|
|
781
|
-
*/
|
|
782
|
-
const createOptionalTypeNode = factory.createOptionalTypeNode;
|
|
783
|
-
/**
|
|
784
|
-
* Creates a tuple type node (e.g., `[string, number]`).
|
|
785
|
-
*/
|
|
786
|
-
const createTupleTypeNode = factory.createTupleTypeNode;
|
|
787
|
-
/**
|
|
788
|
-
* Creates a rest type node for variadic tuple elements (e.g., `...T[]`).
|
|
789
|
-
*/
|
|
790
|
-
const createRestTypeNode = factory.createRestTypeNode;
|
|
791
|
-
/**
|
|
792
|
-
* Creates a boolean true literal type node.
|
|
793
|
-
*/
|
|
794
|
-
const createTrue = factory.createTrue;
|
|
795
|
-
/**
|
|
796
|
-
* Creates a boolean false literal type node.
|
|
797
|
-
*/
|
|
798
|
-
const createFalse = factory.createFalse;
|
|
799
|
-
/**
|
|
800
|
-
* Creates a prefix unary expression (e.g., negative numbers, logical not).
|
|
801
|
-
*/
|
|
802
|
-
const createPrefixUnaryExpression = factory.createPrefixUnaryExpression;
|
|
803
|
-
/**
|
|
804
609
|
* Converts a primitive const value to a TypeScript literal type node.
|
|
805
610
|
* Handles negative numbers via a prefix unary expression.
|
|
806
611
|
*/
|
|
807
612
|
function constToTypeNode(value, format) {
|
|
808
|
-
if (format === "boolean") return createLiteralTypeNode(value === true ? createTrue() : createFalse());
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
return createLiteralTypeNode(createNumericLiteral(value));
|
|
812
|
-
}
|
|
813
|
-
return createLiteralTypeNode(createStringLiteral(String(value)));
|
|
613
|
+
if (format === "boolean") return factory.createLiteralTypeNode(value === true ? factory.createTrue() : factory.createFalse());
|
|
614
|
+
const literal = format === "number" && typeof value === "number" ? value : String(value);
|
|
615
|
+
return factory.createLiteralTypeNode(valueToExpression(literal));
|
|
814
616
|
}
|
|
815
617
|
/**
|
|
816
618
|
* Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
|
|
817
619
|
*/
|
|
818
620
|
function dateOrStringNode(node) {
|
|
819
|
-
return node.representation === "date" ? createTypeReferenceNode(createIdentifier("Date")) : keywordTypeNodes.string;
|
|
621
|
+
return node.representation === "date" ? createTypeReferenceNode(factory.createIdentifier("Date")) : keywordTypeNodes.string;
|
|
820
622
|
}
|
|
821
623
|
/**
|
|
822
624
|
* Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
|
|
@@ -836,20 +638,24 @@ function buildTupleNode(node, print) {
|
|
|
836
638
|
items = items.slice(0, max);
|
|
837
639
|
if (items.length < max && restNode) items = [...items, ...Array(max - items.length).fill(restNode)];
|
|
838
640
|
}
|
|
839
|
-
if (min !== void 0) items = items.map((item, i) => i >= min ? createOptionalTypeNode(item) : item);
|
|
840
|
-
if (max === void 0 && restNode) items.push(createRestTypeNode(createArrayTypeNode(restNode)));
|
|
841
|
-
return createTupleTypeNode(items);
|
|
641
|
+
if (min !== void 0) items = items.map((item, i) => i >= min ? factory.createOptionalTypeNode(item) : item);
|
|
642
|
+
if (max === void 0 && restNode) items.push(factory.createRestTypeNode(factory.createArrayTypeNode(restNode)));
|
|
643
|
+
return factory.createTupleTypeNode(items);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Appends `| null` and then `| undefined` to a type when requested.
|
|
647
|
+
*/
|
|
648
|
+
function wrapNullableOptional(type, nullable, addsUndefined) {
|
|
649
|
+
const withNullable = nullable ? createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] }) : type;
|
|
650
|
+
return addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
842
651
|
}
|
|
843
652
|
/**
|
|
844
653
|
* Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
|
|
845
654
|
*/
|
|
846
655
|
function buildPropertyType(schema, baseType, optionalType, optional) {
|
|
847
|
-
const addsUndefined =
|
|
656
|
+
const addsUndefined = optionalType === "undefined" || optionalType === "questionTokenAndUndefined";
|
|
848
657
|
const meta = (0, kubb_kit.syncSchemaRef)(schema);
|
|
849
|
-
|
|
850
|
-
if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
851
|
-
if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
852
|
-
return type;
|
|
658
|
+
return wrapNullableOptional(baseType, !!meta.nullable, addsUndefined && !!(optional || meta.nullish || meta.optional));
|
|
853
659
|
}
|
|
854
660
|
const indexSignaturePrinter = typescript.createPrinter();
|
|
855
661
|
const indexSignatureSource = typescript.createSourceFile("", "", typescript.ScriptTarget.Latest);
|
|
@@ -892,7 +698,7 @@ function getEnumNames({ node, enum: enumOptions, resolver }) {
|
|
|
892
698
|
const resolved = resolver.name(node.name);
|
|
893
699
|
return {
|
|
894
700
|
enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
|
|
895
|
-
typeName:
|
|
701
|
+
typeName: enumOptions.type === "asConst" ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
|
|
896
702
|
};
|
|
897
703
|
}
|
|
898
704
|
/**
|
|
@@ -933,30 +739,16 @@ function Enum({ node, enum: enumOptions, resolver }) {
|
|
|
933
739
|
}), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
934
740
|
name: typeName,
|
|
935
741
|
isIndexable: !namesMerge,
|
|
936
|
-
isExportable: !namesMerge &&
|
|
937
|
-
isTypeOnly:
|
|
742
|
+
isExportable: !namesMerge && enumOptions.type !== "inlineLiteral",
|
|
743
|
+
isTypeOnly: [
|
|
744
|
+
"asConst",
|
|
745
|
+
"literal",
|
|
746
|
+
void 0
|
|
747
|
+
].includes(enumOptions.type),
|
|
938
748
|
children: (0, _kubb_parser_ts.parserTs)().print(typeNode)
|
|
939
749
|
})] });
|
|
940
750
|
}
|
|
941
751
|
//#endregion
|
|
942
|
-
//#region ../../internals/shared/src/params.ts
|
|
943
|
-
/**
|
|
944
|
-
* Drops parameters that share the same name, keeping the first.
|
|
945
|
-
*
|
|
946
|
-
* A malformed spec can declare the same parameter name twice within one `in` location. Both would
|
|
947
|
-
* resolve to the same output property, so emitting both would yield an object type with a duplicate
|
|
948
|
-
* member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
|
|
949
|
-
* parameter names flow through unchanged, so no two distinct names ever collide here anymore.
|
|
950
|
-
*/
|
|
951
|
-
function dedupeParams(params) {
|
|
952
|
-
const seen = /* @__PURE__ */ new Set();
|
|
953
|
-
return params.filter((param) => {
|
|
954
|
-
if (seen.has(param.name)) return false;
|
|
955
|
-
seen.add(param.name);
|
|
956
|
-
return true;
|
|
957
|
-
});
|
|
958
|
-
}
|
|
959
|
-
//#endregion
|
|
960
752
|
//#region ../../internals/shared/src/operation.ts
|
|
961
753
|
/**
|
|
962
754
|
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
@@ -1016,11 +808,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
|
1016
808
|
function getOperationParameters(node) {
|
|
1017
809
|
const cached = operationParameterGroupsByNode.get(node);
|
|
1018
810
|
if (cached) return cached;
|
|
811
|
+
const group = (location) => {
|
|
812
|
+
const seen = /* @__PURE__ */ new Set();
|
|
813
|
+
return node.parameters.filter((param) => {
|
|
814
|
+
if (param.in !== location || seen.has(param.name)) return false;
|
|
815
|
+
seen.add(param.name);
|
|
816
|
+
return true;
|
|
817
|
+
});
|
|
818
|
+
};
|
|
1019
819
|
const groups = {
|
|
1020
|
-
path:
|
|
1021
|
-
query:
|
|
1022
|
-
header:
|
|
1023
|
-
cookie:
|
|
820
|
+
path: group("path"),
|
|
821
|
+
query: group("query"),
|
|
822
|
+
header: group("header"),
|
|
823
|
+
cookie: group("cookie")
|
|
1024
824
|
};
|
|
1025
825
|
operationParameterGroupsByNode.set(node, groups);
|
|
1026
826
|
return groups;
|
|
@@ -1222,20 +1022,6 @@ function createCasedFile(caseLast) {
|
|
|
1222
1022
|
} };
|
|
1223
1023
|
}
|
|
1224
1024
|
//#endregion
|
|
1225
|
-
//#region ../../internals/shared/src/refs.ts
|
|
1226
|
-
/**
|
|
1227
|
-
* Collects the resolved target name of every pointer-carrying ref in a schema tree, in
|
|
1228
|
-
* first-occurrence order. Use this for name-only checks (e.g. redeclaration detection) where
|
|
1229
|
-
* `resolver.imports` would resolve file paths that are then discarded.
|
|
1230
|
-
*/
|
|
1231
|
-
function collectRefNames(schema) {
|
|
1232
|
-
return kubb_kit.ast.collectSync(schema, { schema: (node) => {
|
|
1233
|
-
const refNode = kubb_kit.ast.narrowSchema(node, "ref");
|
|
1234
|
-
if (!refNode?.ref) return null;
|
|
1235
|
-
return kubb_kit.ast.resolveRefName(refNode);
|
|
1236
|
-
} });
|
|
1237
|
-
}
|
|
1238
|
-
//#endregion
|
|
1239
1025
|
//#region ../../internals/shared/src/group.ts
|
|
1240
1026
|
/**
|
|
1241
1027
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -1297,6 +1083,9 @@ function mapSchemaItems(node, transform) {
|
|
|
1297
1083
|
}
|
|
1298
1084
|
//#endregion
|
|
1299
1085
|
//#region src/utils.ts
|
|
1086
|
+
function enumTypeName({ resolver, name, enumOptions, isEnum }) {
|
|
1087
|
+
return isEnum && enumOptions?.type === "asConst" && enumOptions.typeSuffix ? resolver.enum.keyName({ name }, enumOptions.typeSuffix) : resolver.name(name);
|
|
1088
|
+
}
|
|
1300
1089
|
/**
|
|
1301
1090
|
* Tells whether a `const` (single-value enum) should render as a bare literal type (`'active'`)
|
|
1302
1091
|
* rather than a named enum reference or a runtime enum declaration.
|
|
@@ -1433,7 +1222,7 @@ const { isNonNullable } = factory_exports;
|
|
|
1433
1222
|
* ```
|
|
1434
1223
|
*/
|
|
1435
1224
|
const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
1436
|
-
const addsUndefined =
|
|
1225
|
+
const addsUndefined = options.optionalType === "undefined" || options.optionalType === "questionTokenAndUndefined";
|
|
1437
1226
|
return {
|
|
1438
1227
|
name: "typescript",
|
|
1439
1228
|
options,
|
|
@@ -1464,7 +1253,12 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1464
1253
|
if (!node.name) return null;
|
|
1465
1254
|
const refName = kubb_kit.ast.resolveRefName(node);
|
|
1466
1255
|
if (!refName) return null;
|
|
1467
|
-
const name = node.ref
|
|
1256
|
+
const name = node.ref ? enumTypeName({
|
|
1257
|
+
resolver: this.options.resolver,
|
|
1258
|
+
name: refName,
|
|
1259
|
+
enumOptions: this.options.enum,
|
|
1260
|
+
isEnum: !!this.options.enumSchemaNames?.has(refName)
|
|
1261
|
+
}) : refName;
|
|
1468
1262
|
return createTypeReferenceNode(name, void 0);
|
|
1469
1263
|
},
|
|
1470
1264
|
enum(node) {
|
|
@@ -1472,8 +1266,13 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1472
1266
|
if (this.options.enum.type === "inlineLiteral" || !node.name || isInlineConstEnum(node, this.options.enumSchemaNames)) return createUnionDeclaration({
|
|
1473
1267
|
withParentheses: true,
|
|
1474
1268
|
nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
|
|
1475
|
-
})
|
|
1476
|
-
const resolvedName =
|
|
1269
|
+
});
|
|
1270
|
+
const resolvedName = enumTypeName({
|
|
1271
|
+
resolver: this.options.resolver,
|
|
1272
|
+
name: node.name,
|
|
1273
|
+
enumOptions: this.options.enum,
|
|
1274
|
+
isEnum: true
|
|
1275
|
+
});
|
|
1477
1276
|
return createTypeReferenceNode(resolvedName, void 0);
|
|
1478
1277
|
},
|
|
1479
1278
|
union(node) {
|
|
@@ -1491,30 +1290,30 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1491
1290
|
});
|
|
1492
1291
|
return this.transform(m);
|
|
1493
1292
|
}).filter(isNonNullable)
|
|
1494
|
-
})
|
|
1293
|
+
});
|
|
1495
1294
|
return createUnionDeclaration({
|
|
1496
1295
|
withParentheses: true,
|
|
1497
1296
|
nodes: buildMemberNodes(members, this.transform)
|
|
1498
|
-
})
|
|
1297
|
+
});
|
|
1499
1298
|
},
|
|
1500
1299
|
intersection(node) {
|
|
1501
1300
|
return createIntersectionDeclaration({
|
|
1502
1301
|
withParentheses: true,
|
|
1503
1302
|
nodes: buildMemberNodes(node.members, this.transform)
|
|
1504
|
-
})
|
|
1303
|
+
});
|
|
1505
1304
|
},
|
|
1506
1305
|
array(node) {
|
|
1507
1306
|
return createArrayDeclaration({
|
|
1508
1307
|
nodes: mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
|
|
1509
1308
|
arrayType: this.options.arrayType
|
|
1510
|
-
})
|
|
1309
|
+
});
|
|
1511
1310
|
},
|
|
1512
1311
|
tuple(node) {
|
|
1513
|
-
return buildTupleNode(node, this.transform)
|
|
1312
|
+
return buildTupleNode(node, this.transform);
|
|
1514
1313
|
},
|
|
1515
1314
|
object(node) {
|
|
1516
1315
|
const { transform, options } = this;
|
|
1517
|
-
const addsQuestionToken =
|
|
1316
|
+
const addsQuestionToken = options.optionalType === "questionToken" || options.optionalType === "questionTokenAndUndefined";
|
|
1518
1317
|
const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
|
|
1519
1318
|
const baseType = output ?? keywordTypeNodes.unknown;
|
|
1520
1319
|
const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
|
|
@@ -1542,24 +1341,21 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1542
1341
|
if (!transformed) return null;
|
|
1543
1342
|
const meta = (0, kubb_kit.syncSchemaRef)(node);
|
|
1544
1343
|
if (!name) {
|
|
1545
|
-
const
|
|
1546
|
-
const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
1344
|
+
const result = wrapNullableOptional(transformed, !!meta.nullable, !!(meta.nullish || meta.optional) && addsUndefined);
|
|
1547
1345
|
return (0, _kubb_parser_ts.parserTs)().print(result);
|
|
1548
1346
|
}
|
|
1549
1347
|
const inner = (() => {
|
|
1550
|
-
|
|
1348
|
+
return wrapNullableOptional(keysToOmit?.length ? createOmitDeclaration({
|
|
1551
1349
|
keys: keysToOmit,
|
|
1552
1350
|
type: transformed,
|
|
1553
1351
|
nonNullable: true
|
|
1554
|
-
}) : transformed;
|
|
1555
|
-
const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [omitted, keywordTypeNodes.null] }) : omitted;
|
|
1556
|
-
return meta.nullish || meta.optional ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
1352
|
+
}) : transformed, !!meta.nullable, !!(meta.nullish || meta.optional));
|
|
1557
1353
|
})();
|
|
1558
1354
|
const typeNode = createTypeDeclaration({
|
|
1559
1355
|
name,
|
|
1560
1356
|
isExportable: true,
|
|
1561
1357
|
type: inner,
|
|
1562
|
-
syntax: syntaxType === "type" || inner
|
|
1358
|
+
syntax: syntaxType === "type" || isUnionTypeNode(inner) || !!keysToOmit?.length ? "type" : "interface",
|
|
1563
1359
|
comments: buildPropertyJSDocComments({
|
|
1564
1360
|
...meta,
|
|
1565
1361
|
description
|
|
@@ -1572,15 +1368,6 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1572
1368
|
//#endregion
|
|
1573
1369
|
//#region src/generators/typeGenerator.tsx
|
|
1574
1370
|
/**
|
|
1575
|
-
* Resolves the imported type name for a referenced schema. An enum schema emitted
|
|
1576
|
-
* as a `const` object imports its suffixed key alias (e.g. `StatusKey`); every other
|
|
1577
|
-
* schema imports its plain resolved name.
|
|
1578
|
-
*/
|
|
1579
|
-
function resolveImportName({ schemaName, enumOptions, enumSchemaNames, resolver }) {
|
|
1580
|
-
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
|
|
1581
|
-
return resolver.name(schemaName);
|
|
1582
|
-
}
|
|
1583
|
-
/**
|
|
1584
1371
|
* Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
|
|
1585
1372
|
* schema in the spec plus per-operation request, response, and parameter
|
|
1586
1373
|
* types. Drop-replace with a custom `Generator<PluginTs>` to change how
|
|
@@ -1594,11 +1381,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1594
1381
|
const { config, resolver, root } = ctx;
|
|
1595
1382
|
if (!node.name) return;
|
|
1596
1383
|
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1597
|
-
const importName = (schemaName) =>
|
|
1598
|
-
|
|
1384
|
+
const importName = (schemaName) => enumTypeName({
|
|
1385
|
+
resolver,
|
|
1386
|
+
name: schemaName,
|
|
1599
1387
|
enumOptions,
|
|
1600
|
-
enumSchemaNames
|
|
1601
|
-
resolver
|
|
1388
|
+
isEnum: enumSchemaNames.has(schemaName)
|
|
1602
1389
|
});
|
|
1603
1390
|
const imports = resolver.imports({
|
|
1604
1391
|
node,
|
|
@@ -1610,7 +1397,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1610
1397
|
const enumNode = kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
|
|
1611
1398
|
const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
|
|
1612
1399
|
const meta = {
|
|
1613
|
-
name:
|
|
1400
|
+
name: enumOptions.type === "asConst" && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
|
|
1614
1401
|
file: resolver.file({
|
|
1615
1402
|
name: node.name,
|
|
1616
1403
|
extname: ".ts",
|
|
@@ -1681,11 +1468,11 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1681
1468
|
group: group ?? void 0
|
|
1682
1469
|
}) };
|
|
1683
1470
|
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1684
|
-
const importName = (schemaName) =>
|
|
1685
|
-
|
|
1471
|
+
const importName = (schemaName) => enumTypeName({
|
|
1472
|
+
resolver,
|
|
1473
|
+
name: schemaName,
|
|
1686
1474
|
enumOptions,
|
|
1687
|
-
enumSchemaNames
|
|
1688
|
-
resolver
|
|
1475
|
+
isEnum: enumSchemaNames.has(schemaName)
|
|
1689
1476
|
});
|
|
1690
1477
|
function renderSchemaType({ schema, name, keysToOmit }) {
|
|
1691
1478
|
if (!schema) return null;
|
|
@@ -1808,7 +1595,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1808
1595
|
if (!node.responses.some(hasSchema)) return null;
|
|
1809
1596
|
const responseName = resolver.response.response(node);
|
|
1810
1597
|
const responsesWithSchema = node.responses.filter(hasSchema);
|
|
1811
|
-
if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ?
|
|
1598
|
+
if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? kubb_kit.ast.collectImportedRefNames(entry.schema).map(importName) : []))).has(responseName)) return null;
|
|
1812
1599
|
return renderSchemaType({
|
|
1813
1600
|
schema: {
|
|
1814
1601
|
...buildResponseUnion(node, { resolver }),
|
|
@@ -1857,7 +1644,7 @@ var compatibility = {
|
|
|
1857
1644
|
};
|
|
1858
1645
|
//#endregion
|
|
1859
1646
|
//#region package.json
|
|
1860
|
-
var version = "5.0.
|
|
1647
|
+
var version = "5.0.12";
|
|
1861
1648
|
//#endregion
|
|
1862
1649
|
//#region src/resolvers/resolverTs.ts
|
|
1863
1650
|
/**
|
|
@@ -2135,6 +1922,15 @@ function createFunctionParameters(props = {}) {
|
|
|
2135
1922
|
//#endregion
|
|
2136
1923
|
//#region src/printers/functionPrinter.ts
|
|
2137
1924
|
/**
|
|
1925
|
+
* Ordering priority for function parameters: lower = sorted earlier.
|
|
1926
|
+
*/
|
|
1927
|
+
const PARAM_RANK = {
|
|
1928
|
+
required: 0,
|
|
1929
|
+
optional: 1,
|
|
1930
|
+
withDefault: 2,
|
|
1931
|
+
rest: 3
|
|
1932
|
+
};
|
|
1933
|
+
/**
|
|
2138
1934
|
* Renders a {@link TypeExpression} to its TypeScript source.
|
|
2139
1935
|
*
|
|
2140
1936
|
* - a `string` is a type reference, returned as-is
|
|
@@ -2155,13 +1951,17 @@ function renderType(type, transformType) {
|
|
|
2155
1951
|
function renderKey(name) {
|
|
2156
1952
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
|
|
2157
1953
|
}
|
|
1954
|
+
function renderMembers(members) {
|
|
1955
|
+
return `{ ${members.map((member) => `${renderKey(member.key)}${member.optional ? "?" : ""}: ${member.type}`).join("; ")} }`;
|
|
1956
|
+
}
|
|
2158
1957
|
function renderTypeExpression(type) {
|
|
2159
1958
|
if (typeof type === "string") return type;
|
|
2160
1959
|
if (isIndexedAccessType(type)) return `${type.target}['${type.key}']`;
|
|
2161
|
-
return
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
1960
|
+
return renderMembers(type.members.map((member) => ({
|
|
1961
|
+
key: member.name,
|
|
1962
|
+
type: renderTypeExpression(member.type),
|
|
1963
|
+
optional: member.optional
|
|
1964
|
+
})));
|
|
2165
1965
|
}
|
|
2166
1966
|
function groupMembers(param) {
|
|
2167
1967
|
if (typeof param.name === "string") return null;
|
|
@@ -2174,9 +1974,6 @@ function rank(param) {
|
|
|
2174
1974
|
if (members) return members.every((m) => m.optional) ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
2175
1975
|
return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
2176
1976
|
}
|
|
2177
|
-
function sortParams(params) {
|
|
2178
|
-
return params.toSorted((a, b) => rank(a) - rank(b));
|
|
2179
|
-
}
|
|
2180
1977
|
function sortedGroupMembers(name, type) {
|
|
2181
1978
|
const members = type && isTypeLiteral(type) ? type.members : [];
|
|
2182
1979
|
const memberRank = (optional) => optional ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
@@ -2205,11 +2002,11 @@ function renderGroupType(type, sorted, transformType) {
|
|
|
2205
2002
|
if (!isTypeLiteral(type)) return renderType(type);
|
|
2206
2003
|
const typed = sorted.filter((member) => member.type !== void 0);
|
|
2207
2004
|
if (!typed.length) return void 0;
|
|
2208
|
-
return
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
})
|
|
2005
|
+
return renderMembers(typed.map((member) => ({
|
|
2006
|
+
key: member.propertyName ?? member.name,
|
|
2007
|
+
type: renderType(member.type, transformType),
|
|
2008
|
+
optional: member.optional
|
|
2009
|
+
})));
|
|
2213
2010
|
}
|
|
2214
2011
|
function printParameter(node, options) {
|
|
2215
2012
|
const { mode, transformName, transformType } = options;
|
|
@@ -2262,190 +2059,11 @@ function functionPrinter(options) {
|
|
|
2262
2059
|
name: "functionParameters",
|
|
2263
2060
|
options,
|
|
2264
2061
|
print(node) {
|
|
2265
|
-
return
|
|
2062
|
+
return node.params.toSorted((a, b) => rank(a) - rank(b)).map((p) => printParameter(p, options)).filter(Boolean).join(", ");
|
|
2266
2063
|
}
|
|
2267
2064
|
};
|
|
2268
2065
|
}
|
|
2269
2066
|
//#endregion
|
|
2270
|
-
//#region src/printers/operationParams.ts
|
|
2271
|
-
/**
|
|
2272
|
-
* Resolves the {@link TypeExpression} for an individual parameter.
|
|
2273
|
-
*
|
|
2274
|
-
* Without a resolver, it falls back to the schema primitive (a plain type-name string). When the
|
|
2275
|
-
* parameter belongs to a named group, it emits an `IndexedAccessType` like `GroupParams['petId']`,
|
|
2276
|
-
* otherwise the resolved individual name.
|
|
2277
|
-
*/
|
|
2278
|
-
function resolveParamType({ node, param, resolver }) {
|
|
2279
|
-
if (!resolver) return param.schema.primitive ?? "unknown";
|
|
2280
|
-
const individualName = resolver.param.name(node, param);
|
|
2281
|
-
const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
|
|
2282
|
-
const groupResolvers = {
|
|
2283
|
-
path: resolver.param.path,
|
|
2284
|
-
query: resolver.param.query,
|
|
2285
|
-
header: resolver.param.headers
|
|
2286
|
-
};
|
|
2287
|
-
const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
|
|
2288
|
-
if (groupName && groupName !== individualName) return createIndexedAccessType({
|
|
2289
|
-
target: groupName,
|
|
2290
|
-
key: param.name
|
|
2291
|
-
});
|
|
2292
|
-
return individualName;
|
|
2293
|
-
}
|
|
2294
|
-
/**
|
|
2295
|
-
* Derives a {@link ParamGroupType} for a query or header group from the resolver.
|
|
2296
|
-
*
|
|
2297
|
-
* Returns `null` when there is no resolver, no params, or the group name equals the
|
|
2298
|
-
* individual param name (so there is no real group to emit).
|
|
2299
|
-
*/
|
|
2300
|
-
function resolveGroupType({ node, params, group, resolver }) {
|
|
2301
|
-
if (!resolver || !params.length) return null;
|
|
2302
|
-
const firstParam = params[0];
|
|
2303
|
-
const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
|
|
2304
|
-
if (groupName === resolver.param.name(node, firstParam)) return null;
|
|
2305
|
-
return {
|
|
2306
|
-
type: groupName,
|
|
2307
|
-
optional: params.every((p) => !p.required)
|
|
2308
|
-
};
|
|
2309
|
-
}
|
|
2310
|
-
/**
|
|
2311
|
-
* Converts an `OperationNode` into function parameters for code generation.
|
|
2312
|
-
*
|
|
2313
|
-
* Centralizes parameter grouping logic for all plugins. `paramsType` chooses between one
|
|
2314
|
-
* destructured object parameter (`object`) and separate top-level parameters (`inline`), while
|
|
2315
|
-
* `pathParamsType` controls how path params render in inline mode. Provide a `resolver` for type
|
|
2316
|
-
* name resolution and `extraParams` for plugin-specific trailing parameters such as an `options` object.
|
|
2317
|
-
*/
|
|
2318
|
-
function createOperationParams(node, options) {
|
|
2319
|
-
const { paramsType, pathParamsType, resolver, pathParamsDefault, extraParams = [], paramNames, typeWrapper } = options;
|
|
2320
|
-
const dataName = paramNames?.data ?? "data";
|
|
2321
|
-
const paramsName = paramNames?.params ?? "params";
|
|
2322
|
-
const headersName = paramNames?.headers ?? "headers";
|
|
2323
|
-
const pathName = paramNames?.path ?? "pathParams";
|
|
2324
|
-
const wrapType = (type) => typeWrapper ? typeWrapper(type) : type;
|
|
2325
|
-
const wrapTypeExpression = (type) => typeof type === "string" ? wrapType(type) : type;
|
|
2326
|
-
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
|
|
2327
|
-
const toProperty = (param) => ({
|
|
2328
|
-
name: param.name,
|
|
2329
|
-
type: wrapTypeExpression(resolveParamType({
|
|
2330
|
-
node,
|
|
2331
|
-
param,
|
|
2332
|
-
resolver
|
|
2333
|
-
})),
|
|
2334
|
-
optional: !param.required
|
|
2335
|
-
});
|
|
2336
|
-
const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
|
|
2337
|
-
const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
|
|
2338
|
-
const bodyProperty = bodyType ? [{
|
|
2339
|
-
name: dataName,
|
|
2340
|
-
type: bodyType,
|
|
2341
|
-
optional: !(node.requestBody?.required ?? false)
|
|
2342
|
-
}] : [];
|
|
2343
|
-
const trailingGroups = [{
|
|
2344
|
-
name: paramsName,
|
|
2345
|
-
node,
|
|
2346
|
-
params: queryParams,
|
|
2347
|
-
groupType: resolveGroupType({
|
|
2348
|
-
node,
|
|
2349
|
-
params: queryParams,
|
|
2350
|
-
group: "query",
|
|
2351
|
-
resolver
|
|
2352
|
-
}),
|
|
2353
|
-
resolver,
|
|
2354
|
-
wrapType
|
|
2355
|
-
}, {
|
|
2356
|
-
name: headersName,
|
|
2357
|
-
node,
|
|
2358
|
-
params: headerParams,
|
|
2359
|
-
groupType: resolveGroupType({
|
|
2360
|
-
node,
|
|
2361
|
-
params: headerParams,
|
|
2362
|
-
group: "header",
|
|
2363
|
-
resolver
|
|
2364
|
-
}),
|
|
2365
|
-
resolver,
|
|
2366
|
-
wrapType
|
|
2367
|
-
}];
|
|
2368
|
-
const params = [];
|
|
2369
|
-
if (paramsType === "object") {
|
|
2370
|
-
const children = [
|
|
2371
|
-
...pathParams.map(toProperty),
|
|
2372
|
-
...bodyProperty,
|
|
2373
|
-
...trailingGroups.flatMap(buildGroupProperty)
|
|
2374
|
-
];
|
|
2375
|
-
if (children.length) params.push(createFunctionParameter({
|
|
2376
|
-
properties: children,
|
|
2377
|
-
default: emptyObjectDefault(children)
|
|
2378
|
-
}));
|
|
2379
|
-
} else {
|
|
2380
|
-
if (pathParamsType === "inlineSpread" && pathParams.length) {
|
|
2381
|
-
const spreadType = resolver?.param.path(node, pathParams[0]);
|
|
2382
|
-
params.push(createFunctionParameter({
|
|
2383
|
-
name: pathName,
|
|
2384
|
-
type: spreadType ? wrapType(spreadType) : void 0,
|
|
2385
|
-
rest: true
|
|
2386
|
-
}));
|
|
2387
|
-
} else if (pathParamsType === "inline") params.push(...pathParams.map((p) => createFunctionParameter(toProperty(p))));
|
|
2388
|
-
else if (pathParams.length) {
|
|
2389
|
-
const pathChildren = pathParams.map(toProperty);
|
|
2390
|
-
params.push(createFunctionParameter({
|
|
2391
|
-
properties: pathChildren,
|
|
2392
|
-
default: pathParamsDefault ?? emptyObjectDefault(pathChildren)
|
|
2393
|
-
}));
|
|
2394
|
-
}
|
|
2395
|
-
params.push(...bodyProperty.map((p) => createFunctionParameter(p)));
|
|
2396
|
-
params.push(...trailingGroups.flatMap(buildGroupParam));
|
|
2397
|
-
}
|
|
2398
|
-
params.push(...extraParams);
|
|
2399
|
-
return createFunctionParameters({ params });
|
|
2400
|
-
}
|
|
2401
|
-
/**
|
|
2402
|
-
* Builds the property descriptor for a query or header group.
|
|
2403
|
-
* Returns an empty array when there are no params to emit.
|
|
2404
|
-
*
|
|
2405
|
-
* A pre-resolved `groupType` emits `name: GroupType`. Otherwise it builds an inline
|
|
2406
|
-
* {@link TypeLiteralNode} from the individual params.
|
|
2407
|
-
*/
|
|
2408
|
-
function buildGroupProperty({ name, node, params, groupType, resolver, wrapType }) {
|
|
2409
|
-
if (groupType) return [{
|
|
2410
|
-
name,
|
|
2411
|
-
type: typeof groupType.type === "string" ? wrapType(groupType.type) : groupType.type,
|
|
2412
|
-
optional: groupType.optional
|
|
2413
|
-
}];
|
|
2414
|
-
if (params.length) return [{
|
|
2415
|
-
name,
|
|
2416
|
-
type: buildTypeLiteral({
|
|
2417
|
-
node,
|
|
2418
|
-
params,
|
|
2419
|
-
resolver
|
|
2420
|
-
}),
|
|
2421
|
-
optional: params.every((p) => !p.required)
|
|
2422
|
-
}];
|
|
2423
|
-
return [];
|
|
2424
|
-
}
|
|
2425
|
-
/**
|
|
2426
|
-
* Builds a single {@link FunctionParameterNode} for a query or header group.
|
|
2427
|
-
* Returns an empty array when there are no params to emit.
|
|
2428
|
-
*/
|
|
2429
|
-
function buildGroupParam(args) {
|
|
2430
|
-
return buildGroupProperty(args).map((p) => createFunctionParameter(p));
|
|
2431
|
-
}
|
|
2432
|
-
/**
|
|
2433
|
-
* Builds a {@link TypeLiteralNode} for an inline anonymous type grouping named fields.
|
|
2434
|
-
*
|
|
2435
|
-
* Used when query or header parameters have no dedicated group type name.
|
|
2436
|
-
*/
|
|
2437
|
-
function buildTypeLiteral({ node, params, resolver }) {
|
|
2438
|
-
return createTypeLiteral({ members: params.map((p) => ({
|
|
2439
|
-
name: p.name,
|
|
2440
|
-
type: resolveParamType({
|
|
2441
|
-
node,
|
|
2442
|
-
param: p,
|
|
2443
|
-
resolver
|
|
2444
|
-
}),
|
|
2445
|
-
optional: !p.required
|
|
2446
|
-
})) });
|
|
2447
|
-
}
|
|
2448
|
-
//#endregion
|
|
2449
2067
|
exports.Enum = Enum;
|
|
2450
2068
|
exports.Type = Type;
|
|
2451
2069
|
exports.buildParams = buildParams;
|
|
@@ -2453,9 +2071,9 @@ exports.createFunctionParameter = createFunctionParameter;
|
|
|
2453
2071
|
exports.createFunctionParameters = createFunctionParameters;
|
|
2454
2072
|
exports.createIndexedAccessType = createIndexedAccessType;
|
|
2455
2073
|
exports.createObjectBindingPattern = createObjectBindingPattern;
|
|
2456
|
-
exports.createOperationParams = createOperationParams;
|
|
2457
2074
|
exports.createTypeLiteral = createTypeLiteral;
|
|
2458
2075
|
exports.default = pluginTs;
|
|
2076
|
+
exports.enumTypeName = enumTypeName;
|
|
2459
2077
|
exports.functionPrinter = functionPrinter;
|
|
2460
2078
|
exports.pluginTs = pluginTs;
|
|
2461
2079
|
exports.pluginTsName = pluginTsName;
|