@kubb/plugin-ts 5.0.0-beta.56 → 5.0.0-beta.64
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 +139 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +31 -19
- package/dist/index.js +140 -117
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
- package/src/components/Enum.tsx +0 -87
- package/src/components/Type.tsx +0 -55
- package/src/constants.ts +0 -39
- package/src/factory.ts +0 -970
- package/src/generators/typeGenerator.tsx +0 -274
- package/src/index.ts +0 -9
- package/src/plugin.ts +0 -95
- package/src/printers/functionPrinter.ts +0 -197
- package/src/printers/printerTs.ts +0 -315
- package/src/resolvers/resolverTs.ts +0 -69
- package/src/types.ts +0 -335
- package/src/utils.ts +0 -140
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __name } from "./chunk-C0LytTxp.js";
|
|
2
|
-
import { Exclude, Generator, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
|
|
3
2
|
import ts from "typescript";
|
|
3
|
+
import { Exclude, Generator, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
|
|
4
4
|
import { KubbReactNode } from "@kubb/renderer-jsx/types";
|
|
5
5
|
|
|
6
6
|
//#region src/printers/printerTs.d.ts
|
|
@@ -368,19 +368,22 @@ type Options = OutputOptions & {
|
|
|
368
368
|
*/
|
|
369
369
|
resolver?: Partial<ResolverTs> & ThisType<ResolverTs>;
|
|
370
370
|
/**
|
|
371
|
-
*
|
|
372
|
-
*
|
|
371
|
+
* Macros applied to each schema or operation node before printing.
|
|
372
|
+
* Callbacks you omit fall back to the preset behavior.
|
|
373
373
|
*
|
|
374
374
|
* @example Drop writeOnly properties from response types
|
|
375
375
|
* ```ts
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
376
|
+
* macros: [
|
|
377
|
+
* {
|
|
378
|
+
* name: 'drop-write-only',
|
|
379
|
+
* property(node) {
|
|
380
|
+
* if (node.schema.writeOnly) return undefined
|
|
381
|
+
* },
|
|
382
|
+
* },
|
|
383
|
+
* ]
|
|
381
384
|
* ```
|
|
382
385
|
*/
|
|
383
|
-
|
|
386
|
+
macros?: Array<ast.Macro>;
|
|
384
387
|
/**
|
|
385
388
|
* Replace the TypeScript handler for a specific schema type (`'integer'`, `'date'`, ...).
|
|
386
389
|
* Each handler returns a TypeScript AST node for that schema type. Use `this.transform`
|
|
@@ -533,18 +536,27 @@ declare const pluginTsName = "plugin-ts";
|
|
|
533
536
|
declare const pluginTs: (options?: Options | undefined) => import("@kubb/core").Plugin<PluginTs>;
|
|
534
537
|
//#endregion
|
|
535
538
|
//#region src/printers/functionPrinter.d.ts
|
|
539
|
+
/**
|
|
540
|
+
* Renders a {@link ast.TypeExpression} to its TypeScript source.
|
|
541
|
+
*
|
|
542
|
+
* - a `string` is a type reference, returned as-is
|
|
543
|
+
* - an `IndexedAccessType` becomes `objectType['indexType']`
|
|
544
|
+
* - a `TypeLiteral` becomes `{ key: Type; key?: Type }`
|
|
545
|
+
*
|
|
546
|
+
* `transformType` is applied once to the fully rendered type, matching how the
|
|
547
|
+
* printer wrapped reference types before the `ts.factory` model.
|
|
548
|
+
*/
|
|
549
|
+
declare function renderType(type: ast.TypeExpression, transformType?: (type: string) => string): string;
|
|
536
550
|
type FunctionPrinterOptions = {
|
|
537
551
|
/**
|
|
538
552
|
* Rendering modes supported by `functionPrinter`.
|
|
539
553
|
*
|
|
540
|
-
* | Mode | Output example
|
|
541
|
-
*
|
|
542
|
-
* | `declaration` | `id: string, config: Config = {}`
|
|
543
|
-
* | `call` | `id, { method, url }`
|
|
544
|
-
* | `keys` | `{ id, config }` | Key names only (destructuring) |
|
|
545
|
-
* | `values` | `{ id: id, config: config }` | Key/value object entries |
|
|
554
|
+
* | Mode | Output example | Use case |
|
|
555
|
+
* |---------------|-----------------------------------|--------------------------------|
|
|
556
|
+
* | `declaration` | `id: string, config: Config = {}` | Function parameter declaration |
|
|
557
|
+
* | `call` | `id, { method, url }` | Function call arguments |
|
|
546
558
|
*/
|
|
547
|
-
mode: 'declaration' | 'call'
|
|
559
|
+
mode: 'declaration' | 'call';
|
|
548
560
|
/**
|
|
549
561
|
* Optional transformation applied to every parameter name before printing.
|
|
550
562
|
*/
|
|
@@ -555,8 +567,8 @@ type FunctionPrinterOptions = {
|
|
|
555
567
|
transformType?: (type: string) => string;
|
|
556
568
|
};
|
|
557
569
|
/**
|
|
558
|
-
* Default function-signature printer.
|
|
559
|
-
*
|
|
570
|
+
* Default function-signature printer. Renders a parameter list in one of two modes:
|
|
571
|
+
* `declaration` for the function signature and `call` for the call arguments.
|
|
560
572
|
*
|
|
561
573
|
* @example
|
|
562
574
|
* ```ts
|
|
@@ -600,5 +612,5 @@ declare const functionPrinter: (options?: FunctionPrinterOptions | undefined) =>
|
|
|
600
612
|
*/
|
|
601
613
|
declare const resolverTs: ResolverTs;
|
|
602
614
|
//#endregion
|
|
603
|
-
export { Enum, type PluginTs, type PrinterTsFactory, type PrinterTsNodes, type PrinterTsOptions, type ResolverTs, Type, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, resolverTs, typeGenerator };
|
|
615
|
+
export { Enum, type PluginTs, type PrinterTsFactory, type PrinterTsNodes, type PrinterTsOptions, type ResolverTs, Type, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
|
|
604
616
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as __name } from "./chunk-C0LytTxp.js";
|
|
2
|
-
import { extractRefName, jsStringEscape, stringify, trimQuotes } from "@kubb/ast/utils";
|
|
2
|
+
import { caseParams, extractRefName, isStringType, jsStringEscape, mapSchemaItems, mapSchemaProperties, stringify, syncSchemaRef, trimQuotes } from "@kubb/ast/utils";
|
|
3
3
|
import { parserTs } from "@kubb/parser-ts";
|
|
4
4
|
import { File, jsxRenderer } from "@kubb/renderer-jsx";
|
|
5
|
-
import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
|
|
6
5
|
import ts from "typescript";
|
|
7
6
|
import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
|
|
7
|
+
import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
|
|
8
8
|
//#region ../../internals/utils/src/casing.ts
|
|
9
9
|
/**
|
|
10
10
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -454,7 +454,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
454
454
|
return factory.createLiteralTypeNode(factory.createNumericLiteral(value?.toString()));
|
|
455
455
|
}
|
|
456
456
|
if (typeof value === "boolean") return factory.createLiteralTypeNode(value ? factory.createTrue() : factory.createFalse());
|
|
457
|
-
if (value) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
|
|
457
|
+
if (value !== null && value !== void 0) return factory.createLiteralTypeNode(factory.createStringLiteral(value.toString()));
|
|
458
458
|
}).filter((node) => node !== void 0)))];
|
|
459
459
|
if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(ts.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(ts.SyntaxKind.ConstKeyword) : void 0].filter((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value]) => {
|
|
460
460
|
let initializer = factory.createStringLiteral(value?.toString());
|
|
@@ -465,7 +465,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
465
465
|
const casingKey = applyEnumKeyCasing(`${typeName}_${key}`, enumKeyCasing);
|
|
466
466
|
return factory.createEnumMember(propertyName(casingKey), initializer);
|
|
467
467
|
}
|
|
468
|
-
if (key) {
|
|
468
|
+
if (key !== null && key !== void 0) {
|
|
469
469
|
const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
|
|
470
470
|
return factory.createEnumMember(propertyName(casingKey), initializer);
|
|
471
471
|
}
|
|
@@ -477,7 +477,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
477
477
|
if (isNumber(value)) if (value < 0) initializer = factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
|
|
478
478
|
else initializer = factory.createNumericLiteral(value);
|
|
479
479
|
if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
|
|
480
|
-
if (key) {
|
|
480
|
+
if (key !== null && key !== void 0) {
|
|
481
481
|
const casingKey = applyEnumKeyCasing(key.toString(), enumKeyCasing);
|
|
482
482
|
return factory.createPropertyAssignment(propertyName(casingKey), initializer);
|
|
483
483
|
}
|
|
@@ -638,12 +638,12 @@ function buildTupleNode(node, print) {
|
|
|
638
638
|
/**
|
|
639
639
|
* Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
|
|
640
640
|
*/
|
|
641
|
-
function buildPropertyType(schema, baseType, optionalType) {
|
|
641
|
+
function buildPropertyType(schema, baseType, optionalType, optional) {
|
|
642
642
|
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
|
|
643
|
-
const meta =
|
|
643
|
+
const meta = syncSchemaRef(schema);
|
|
644
644
|
let type = baseType;
|
|
645
645
|
if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
646
|
-
if ((meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
646
|
+
if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
647
647
|
return type;
|
|
648
648
|
}
|
|
649
649
|
/**
|
|
@@ -807,7 +807,7 @@ function resolveContentTypeVariants(entries, baseName) {
|
|
|
807
807
|
});
|
|
808
808
|
}
|
|
809
809
|
function getOperationParameters(node, options = {}) {
|
|
810
|
-
const params =
|
|
810
|
+
const params = caseParams(node.parameters, options.paramsCasing);
|
|
811
811
|
return {
|
|
812
812
|
path: params.filter((param) => param.in === "path"),
|
|
813
813
|
query: params.filter((param) => param.in === "query"),
|
|
@@ -855,8 +855,11 @@ function createGroupConfig(group) {
|
|
|
855
855
|
* Constraint metadata (min/max length, pattern, multipleOf, min/maxProperties) is emitted as plain-text lines.
|
|
856
856
|
|
|
857
857
|
*/
|
|
858
|
-
function
|
|
859
|
-
|
|
858
|
+
function isSchemaOptional(schema) {
|
|
859
|
+
return Boolean("optional" in schema && schema.optional || "nullish" in schema && schema.nullish);
|
|
860
|
+
}
|
|
861
|
+
function buildPropertyJSDocComments(schema, optional) {
|
|
862
|
+
const meta = syncSchemaRef(schema);
|
|
860
863
|
const isArray = meta?.primitive === "array";
|
|
861
864
|
const hasDescription = meta && "description" in meta && meta.description;
|
|
862
865
|
const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
|
|
@@ -869,83 +872,85 @@ function buildPropertyJSDocComments(schema) {
|
|
|
869
872
|
meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
|
|
870
873
|
meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
|
|
871
874
|
meta && "example" in meta && meta.example !== void 0 ? `@example ${meta.example}` : null,
|
|
872
|
-
meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`,
|
|
875
|
+
meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
|
|
873
876
|
].filter(Boolean);
|
|
874
877
|
}
|
|
875
878
|
function buildParams(node, { params, resolver }) {
|
|
876
|
-
return ast.createSchema({
|
|
879
|
+
return ast.factory.createSchema({
|
|
877
880
|
type: "object",
|
|
878
|
-
properties: params.map((param) => ast.createProperty({
|
|
881
|
+
properties: params.map((param) => ast.factory.createProperty({
|
|
879
882
|
name: param.name,
|
|
880
883
|
required: param.required,
|
|
881
|
-
schema: ast.createSchema({
|
|
884
|
+
schema: ast.factory.createSchema({
|
|
882
885
|
type: "ref",
|
|
883
|
-
name: resolver.resolveParamName(node, param)
|
|
886
|
+
name: resolver.resolveParamName(node, param),
|
|
887
|
+
optional: !param.required
|
|
884
888
|
})
|
|
885
889
|
}))
|
|
886
890
|
});
|
|
887
891
|
}
|
|
888
892
|
function buildData(node, { resolver }) {
|
|
889
893
|
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
|
|
890
|
-
return ast.createSchema({
|
|
894
|
+
return ast.factory.createSchema({
|
|
891
895
|
type: "object",
|
|
892
896
|
deprecated: node.deprecated,
|
|
893
897
|
properties: [
|
|
894
|
-
ast.createProperty({
|
|
898
|
+
ast.factory.createProperty({
|
|
895
899
|
name: "data",
|
|
896
|
-
schema: node.requestBody?.content?.[0]?.schema ? ast.createSchema({
|
|
900
|
+
schema: node.requestBody?.content?.[0]?.schema ? ast.factory.createSchema({
|
|
897
901
|
type: "ref",
|
|
898
902
|
name: resolver.resolveDataName(node),
|
|
899
903
|
optional: true
|
|
900
|
-
}) : ast.createSchema({
|
|
904
|
+
}) : ast.factory.createSchema({
|
|
901
905
|
type: "never",
|
|
902
906
|
primitive: void 0,
|
|
903
907
|
optional: true
|
|
904
908
|
})
|
|
905
909
|
}),
|
|
906
|
-
ast.createProperty({
|
|
910
|
+
ast.factory.createProperty({
|
|
907
911
|
name: "pathParams",
|
|
908
912
|
required: pathParams.length > 0,
|
|
909
913
|
schema: pathParams.length > 0 ? buildParams(node, {
|
|
910
914
|
params: pathParams,
|
|
911
915
|
resolver
|
|
912
|
-
}) : ast.createSchema({
|
|
916
|
+
}) : ast.factory.createSchema({
|
|
913
917
|
type: "never",
|
|
914
|
-
primitive: void 0
|
|
918
|
+
primitive: void 0,
|
|
919
|
+
optional: true
|
|
915
920
|
})
|
|
916
921
|
}),
|
|
917
|
-
ast.createProperty({
|
|
922
|
+
ast.factory.createProperty({
|
|
918
923
|
name: "queryParams",
|
|
919
|
-
schema: queryParams.length > 0 ? ast.createSchema({
|
|
924
|
+
schema: queryParams.length > 0 ? ast.factory.createSchema({
|
|
920
925
|
...buildParams(node, {
|
|
921
926
|
params: queryParams,
|
|
922
927
|
resolver
|
|
923
928
|
}),
|
|
924
929
|
optional: true
|
|
925
|
-
}) : ast.createSchema({
|
|
930
|
+
}) : ast.factory.createSchema({
|
|
926
931
|
type: "never",
|
|
927
932
|
primitive: void 0,
|
|
928
933
|
optional: true
|
|
929
934
|
})
|
|
930
935
|
}),
|
|
931
|
-
ast.createProperty({
|
|
936
|
+
ast.factory.createProperty({
|
|
932
937
|
name: "headerParams",
|
|
933
|
-
schema: headerParams.length > 0 ? ast.createSchema({
|
|
938
|
+
schema: headerParams.length > 0 ? ast.factory.createSchema({
|
|
934
939
|
...buildParams(node, {
|
|
935
940
|
params: headerParams,
|
|
936
941
|
resolver
|
|
937
942
|
}),
|
|
938
943
|
optional: true
|
|
939
|
-
}) : ast.createSchema({
|
|
944
|
+
}) : ast.factory.createSchema({
|
|
940
945
|
type: "never",
|
|
941
946
|
primitive: void 0,
|
|
942
947
|
optional: true
|
|
943
948
|
})
|
|
944
949
|
}),
|
|
945
|
-
ast.createProperty({
|
|
950
|
+
ast.factory.createProperty({
|
|
946
951
|
name: "url",
|
|
947
952
|
required: true,
|
|
948
|
-
schema: ast.createSchema({
|
|
953
|
+
schema: ast.factory.createSchema({
|
|
949
954
|
type: "url",
|
|
950
955
|
path: node.path
|
|
951
956
|
})
|
|
@@ -955,12 +960,12 @@ function buildData(node, { resolver }) {
|
|
|
955
960
|
}
|
|
956
961
|
function buildResponses(node, { resolver }) {
|
|
957
962
|
if (node.responses.length === 0) return null;
|
|
958
|
-
return ast.createSchema({
|
|
963
|
+
return ast.factory.createSchema({
|
|
959
964
|
type: "object",
|
|
960
|
-
properties: node.responses.map((res) => ast.createProperty({
|
|
965
|
+
properties: node.responses.map((res) => ast.factory.createProperty({
|
|
961
966
|
name: String(res.statusCode),
|
|
962
967
|
required: true,
|
|
963
|
-
schema: ast.createSchema({
|
|
968
|
+
schema: ast.factory.createSchema({
|
|
964
969
|
type: "ref",
|
|
965
970
|
name: resolver.resolveResponseStatusName(node, res.statusCode)
|
|
966
971
|
})
|
|
@@ -970,9 +975,9 @@ function buildResponses(node, { resolver }) {
|
|
|
970
975
|
function buildResponseUnion(node, { resolver }) {
|
|
971
976
|
const responsesWithSchema = node.responses.filter((res) => res.content?.some((entry) => entry.schema));
|
|
972
977
|
if (responsesWithSchema.length === 0) return null;
|
|
973
|
-
return ast.createSchema({
|
|
978
|
+
return ast.factory.createSchema({
|
|
974
979
|
type: "union",
|
|
975
|
-
members: responsesWithSchema.map((res) => ast.createSchema({
|
|
980
|
+
members: responsesWithSchema.map((res) => ast.factory.createSchema({
|
|
976
981
|
type: "ref",
|
|
977
982
|
name: resolver.resolveResponseStatusName(node, res.statusCode)
|
|
978
983
|
}))
|
|
@@ -1052,11 +1057,11 @@ const printerTs = ast.definePrinter((options) => {
|
|
|
1052
1057
|
const hasStringLiteral = members.some((m) => {
|
|
1053
1058
|
return ast.narrowSchema(m, ast.schemaTypes.enum)?.primitive === "string";
|
|
1054
1059
|
});
|
|
1055
|
-
const hasPlainString = members.some((m) =>
|
|
1060
|
+
const hasPlainString = members.some((m) => isStringType(m));
|
|
1056
1061
|
if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
|
|
1057
1062
|
withParentheses: true,
|
|
1058
1063
|
nodes: members.map((m) => {
|
|
1059
|
-
if (
|
|
1064
|
+
if (isStringType(m)) return createIntersectionDeclaration({
|
|
1060
1065
|
nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
|
|
1061
1066
|
withParentheses: true
|
|
1062
1067
|
});
|
|
@@ -1076,7 +1081,7 @@ const printerTs = ast.definePrinter((options) => {
|
|
|
1076
1081
|
},
|
|
1077
1082
|
array(node) {
|
|
1078
1083
|
return createArrayDeclaration({
|
|
1079
|
-
nodes: (node
|
|
1084
|
+
nodes: mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
|
|
1080
1085
|
arrayType: this.options.arrayType
|
|
1081
1086
|
}) ?? null;
|
|
1082
1087
|
},
|
|
@@ -1086,18 +1091,19 @@ const printerTs = ast.definePrinter((options) => {
|
|
|
1086
1091
|
object(node) {
|
|
1087
1092
|
const { transform, options } = this;
|
|
1088
1093
|
const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
|
|
1089
|
-
const propertyNodes = node.
|
|
1090
|
-
const baseType =
|
|
1091
|
-
const
|
|
1092
|
-
const
|
|
1094
|
+
const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
|
|
1095
|
+
const baseType = output ?? keywordTypeNodes.unknown;
|
|
1096
|
+
const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
|
|
1097
|
+
const type = buildPropertyType(property.schema, baseType, options.optionalType, optional);
|
|
1098
|
+
const propMeta = syncSchemaRef(property.schema);
|
|
1093
1099
|
return appendJSDocToNode({
|
|
1094
1100
|
node: createPropertySignature({
|
|
1095
|
-
questionToken:
|
|
1096
|
-
name
|
|
1101
|
+
questionToken: optional ? addsQuestionToken : false,
|
|
1102
|
+
name,
|
|
1097
1103
|
type,
|
|
1098
1104
|
readOnly: propMeta?.readOnly
|
|
1099
1105
|
}),
|
|
1100
|
-
comments: buildPropertyJSDocComments(
|
|
1106
|
+
comments: buildPropertyJSDocComments(property.schema, optional)
|
|
1101
1107
|
});
|
|
1102
1108
|
});
|
|
1103
1109
|
const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, transform)];
|
|
@@ -1110,7 +1116,7 @@ const printerTs = ast.definePrinter((options) => {
|
|
|
1110
1116
|
const { name, syntaxType = "type", description, keysToOmit } = this.options;
|
|
1111
1117
|
const transformed = this.transform(node);
|
|
1112
1118
|
if (!transformed) return null;
|
|
1113
|
-
const meta =
|
|
1119
|
+
const meta = syncSchemaRef(node);
|
|
1114
1120
|
if (!name) {
|
|
1115
1121
|
const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
|
|
1116
1122
|
const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
@@ -1234,7 +1240,7 @@ const typeGenerator = defineGenerator({
|
|
|
1234
1240
|
operation(node, ctx) {
|
|
1235
1241
|
const { enum: enumOptions, optionalType, arrayType, syntaxType, paramsCasing, group, output, printer } = ctx.options;
|
|
1236
1242
|
const { adapter, config, resolver, root } = ctx;
|
|
1237
|
-
const params =
|
|
1243
|
+
const params = caseParams(node.parameters, paramsCasing);
|
|
1238
1244
|
const meta = { file: resolver.resolveFile({
|
|
1239
1245
|
name: node.operationId,
|
|
1240
1246
|
extname: ".ts",
|
|
@@ -1298,9 +1304,9 @@ const typeGenerator = defineGenerator({
|
|
|
1298
1304
|
*/
|
|
1299
1305
|
function buildContentTypeVariants(entries, baseName, decorate) {
|
|
1300
1306
|
const variants = resolveContentTypeVariants(entries, baseName);
|
|
1301
|
-
const unionSchema = ast.createSchema({
|
|
1307
|
+
const unionSchema = ast.factory.createSchema({
|
|
1302
1308
|
type: "union",
|
|
1303
|
-
members: variants.map((variant) => ast.createSchema({
|
|
1309
|
+
members: variants.map((variant) => ast.factory.createSchema({
|
|
1304
1310
|
type: "ref",
|
|
1305
1311
|
name: variant.name
|
|
1306
1312
|
}))
|
|
@@ -1315,7 +1321,10 @@ const typeGenerator = defineGenerator({
|
|
|
1315
1321
|
})] });
|
|
1316
1322
|
}
|
|
1317
1323
|
const paramTypes = params.map((param) => renderSchemaType({
|
|
1318
|
-
schema:
|
|
1324
|
+
schema: {
|
|
1325
|
+
...param.schema,
|
|
1326
|
+
optional: !param.required
|
|
1327
|
+
},
|
|
1319
1328
|
name: resolver.resolveParamName(node, param)
|
|
1320
1329
|
}));
|
|
1321
1330
|
const requestBodyContent = node.requestBody?.content ?? [];
|
|
@@ -1511,7 +1520,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1511
1520
|
const { output = {
|
|
1512
1521
|
path: "types",
|
|
1513
1522
|
barrel: { type: "named" }
|
|
1514
|
-
}, group, exclude = [], include, override = [], enum: enumOptions = {}, optionalType = "questionToken", arrayType = "array", syntaxType = "type", paramsCasing, printer, resolver: userResolver,
|
|
1523
|
+
}, group, exclude = [], include, override = [], enum: enumOptions = {}, optionalType = "questionToken", arrayType = "array", syntaxType = "type", paramsCasing, printer, resolver: userResolver, macros: userMacros, generators: userGenerators = [] } = options;
|
|
1515
1524
|
const groupConfig = createGroupConfig(group);
|
|
1516
1525
|
const resolvedEnum = {
|
|
1517
1526
|
type: enumOptions.type ?? "asConst",
|
|
@@ -1540,7 +1549,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1540
1549
|
...resolverTs,
|
|
1541
1550
|
...userResolver
|
|
1542
1551
|
} : resolverTs);
|
|
1543
|
-
if (
|
|
1552
|
+
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1544
1553
|
ctx.addGenerator(typeGenerator);
|
|
1545
1554
|
for (const gen of userGenerators) ctx.addGenerator(gen);
|
|
1546
1555
|
} }
|
|
@@ -1548,37 +1557,75 @@ const pluginTs = definePlugin((options) => {
|
|
|
1548
1557
|
});
|
|
1549
1558
|
//#endregion
|
|
1550
1559
|
//#region src/printers/functionPrinter.ts
|
|
1551
|
-
const kindToHandlerKey = {
|
|
1552
|
-
FunctionParameter: "functionParameter",
|
|
1553
|
-
ParameterGroup: "parameterGroup",
|
|
1554
|
-
FunctionParameters: "functionParameters",
|
|
1555
|
-
ParamsType: "paramsType"
|
|
1556
|
-
};
|
|
1557
1560
|
/**
|
|
1558
|
-
*
|
|
1561
|
+
* Renders a {@link ast.TypeExpression} to its TypeScript source.
|
|
1559
1562
|
*
|
|
1560
|
-
*
|
|
1561
|
-
*
|
|
1563
|
+
* - a `string` is a type reference, returned as-is
|
|
1564
|
+
* - an `IndexedAccessType` becomes `objectType['indexType']`
|
|
1565
|
+
* - a `TypeLiteral` becomes `{ key: Type; key?: Type }`
|
|
1566
|
+
*
|
|
1567
|
+
* `transformType` is applied once to the fully rendered type, matching how the
|
|
1568
|
+
* printer wrapped reference types before the `ts.factory` model.
|
|
1562
1569
|
*/
|
|
1563
|
-
|
|
1570
|
+
function renderType(type, transformType) {
|
|
1571
|
+
const rendered = renderTypeExpression(type);
|
|
1572
|
+
return transformType ? transformType(rendered) : rendered;
|
|
1573
|
+
}
|
|
1574
|
+
function renderTypeExpression(type) {
|
|
1575
|
+
if (typeof type === "string") return type;
|
|
1576
|
+
if (ast.indexedAccessTypeDef.is(type)) return `${type.target}['${type.key}']`;
|
|
1577
|
+
return `{ ${type.members.map((member) => {
|
|
1578
|
+
const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(member.name) ? member.name : JSON.stringify(member.name);
|
|
1579
|
+
const value = renderTypeExpression(member.type);
|
|
1580
|
+
return member.optional ? `${key}?: ${value}` : `${key}: ${value}`;
|
|
1581
|
+
}).join("; ")} }`;
|
|
1582
|
+
}
|
|
1583
|
+
function groupMembers(param) {
|
|
1584
|
+
if (typeof param.name === "string") return null;
|
|
1585
|
+
return param.type && ast.typeLiteralDef.is(param.type) ? param.type.members : [];
|
|
1586
|
+
}
|
|
1564
1587
|
function rank(param) {
|
|
1565
|
-
if (param.kind === "ParameterGroup") {
|
|
1566
|
-
if (param.default) return PARAM_RANK.withDefault;
|
|
1567
|
-
return param.optional ?? param.properties.every((p) => p.optional || p.default !== void 0) ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
1568
|
-
}
|
|
1569
1588
|
if (param.rest) return PARAM_RANK.rest;
|
|
1570
1589
|
if (param.default) return PARAM_RANK.withDefault;
|
|
1590
|
+
const members = groupMembers(param);
|
|
1591
|
+
if (members) return members.every((m) => m.optional) ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
1571
1592
|
return param.optional ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
1572
1593
|
}
|
|
1573
1594
|
function sortParams(params) {
|
|
1574
1595
|
return params.toSorted((a, b) => rank(a) - rank(b));
|
|
1575
1596
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1597
|
+
/**
|
|
1598
|
+
* Orders a destructured group's binding elements and type members together,
|
|
1599
|
+
* required fields first, matching how grouped children were sorted before.
|
|
1600
|
+
*/
|
|
1601
|
+
function sortedGroupMembers(name, type) {
|
|
1602
|
+
const members = type && ast.typeLiteralDef.is(type) ? type.members : [];
|
|
1603
|
+
const memberRank = (optional) => optional ? PARAM_RANK.optional : PARAM_RANK.required;
|
|
1604
|
+
return name.elements.map((element, index) => ({
|
|
1605
|
+
name: element.name,
|
|
1606
|
+
type: members[index]?.type,
|
|
1607
|
+
optional: members[index]?.optional
|
|
1608
|
+
})).toSorted((a, b) => memberRank(a.optional) - memberRank(b.optional));
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Renders the type annotation of a destructured group. An inline object type is
|
|
1612
|
+
* rendered from the already-sorted members so its key order matches the binding;
|
|
1613
|
+
* a reference type is rendered as-is.
|
|
1614
|
+
*/
|
|
1615
|
+
function renderGroupType(type, sorted, transformType) {
|
|
1616
|
+
if (!type) return void 0;
|
|
1617
|
+
if (!ast.typeLiteralDef.is(type)) return renderType(type);
|
|
1618
|
+
const typed = sorted.filter((member) => member.type !== void 0);
|
|
1619
|
+
if (!typed.length) return void 0;
|
|
1620
|
+
return `{ ${typed.map((member) => {
|
|
1621
|
+
const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(member.name) ? member.name : JSON.stringify(member.name);
|
|
1622
|
+
const value = renderType(member.type, transformType);
|
|
1623
|
+
return member.optional ? `${key}?: ${value}` : `${key}: ${value}`;
|
|
1624
|
+
}).join("; ")} }`;
|
|
1578
1625
|
}
|
|
1579
1626
|
/**
|
|
1580
|
-
* Default function-signature printer.
|
|
1581
|
-
*
|
|
1627
|
+
* Default function-signature printer. Renders a parameter list in one of two modes:
|
|
1628
|
+
* `declaration` for the function signature and `call` for the call arguments.
|
|
1582
1629
|
*
|
|
1583
1630
|
* @example
|
|
1584
1631
|
* ```ts
|
|
@@ -1594,28 +1641,31 @@ function sortChildParams(params) {
|
|
|
1594
1641
|
* printer.print(sig) // → "petId: string, config: Config = {}"
|
|
1595
1642
|
* ```
|
|
1596
1643
|
*/
|
|
1597
|
-
const functionPrinter =
|
|
1644
|
+
const functionPrinter = ast.createPrinterFactory((node) => node.kind)((options) => ({
|
|
1598
1645
|
name: "functionParameters",
|
|
1599
1646
|
options,
|
|
1600
1647
|
nodes: {
|
|
1601
|
-
|
|
1602
|
-
if (node.kind !== "ParamsType") return null;
|
|
1603
|
-
if (node.variant === "member") return `${node.base}['${node.key}']`;
|
|
1604
|
-
if (node.variant === "struct") return `{ ${node.properties.map((p) => {
|
|
1605
|
-
const typeStr = this.transform(p.type);
|
|
1606
|
-
const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.name) ? p.name : JSON.stringify(p.name);
|
|
1607
|
-
return p.optional ? `${key}?: ${typeStr}` : `${key}: ${typeStr}`;
|
|
1608
|
-
}).join("; ")} }`;
|
|
1609
|
-
if (node.variant === "reference") return node.name;
|
|
1610
|
-
return null;
|
|
1611
|
-
},
|
|
1612
|
-
functionParameter(node) {
|
|
1648
|
+
FunctionParameter(node) {
|
|
1613
1649
|
const { mode, transformName, transformType } = this.options;
|
|
1650
|
+
const isGroup = typeof node.name !== "string";
|
|
1651
|
+
if (mode === "call") {
|
|
1652
|
+
if (isGroup) return `{ ${sortedGroupMembers(node.name, node.type).map((member) => member.name).join(", ")} }`;
|
|
1653
|
+
const name = transformName ? transformName(node.name) : node.name;
|
|
1654
|
+
return node.rest ? `...${name}` : name;
|
|
1655
|
+
}
|
|
1656
|
+
if (isGroup) {
|
|
1657
|
+
const sorted = sortedGroupMembers(node.name, node.type);
|
|
1658
|
+
const binding = `{ ${sorted.map((member) => transformName ? transformName(member.name) : member.name).join(", ")} }`;
|
|
1659
|
+
const allOptional = sorted.every((member) => member.optional);
|
|
1660
|
+
const type = renderGroupType(node.type, sorted, transformType);
|
|
1661
|
+
if (type) {
|
|
1662
|
+
if (allOptional) return `${binding}: ${type} = ${node.default ?? "{}"}`;
|
|
1663
|
+
return node.default ? `${binding}: ${type} = ${node.default}` : `${binding}: ${type}`;
|
|
1664
|
+
}
|
|
1665
|
+
return node.default ? `${binding} = ${node.default}` : binding;
|
|
1666
|
+
}
|
|
1614
1667
|
const name = transformName ? transformName(node.name) : node.name;
|
|
1615
|
-
const
|
|
1616
|
-
const type = rawType != null && transformType ? transformType(rawType) : rawType;
|
|
1617
|
-
if (mode === "keys" || mode === "values") return node.rest ? `...${name}` : name;
|
|
1618
|
-
if (mode === "call") return node.rest ? `...${name}` : name;
|
|
1668
|
+
const type = node.type ? renderType(node.type, transformType) : void 0;
|
|
1619
1669
|
if (node.rest) return type ? `...${name}: ${type}` : `...${name}`;
|
|
1620
1670
|
if (type) {
|
|
1621
1671
|
if (node.optional) return `${name}?: ${type}`;
|
|
@@ -1623,39 +1673,12 @@ const functionPrinter = defineFunctionPrinter((options) => ({
|
|
|
1623
1673
|
}
|
|
1624
1674
|
return node.default ? `${name} = ${node.default}` : name;
|
|
1625
1675
|
},
|
|
1626
|
-
|
|
1627
|
-
const { mode, transformName, transformType } = this.options;
|
|
1628
|
-
const sorted = sortChildParams(node.properties);
|
|
1629
|
-
const isOptional = node.optional ?? sorted.every((p) => p.optional || p.default !== void 0);
|
|
1630
|
-
if (node.inline) return sorted.map((p) => this.transform(p)).filter(Boolean).join(", ");
|
|
1631
|
-
if (mode === "keys" || mode === "values") return `{ ${sorted.map((p) => p.name).join(", ")} }`;
|
|
1632
|
-
if (mode === "call") return `{ ${sorted.map((p) => p.name).join(", ")} }`;
|
|
1633
|
-
const names = sorted.map((p) => {
|
|
1634
|
-
return transformName ? transformName(p.name) : p.name;
|
|
1635
|
-
});
|
|
1636
|
-
const nameStr = names.length ? `{ ${names.join(", ")} }` : void 0;
|
|
1637
|
-
if (!nameStr) return null;
|
|
1638
|
-
let typeAnnotation = node.type ? this.transform(node.type) ?? void 0 : void 0;
|
|
1639
|
-
if (!typeAnnotation) {
|
|
1640
|
-
const typeParts = sorted.filter((p) => p.type).map((p) => {
|
|
1641
|
-
const rawT = p.type ? this.transform(p.type) : void 0;
|
|
1642
|
-
const t = rawT != null && transformType ? transformType(rawT) : rawT;
|
|
1643
|
-
return p.optional || p.default !== void 0 ? `${p.name}?: ${t}` : `${p.name}: ${t}`;
|
|
1644
|
-
});
|
|
1645
|
-
typeAnnotation = typeParts.length ? `{ ${typeParts.join("; ")} }` : void 0;
|
|
1646
|
-
}
|
|
1647
|
-
if (typeAnnotation) {
|
|
1648
|
-
if (isOptional) return `${nameStr}: ${typeAnnotation} = ${node.default ?? "{}"}`;
|
|
1649
|
-
return node.default ? `${nameStr}: ${typeAnnotation} = ${node.default}` : `${nameStr}: ${typeAnnotation}`;
|
|
1650
|
-
}
|
|
1651
|
-
return node.default ? `${nameStr} = ${node.default}` : nameStr;
|
|
1652
|
-
},
|
|
1653
|
-
functionParameters(node) {
|
|
1676
|
+
FunctionParameters(node) {
|
|
1654
1677
|
return sortParams(node.params).map((p) => this.transform(p)).filter(Boolean).join(", ");
|
|
1655
1678
|
}
|
|
1656
1679
|
}
|
|
1657
1680
|
}));
|
|
1658
1681
|
//#endregion
|
|
1659
|
-
export { Enum, Type, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, resolverTs, typeGenerator };
|
|
1682
|
+
export { Enum, Type, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
|
|
1660
1683
|
|
|
1661
1684
|
//# sourceMappingURL=index.js.map
|