@kubb/plugin-ts 5.0.0-alpha.11 → 5.0.0-alpha.13
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/Type-C8EHVKjc.js +663 -0
- package/dist/Type-C8EHVKjc.js.map +1 -0
- package/dist/Type-DrOq6-nh.cjs +680 -0
- package/dist/Type-DrOq6-nh.cjs.map +1 -0
- package/dist/casing-Cp-jbC_k.js +84 -0
- package/dist/casing-Cp-jbC_k.js.map +1 -0
- package/dist/casing-D2uQKLWS.cjs +144 -0
- package/dist/casing-D2uQKLWS.cjs.map +1 -0
- package/dist/components.cjs +3 -2
- package/dist/components.d.ts +41 -9
- package/dist/components.js +2 -2
- package/dist/generators-CX3cSSdF.cjs +551 -0
- package/dist/generators-CX3cSSdF.cjs.map +1 -0
- package/dist/generators-dCqW0ECC.js +547 -0
- package/dist/generators-dCqW0ECC.js.map +1 -0
- package/dist/generators.cjs +2 -3
- package/dist/generators.d.ts +3 -503
- package/dist/generators.js +2 -2
- package/dist/index.cjs +135 -4
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -41
- package/dist/index.js +134 -2
- package/dist/index.js.map +1 -0
- package/dist/resolvers-CH7hINyz.js +181 -0
- package/dist/resolvers-CH7hINyz.js.map +1 -0
- package/dist/resolvers-ebHaaCyw.cjs +191 -0
- package/dist/resolvers-ebHaaCyw.cjs.map +1 -0
- package/dist/resolvers.cjs +4 -0
- package/dist/resolvers.d.ts +51 -0
- package/dist/resolvers.js +2 -0
- package/dist/{types-mSXmB8WU.d.ts → types-BSRhtbGl.d.ts} +80 -57
- package/package.json +12 -5
- package/src/components/{v2/Enum.tsx → Enum.tsx} +27 -11
- package/src/components/Type.tsx +24 -141
- package/src/components/index.ts +1 -0
- package/src/generators/index.ts +0 -1
- package/src/generators/typeGenerator.tsx +204 -413
- package/src/generators/utils.ts +300 -0
- package/src/index.ts +0 -1
- package/src/plugin.ts +81 -126
- package/src/printer.ts +20 -6
- package/src/resolvers/index.ts +2 -0
- package/src/{resolverTs.ts → resolvers/resolverTs.ts} +26 -2
- package/src/resolvers/resolverTsLegacy.ts +85 -0
- package/src/types.ts +75 -52
- package/dist/components-CRu8IKY3.js +0 -729
- package/dist/components-CRu8IKY3.js.map +0 -1
- package/dist/components-DeNDKlzf.cjs +0 -982
- package/dist/components-DeNDKlzf.cjs.map +0 -1
- package/dist/plugin-CJ29AwE2.cjs +0 -1320
- package/dist/plugin-CJ29AwE2.cjs.map +0 -1
- package/dist/plugin-D60XNJSD.js +0 -1267
- package/dist/plugin-D60XNJSD.js.map +0 -1
- package/src/components/v2/Type.tsx +0 -59
- package/src/generators/v2/typeGenerator.tsx +0 -167
- package/src/generators/v2/utils.ts +0 -140
- package/src/parser.ts +0 -389
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
|
+
import { r as ResolverTs } from "./types-BSRhtbGl.js";
|
|
3
|
+
|
|
4
|
+
//#region src/resolvers/resolverTs.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Resolver for `@kubb/plugin-ts` that provides the default naming and path-resolution
|
|
7
|
+
* helpers used by the plugin. Import this in other plugins to resolve the exact names and
|
|
8
|
+
* paths that `plugin-ts` generates without hardcoding the conventions.
|
|
9
|
+
*
|
|
10
|
+
* The `default` method is automatically injected by `defineResolver` — it uses `camelCase`
|
|
11
|
+
* for identifiers/files and `pascalCase` for type names.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { resolver } from '@kubb/plugin-ts'
|
|
16
|
+
*
|
|
17
|
+
* resolver.default('list pets', 'type') // → 'ListPets'
|
|
18
|
+
* resolver.resolveName('list pets status 200') // → 'listPetsStatus200'
|
|
19
|
+
* resolver.resolveTypedName('list pets status 200') // → 'ListPetsStatus200'
|
|
20
|
+
* resolver.resolvePathName('list pets', 'file') // → 'listPets'
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare const resolverTs: ResolverTs;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/resolvers/resolverTsLegacy.d.ts
|
|
26
|
+
/**
|
|
27
|
+
* Legacy resolver for `@kubb/plugin-ts` that reproduces the naming conventions
|
|
28
|
+
* used before the v2 resolver refactor. Enable via `legacy: true` in plugin options.
|
|
29
|
+
*
|
|
30
|
+
* Key differences from the default resolver:
|
|
31
|
+
* - Response status types: `<OperationId><StatusCode>` (e.g. `CreatePets201`) instead of `<OperationId>Status201`
|
|
32
|
+
* - Default/error responses: `<OperationId>Error` instead of `<OperationId>StatusDefault`
|
|
33
|
+
* - Request body: `<OperationId>MutationRequest` (non-GET) / `<OperationId>QueryRequest` (GET)
|
|
34
|
+
* - Combined responses type: `<OperationId>Mutation` / `<OperationId>Query`
|
|
35
|
+
* - Response union: `<OperationId>MutationResponse` / `<OperationId>QueryResponse`
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { resolverTsLegacy } from '@kubb/plugin-ts'
|
|
40
|
+
*
|
|
41
|
+
* resolverTsLegacy.resolveResponseStatusTypedName(node, 201) // → 'CreatePets201'
|
|
42
|
+
* resolverTsLegacy.resolveResponseStatusTypedName(node, 'default') // → 'CreatePetsError'
|
|
43
|
+
* resolverTsLegacy.resolveDataTypedName(node) // → 'CreatePetsMutationRequest' (POST)
|
|
44
|
+
* resolverTsLegacy.resolveResponsesTypedName(node) // → 'CreatePetsMutation' (POST)
|
|
45
|
+
* resolverTsLegacy.resolveResponseTypedName(node) // → 'CreatePetsMutationResponse' (POST)
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare const resolverTsLegacy: ResolverTs;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { resolverTs, resolverTsLegacy };
|
|
51
|
+
//# sourceMappingURL=resolvers.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
2
|
import { Group, Output, PluginFactoryOptions, ResolveNameParams, Resolver } from "@kubb/core";
|
|
3
|
-
import { Exclude, Include, Override, ResolvePathOptions } from "@kubb/plugin-oas";
|
|
4
|
-
import { Generator as Generator$1 } from "@kubb/plugin-oas/generators";
|
|
5
|
-
import { Oas, contentType } from "@kubb/oas";
|
|
6
3
|
import { OperationNode, ParameterNode, SchemaNode, StatusCode } from "@kubb/ast/types";
|
|
4
|
+
import { Oas, contentType } from "@kubb/oas";
|
|
5
|
+
import { Exclude, Include, Override, ResolvePathOptions } from "@kubb/plugin-oas";
|
|
6
|
+
import { Generator } from "@kubb/plugin-oas/generators";
|
|
7
7
|
|
|
8
8
|
//#region src/types.d.ts
|
|
9
9
|
/**
|
|
@@ -135,6 +135,60 @@ type ResolverTs = Resolver & {
|
|
|
135
135
|
* resolver.resolveEnumKeyTypedName(node) // → 'PetStatusKey'
|
|
136
136
|
*/
|
|
137
137
|
resolveEnumKeyTypedName(node: SchemaNode): string;
|
|
138
|
+
/**
|
|
139
|
+
* Resolves the variable/function name for an operation's grouped path parameters type.
|
|
140
|
+
* Only available in legacy mode (`legacy: true`).
|
|
141
|
+
*
|
|
142
|
+
* @deprecated Legacy only — will be removed in v6. Use `resolveParamName` per individual parameter instead.
|
|
143
|
+
* @example
|
|
144
|
+
* resolver.resolvePathParamsName(node) // → 'GetPetByIdPathParams'
|
|
145
|
+
*/
|
|
146
|
+
resolvePathParamsName?(node: OperationNode): string;
|
|
147
|
+
/**
|
|
148
|
+
* Resolves the TypeScript type alias name for an operation's grouped path parameters type.
|
|
149
|
+
* Only available in legacy mode (`legacy: true`).
|
|
150
|
+
*
|
|
151
|
+
* @deprecated Legacy only — will be removed in v6. Use `resolveParamTypedName` per individual parameter instead.
|
|
152
|
+
* @example
|
|
153
|
+
* resolver.resolvePathParamsTypedName(node) // → 'GetPetByIdPathParams'
|
|
154
|
+
*/
|
|
155
|
+
resolvePathParamsTypedName?(node: OperationNode): string;
|
|
156
|
+
/**
|
|
157
|
+
* Resolves the variable/function name for an operation's grouped query parameters type.
|
|
158
|
+
* Only available in legacy mode (`legacy: true`).
|
|
159
|
+
*
|
|
160
|
+
* @deprecated Legacy only — will be removed in v6. Use `resolveParamName` per individual parameter instead.
|
|
161
|
+
* @example
|
|
162
|
+
* resolver.resolveQueryParamsName(node) // → 'FindPetsByStatusQueryParams'
|
|
163
|
+
*/
|
|
164
|
+
resolveQueryParamsName?(node: OperationNode): string;
|
|
165
|
+
/**
|
|
166
|
+
* Resolves the TypeScript type alias name for an operation's grouped query parameters type.
|
|
167
|
+
* Only available in legacy mode (`legacy: true`).
|
|
168
|
+
*
|
|
169
|
+
* @deprecated Legacy only — will be removed in v6. Use `resolveParamTypedName` per individual parameter instead.
|
|
170
|
+
* @example
|
|
171
|
+
* resolver.resolveQueryParamsTypedName(node) // → 'FindPetsByStatusQueryParams'
|
|
172
|
+
*/
|
|
173
|
+
resolveQueryParamsTypedName?(node: OperationNode): string;
|
|
174
|
+
/**
|
|
175
|
+
* Resolves the variable/function name for an operation's grouped header parameters type.
|
|
176
|
+
* Only available in legacy mode (`legacy: true`).
|
|
177
|
+
*
|
|
178
|
+
* @deprecated Legacy only — will be removed in v6. Use `resolveParamName` per individual parameter instead.
|
|
179
|
+
* @example
|
|
180
|
+
* resolver.resolveHeaderParamsName(node) // → 'DeletePetHeaderParams'
|
|
181
|
+
*/
|
|
182
|
+
resolveHeaderParamsName?(node: OperationNode): string;
|
|
183
|
+
/**
|
|
184
|
+
* Resolves the TypeScript type alias name for an operation's grouped header parameters type.
|
|
185
|
+
* Only available in legacy mode (`legacy: true`).
|
|
186
|
+
*
|
|
187
|
+
* @deprecated Legacy only — will be removed in v6. Use `resolveParamTypedName` per individual parameter instead.
|
|
188
|
+
* @example
|
|
189
|
+
* resolver.resolveHeaderParamsTypedName(node) // → 'DeletePetHeaderParams'
|
|
190
|
+
*/
|
|
191
|
+
resolveHeaderParamsTypedName?(node: OperationNode): string;
|
|
138
192
|
};
|
|
139
193
|
type Options = {
|
|
140
194
|
/**
|
|
@@ -192,52 +246,6 @@ type Options = {
|
|
|
192
246
|
* @default 'type'
|
|
193
247
|
*/
|
|
194
248
|
syntaxType?: 'type' | 'interface';
|
|
195
|
-
/**
|
|
196
|
-
* Set a suffix for the generated enums.
|
|
197
|
-
* @default 'enum'
|
|
198
|
-
* @deprecated Set `enumSuffix` on the adapter (`adapterOas({ enumSuffix })`) instead.
|
|
199
|
-
* In v5, the adapter owns this decision at parse time; the plugin option is ignored.
|
|
200
|
-
*/
|
|
201
|
-
enumSuffix?: string;
|
|
202
|
-
/**
|
|
203
|
-
* Choose to use date or datetime as JavaScript Date instead of string.
|
|
204
|
-
* - 'string' represents dates as string values.
|
|
205
|
-
* - 'date' represents dates as JavaScript Date objects.
|
|
206
|
-
* @default 'string'
|
|
207
|
-
* @deprecated Set `dateType` on the adapter (`adapterOas({ dateType })`) instead.
|
|
208
|
-
* In v5, the adapter owns this decision at parse time; the plugin option is ignored.
|
|
209
|
-
*/
|
|
210
|
-
dateType?: 'string' | 'date';
|
|
211
|
-
/**
|
|
212
|
-
* Choose to use `number` or `bigint` for integer fields with `int64` format.
|
|
213
|
-
* - 'number' uses the TypeScript `number` type (matches JSON.parse() runtime behavior).
|
|
214
|
-
* - 'bigint' uses the TypeScript `bigint` type (accurate for values exceeding Number.MAX_SAFE_INTEGER).
|
|
215
|
-
* @note in v5 of Kubb 'bigint' will become the default to better align with OpenAPI's int64 specification.
|
|
216
|
-
* @default 'number'
|
|
217
|
-
* @deprecated Set `integerType` on the adapter (`adapterOas({ integerType })`) instead.
|
|
218
|
-
* In v5, the adapter owns this decision at parse time; the plugin option is ignored.
|
|
219
|
-
*/
|
|
220
|
-
integerType?: 'number' | 'bigint';
|
|
221
|
-
/**
|
|
222
|
-
* Which type to use when the Swagger/OpenAPI file is not providing more information.
|
|
223
|
-
* - 'any' allows any value.
|
|
224
|
-
* - 'unknown' requires type narrowing before use.
|
|
225
|
-
* - 'void' represents no value.
|
|
226
|
-
* @default 'any'
|
|
227
|
-
* @deprecated Set `unknownType` on the adapter (`adapterOas({ unknownType })`) instead.
|
|
228
|
-
* In v5, the adapter owns this decision at parse time; the plugin option is ignored.
|
|
229
|
-
*/
|
|
230
|
-
unknownType?: 'any' | 'unknown' | 'void';
|
|
231
|
-
/**
|
|
232
|
-
* Which type to use for empty schema values.
|
|
233
|
-
* - 'any' allows any value.
|
|
234
|
-
* - 'unknown' requires type narrowing before use.
|
|
235
|
-
* - 'void' represents no value.
|
|
236
|
-
* @default `unknownType`
|
|
237
|
-
* @deprecated Set `emptySchemaType` on the adapter (`adapterOas({ emptySchemaType })`) instead.
|
|
238
|
-
* In v5, the adapter owns this decision at parse time; the plugin option is ignored.
|
|
239
|
-
*/
|
|
240
|
-
emptySchemaType?: 'any' | 'unknown' | 'void';
|
|
241
249
|
/**
|
|
242
250
|
* Choose what to use as mode for an optional value.
|
|
243
251
|
* - 'questionToken' marks the property as optional with ? (e.g., type?: string).
|
|
@@ -269,11 +277,22 @@ type Options = {
|
|
|
269
277
|
/**
|
|
270
278
|
* Define some generators next to the ts generators
|
|
271
279
|
*/
|
|
272
|
-
generators?: Array<Generator
|
|
280
|
+
generators?: Array<Generator<PluginTs>>;
|
|
273
281
|
/**
|
|
274
282
|
* Unstable naming for v5
|
|
275
283
|
*/
|
|
276
284
|
UNSTABLE_NAMING?: true;
|
|
285
|
+
/**
|
|
286
|
+
* Enable legacy naming conventions for backwards compatibility.
|
|
287
|
+
* When enabled, operation-level types use the old naming scheme:
|
|
288
|
+
* - GET responses → `<OperationId>QueryResponse`, `<OperationId>Query`
|
|
289
|
+
* - Non-GET responses → `<OperationId>MutationResponse`, `<OperationId>Mutation`
|
|
290
|
+
* - Request body → `<OperationId>QueryRequest` / `<OperationId>MutationRequest`
|
|
291
|
+
* - Response status codes → `<OperationId><StatusCode>` (e.g. `CreatePets201`)
|
|
292
|
+
* - Default/error response → `<OperationId>Error`
|
|
293
|
+
* @default false
|
|
294
|
+
*/
|
|
295
|
+
legacy?: boolean;
|
|
277
296
|
};
|
|
278
297
|
type ResolvedOptions = {
|
|
279
298
|
output: Output<Oas>;
|
|
@@ -281,18 +300,22 @@ type ResolvedOptions = {
|
|
|
281
300
|
override: NonNullable<Options['override']>;
|
|
282
301
|
enumType: NonNullable<Options['enumType']>;
|
|
283
302
|
enumKeyCasing: NonNullable<Options['enumKeyCasing']>;
|
|
284
|
-
enumSuffix: NonNullable<Options['enumSuffix']>;
|
|
285
|
-
dateType: NonNullable<Options['dateType']>;
|
|
286
|
-
integerType: NonNullable<Options['integerType']>;
|
|
287
|
-
unknownType: NonNullable<Options['unknownType']>;
|
|
288
|
-
emptySchemaType: NonNullable<Options['emptySchemaType']>;
|
|
289
303
|
optionalType: NonNullable<Options['optionalType']>;
|
|
290
304
|
arrayType: NonNullable<Options['arrayType']>;
|
|
291
305
|
transformers: NonNullable<Options['transformers']>;
|
|
292
306
|
syntaxType: NonNullable<Options['syntaxType']>;
|
|
293
307
|
paramsCasing: Options['paramsCasing'];
|
|
308
|
+
legacy: NonNullable<Options['legacy']>;
|
|
309
|
+
resolver: ResolverTs;
|
|
310
|
+
/**
|
|
311
|
+
* The base resolver without any `transformers.name` wrapping.
|
|
312
|
+
* Used internally to derive enum prefix names so that user-defined
|
|
313
|
+
* name transformations (e.g. appending `Type`) are not embedded in
|
|
314
|
+
* the middle of inline-enum identifiers.
|
|
315
|
+
*/
|
|
316
|
+
baseResolver?: ResolverTs;
|
|
294
317
|
};
|
|
295
318
|
type PluginTs = PluginFactoryOptions<'plugin-ts', Options, ResolvedOptions, never, ResolvePathOptions, ResolverTs>;
|
|
296
319
|
//#endregion
|
|
297
|
-
export { PluginTs as n, Options as t };
|
|
298
|
-
//# sourceMappingURL=types-
|
|
320
|
+
export { PluginTs as n, ResolverTs as r, Options as t };
|
|
321
|
+
//# sourceMappingURL=types-BSRhtbGl.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-ts",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.13",
|
|
4
4
|
"description": "TypeScript code generation plugin for Kubb, transforming OpenAPI schemas into TypeScript interfaces, types, and utility functions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"import": "./dist/generators.js",
|
|
40
40
|
"require": "./dist/generators.cjs"
|
|
41
41
|
},
|
|
42
|
+
"./resolvers": {
|
|
43
|
+
"import": "./dist/resolvers.js",
|
|
44
|
+
"require": "./dist/resolvers.cjs"
|
|
45
|
+
},
|
|
42
46
|
"./package.json": "./package.json"
|
|
43
47
|
},
|
|
44
48
|
"types": "./dist/index.d.ts",
|
|
@@ -49,6 +53,9 @@
|
|
|
49
53
|
],
|
|
50
54
|
"generators": [
|
|
51
55
|
"./dist/generators.d.ts"
|
|
56
|
+
],
|
|
57
|
+
"resolvers": [
|
|
58
|
+
"./dist/resolvers.d.ts"
|
|
52
59
|
]
|
|
53
60
|
}
|
|
54
61
|
},
|
|
@@ -71,10 +78,10 @@
|
|
|
71
78
|
"@kubb/react-fabric": "0.14.0",
|
|
72
79
|
"remeda": "^2.33.6",
|
|
73
80
|
"typescript": "5.9.3",
|
|
74
|
-
"@kubb/ast": "5.0.0-alpha.
|
|
75
|
-
"@kubb/core": "5.0.0-alpha.
|
|
76
|
-
"@kubb/oas": "5.0.0-alpha.
|
|
77
|
-
"@kubb/plugin-oas": "5.0.0-alpha.
|
|
81
|
+
"@kubb/ast": "5.0.0-alpha.13",
|
|
82
|
+
"@kubb/core": "5.0.0-alpha.13",
|
|
83
|
+
"@kubb/oas": "5.0.0-alpha.13",
|
|
84
|
+
"@kubb/plugin-oas": "5.0.0-alpha.13"
|
|
78
85
|
},
|
|
79
86
|
"peerDependencies": {
|
|
80
87
|
"@kubb/react-fabric": "0.14.0"
|
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
import { camelCase,
|
|
1
|
+
import { camelCase, trimQuotes } from '@internals/utils'
|
|
2
2
|
import type { EnumSchemaNode } from '@kubb/ast/types'
|
|
3
3
|
import { safePrint } from '@kubb/fabric-core/parsers/typescript'
|
|
4
4
|
import { File } from '@kubb/react-fabric'
|
|
5
5
|
import type { FabricReactNode } from '@kubb/react-fabric/types'
|
|
6
|
-
import { ENUM_TYPES_WITH_KEY_SUFFIX, ENUM_TYPES_WITH_RUNTIME_VALUE, ENUM_TYPES_WITH_TYPE_ONLY } from '
|
|
7
|
-
import * as factory from '
|
|
8
|
-
import type { PluginTs } from '
|
|
6
|
+
import { ENUM_TYPES_WITH_KEY_SUFFIX, ENUM_TYPES_WITH_RUNTIME_VALUE, ENUM_TYPES_WITH_TYPE_ONLY } from '../constants.ts'
|
|
7
|
+
import * as factory from '../factory.ts'
|
|
8
|
+
import type { PluginTs, ResolverTs } from '../types.ts'
|
|
9
9
|
|
|
10
10
|
type Props = {
|
|
11
11
|
node: EnumSchemaNode
|
|
12
12
|
enumType: PluginTs['resolvedOptions']['enumType']
|
|
13
13
|
enumKeyCasing: PluginTs['resolvedOptions']['enumKeyCasing']
|
|
14
|
+
resolver: ResolverTs
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
|
|
18
19
|
*
|
|
19
20
|
* The raw `node.name` may be a YAML key such as `"enumNames.Type"` which is not a
|
|
20
|
-
* valid TypeScript identifier.
|
|
21
|
-
* properties the adapter already emits a PascalCase+suffix name so
|
|
21
|
+
* valid TypeScript identifier. The resolver normalizes it; for inline enum
|
|
22
|
+
* properties the adapter already emits a PascalCase+suffix name so resolution is typically a no-op.
|
|
22
23
|
*/
|
|
23
|
-
export function getEnumNames(node: EnumSchemaNode
|
|
24
|
-
|
|
24
|
+
export function getEnumNames({ node, enumType, resolver }: { node: EnumSchemaNode; enumType: PluginTs['resolvedOptions']['enumType']; resolver: ResolverTs }): {
|
|
25
|
+
enumName: string
|
|
26
|
+
typeName: string
|
|
27
|
+
/**
|
|
28
|
+
* The PascalCase name that `$ref` importers will use to reference this enum type.
|
|
29
|
+
* For `asConst`/`asPascalConst` this differs from `typeName` (which has a `Key` suffix).
|
|
30
|
+
*/
|
|
31
|
+
refName: string
|
|
32
|
+
} {
|
|
33
|
+
const resolved = resolver.default(node.name!, 'type')
|
|
25
34
|
const enumName = enumType === 'asPascalConst' ? resolved : camelCase(node.name!)
|
|
26
35
|
const typeName = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? `${resolved}Key` : resolved
|
|
27
36
|
|
|
28
|
-
return { enumName, typeName }
|
|
37
|
+
return { enumName, typeName, refName: resolved }
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
/**
|
|
@@ -39,8 +48,8 @@ export function getEnumNames(node: EnumSchemaNode, enumType: PluginTs['resolvedO
|
|
|
39
48
|
* The emitted `File.Source` nodes carry the resolved names so that the barrel
|
|
40
49
|
* index picks up the correct export identifiers.
|
|
41
50
|
*/
|
|
42
|
-
export function Enum({ node, enumType, enumKeyCasing }: Props): FabricReactNode {
|
|
43
|
-
const { enumName, typeName } = getEnumNames(node, enumType)
|
|
51
|
+
export function Enum({ node, enumType, enumKeyCasing, resolver }: Props): FabricReactNode {
|
|
52
|
+
const { enumName, typeName, refName } = getEnumNames({ node, enumType, resolver })
|
|
44
53
|
|
|
45
54
|
const [nameNode, typeNode] = factory.createEnumDeclaration({
|
|
46
55
|
name: enumName,
|
|
@@ -52,6 +61,8 @@ export function Enum({ node, enumType, enumKeyCasing }: Props): FabricReactNode
|
|
|
52
61
|
enumKeyCasing,
|
|
53
62
|
})
|
|
54
63
|
|
|
64
|
+
const needsRefAlias = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && refName !== typeName
|
|
65
|
+
|
|
55
66
|
return (
|
|
56
67
|
<>
|
|
57
68
|
{nameNode && (
|
|
@@ -62,6 +73,11 @@ export function Enum({ node, enumType, enumKeyCasing }: Props): FabricReactNode
|
|
|
62
73
|
<File.Source name={typeName} isIndexable isExportable={ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType)} isTypeOnly={ENUM_TYPES_WITH_TYPE_ONLY.has(enumType)}>
|
|
63
74
|
{safePrint(typeNode)}
|
|
64
75
|
</File.Source>
|
|
76
|
+
{needsRefAlias && (
|
|
77
|
+
<File.Source name={refName} isExportable isIndexable isTypeOnly>
|
|
78
|
+
{`export type ${refName} = ${typeName}`}
|
|
79
|
+
</File.Source>
|
|
80
|
+
)}
|
|
65
81
|
</>
|
|
66
82
|
)
|
|
67
83
|
}
|
package/src/components/Type.tsx
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { collect } from '@kubb/ast'
|
|
2
|
+
import type { EnumSchemaNode, SchemaNode } from '@kubb/ast/types'
|
|
2
3
|
import { safePrint } from '@kubb/fabric-core/parsers/typescript'
|
|
3
|
-
import type { SchemaObject } from '@kubb/oas'
|
|
4
|
-
import { isKeyword, type Schema, SchemaGenerator, schemaKeywords } from '@kubb/plugin-oas'
|
|
5
4
|
import { File } from '@kubb/react-fabric'
|
|
6
5
|
import type { FabricReactNode } from '@kubb/react-fabric/types'
|
|
7
|
-
import
|
|
8
|
-
import * as factory from '../factory.ts'
|
|
9
|
-
import { parse, typeKeywordMapper } from '../parser.ts'
|
|
6
|
+
import { printerTs } from '../printer.ts'
|
|
10
7
|
import type { PluginTs } from '../types.ts'
|
|
8
|
+
import { Enum, getEnumNames } from './Enum.tsx'
|
|
11
9
|
|
|
12
10
|
type Props = {
|
|
13
11
|
name: string
|
|
14
12
|
typedName: string
|
|
15
|
-
|
|
16
|
-
tree: Array<Schema>
|
|
13
|
+
node: SchemaNode
|
|
17
14
|
optionalType: PluginTs['resolvedOptions']['optionalType']
|
|
18
15
|
arrayType: PluginTs['resolvedOptions']['arrayType']
|
|
19
16
|
enumType: PluginTs['resolvedOptions']['enumType']
|
|
20
17
|
enumKeyCasing: PluginTs['resolvedOptions']['enumKeyCasing']
|
|
21
18
|
syntaxType: PluginTs['resolvedOptions']['syntaxType']
|
|
19
|
+
resolver: PluginTs['resolvedOptions']['resolver']
|
|
20
|
+
legacy?: boolean
|
|
22
21
|
description?: string
|
|
23
22
|
keysToOmit?: string[]
|
|
24
23
|
}
|
|
@@ -26,131 +25,34 @@ type Props = {
|
|
|
26
25
|
export function Type({
|
|
27
26
|
name,
|
|
28
27
|
typedName,
|
|
29
|
-
|
|
28
|
+
node,
|
|
30
29
|
keysToOmit,
|
|
31
|
-
schema,
|
|
32
30
|
optionalType,
|
|
33
31
|
arrayType,
|
|
34
32
|
syntaxType,
|
|
35
33
|
enumType,
|
|
36
34
|
enumKeyCasing,
|
|
37
35
|
description,
|
|
36
|
+
resolver,
|
|
38
37
|
}: Props): FabricReactNode {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const schemaFromTree = tree.find((item) => item.keyword === schemaKeywords.schema)
|
|
46
|
-
const enumSchemas = SchemaGenerator.deepSearch(tree, schemaKeywords.enum)
|
|
47
|
-
|
|
48
|
-
let type =
|
|
49
|
-
(tree
|
|
50
|
-
.map((current, _index, siblings) =>
|
|
51
|
-
parse(
|
|
52
|
-
{ name, schema, parent: undefined, current, siblings },
|
|
53
|
-
{
|
|
54
|
-
optionalType,
|
|
55
|
-
arrayType,
|
|
56
|
-
enumType,
|
|
57
|
-
},
|
|
58
|
-
),
|
|
59
|
-
)
|
|
60
|
-
.filter(Boolean)
|
|
61
|
-
.at(0) as ts.TypeNode) || typeKeywordMapper.undefined()
|
|
62
|
-
|
|
63
|
-
// Add a "Key" suffix to avoid collisions where necessary
|
|
64
|
-
if (['asConst', 'asPascalConst'].includes(enumType) && enumSchemas.length > 0) {
|
|
65
|
-
const isDirectEnum = schema.type === 'array' && schema.items !== undefined
|
|
66
|
-
const isEnumOnly = 'enum' in schema && schema.enum
|
|
67
|
-
|
|
68
|
-
if (isDirectEnum || isEnumOnly) {
|
|
69
|
-
const enumSchema = enumSchemas[0]!
|
|
70
|
-
const typeNameWithKey = `${enumSchema.args.typeName}Key`
|
|
71
|
-
|
|
72
|
-
type = factory.createTypeReferenceNode(typeNameWithKey)
|
|
73
|
-
|
|
74
|
-
if (schema.type === 'array') {
|
|
75
|
-
if (arrayType === 'generic') {
|
|
76
|
-
type = factory.createTypeReferenceNode(factory.createIdentifier('Array'), [type])
|
|
77
|
-
} else {
|
|
78
|
-
type = factory.createArrayTypeNode(type)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (schemaFromTree && isKeyword(schemaFromTree, schemaKeywords.schema)) {
|
|
85
|
-
const isNullish = tree.some((item) => item.keyword === schemaKeywords.nullish)
|
|
86
|
-
const isNullable = tree.some((item) => item.keyword === schemaKeywords.nullable)
|
|
87
|
-
const isOptional = tree.some((item) => item.keyword === schemaKeywords.optional)
|
|
38
|
+
const resolvedDescription = description || node?.description
|
|
39
|
+
const enumSchemaNodes = collect<EnumSchemaNode>(node, {
|
|
40
|
+
schema(n): EnumSchemaNode | undefined {
|
|
41
|
+
if (n.type === 'enum' && n.name) return n as EnumSchemaNode
|
|
42
|
+
},
|
|
43
|
+
})
|
|
88
44
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
nodes: [type, factory.keywordTypeNodes.null],
|
|
92
|
-
}) as ts.TypeNode
|
|
93
|
-
}
|
|
45
|
+
const printer = printerTs({ optionalType, arrayType, enumType, typeName: name, syntaxType, description: resolvedDescription, keysToOmit, resolver })
|
|
46
|
+
const typeNode = printer.print(node)
|
|
94
47
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
nodes: [type, factory.keywordTypeNodes.undefined],
|
|
98
|
-
}) as ts.TypeNode
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (isOptional && ['undefined', 'questionTokenAndUndefined'].includes(optionalType as string)) {
|
|
102
|
-
type = factory.createUnionDeclaration({
|
|
103
|
-
nodes: [type, factory.keywordTypeNodes.undefined],
|
|
104
|
-
}) as ts.TypeNode
|
|
105
|
-
}
|
|
48
|
+
if (!typeNode) {
|
|
49
|
+
return
|
|
106
50
|
}
|
|
107
51
|
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
typeNodes.push(
|
|
111
|
-
factory.createTypeDeclaration({
|
|
112
|
-
name,
|
|
113
|
-
isExportable: true,
|
|
114
|
-
type: keysToOmit?.length
|
|
115
|
-
? factory.createOmitDeclaration({
|
|
116
|
-
keys: keysToOmit,
|
|
117
|
-
type,
|
|
118
|
-
nonNullable: true,
|
|
119
|
-
})
|
|
120
|
-
: type,
|
|
121
|
-
syntax: useTypeGeneration ? 'type' : 'interface',
|
|
122
|
-
comments: [
|
|
123
|
-
schema.title ? `${jsStringEscape(schema.title)}` : undefined,
|
|
124
|
-
description ? `@description ${jsStringEscape(description)}` : undefined,
|
|
125
|
-
schema.deprecated ? '@deprecated' : undefined,
|
|
126
|
-
schema.minLength ? `@minLength ${schema.minLength}` : undefined,
|
|
127
|
-
schema.maxLength ? `@maxLength ${schema.maxLength}` : undefined,
|
|
128
|
-
schema.pattern ? `@pattern ${schema.pattern}` : undefined,
|
|
129
|
-
schema.default ? `@default ${schema.default}` : undefined,
|
|
130
|
-
schema.example ? `@example ${schema.example}` : undefined,
|
|
131
|
-
],
|
|
132
|
-
}),
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
const enums = [...new Set(enumSchemas)].map((enumSchema) => {
|
|
136
|
-
const name = enumType === 'asPascalConst' ? pascalCase(enumSchema.args.name) : camelCase(enumSchema.args.name)
|
|
137
|
-
const typeName = ['asConst', 'asPascalConst'].includes(enumType) ? `${enumSchema.args.typeName}Key` : enumSchema.args.typeName
|
|
138
|
-
|
|
139
|
-
const [nameNode, typeNode] = factory.createEnumDeclaration({
|
|
140
|
-
name,
|
|
141
|
-
typeName,
|
|
142
|
-
enums: enumSchema.args.items
|
|
143
|
-
.map((item) => (item.value === undefined ? undefined : [trimQuotes(item.name?.toString()), item.value]))
|
|
144
|
-
.filter(Boolean) as unknown as Array<[string, string]>,
|
|
145
|
-
type: enumType,
|
|
146
|
-
enumKeyCasing,
|
|
147
|
-
})
|
|
148
|
-
|
|
52
|
+
const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
|
|
149
53
|
return {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
name,
|
|
153
|
-
typeName,
|
|
54
|
+
node,
|
|
55
|
+
...getEnumNames({ node, enumType, resolver }),
|
|
154
56
|
}
|
|
155
57
|
})
|
|
156
58
|
|
|
@@ -160,29 +62,10 @@ export function Type({
|
|
|
160
62
|
|
|
161
63
|
return (
|
|
162
64
|
<>
|
|
163
|
-
{shouldExportEnums &&
|
|
164
|
-
enums.map(({ name, nameNode, typeName, typeNode }) => (
|
|
165
|
-
<>
|
|
166
|
-
{nameNode && (
|
|
167
|
-
<File.Source name={name} isExportable isIndexable isTypeOnly={false}>
|
|
168
|
-
{safePrint(nameNode)}
|
|
169
|
-
</File.Source>
|
|
170
|
-
)}
|
|
171
|
-
{
|
|
172
|
-
<File.Source
|
|
173
|
-
name={typeName}
|
|
174
|
-
isIndexable
|
|
175
|
-
isExportable={['enum', 'asConst', 'asPascalConst', 'constEnum', 'literal', undefined].includes(enumType)}
|
|
176
|
-
isTypeOnly={['asConst', 'asPascalConst', 'literal', undefined].includes(enumType)}
|
|
177
|
-
>
|
|
178
|
-
{safePrint(typeNode)}
|
|
179
|
-
</File.Source>
|
|
180
|
-
}
|
|
181
|
-
</>
|
|
182
|
-
))}
|
|
65
|
+
{shouldExportEnums && enums.map(({ node }) => <Enum node={node} enumType={enumType} enumKeyCasing={enumKeyCasing} resolver={resolver} />)}
|
|
183
66
|
{shouldExportType && (
|
|
184
67
|
<File.Source name={typedName} isTypeOnly isExportable isIndexable>
|
|
185
|
-
{safePrint(
|
|
68
|
+
{safePrint(typeNode)}
|
|
186
69
|
</File.Source>
|
|
187
70
|
)}
|
|
188
71
|
</>
|
package/src/components/index.ts
CHANGED
package/src/generators/index.ts
CHANGED