@kubb/plugin-ts 5.0.0-alpha.20 → 5.0.0-alpha.22
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-Bf8raoQX.cjs +124 -0
- package/dist/Type-Bf8raoQX.cjs.map +1 -0
- package/dist/Type-BpXxT4l_.js +113 -0
- package/dist/Type-BpXxT4l_.js.map +1 -0
- package/dist/builderTs-COUg3xtQ.cjs +135 -0
- package/dist/builderTs-COUg3xtQ.cjs.map +1 -0
- package/dist/builderTs-DPpkJKd1.js +131 -0
- package/dist/builderTs-DPpkJKd1.js.map +1 -0
- package/dist/builders.cjs +3 -0
- package/dist/builders.d.ts +23 -0
- package/dist/builders.js +2 -0
- package/dist/{casing-Cp-jbC_k.js → casing-BJHFg-zZ.js} +1 -1
- package/dist/{casing-Cp-jbC_k.js.map → casing-BJHFg-zZ.js.map} +1 -1
- package/dist/{casing-D2uQKLWS.cjs → casing-DHfdqpLi.cjs} +2 -39
- package/dist/{casing-D2uQKLWS.cjs.map → casing-DHfdqpLi.cjs.map} +1 -1
- package/dist/chunk-ByKO4r7w.cjs +38 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.ts +5 -2
- package/dist/components.js +1 -1
- package/dist/generators-DFDut8o-.js +555 -0
- package/dist/generators-DFDut8o-.js.map +1 -0
- package/dist/{generators-xHWQCNd9.cjs → generators-DKd7MYbx.cjs} +300 -293
- package/dist/generators-DKd7MYbx.cjs.map +1 -0
- package/dist/generators.cjs +2 -1
- package/dist/generators.d.ts +5 -2
- package/dist/generators.js +2 -2
- package/dist/index.cjs +75 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -2
- package/dist/index.js +73 -35
- package/dist/index.js.map +1 -1
- package/dist/{Type-B70QnSzH.cjs → printerTs-BcHudagv.cjs} +41 -135
- package/dist/printerTs-BcHudagv.cjs.map +1 -0
- package/dist/{Type-CMC7L-38.js → printerTs-CMBCOuqd.js} +19 -132
- package/dist/printerTs-CMBCOuqd.js.map +1 -0
- package/dist/printers.cjs +3 -0
- package/dist/printers.d.ts +81 -0
- package/dist/printers.js +2 -0
- package/dist/{resolvers-DsKabI0F.js → resolverTsLegacy-CPiqqsO6.js} +10 -9
- package/dist/resolverTsLegacy-CPiqqsO6.js.map +1 -0
- package/dist/{resolvers-YIpeP5YD.cjs → resolverTsLegacy-CuR9XbKk.cjs} +11 -9
- package/dist/resolverTsLegacy-CuR9XbKk.cjs.map +1 -0
- package/dist/resolvers.cjs +3 -3
- package/dist/resolvers.d.ts +1 -1
- package/dist/resolvers.js +1 -1
- package/dist/{types-zqLMbIqZ.d.ts → types-CRtcZOCz.d.ts} +59 -25
- package/package.json +17 -5
- package/src/builders/builderTs.ts +107 -0
- package/src/builders/index.ts +1 -0
- package/src/components/Enum.tsx +15 -11
- package/src/components/Type.tsx +20 -9
- package/src/factory.ts +0 -32
- package/src/generators/index.ts +1 -0
- package/src/generators/typeGenerator.tsx +53 -141
- package/src/generators/typeGeneratorLegacy.tsx +348 -0
- package/src/index.ts +1 -1
- package/src/plugin.ts +36 -44
- package/src/presets.ts +27 -7
- package/src/printers/index.ts +1 -0
- package/src/{printer.ts → printers/printerTs.ts} +31 -19
- package/src/resolvers/resolverTs.ts +9 -6
- package/src/resolvers/resolverTsLegacy.ts +1 -1
- package/src/types.ts +72 -24
- package/dist/Type-B70QnSzH.cjs.map +0 -1
- package/dist/Type-CMC7L-38.js.map +0 -1
- package/dist/generators-BFkr7ecU.js +0 -556
- package/dist/generators-BFkr7ecU.js.map +0 -1
- package/dist/generators-xHWQCNd9.cjs.map +0 -1
- package/dist/resolvers-DsKabI0F.js.map +0 -1
- package/dist/resolvers-YIpeP5YD.cjs.map +0 -1
- package/src/generators/utils.ts +0 -308
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { pascalCase } from '@internals/utils'
|
|
3
|
+
import { caseParams, composeTransformers, createProperty, createSchema, narrowSchema, schemaTypes, transform } from '@kubb/ast'
|
|
4
|
+
import type { OperationNode, ParameterNode, SchemaNode } from '@kubb/ast/types'
|
|
5
|
+
import { defineGenerator, getMode } from '@kubb/core'
|
|
6
|
+
import { File } from '@kubb/react-fabric'
|
|
7
|
+
import { Type } from '../components/Type.tsx'
|
|
8
|
+
import { ENUM_TYPES_WITH_KEY_SUFFIX } from '../constants.ts'
|
|
9
|
+
import { resolverTsLegacy } from '../resolvers/resolverTsLegacy.ts'
|
|
10
|
+
import type { PluginTs, ResolverTs } from '../types'
|
|
11
|
+
|
|
12
|
+
type BuildGroupedParamsSchemaOptions = {
|
|
13
|
+
params: Array<ParameterNode>
|
|
14
|
+
parentName?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function buildGroupedParamsSchema({ params, parentName }: BuildGroupedParamsSchemaOptions): SchemaNode {
|
|
18
|
+
return createSchema({
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: params.map((param) => {
|
|
21
|
+
let schema = param.schema
|
|
22
|
+
if (narrowSchema(schema, 'enum') && !schema.name && parentName) {
|
|
23
|
+
schema = { ...schema, name: pascalCase([parentName, param.name, 'enum'].join(' ')) }
|
|
24
|
+
}
|
|
25
|
+
return createProperty({
|
|
26
|
+
name: param.name,
|
|
27
|
+
required: param.required,
|
|
28
|
+
schema,
|
|
29
|
+
})
|
|
30
|
+
}),
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type BuildOperationSchemaOptions = {
|
|
35
|
+
node: OperationNode
|
|
36
|
+
resolver: ResolverTs
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function buildLegacyResponsesSchemaNode({ node, resolver }: BuildOperationSchemaOptions): SchemaNode | null {
|
|
40
|
+
const isGet = node.method.toLowerCase() === 'get'
|
|
41
|
+
const successResponses = node.responses.filter((res) => {
|
|
42
|
+
const code = Number(res.statusCode)
|
|
43
|
+
return !Number.isNaN(code) && code >= 200 && code < 300
|
|
44
|
+
})
|
|
45
|
+
const errorResponses = node.responses.filter((res) => res.statusCode === 'default' || Number(res.statusCode) >= 400)
|
|
46
|
+
|
|
47
|
+
const responseSchema =
|
|
48
|
+
successResponses.length > 0
|
|
49
|
+
? successResponses.length === 1
|
|
50
|
+
? createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, successResponses[0]!.statusCode) })
|
|
51
|
+
: createSchema({
|
|
52
|
+
type: 'union',
|
|
53
|
+
members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
|
|
54
|
+
})
|
|
55
|
+
: createSchema({ type: 'any' })
|
|
56
|
+
|
|
57
|
+
const errorsSchema =
|
|
58
|
+
errorResponses.length > 0
|
|
59
|
+
? errorResponses.length === 1
|
|
60
|
+
? createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, errorResponses[0]!.statusCode) })
|
|
61
|
+
: createSchema({
|
|
62
|
+
type: 'union',
|
|
63
|
+
members: errorResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
|
|
64
|
+
})
|
|
65
|
+
: createSchema({ type: 'any' })
|
|
66
|
+
|
|
67
|
+
const properties = [createProperty({ name: 'Response', required: true, schema: responseSchema })]
|
|
68
|
+
|
|
69
|
+
if (!isGet && node.requestBody?.schema) {
|
|
70
|
+
properties.push(
|
|
71
|
+
createProperty({
|
|
72
|
+
name: 'Request',
|
|
73
|
+
required: true,
|
|
74
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveDataTypedName(node) }),
|
|
75
|
+
}),
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (node.parameters.some((p) => p.in === 'query') && resolver.resolveQueryParamsTypedName) {
|
|
80
|
+
properties.push(
|
|
81
|
+
createProperty({
|
|
82
|
+
name: 'QueryParams',
|
|
83
|
+
required: true,
|
|
84
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveQueryParamsTypedName(node) }),
|
|
85
|
+
}),
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (node.parameters.some((p) => p.in === 'path') && resolver.resolvePathParamsTypedName) {
|
|
90
|
+
properties.push(
|
|
91
|
+
createProperty({
|
|
92
|
+
name: 'PathParams',
|
|
93
|
+
required: true,
|
|
94
|
+
schema: createSchema({ type: 'ref', name: resolver.resolvePathParamsTypedName(node) }),
|
|
95
|
+
}),
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (node.parameters.some((p) => p.in === 'header') && resolver.resolveHeaderParamsTypedName) {
|
|
100
|
+
properties.push(
|
|
101
|
+
createProperty({
|
|
102
|
+
name: 'HeaderParams',
|
|
103
|
+
required: true,
|
|
104
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveHeaderParamsTypedName(node) }),
|
|
105
|
+
}),
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
properties.push(createProperty({ name: 'Errors', required: true, schema: errorsSchema }))
|
|
110
|
+
|
|
111
|
+
return createSchema({ type: 'object', properties })
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function buildLegacyResponseUnionSchemaNode({ node, resolver }: BuildOperationSchemaOptions): SchemaNode {
|
|
115
|
+
const successResponses = node.responses.filter((res) => {
|
|
116
|
+
const code = Number(res.statusCode)
|
|
117
|
+
return !Number.isNaN(code) && code >= 200 && code < 300
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
if (successResponses.length === 0) {
|
|
121
|
+
return createSchema({ type: 'any' })
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (successResponses.length === 1) {
|
|
125
|
+
return createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, successResponses[0]!.statusCode) })
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return createSchema({
|
|
129
|
+
type: 'union',
|
|
130
|
+
members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function nameUnnamedEnums(node: SchemaNode, parentName: string): SchemaNode {
|
|
135
|
+
return transform(node, {
|
|
136
|
+
schema(n) {
|
|
137
|
+
const enumNode = narrowSchema(n, 'enum')
|
|
138
|
+
if (enumNode && !enumNode.name) {
|
|
139
|
+
return { ...enumNode, name: pascalCase([parentName, 'enum'].join(' ')) }
|
|
140
|
+
}
|
|
141
|
+
return undefined
|
|
142
|
+
},
|
|
143
|
+
property(p) {
|
|
144
|
+
const enumNode = narrowSchema(p.schema, 'enum')
|
|
145
|
+
if (enumNode && !enumNode.name) {
|
|
146
|
+
return {
|
|
147
|
+
...p,
|
|
148
|
+
schema: { ...enumNode, name: pascalCase([parentName, p.name, 'enum'].join(' ')) },
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return undefined
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
157
|
+
name: 'typescript-legacy',
|
|
158
|
+
type: 'react',
|
|
159
|
+
Operation({ node, adapter, options, config }) {
|
|
160
|
+
const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, resolver, transformers = [] } = options
|
|
161
|
+
|
|
162
|
+
const root = path.resolve(config.root, config.output.path)
|
|
163
|
+
const mode = getMode(path.resolve(root, output.path))
|
|
164
|
+
|
|
165
|
+
const file = resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group })
|
|
166
|
+
const params = caseParams(node.parameters, paramsCasing)
|
|
167
|
+
|
|
168
|
+
function renderSchemaType({
|
|
169
|
+
node: schemaNode,
|
|
170
|
+
name,
|
|
171
|
+
typedName,
|
|
172
|
+
description,
|
|
173
|
+
keysToOmit,
|
|
174
|
+
}: {
|
|
175
|
+
node: SchemaNode | null
|
|
176
|
+
name: string
|
|
177
|
+
typedName: string
|
|
178
|
+
description?: string
|
|
179
|
+
keysToOmit?: Array<string>
|
|
180
|
+
}) {
|
|
181
|
+
if (!schemaNode) {
|
|
182
|
+
return null
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const transformedNode = transform(schemaNode, composeTransformers(...transformers))
|
|
186
|
+
|
|
187
|
+
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
188
|
+
name: resolver.default(schemaName, 'type'),
|
|
189
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
190
|
+
}))
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<>
|
|
194
|
+
{mode === 'split' &&
|
|
195
|
+
imports.map((imp) => <File.Import key={[name, imp.path, imp.isTypeOnly].join('-')} root={file.path} path={imp.path} name={imp.name} isTypeOnly />)}
|
|
196
|
+
<Type
|
|
197
|
+
name={name}
|
|
198
|
+
typedName={typedName}
|
|
199
|
+
node={transformedNode}
|
|
200
|
+
description={description}
|
|
201
|
+
enumType={enumType}
|
|
202
|
+
enumTypeSuffix={enumTypeSuffix}
|
|
203
|
+
enumKeyCasing={enumKeyCasing}
|
|
204
|
+
optionalType={optionalType}
|
|
205
|
+
arrayType={arrayType}
|
|
206
|
+
syntaxType={syntaxType}
|
|
207
|
+
resolver={resolver}
|
|
208
|
+
keysToOmit={keysToOmit}
|
|
209
|
+
/>
|
|
210
|
+
</>
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const pathParams = params.filter((p) => p.in === 'path')
|
|
215
|
+
const queryParams = params.filter((p) => p.in === 'query')
|
|
216
|
+
const headerParams = params.filter((p) => p.in === 'header')
|
|
217
|
+
|
|
218
|
+
const responseTypes = node.responses.map((res) => {
|
|
219
|
+
const responseName = resolver.resolveResponseStatusName(node, res.statusCode)
|
|
220
|
+
const baseResponseName = resolverTsLegacy.resolveResponseStatusName(node, res.statusCode)
|
|
221
|
+
|
|
222
|
+
return renderSchemaType({
|
|
223
|
+
node: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
|
|
224
|
+
name: responseName,
|
|
225
|
+
typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
|
|
226
|
+
description: res.description,
|
|
227
|
+
keysToOmit: res.keysToOmit,
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
const requestType = node.requestBody?.schema
|
|
232
|
+
? renderSchemaType({
|
|
233
|
+
node: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
|
|
234
|
+
name: resolver.resolveDataName(node),
|
|
235
|
+
typedName: resolver.resolveDataTypedName(node),
|
|
236
|
+
description: node.requestBody.description ?? node.requestBody.schema.description,
|
|
237
|
+
keysToOmit: node.requestBody.keysToOmit,
|
|
238
|
+
})
|
|
239
|
+
: null
|
|
240
|
+
|
|
241
|
+
const legacyParamTypes = [
|
|
242
|
+
pathParams.length > 0
|
|
243
|
+
? renderSchemaType({
|
|
244
|
+
node: buildGroupedParamsSchema({ params: pathParams, parentName: resolverTsLegacy.resolvePathParamsName!(node) }),
|
|
245
|
+
name: resolver.resolvePathParamsName!(node),
|
|
246
|
+
typedName: resolver.resolvePathParamsTypedName!(node),
|
|
247
|
+
})
|
|
248
|
+
: null,
|
|
249
|
+
queryParams.length > 0
|
|
250
|
+
? renderSchemaType({
|
|
251
|
+
node: buildGroupedParamsSchema({ params: queryParams, parentName: resolverTsLegacy.resolveQueryParamsName!(node) }),
|
|
252
|
+
name: resolver.resolveQueryParamsName!(node),
|
|
253
|
+
typedName: resolver.resolveQueryParamsTypedName!(node),
|
|
254
|
+
})
|
|
255
|
+
: null,
|
|
256
|
+
headerParams.length > 0
|
|
257
|
+
? renderSchemaType({
|
|
258
|
+
node: buildGroupedParamsSchema({ params: headerParams, parentName: resolverTsLegacy.resolveHeaderParamsName!(node) }),
|
|
259
|
+
name: resolver.resolveHeaderParamsName!(node),
|
|
260
|
+
typedName: resolver.resolveHeaderParamsTypedName!(node),
|
|
261
|
+
})
|
|
262
|
+
: null,
|
|
263
|
+
]
|
|
264
|
+
|
|
265
|
+
const legacyResponsesType = renderSchemaType({
|
|
266
|
+
node: buildLegacyResponsesSchemaNode({ node, resolver }),
|
|
267
|
+
name: resolver.resolveResponsesName(node),
|
|
268
|
+
typedName: resolver.resolveResponsesTypedName(node),
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
const legacyResponseType = renderSchemaType({
|
|
272
|
+
node: buildLegacyResponseUnionSchemaNode({ node, resolver }),
|
|
273
|
+
name: resolver.resolveResponseName(node),
|
|
274
|
+
typedName: resolver.resolveResponseTypedName(node),
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
<File
|
|
279
|
+
baseName={file.baseName}
|
|
280
|
+
path={file.path}
|
|
281
|
+
meta={file.meta}
|
|
282
|
+
banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
|
|
283
|
+
footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
|
|
284
|
+
>
|
|
285
|
+
{legacyParamTypes}
|
|
286
|
+
{responseTypes}
|
|
287
|
+
{requestType}
|
|
288
|
+
{legacyResponseType}
|
|
289
|
+
{legacyResponsesType}
|
|
290
|
+
</File>
|
|
291
|
+
)
|
|
292
|
+
},
|
|
293
|
+
Schema({ node, adapter, options, config }) {
|
|
294
|
+
const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, resolver, transformers = [] } = options
|
|
295
|
+
|
|
296
|
+
const root = path.resolve(config.root, config.output.path)
|
|
297
|
+
const mode = getMode(path.resolve(root, output.path))
|
|
298
|
+
|
|
299
|
+
if (!node.name) {
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const transformedNode = transform(node, composeTransformers(...transformers))
|
|
304
|
+
|
|
305
|
+
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
306
|
+
name: resolver.default(schemaName, 'type'),
|
|
307
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
308
|
+
}))
|
|
309
|
+
|
|
310
|
+
const isEnumSchema = !!narrowSchema(node, schemaTypes.enum)
|
|
311
|
+
|
|
312
|
+
const typedName =
|
|
313
|
+
ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyTypedName(node, enumTypeSuffix) : resolver.resolveTypedName(node.name)
|
|
314
|
+
|
|
315
|
+
const type = {
|
|
316
|
+
name: resolver.resolveName(node.name),
|
|
317
|
+
typedName,
|
|
318
|
+
file: resolver.resolveFile({ name: node.name, extname: '.ts' }, { root, output, group }),
|
|
319
|
+
} as const
|
|
320
|
+
|
|
321
|
+
return (
|
|
322
|
+
<File
|
|
323
|
+
baseName={type.file.baseName}
|
|
324
|
+
path={type.file.path}
|
|
325
|
+
meta={type.file.meta}
|
|
326
|
+
banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
|
|
327
|
+
footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
|
|
328
|
+
>
|
|
329
|
+
{mode === 'split' &&
|
|
330
|
+
imports.map((imp) => (
|
|
331
|
+
<File.Import key={[node.name, imp.path, imp.isTypeOnly].join('-')} root={type.file.path} path={imp.path} name={imp.name} isTypeOnly />
|
|
332
|
+
))}
|
|
333
|
+
<Type
|
|
334
|
+
name={type.name}
|
|
335
|
+
typedName={type.typedName}
|
|
336
|
+
node={transformedNode}
|
|
337
|
+
enumType={enumType}
|
|
338
|
+
enumTypeSuffix={enumTypeSuffix}
|
|
339
|
+
enumKeyCasing={enumKeyCasing}
|
|
340
|
+
optionalType={optionalType}
|
|
341
|
+
arrayType={arrayType}
|
|
342
|
+
syntaxType={syntaxType}
|
|
343
|
+
resolver={resolver}
|
|
344
|
+
/>
|
|
345
|
+
</File>
|
|
346
|
+
)
|
|
347
|
+
},
|
|
348
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { pluginTs, pluginTsName } from './plugin.ts'
|
|
2
|
-
export type { PluginTs
|
|
2
|
+
export type { PluginTs } from './types.ts'
|
package/src/plugin.ts
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import { camelCase } from '@internals/utils'
|
|
3
2
|
import { walk } from '@kubb/ast'
|
|
4
|
-
import { createPlugin,
|
|
5
|
-
import { typeGenerator } from './generators/index.ts'
|
|
3
|
+
import { createPlugin, getBarrelFiles, renderOperation, renderSchema } from '@kubb/core'
|
|
6
4
|
import { getPreset } from './presets.ts'
|
|
7
5
|
import type { PluginTs } from './types.ts'
|
|
8
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Canonical plugin name for `@kubb/plugin-ts`, used to identify the plugin in driver lookups and warnings.
|
|
9
|
+
*/
|
|
9
10
|
export const pluginTsName = 'plugin-ts' satisfies PluginTs['name']
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* The `@kubb/plugin-ts` plugin factory.
|
|
14
|
+
*
|
|
15
|
+
* Generates TypeScript type declarations from an OpenAPI/AST `RootNode`.
|
|
16
|
+
* Walks schemas and operations, delegates rendering to the active generators,
|
|
17
|
+
* and writes barrel files based on `output.barrelType`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
22
|
+
*
|
|
23
|
+
* export default defineConfig({
|
|
24
|
+
* plugins: [pluginTs({ output: { path: 'types' }, enumType: 'asConst' })],
|
|
25
|
+
* })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
11
28
|
export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
12
29
|
const {
|
|
13
30
|
output = { path: 'types', barrelType: 'named' },
|
|
@@ -16,78 +33,56 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
16
33
|
include,
|
|
17
34
|
override = [],
|
|
18
35
|
enumType = 'asConst',
|
|
36
|
+
enumTypeSuffix = 'Key',
|
|
19
37
|
enumKeyCasing = 'none',
|
|
20
38
|
optionalType = 'questionToken',
|
|
21
39
|
arrayType = 'array',
|
|
22
40
|
syntaxType = 'type',
|
|
23
41
|
paramsCasing,
|
|
24
|
-
generators = [typeGenerator].filter(Boolean),
|
|
25
42
|
compatibilityPreset = 'default',
|
|
26
|
-
resolvers: userResolvers,
|
|
43
|
+
resolvers: userResolvers = [],
|
|
27
44
|
transformers: userTransformers = [],
|
|
45
|
+
generators: userGenerators = [],
|
|
28
46
|
} = options
|
|
29
47
|
|
|
30
|
-
const {
|
|
48
|
+
const { resolver, transformers, generators } = getPreset(compatibilityPreset, {
|
|
31
49
|
resolvers: userResolvers,
|
|
32
50
|
transformers: userTransformers,
|
|
51
|
+
generators: userGenerators,
|
|
33
52
|
})
|
|
34
53
|
|
|
35
54
|
let resolveNameWarning = false
|
|
55
|
+
let resolvePathWarning = false
|
|
36
56
|
|
|
37
57
|
return {
|
|
38
58
|
name: pluginTsName,
|
|
39
59
|
options: {
|
|
40
60
|
output,
|
|
41
61
|
optionalType,
|
|
62
|
+
group,
|
|
42
63
|
arrayType,
|
|
43
64
|
enumType,
|
|
65
|
+
enumTypeSuffix,
|
|
44
66
|
enumKeyCasing,
|
|
45
67
|
syntaxType,
|
|
46
|
-
group,
|
|
47
|
-
override,
|
|
48
68
|
paramsCasing,
|
|
49
|
-
compatibilityPreset,
|
|
50
|
-
baseResolver,
|
|
51
69
|
resolver,
|
|
52
70
|
transformers,
|
|
53
71
|
},
|
|
54
72
|
resolvePath(baseName, pathMode, options) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (mode === 'single') {
|
|
59
|
-
/**
|
|
60
|
-
* when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
|
|
61
|
-
* Other plugins then need to call addOrAppend instead of just add from the fileManager class
|
|
62
|
-
*/
|
|
63
|
-
return path.resolve(root, output.path)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (group && (options?.group?.path || options?.group?.tag)) {
|
|
67
|
-
const groupName: Group['name'] = group?.name
|
|
68
|
-
? group.name
|
|
69
|
-
: (ctx) => {
|
|
70
|
-
if (group?.type === 'path') {
|
|
71
|
-
return `${ctx.group.split('/')[1]}`
|
|
72
|
-
}
|
|
73
|
-
return `${camelCase(ctx.group)}Controller`
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return path.resolve(
|
|
77
|
-
root,
|
|
78
|
-
output.path,
|
|
79
|
-
groupName({
|
|
80
|
-
group: group.type === 'path' ? options.group.path! : options.group.tag!,
|
|
81
|
-
}),
|
|
82
|
-
baseName,
|
|
83
|
-
)
|
|
73
|
+
if (!resolvePathWarning) {
|
|
74
|
+
this.driver.events.emit('warn', 'Do not use resolvePath for pluginTs, use resolverTs.resolvePath instead')
|
|
75
|
+
resolvePathWarning = true
|
|
84
76
|
}
|
|
85
77
|
|
|
86
|
-
return
|
|
78
|
+
return resolver.resolvePath(
|
|
79
|
+
{ baseName, pathMode, tag: options?.group?.tag, path: options?.group?.path },
|
|
80
|
+
{ root: path.resolve(this.config.root, this.config.output.path), output, group },
|
|
81
|
+
)
|
|
87
82
|
},
|
|
88
83
|
resolveName(name, type) {
|
|
89
84
|
if (!resolveNameWarning) {
|
|
90
|
-
this.driver.events.emit('warn', 'Do not use resolveName for pluginTs, use resolverTs instead')
|
|
85
|
+
this.driver.events.emit('warn', 'Do not use resolveName for pluginTs, use resolverTs.default instead')
|
|
91
86
|
resolveNameWarning = true
|
|
92
87
|
}
|
|
93
88
|
|
|
@@ -97,7 +92,6 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
97
92
|
const { config, fabric, plugin, adapter, rootNode, driver, openInStudio } = this
|
|
98
93
|
|
|
99
94
|
const root = path.resolve(config.root, config.output.path)
|
|
100
|
-
const mode = getMode(path.resolve(root, output.path))
|
|
101
95
|
|
|
102
96
|
if (!adapter) {
|
|
103
97
|
throw new Error('Plugin cannot work without adapter being set')
|
|
@@ -124,7 +118,6 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
124
118
|
Component: generator.Schema,
|
|
125
119
|
plugin,
|
|
126
120
|
driver,
|
|
127
|
-
mode,
|
|
128
121
|
})
|
|
129
122
|
}
|
|
130
123
|
})
|
|
@@ -148,7 +141,6 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
148
141
|
Component: generator.Operation,
|
|
149
142
|
plugin,
|
|
150
143
|
driver,
|
|
151
|
-
mode,
|
|
152
144
|
})
|
|
153
145
|
}
|
|
154
146
|
})
|
package/src/presets.ts
CHANGED
|
@@ -1,23 +1,43 @@
|
|
|
1
1
|
import type { Visitor } from '@kubb/ast/types'
|
|
2
|
-
import { type CompatibilityPreset, definePreset, definePresets, getPreset as getCorePreset } from '@kubb/core'
|
|
2
|
+
import { type CompatibilityPreset, definePreset, definePresets, type Generator, getPreset as getCorePreset } from '@kubb/core'
|
|
3
|
+
import { typeGenerator, typeGeneratorLegacy } from './generators/index.ts'
|
|
3
4
|
import { resolverTs, resolverTsLegacy } from './resolvers/index.ts'
|
|
4
|
-
import type { ResolverTs } from './types.ts'
|
|
5
|
+
import type { PluginTs, ResolverTs } from './types.ts'
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Built-in preset registry for `@kubb/plugin-ts`.
|
|
9
|
+
*
|
|
10
|
+
* - `default` — uses `resolverTs` and `typeGenerator` (current naming conventions).
|
|
11
|
+
* - `kubbV4` — uses `resolverTsLegacy` and `typeGeneratorLegacy` (Kubb v4 naming conventions).
|
|
12
|
+
*/
|
|
6
13
|
export const presets = definePresets<ResolverTs>({
|
|
7
|
-
default: definePreset('default', { resolvers: [resolverTs] }),
|
|
8
|
-
kubbV4: definePreset('kubbV4', { resolvers: [resolverTsLegacy] }),
|
|
14
|
+
default: definePreset('default', { resolvers: [resolverTs], generators: [typeGenerator] }),
|
|
15
|
+
kubbV4: definePreset('kubbV4', { resolvers: [resolverTsLegacy], generators: [typeGeneratorLegacy] }),
|
|
9
16
|
})
|
|
10
17
|
|
|
11
18
|
type GetPresetOptions = {
|
|
12
|
-
resolvers
|
|
13
|
-
transformers
|
|
19
|
+
resolvers: Array<ResolverTs>
|
|
20
|
+
transformers: Array<Visitor>
|
|
21
|
+
generators: Array<Generator<PluginTs>>
|
|
14
22
|
}
|
|
15
23
|
|
|
16
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Resolves a compatibility preset for `plugin-ts`, merging user-supplied resolvers,
|
|
26
|
+
* transformers, and generators on top of the built-in preset defaults.
|
|
27
|
+
*
|
|
28
|
+
* `resolverTs` is always prepended to the resolver list as the baseline.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const preset = getPreset('kubbV4', { resolvers: [], transformers: [], generators: [] })
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function getPreset(preset: CompatibilityPreset, { resolvers, transformers, generators }: GetPresetOptions) {
|
|
17
36
|
return getCorePreset({
|
|
18
37
|
preset,
|
|
19
38
|
presets,
|
|
20
39
|
resolvers: [resolverTs, ...(resolvers ?? [])],
|
|
21
40
|
transformers,
|
|
41
|
+
generators,
|
|
22
42
|
})
|
|
23
43
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { printerTs } from './printerTs.ts'
|