@kubb/plugin-ts 5.0.0-alpha.23 → 5.0.0-alpha.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +21 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +97 -34
- package/dist/index.js +21 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/Enum.tsx +1 -6
- package/src/components/Type.tsx +8 -0
- package/src/generators/typeGenerator.tsx +26 -2
- package/src/printers/printerTs.ts +17 -1
- package/src/types.ts +88 -33
package/dist/index.d.ts
CHANGED
|
@@ -90,6 +90,87 @@ type ResolverTs = Resolver & OperationParamsResolver & {
|
|
|
90
90
|
*/
|
|
91
91
|
resolveHeaderParamsName(node: OperationNode, param: ParameterNode): string;
|
|
92
92
|
};
|
|
93
|
+
type EnumKeyCasing = 'screamingSnakeCase' | 'snakeCase' | 'pascalCase' | 'camelCase' | 'none';
|
|
94
|
+
/**
|
|
95
|
+
* Discriminated union that ties `enumTypeSuffix` and `enumKeyCasing` to the enum types that actually use them.
|
|
96
|
+
*
|
|
97
|
+
* - `'asConst'` / `'asPascalConst'` — emit a `const` object; both `enumTypeSuffix` (type-alias suffix) and
|
|
98
|
+
* `enumKeyCasing` (key formatting) are meaningful.
|
|
99
|
+
* - `'enum'` / `'constEnum'` — emit a TypeScript enum; `enumKeyCasing` applies to member names,
|
|
100
|
+
* but there is no separate type alias so `enumTypeSuffix` is not used.
|
|
101
|
+
* - `'literal'` / `'inlineLiteral'` — emit only union literals; keys are discarded entirely,
|
|
102
|
+
* so neither `enumTypeSuffix` nor `enumKeyCasing` have any effect.
|
|
103
|
+
*/
|
|
104
|
+
type EnumTypeOptions = {
|
|
105
|
+
/**
|
|
106
|
+
* Choose to use enum, asConst, asPascalConst, constEnum, literal, or inlineLiteral for enums.
|
|
107
|
+
* - 'asConst' generates const objects with camelCase names and as const assertion.
|
|
108
|
+
* - 'asPascalConst' generates const objects with PascalCase names and as const assertion.
|
|
109
|
+
* @default 'asConst'
|
|
110
|
+
*/
|
|
111
|
+
enumType?: 'asConst' | 'asPascalConst';
|
|
112
|
+
/**
|
|
113
|
+
* Suffix appended to the generated type alias name.
|
|
114
|
+
*
|
|
115
|
+
* Only affects the type alias — the const object name is unchanged.
|
|
116
|
+
*
|
|
117
|
+
* @default 'Key'
|
|
118
|
+
* @example enumTypeSuffix: 'Value' → `export type PetStatusValue = …`
|
|
119
|
+
*/
|
|
120
|
+
enumTypeSuffix?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Choose the casing for enum key names.
|
|
123
|
+
* - 'screamingSnakeCase' generates keys in SCREAMING_SNAKE_CASE format.
|
|
124
|
+
* - 'snakeCase' generates keys in snake_case format.
|
|
125
|
+
* - 'pascalCase' generates keys in PascalCase format.
|
|
126
|
+
* - 'camelCase' generates keys in camelCase format.
|
|
127
|
+
* - 'none' uses the enum value as-is without transformation.
|
|
128
|
+
* @default 'none'
|
|
129
|
+
*/
|
|
130
|
+
enumKeyCasing?: EnumKeyCasing;
|
|
131
|
+
} | {
|
|
132
|
+
/**
|
|
133
|
+
* Choose to use enum, asConst, asPascalConst, constEnum, literal, or inlineLiteral for enums.
|
|
134
|
+
* - 'enum' generates TypeScript enum declarations.
|
|
135
|
+
* - 'constEnum' generates TypeScript const enum declarations.
|
|
136
|
+
* @default 'asConst'
|
|
137
|
+
*/
|
|
138
|
+
enumType?: 'enum' | 'constEnum';
|
|
139
|
+
/**
|
|
140
|
+
* `enumTypeSuffix` has no effect for this `enumType`.
|
|
141
|
+
* It is only used when `enumType` is `'asConst'` or `'asPascalConst'`.
|
|
142
|
+
*/
|
|
143
|
+
enumTypeSuffix?: never;
|
|
144
|
+
/**
|
|
145
|
+
* Choose the casing for enum key names.
|
|
146
|
+
* - 'screamingSnakeCase' generates keys in SCREAMING_SNAKE_CASE format.
|
|
147
|
+
* - 'snakeCase' generates keys in snake_case format.
|
|
148
|
+
* - 'pascalCase' generates keys in PascalCase format.
|
|
149
|
+
* - 'camelCase' generates keys in camelCase format.
|
|
150
|
+
* - 'none' uses the enum value as-is without transformation.
|
|
151
|
+
* @default 'none'
|
|
152
|
+
*/
|
|
153
|
+
enumKeyCasing?: EnumKeyCasing;
|
|
154
|
+
} | {
|
|
155
|
+
/**
|
|
156
|
+
* Choose to use enum, asConst, asPascalConst, constEnum, literal, or inlineLiteral for enums.
|
|
157
|
+
* - 'literal' generates literal union types.
|
|
158
|
+
* - 'inlineLiteral' inlines enum values directly into the type (default in v5).
|
|
159
|
+
* @default 'asConst'
|
|
160
|
+
* @note In Kubb v5, 'inlineLiteral' becomes the default.
|
|
161
|
+
*/
|
|
162
|
+
enumType?: 'literal' | 'inlineLiteral';
|
|
163
|
+
/**
|
|
164
|
+
* `enumTypeSuffix` has no effect for this `enumType`.
|
|
165
|
+
* It is only used when `enumType` is `'asConst'` or `'asPascalConst'`.
|
|
166
|
+
*/
|
|
167
|
+
enumTypeSuffix?: never;
|
|
168
|
+
/**
|
|
169
|
+
* `enumKeyCasing` has no effect for this `enumType`.
|
|
170
|
+
* Literal and inlineLiteral modes emit only values — keys are discarded entirely.
|
|
171
|
+
*/
|
|
172
|
+
enumKeyCasing?: never;
|
|
173
|
+
};
|
|
93
174
|
type Options = {
|
|
94
175
|
/**
|
|
95
176
|
* Specify the export location for the files and define the behavior of the output
|
|
@@ -117,37 +198,6 @@ type Options = {
|
|
|
117
198
|
* Array containing override parameters to override `options` based on tags/operations/methods/paths.
|
|
118
199
|
*/
|
|
119
200
|
override?: Array<Override<ResolvedOptions>>;
|
|
120
|
-
/**
|
|
121
|
-
* Choose to use enum, asConst, asPascalConst, constEnum, literal, or inlineLiteral for enums.
|
|
122
|
-
* - 'enum' generates TypeScript enum declarations.
|
|
123
|
-
* - 'asConst' generates const objects with camelCase names and as const assertion.
|
|
124
|
-
* - 'asPascalConst' generates const objects with PascalCase names and as const assertion.
|
|
125
|
-
* - 'constEnum' generates TypeScript const enum declarations.
|
|
126
|
-
* - 'literal' generates literal union types.
|
|
127
|
-
* - 'inlineLiteral' inline enum values directly into the type (default in v5).
|
|
128
|
-
* @default 'asConst'
|
|
129
|
-
* @note In Kubb v5, 'inlineLiteral' becomes the default.
|
|
130
|
-
*/
|
|
131
|
-
enumType?: 'enum' | 'asConst' | 'asPascalConst' | 'constEnum' | 'literal' | 'inlineLiteral';
|
|
132
|
-
/**
|
|
133
|
-
* Suffix appended to the generated type alias name when `enumType` is `asConst` or `asPascalConst`.
|
|
134
|
-
*
|
|
135
|
-
* Only affects the type alias — the const object name is unchanged.
|
|
136
|
-
*
|
|
137
|
-
* @default 'Key'
|
|
138
|
-
* @example enumTypeSuffix: 'Value' → `export type PetStatusValue = …`
|
|
139
|
-
*/
|
|
140
|
-
enumTypeSuffix?: string;
|
|
141
|
-
/**
|
|
142
|
-
* Choose the casing for enum key names.
|
|
143
|
-
* - 'screamingSnakeCase' generates keys in SCREAMING_SNAKE_CASE format.
|
|
144
|
-
* - 'snakeCase' generates keys in snake_case format.
|
|
145
|
-
* - 'pascalCase' generates keys in PascalCase format.
|
|
146
|
-
* - 'camelCase' generates keys in camelCase format.
|
|
147
|
-
* - 'none' uses the enum value as-is without transformation.
|
|
148
|
-
* @default 'none'
|
|
149
|
-
*/
|
|
150
|
-
enumKeyCasing?: 'screamingSnakeCase' | 'snakeCase' | 'pascalCase' | 'camelCase' | 'none';
|
|
151
201
|
/**
|
|
152
202
|
* Switch between type or interface for creating TypeScript types.
|
|
153
203
|
* - 'type' generates type alias declarations.
|
|
@@ -218,13 +268,13 @@ type Options = {
|
|
|
218
268
|
* ```
|
|
219
269
|
*/
|
|
220
270
|
transformers?: Array<Visitor>;
|
|
221
|
-
};
|
|
271
|
+
} & EnumTypeOptions;
|
|
222
272
|
type ResolvedOptions = {
|
|
223
273
|
output: Output;
|
|
224
274
|
group: Group | undefined;
|
|
225
275
|
enumType: NonNullable<Options['enumType']>;
|
|
226
276
|
enumTypeSuffix: NonNullable<Options['enumTypeSuffix']>;
|
|
227
|
-
enumKeyCasing:
|
|
277
|
+
enumKeyCasing: EnumKeyCasing;
|
|
228
278
|
optionalType: NonNullable<Options['optionalType']>;
|
|
229
279
|
arrayType: NonNullable<Options['arrayType']>;
|
|
230
280
|
syntaxType: NonNullable<Options['syntaxType']>;
|
|
@@ -280,6 +330,12 @@ type Props = {
|
|
|
280
330
|
resolver: PluginTs['resolver'];
|
|
281
331
|
description?: string;
|
|
282
332
|
keysToOmit?: string[];
|
|
333
|
+
/**
|
|
334
|
+
* Names of top-level schemas that are enums.
|
|
335
|
+
* Used so the printer's `ref` handler can use the suffixed type name (e.g. `StatusKey`)
|
|
336
|
+
* instead of the plain PascalCase name (e.g. `Status`) when resolving `$ref` enum targets.
|
|
337
|
+
*/
|
|
338
|
+
enumSchemaNames?: Set<string>;
|
|
283
339
|
};
|
|
284
340
|
declare function Type({
|
|
285
341
|
name,
|
|
@@ -292,7 +348,8 @@ declare function Type({
|
|
|
292
348
|
enumTypeSuffix,
|
|
293
349
|
enumKeyCasing,
|
|
294
350
|
description,
|
|
295
|
-
resolver
|
|
351
|
+
resolver,
|
|
352
|
+
enumSchemaNames
|
|
296
353
|
}: Props): FabricReactNode;
|
|
297
354
|
//#endregion
|
|
298
355
|
//#region src/generators/typeGenerator.d.ts
|
|
@@ -411,6 +468,12 @@ type TsOptions = {
|
|
|
411
468
|
* Resolver used to transform raw schema names into valid TypeScript identifiers.
|
|
412
469
|
*/
|
|
413
470
|
resolver: ResolverTs;
|
|
471
|
+
/**
|
|
472
|
+
* Names of top-level schemas that are enums.
|
|
473
|
+
* When set, the `ref` handler uses the suffixed type name (e.g. `StatusKey`) for enum refs
|
|
474
|
+
* instead of the plain PascalCase name, so imports align with what the enum file actually exports.
|
|
475
|
+
*/
|
|
476
|
+
enumSchemaNames?: Set<string>;
|
|
414
477
|
};
|
|
415
478
|
/**
|
|
416
479
|
* TypeScript printer factory options: maps `SchemaNode` → `ts.TypeNode` (raw) or `ts.Node` (full declaration).
|
package/dist/index.js
CHANGED
|
@@ -410,8 +410,7 @@ function getEnumNames({ node, enumType, enumTypeSuffix, resolver }) {
|
|
|
410
410
|
const resolved = resolver.default(node.name, "type");
|
|
411
411
|
return {
|
|
412
412
|
enumName: enumType === "asPascalConst" ? resolved : camelCase(node.name),
|
|
413
|
-
typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolved
|
|
414
|
-
refName: resolved
|
|
413
|
+
typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolved
|
|
415
414
|
};
|
|
416
415
|
}
|
|
417
416
|
/**
|
|
@@ -592,7 +591,7 @@ const printerTs = definePrinter((options) => {
|
|
|
592
591
|
ref(node) {
|
|
593
592
|
if (!node.name) return;
|
|
594
593
|
const refName = node.ref ? node.ref.split("/").at(-1) ?? node.name : node.name;
|
|
595
|
-
return createTypeReferenceNode(node.ref ? this.options.resolver.default(refName, "type") : refName, void 0);
|
|
594
|
+
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);
|
|
596
595
|
},
|
|
597
596
|
enum(node) {
|
|
598
597
|
const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
|
|
@@ -692,7 +691,7 @@ const printerTs = definePrinter((options) => {
|
|
|
692
691
|
});
|
|
693
692
|
//#endregion
|
|
694
693
|
//#region src/components/Type.tsx
|
|
695
|
-
function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumTypeSuffix, enumKeyCasing, description, resolver }) {
|
|
694
|
+
function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumTypeSuffix, enumKeyCasing, description, resolver, enumSchemaNames }) {
|
|
696
695
|
const resolvedDescription = description || node?.description;
|
|
697
696
|
const enumSchemaNodes = collect(node, { schema(n) {
|
|
698
697
|
const enumNode = narrowSchema(n, schemaTypes.enum);
|
|
@@ -707,7 +706,8 @@ function Type({ name, node, keysToOmit, optionalType, arrayType, syntaxType, enu
|
|
|
707
706
|
syntaxType,
|
|
708
707
|
description: resolvedDescription,
|
|
709
708
|
keysToOmit,
|
|
710
|
-
resolver
|
|
709
|
+
resolver,
|
|
710
|
+
enumSchemaNames
|
|
711
711
|
}).print(node);
|
|
712
712
|
if (!output) return;
|
|
713
713
|
const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
|
|
@@ -864,11 +864,16 @@ const typeGenerator = defineGenerator({
|
|
|
864
864
|
group
|
|
865
865
|
});
|
|
866
866
|
const params = caseParams(node.parameters, paramsCasing);
|
|
867
|
+
const enumSchemaNames = new Set((adapter.rootNode?.schemas ?? []).filter((s) => narrowSchema(s, schemaTypes.enum) && s.name).map((s) => s.name));
|
|
868
|
+
function resolveImportName(schemaName) {
|
|
869
|
+
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
|
|
870
|
+
return resolver.default(schemaName, "type");
|
|
871
|
+
}
|
|
867
872
|
function renderSchemaType({ node: schemaNode, name, description, keysToOmit }) {
|
|
868
873
|
if (!schemaNode) return null;
|
|
869
874
|
const transformedNode = transform(schemaNode, composeTransformers(...transformers));
|
|
870
875
|
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
871
|
-
name:
|
|
876
|
+
name: resolveImportName(schemaName),
|
|
872
877
|
path: resolver.resolveFile({
|
|
873
878
|
name: schemaName,
|
|
874
879
|
extname: ".ts"
|
|
@@ -898,7 +903,8 @@ const typeGenerator = defineGenerator({
|
|
|
898
903
|
arrayType,
|
|
899
904
|
syntaxType,
|
|
900
905
|
resolver,
|
|
901
|
-
keysToOmit
|
|
906
|
+
keysToOmit,
|
|
907
|
+
enumSchemaNames
|
|
902
908
|
})] });
|
|
903
909
|
}
|
|
904
910
|
const paramTypes = params.map((param) => renderSchemaType({
|
|
@@ -970,8 +976,13 @@ const typeGenerator = defineGenerator({
|
|
|
970
976
|
const mode = getMode(path.resolve(root, output.path));
|
|
971
977
|
if (!node.name) return;
|
|
972
978
|
const transformedNode = transform(node, composeTransformers(...transformers));
|
|
979
|
+
const enumSchemaNames = new Set((adapter.rootNode?.schemas ?? []).filter((s) => narrowSchema(s, schemaTypes.enum) && s.name).map((s) => s.name));
|
|
980
|
+
function resolveImportName(schemaName) {
|
|
981
|
+
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && enumTypeSuffix && enumSchemaNames.has(schemaName)) return resolver.resolveEnumKeyName({ name: schemaName }, enumTypeSuffix);
|
|
982
|
+
return resolver.default(schemaName, "type");
|
|
983
|
+
}
|
|
973
984
|
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
974
|
-
name:
|
|
985
|
+
name: resolveImportName(schemaName),
|
|
975
986
|
path: resolver.resolveFile({
|
|
976
987
|
name: schemaName,
|
|
977
988
|
extname: ".ts"
|
|
@@ -1023,7 +1034,8 @@ const typeGenerator = defineGenerator({
|
|
|
1023
1034
|
optionalType,
|
|
1024
1035
|
arrayType,
|
|
1025
1036
|
syntaxType,
|
|
1026
|
-
resolver
|
|
1037
|
+
resolver,
|
|
1038
|
+
enumSchemaNames
|
|
1027
1039
|
})]
|
|
1028
1040
|
});
|
|
1029
1041
|
}
|