@kubb/plugin-ts 5.0.0-alpha.2 → 5.0.0-alpha.21
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-B6fo0gSk.js +120 -0
- package/dist/Type-B6fo0gSk.js.map +1 -0
- package/dist/Type-oFwUfkZv.cjs +131 -0
- package/dist/Type-oFwUfkZv.cjs.map +1 -0
- package/dist/builderTs-Cd3juc2G.cjs +120 -0
- package/dist/builderTs-Cd3juc2G.cjs.map +1 -0
- package/dist/builderTs-DausqHpc.js +116 -0
- package/dist/builderTs-DausqHpc.js.map +1 -0
- package/dist/builders.cjs +3 -0
- package/dist/builders.d.ts +8 -0
- package/dist/builders.js +2 -0
- package/dist/casing-BJHFg-zZ.js +84 -0
- package/dist/casing-BJHFg-zZ.js.map +1 -0
- package/dist/casing-DHfdqpLi.cjs +107 -0
- package/dist/casing-DHfdqpLi.cjs.map +1 -0
- package/dist/chunk-ByKO4r7w.cjs +38 -0
- package/dist/components.cjs +3 -2
- package/dist/components.d.ts +40 -11
- package/dist/components.js +2 -2
- package/dist/generators-ByK18qUn.js +551 -0
- package/dist/generators-ByK18qUn.js.map +1 -0
- package/dist/generators-aSsiTfUO.cjs +563 -0
- package/dist/generators-aSsiTfUO.cjs.map +1 -0
- package/dist/generators.cjs +3 -2
- package/dist/generators.d.ts +7 -492
- package/dist/generators.js +2 -2
- package/dist/index.cjs +148 -3
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +146 -1
- package/dist/index.js.map +1 -0
- package/dist/printerTs-BgZucv4T.js +559 -0
- package/dist/printerTs-BgZucv4T.js.map +1 -0
- package/dist/printerTs-CFXc_LpP.cjs +595 -0
- package/dist/printerTs-CFXc_LpP.cjs.map +1 -0
- package/dist/printers.cjs +3 -0
- package/dist/printers.d.ts +75 -0
- package/dist/printers.js +2 -0
- package/dist/resolverTsLegacy-DLl854-P.js +185 -0
- package/dist/resolverTsLegacy-DLl854-P.js.map +1 -0
- package/dist/resolverTsLegacy-sJ16Iqrl.cjs +196 -0
- package/dist/resolverTsLegacy-sJ16Iqrl.cjs.map +1 -0
- package/dist/resolvers.cjs +4 -0
- package/dist/resolvers.d.ts +52 -0
- package/dist/resolvers.js +2 -0
- package/dist/types-BcyuFDn9.d.ts +344 -0
- package/package.json +27 -8
- package/src/builders/builderTs.ts +92 -0
- package/src/builders/index.ts +1 -0
- package/src/components/Enum.tsx +83 -0
- package/src/components/Type.tsx +24 -145
- package/src/components/index.ts +1 -0
- package/src/constants.ts +29 -0
- package/src/factory.ts +14 -48
- package/src/generators/index.ts +1 -0
- package/src/generators/typeGenerator.tsx +119 -403
- package/src/generators/typeGeneratorLegacy.tsx +345 -0
- package/src/plugin.ts +80 -122
- package/src/presets.ts +26 -0
- package/src/printers/index.ts +1 -0
- package/src/printers/printerTs.ts +389 -0
- package/src/resolvers/index.ts +2 -0
- package/src/resolvers/resolverTs.ts +107 -0
- package/src/resolvers/resolverTsLegacy.ts +87 -0
- package/src/types.ts +261 -72
- package/dist/components-9wydyqUx.cjs +0 -848
- package/dist/components-9wydyqUx.cjs.map +0 -1
- package/dist/components-LmqJfxMv.js +0 -721
- package/dist/components-LmqJfxMv.js.map +0 -1
- package/dist/plugin-CNkzbtpl.cjs +0 -508
- package/dist/plugin-CNkzbtpl.cjs.map +0 -1
- package/dist/plugin-DoLrDl9P.js +0 -476
- package/dist/plugin-DoLrDl9P.js.map +0 -1
- package/dist/types-BpeKGgCn.d.ts +0 -170
- package/src/parser.ts +0 -396
- package/src/printer.ts +0 -221
|
@@ -0,0 +1,345 @@
|
|
|
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, 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
|
+
enumKeyCasing={enumKeyCasing}
|
|
203
|
+
optionalType={optionalType}
|
|
204
|
+
arrayType={arrayType}
|
|
205
|
+
syntaxType={syntaxType}
|
|
206
|
+
resolver={resolver}
|
|
207
|
+
keysToOmit={keysToOmit}
|
|
208
|
+
/>
|
|
209
|
+
</>
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const pathParams = params.filter((p) => p.in === 'path')
|
|
214
|
+
const queryParams = params.filter((p) => p.in === 'query')
|
|
215
|
+
const headerParams = params.filter((p) => p.in === 'header')
|
|
216
|
+
|
|
217
|
+
const responseTypes = node.responses.map((res) => {
|
|
218
|
+
const responseName = resolver.resolveResponseStatusName(node, res.statusCode)
|
|
219
|
+
const baseResponseName = resolverTsLegacy.resolveResponseStatusName(node, res.statusCode)
|
|
220
|
+
|
|
221
|
+
return renderSchemaType({
|
|
222
|
+
node: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
|
|
223
|
+
name: responseName,
|
|
224
|
+
typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
|
|
225
|
+
description: res.description,
|
|
226
|
+
keysToOmit: res.keysToOmit,
|
|
227
|
+
})
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
const requestType = node.requestBody?.schema
|
|
231
|
+
? renderSchemaType({
|
|
232
|
+
node: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
|
|
233
|
+
name: resolver.resolveDataName(node),
|
|
234
|
+
typedName: resolver.resolveDataTypedName(node),
|
|
235
|
+
description: node.requestBody.description ?? node.requestBody.schema.description,
|
|
236
|
+
keysToOmit: node.requestBody.keysToOmit,
|
|
237
|
+
})
|
|
238
|
+
: null
|
|
239
|
+
|
|
240
|
+
const legacyParamTypes = [
|
|
241
|
+
pathParams.length > 0
|
|
242
|
+
? renderSchemaType({
|
|
243
|
+
node: buildGroupedParamsSchema({ params: pathParams, parentName: resolverTsLegacy.resolvePathParamsName!(node) }),
|
|
244
|
+
name: resolver.resolvePathParamsName!(node),
|
|
245
|
+
typedName: resolver.resolvePathParamsTypedName!(node),
|
|
246
|
+
})
|
|
247
|
+
: null,
|
|
248
|
+
queryParams.length > 0
|
|
249
|
+
? renderSchemaType({
|
|
250
|
+
node: buildGroupedParamsSchema({ params: queryParams, parentName: resolverTsLegacy.resolveQueryParamsName!(node) }),
|
|
251
|
+
name: resolver.resolveQueryParamsName!(node),
|
|
252
|
+
typedName: resolver.resolveQueryParamsTypedName!(node),
|
|
253
|
+
})
|
|
254
|
+
: null,
|
|
255
|
+
headerParams.length > 0
|
|
256
|
+
? renderSchemaType({
|
|
257
|
+
node: buildGroupedParamsSchema({ params: headerParams, parentName: resolverTsLegacy.resolveHeaderParamsName!(node) }),
|
|
258
|
+
name: resolver.resolveHeaderParamsName!(node),
|
|
259
|
+
typedName: resolver.resolveHeaderParamsTypedName!(node),
|
|
260
|
+
})
|
|
261
|
+
: null,
|
|
262
|
+
]
|
|
263
|
+
|
|
264
|
+
const legacyResponsesType = renderSchemaType({
|
|
265
|
+
node: buildLegacyResponsesSchemaNode({ node, resolver }),
|
|
266
|
+
name: resolver.resolveResponsesName(node),
|
|
267
|
+
typedName: resolver.resolveResponsesTypedName(node),
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
const legacyResponseType = renderSchemaType({
|
|
271
|
+
node: buildLegacyResponseUnionSchemaNode({ node, resolver }),
|
|
272
|
+
name: resolver.resolveResponseName(node),
|
|
273
|
+
typedName: resolver.resolveResponseTypedName(node),
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
return (
|
|
277
|
+
<File
|
|
278
|
+
baseName={file.baseName}
|
|
279
|
+
path={file.path}
|
|
280
|
+
meta={file.meta}
|
|
281
|
+
banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
|
|
282
|
+
footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
|
|
283
|
+
>
|
|
284
|
+
{legacyParamTypes}
|
|
285
|
+
{responseTypes}
|
|
286
|
+
{requestType}
|
|
287
|
+
{legacyResponseType}
|
|
288
|
+
{legacyResponsesType}
|
|
289
|
+
</File>
|
|
290
|
+
)
|
|
291
|
+
},
|
|
292
|
+
Schema({ node, adapter, options, config }) {
|
|
293
|
+
const { enumType, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, resolver, transformers = [] } = options
|
|
294
|
+
|
|
295
|
+
const root = path.resolve(config.root, config.output.path)
|
|
296
|
+
const mode = getMode(path.resolve(root, output.path))
|
|
297
|
+
|
|
298
|
+
if (!node.name) {
|
|
299
|
+
return
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const transformedNode = transform(node, composeTransformers(...transformers))
|
|
303
|
+
|
|
304
|
+
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
305
|
+
name: resolver.default(schemaName, 'type'),
|
|
306
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
307
|
+
}))
|
|
308
|
+
|
|
309
|
+
const isEnumSchema = !!narrowSchema(node, schemaTypes.enum)
|
|
310
|
+
|
|
311
|
+
const typedName = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyTypedName(node) : resolver.resolveTypedName(node.name)
|
|
312
|
+
|
|
313
|
+
const type = {
|
|
314
|
+
name: resolver.resolveName(node.name),
|
|
315
|
+
typedName,
|
|
316
|
+
file: resolver.resolveFile({ name: node.name, extname: '.ts' }, { root, output, group }),
|
|
317
|
+
} as const
|
|
318
|
+
|
|
319
|
+
return (
|
|
320
|
+
<File
|
|
321
|
+
baseName={type.file.baseName}
|
|
322
|
+
path={type.file.path}
|
|
323
|
+
meta={type.file.meta}
|
|
324
|
+
banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
|
|
325
|
+
footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
|
|
326
|
+
>
|
|
327
|
+
{mode === 'split' &&
|
|
328
|
+
imports.map((imp) => (
|
|
329
|
+
<File.Import key={[node.name, imp.path, imp.isTypeOnly].join('-')} root={type.file.path} path={imp.path} name={imp.name} isTypeOnly />
|
|
330
|
+
))}
|
|
331
|
+
<Type
|
|
332
|
+
name={type.name}
|
|
333
|
+
typedName={type.typedName}
|
|
334
|
+
node={transformedNode}
|
|
335
|
+
enumType={enumType}
|
|
336
|
+
enumKeyCasing={enumKeyCasing}
|
|
337
|
+
optionalType={optionalType}
|
|
338
|
+
arrayType={arrayType}
|
|
339
|
+
syntaxType={syntaxType}
|
|
340
|
+
resolver={resolver}
|
|
341
|
+
/>
|
|
342
|
+
</File>
|
|
343
|
+
)
|
|
344
|
+
},
|
|
345
|
+
})
|
package/src/plugin.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import { camelCase, pascalCase } from '@internals/utils'
|
|
3
2
|
import { walk } from '@kubb/ast'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { typeGenerator } from './generators'
|
|
3
|
+
import { createPlugin, getBarrelFiles, renderOperation, renderSchema } from '@kubb/core'
|
|
4
|
+
import { getPreset } from './presets.ts'
|
|
7
5
|
import type { PluginTs } from './types.ts'
|
|
8
6
|
|
|
9
7
|
export const pluginTsName = 'plugin-ts' satisfies PluginTs['name']
|
|
10
8
|
|
|
11
|
-
export const pluginTs =
|
|
9
|
+
export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
12
10
|
const {
|
|
13
11
|
output = { path: 'types', barrelType: 'named' },
|
|
14
12
|
group,
|
|
@@ -17,159 +15,119 @@ export const pluginTs = definePlugin<PluginTs>((options) => {
|
|
|
17
15
|
override = [],
|
|
18
16
|
enumType = 'asConst',
|
|
19
17
|
enumKeyCasing = 'none',
|
|
20
|
-
enumSuffix = 'enum',
|
|
21
|
-
dateType = 'string',
|
|
22
|
-
integerType = 'number',
|
|
23
|
-
unknownType = 'any',
|
|
24
18
|
optionalType = 'questionToken',
|
|
25
19
|
arrayType = 'array',
|
|
26
|
-
emptySchemaType = unknownType,
|
|
27
20
|
syntaxType = 'type',
|
|
28
|
-
transformers = {},
|
|
29
|
-
mapper = {},
|
|
30
21
|
paramsCasing,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
compatibilityPreset = 'default',
|
|
23
|
+
resolvers: userResolvers = [],
|
|
24
|
+
transformers: userTransformers = [],
|
|
25
|
+
generators: userGenerators = [],
|
|
34
26
|
} = options
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
const { resolver, transformers, generators } = getPreset(compatibilityPreset, {
|
|
29
|
+
resolvers: userResolvers,
|
|
30
|
+
transformers: userTransformers,
|
|
31
|
+
generators: userGenerators,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
let resolveNameWarning = false
|
|
35
|
+
let resolvePathWarning = false
|
|
38
36
|
|
|
39
37
|
return {
|
|
40
38
|
name: pluginTsName,
|
|
41
39
|
options: {
|
|
42
40
|
output,
|
|
43
|
-
transformers,
|
|
44
|
-
dateType,
|
|
45
|
-
integerType,
|
|
46
41
|
optionalType,
|
|
42
|
+
group,
|
|
47
43
|
arrayType,
|
|
48
44
|
enumType,
|
|
49
45
|
enumKeyCasing,
|
|
50
|
-
enumSuffix,
|
|
51
|
-
unknownType,
|
|
52
|
-
emptySchemaType,
|
|
53
46
|
syntaxType,
|
|
54
|
-
group,
|
|
55
|
-
override,
|
|
56
|
-
mapper,
|
|
57
47
|
paramsCasing,
|
|
58
|
-
|
|
48
|
+
resolver,
|
|
49
|
+
transformers,
|
|
59
50
|
},
|
|
60
|
-
pre: [pluginOasName],
|
|
61
51
|
resolvePath(baseName, pathMode, options) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (mode === 'single') {
|
|
66
|
-
/**
|
|
67
|
-
* when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
|
|
68
|
-
* Other plugins then need to call addOrAppend instead of just add from the fileManager class
|
|
69
|
-
*/
|
|
70
|
-
return path.resolve(root, output.path)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (group && (options?.group?.path || options?.group?.tag)) {
|
|
74
|
-
const groupName: Group['name'] = group?.name
|
|
75
|
-
? group.name
|
|
76
|
-
: (ctx) => {
|
|
77
|
-
if (group?.type === 'path') {
|
|
78
|
-
return `${ctx.group.split('/')[1]}`
|
|
79
|
-
}
|
|
80
|
-
return `${camelCase(ctx.group)}Controller`
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return path.resolve(
|
|
84
|
-
root,
|
|
85
|
-
output.path,
|
|
86
|
-
groupName({
|
|
87
|
-
group: group.type === 'path' ? options.group.path! : options.group.tag!,
|
|
88
|
-
}),
|
|
89
|
-
baseName,
|
|
90
|
-
)
|
|
52
|
+
if (!resolvePathWarning) {
|
|
53
|
+
this.driver.events.emit('warn', 'Do not use resolvePath for pluginTs, use resolverTs.resolvePath instead')
|
|
54
|
+
resolvePathWarning = true
|
|
91
55
|
}
|
|
92
56
|
|
|
93
|
-
return
|
|
57
|
+
return resolver.resolvePath(
|
|
58
|
+
{ baseName, pathMode, tag: options?.group?.tag, path: options?.group?.path },
|
|
59
|
+
{ root: path.resolve(this.config.root, this.config.output.path), output, group },
|
|
60
|
+
)
|
|
94
61
|
},
|
|
95
62
|
resolveName(name, type) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return transformers?.name?.(resolvedName, type) || resolvedName
|
|
63
|
+
if (!resolveNameWarning) {
|
|
64
|
+
this.driver.events.emit('warn', 'Do not use resolveName for pluginTs, use resolverTs.default instead')
|
|
65
|
+
resolveNameWarning = true
|
|
100
66
|
}
|
|
101
67
|
|
|
102
|
-
return
|
|
68
|
+
return resolver.default(name, type)
|
|
103
69
|
},
|
|
104
70
|
async install() {
|
|
105
|
-
const { config, fabric, plugin } = this
|
|
71
|
+
const { config, fabric, plugin, adapter, rootNode, driver, openInStudio } = this
|
|
106
72
|
|
|
107
73
|
const root = path.resolve(config.root, config.output.path)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
74
|
+
|
|
75
|
+
if (!adapter) {
|
|
76
|
+
throw new Error('Plugin cannot work without adapter being set')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
await openInStudio({ ast: true })
|
|
80
|
+
|
|
81
|
+
await walk(rootNode, {
|
|
82
|
+
depth: 'shallow',
|
|
83
|
+
async schema(schemaNode) {
|
|
84
|
+
const writeTasks = generators.map(async (generator) => {
|
|
85
|
+
if (generator.type === 'react' && generator.version === '2') {
|
|
86
|
+
const options = resolver.resolveOptions(schemaNode, { options: plugin.options, exclude, include, override })
|
|
87
|
+
|
|
88
|
+
if (options === null) {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await renderSchema(schemaNode, {
|
|
93
|
+
options,
|
|
94
|
+
adapter,
|
|
95
|
+
config,
|
|
96
|
+
fabric,
|
|
97
|
+
Component: generator.Schema,
|
|
98
|
+
plugin,
|
|
99
|
+
driver,
|
|
127
100
|
})
|
|
101
|
+
}
|
|
102
|
+
})
|
|
128
103
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
104
|
+
await Promise.all(writeTasks)
|
|
105
|
+
},
|
|
106
|
+
async operation(operationNode) {
|
|
107
|
+
const writeTasks = generators.map(async (generator) => {
|
|
108
|
+
if (generator.type === 'react' && generator.version === '2') {
|
|
109
|
+
const options = resolver.resolveOptions(operationNode, { options: plugin.options, exclude, include, override })
|
|
134
110
|
|
|
135
|
-
|
|
136
|
-
|
|
111
|
+
if (options === null) {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
137
114
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
mode,
|
|
150
|
-
output: output.path,
|
|
151
|
-
})
|
|
115
|
+
await renderOperation(operationNode, {
|
|
116
|
+
options,
|
|
117
|
+
adapter,
|
|
118
|
+
config,
|
|
119
|
+
fabric,
|
|
120
|
+
Component: generator.Operation,
|
|
121
|
+
plugin,
|
|
122
|
+
driver,
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
})
|
|
152
126
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const operationGenerator = new OperationGenerator(this.plugin.options, {
|
|
157
|
-
fabric: this.fabric,
|
|
158
|
-
oas,
|
|
159
|
-
pluginManager: this.pluginManager,
|
|
160
|
-
events: this.events,
|
|
161
|
-
plugin: this.plugin,
|
|
162
|
-
contentType,
|
|
163
|
-
exclude,
|
|
164
|
-
include,
|
|
165
|
-
override,
|
|
166
|
-
mode,
|
|
167
|
-
UNSTABLE_NAMING,
|
|
127
|
+
await Promise.all(writeTasks)
|
|
128
|
+
},
|
|
168
129
|
})
|
|
169
130
|
|
|
170
|
-
const operationFiles = await operationGenerator.build(...generators)
|
|
171
|
-
await this.upsertFile(...operationFiles)
|
|
172
|
-
|
|
173
131
|
const barrelFiles = await getBarrelFiles(this.fabric.files, {
|
|
174
132
|
type: output.barrelType ?? 'named',
|
|
175
133
|
root,
|
package/src/presets.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Visitor } from '@kubb/ast/types'
|
|
2
|
+
import { type CompatibilityPreset, definePreset, definePresets, type Generator, getPreset as getCorePreset } from '@kubb/core'
|
|
3
|
+
import { typeGenerator, typeGeneratorLegacy } from './generators/index.ts'
|
|
4
|
+
import { resolverTs, resolverTsLegacy } from './resolvers/index.ts'
|
|
5
|
+
import type { PluginTs, ResolverTs } from './types.ts'
|
|
6
|
+
|
|
7
|
+
export const presets = definePresets<ResolverTs>({
|
|
8
|
+
default: definePreset('default', { resolvers: [resolverTs], generators: [typeGenerator] }),
|
|
9
|
+
kubbV4: definePreset('kubbV4', { resolvers: [resolverTsLegacy], generators: [typeGeneratorLegacy] }),
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
type GetPresetOptions = {
|
|
13
|
+
resolvers: Array<ResolverTs>
|
|
14
|
+
transformers: Array<Visitor>
|
|
15
|
+
generators: Array<Generator<PluginTs>>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getPreset(preset: CompatibilityPreset, { resolvers, transformers, generators }: GetPresetOptions) {
|
|
19
|
+
return getCorePreset({
|
|
20
|
+
preset,
|
|
21
|
+
presets,
|
|
22
|
+
resolvers: [resolverTs, ...(resolvers ?? [])],
|
|
23
|
+
transformers,
|
|
24
|
+
generators,
|
|
25
|
+
})
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { printerTs } from './printerTs.ts'
|