@kubb/plugin-ts 5.0.0-alpha.22 → 5.0.0-alpha.23
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 +1668 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +466 -4
- package/dist/index.js +1641 -52
- package/dist/index.js.map +1 -1
- package/package.json +3 -42
- package/src/components/Enum.tsx +1 -1
- package/src/components/Type.tsx +3 -5
- package/src/generators/typeGenerator.tsx +10 -22
- package/src/generators/typeGeneratorLegacy.tsx +28 -38
- package/src/index.ts +13 -1
- package/src/plugin.ts +42 -23
- package/src/presets.ts +16 -34
- package/src/printers/functionPrinter.ts +194 -0
- package/src/printers/printerTs.ts +6 -6
- package/src/resolvers/resolverTs.ts +10 -47
- package/src/resolvers/resolverTsLegacy.ts +4 -31
- package/src/types.ts +85 -225
- package/src/utils.ts +103 -0
- package/dist/Type-Bf8raoQX.cjs +0 -124
- package/dist/Type-Bf8raoQX.cjs.map +0 -1
- package/dist/Type-BpXxT4l_.js +0 -113
- package/dist/Type-BpXxT4l_.js.map +0 -1
- package/dist/builderTs-COUg3xtQ.cjs +0 -135
- package/dist/builderTs-COUg3xtQ.cjs.map +0 -1
- package/dist/builderTs-DPpkJKd1.js +0 -131
- package/dist/builderTs-DPpkJKd1.js.map +0 -1
- package/dist/builders.cjs +0 -3
- package/dist/builders.d.ts +0 -23
- package/dist/builders.js +0 -2
- package/dist/casing-BJHFg-zZ.js +0 -84
- package/dist/casing-BJHFg-zZ.js.map +0 -1
- package/dist/casing-DHfdqpLi.cjs +0 -107
- package/dist/casing-DHfdqpLi.cjs.map +0 -1
- package/dist/chunk-ByKO4r7w.cjs +0 -38
- package/dist/components.cjs +0 -4
- package/dist/components.d.ts +0 -71
- package/dist/components.js +0 -2
- package/dist/generators-DFDut8o-.js +0 -555
- package/dist/generators-DFDut8o-.js.map +0 -1
- package/dist/generators-DKd7MYbx.cjs +0 -567
- package/dist/generators-DKd7MYbx.cjs.map +0 -1
- package/dist/generators.cjs +0 -4
- package/dist/generators.d.ts +0 -12
- package/dist/generators.js +0 -2
- package/dist/printerTs-BcHudagv.cjs +0 -594
- package/dist/printerTs-BcHudagv.cjs.map +0 -1
- package/dist/printerTs-CMBCOuqd.js +0 -558
- package/dist/printerTs-CMBCOuqd.js.map +0 -1
- package/dist/printers.cjs +0 -3
- package/dist/printers.d.ts +0 -81
- package/dist/printers.js +0 -2
- package/dist/resolverTsLegacy-CPiqqsO6.js +0 -185
- package/dist/resolverTsLegacy-CPiqqsO6.js.map +0 -1
- package/dist/resolverTsLegacy-CuR9XbKk.cjs +0 -196
- package/dist/resolverTsLegacy-CuR9XbKk.cjs.map +0 -1
- package/dist/resolvers.cjs +0 -4
- package/dist/resolvers.d.ts +0 -52
- package/dist/resolvers.js +0 -2
- package/dist/types-CRtcZOCz.d.ts +0 -374
- package/src/builders/builderTs.ts +0 -107
- package/src/builders/index.ts +0 -1
- package/src/components/index.ts +0 -2
- package/src/generators/index.ts +0 -2
- package/src/printers/index.ts +0 -1
- package/src/resolvers/index.ts +0 -2
|
@@ -47,20 +47,20 @@ function buildLegacyResponsesSchemaNode({ node, resolver }: BuildOperationSchema
|
|
|
47
47
|
const responseSchema =
|
|
48
48
|
successResponses.length > 0
|
|
49
49
|
? successResponses.length === 1
|
|
50
|
-
? createSchema({ type: 'ref', name: resolver.
|
|
50
|
+
? createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, successResponses[0]!.statusCode) })
|
|
51
51
|
: createSchema({
|
|
52
52
|
type: 'union',
|
|
53
|
-
members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.
|
|
53
|
+
members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, res.statusCode) })),
|
|
54
54
|
})
|
|
55
55
|
: createSchema({ type: 'any' })
|
|
56
56
|
|
|
57
57
|
const errorsSchema =
|
|
58
58
|
errorResponses.length > 0
|
|
59
59
|
? errorResponses.length === 1
|
|
60
|
-
? createSchema({ type: 'ref', name: resolver.
|
|
60
|
+
? createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, errorResponses[0]!.statusCode) })
|
|
61
61
|
: createSchema({
|
|
62
62
|
type: 'union',
|
|
63
|
-
members: errorResponses.map((res) => createSchema({ type: 'ref', name: resolver.
|
|
63
|
+
members: errorResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, res.statusCode) })),
|
|
64
64
|
})
|
|
65
65
|
: createSchema({ type: 'any' })
|
|
66
66
|
|
|
@@ -71,37 +71,40 @@ function buildLegacyResponsesSchemaNode({ node, resolver }: BuildOperationSchema
|
|
|
71
71
|
createProperty({
|
|
72
72
|
name: 'Request',
|
|
73
73
|
required: true,
|
|
74
|
-
schema: createSchema({ type: 'ref', name: resolver.
|
|
74
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveDataName(node) }),
|
|
75
75
|
}),
|
|
76
76
|
)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
const queryParam = node.parameters.find((p) => p.in === 'query')
|
|
80
|
+
if (queryParam) {
|
|
80
81
|
properties.push(
|
|
81
82
|
createProperty({
|
|
82
83
|
name: 'QueryParams',
|
|
83
84
|
required: true,
|
|
84
|
-
schema: createSchema({ type: 'ref', name: resolver.
|
|
85
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveQueryParamsName(node, queryParam) }),
|
|
85
86
|
}),
|
|
86
87
|
)
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
const pathParam = node.parameters.find((p) => p.in === 'path')
|
|
91
|
+
if (pathParam) {
|
|
90
92
|
properties.push(
|
|
91
93
|
createProperty({
|
|
92
94
|
name: 'PathParams',
|
|
93
95
|
required: true,
|
|
94
|
-
schema: createSchema({ type: 'ref', name: resolver.
|
|
96
|
+
schema: createSchema({ type: 'ref', name: resolver.resolvePathParamsName(node, pathParam) }),
|
|
95
97
|
}),
|
|
96
98
|
)
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
const headerParam = node.parameters.find((p) => p.in === 'header')
|
|
102
|
+
if (headerParam) {
|
|
100
103
|
properties.push(
|
|
101
104
|
createProperty({
|
|
102
105
|
name: 'HeaderParams',
|
|
103
106
|
required: true,
|
|
104
|
-
schema: createSchema({ type: 'ref', name: resolver.
|
|
107
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveHeaderParamsName(node, headerParam) }),
|
|
105
108
|
}),
|
|
106
109
|
)
|
|
107
110
|
}
|
|
@@ -122,12 +125,12 @@ function buildLegacyResponseUnionSchemaNode({ node, resolver }: BuildOperationSc
|
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
if (successResponses.length === 1) {
|
|
125
|
-
return createSchema({ type: 'ref', name: resolver.
|
|
128
|
+
return createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, successResponses[0]!.statusCode) })
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
return createSchema({
|
|
129
132
|
type: 'union',
|
|
130
|
-
members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.
|
|
133
|
+
members: successResponses.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, res.statusCode) })),
|
|
131
134
|
})
|
|
132
135
|
}
|
|
133
136
|
|
|
@@ -156,8 +159,8 @@ function nameUnnamedEnums(node: SchemaNode, parentName: string): SchemaNode {
|
|
|
156
159
|
export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
157
160
|
name: 'typescript-legacy',
|
|
158
161
|
type: 'react',
|
|
159
|
-
Operation({ node, adapter, options, config }) {
|
|
160
|
-
const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output,
|
|
162
|
+
Operation({ node, adapter, options, config, resolver }) {
|
|
163
|
+
const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, transformers = [] } = options
|
|
161
164
|
|
|
162
165
|
const root = path.resolve(config.root, config.output.path)
|
|
163
166
|
const mode = getMode(path.resolve(root, output.path))
|
|
@@ -168,13 +171,11 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
168
171
|
function renderSchemaType({
|
|
169
172
|
node: schemaNode,
|
|
170
173
|
name,
|
|
171
|
-
typedName,
|
|
172
174
|
description,
|
|
173
175
|
keysToOmit,
|
|
174
176
|
}: {
|
|
175
177
|
node: SchemaNode | null
|
|
176
178
|
name: string
|
|
177
|
-
typedName: string
|
|
178
179
|
description?: string
|
|
179
180
|
keysToOmit?: Array<string>
|
|
180
181
|
}) {
|
|
@@ -195,7 +196,6 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
195
196
|
imports.map((imp) => <File.Import key={[name, imp.path, imp.isTypeOnly].join('-')} root={file.path} path={imp.path} name={imp.name} isTypeOnly />)}
|
|
196
197
|
<Type
|
|
197
198
|
name={name}
|
|
198
|
-
typedName={typedName}
|
|
199
199
|
node={transformedNode}
|
|
200
200
|
description={description}
|
|
201
201
|
enumType={enumType}
|
|
@@ -222,7 +222,6 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
222
222
|
return renderSchemaType({
|
|
223
223
|
node: res.schema ? nameUnnamedEnums(res.schema, baseResponseName) : res.schema,
|
|
224
224
|
name: responseName,
|
|
225
|
-
typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
|
|
226
225
|
description: res.description,
|
|
227
226
|
keysToOmit: res.keysToOmit,
|
|
228
227
|
})
|
|
@@ -232,7 +231,6 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
232
231
|
? renderSchemaType({
|
|
233
232
|
node: nameUnnamedEnums(node.requestBody.schema, resolverTsLegacy.resolveDataName(node)),
|
|
234
233
|
name: resolver.resolveDataName(node),
|
|
235
|
-
typedName: resolver.resolveDataTypedName(node),
|
|
236
234
|
description: node.requestBody.description ?? node.requestBody.schema.description,
|
|
237
235
|
keysToOmit: node.requestBody.keysToOmit,
|
|
238
236
|
})
|
|
@@ -241,23 +239,20 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
241
239
|
const legacyParamTypes = [
|
|
242
240
|
pathParams.length > 0
|
|
243
241
|
? renderSchemaType({
|
|
244
|
-
node: buildGroupedParamsSchema({ params: pathParams, parentName: resolverTsLegacy.resolvePathParamsName
|
|
245
|
-
name: resolver.resolvePathParamsName
|
|
246
|
-
typedName: resolver.resolvePathParamsTypedName!(node),
|
|
242
|
+
node: buildGroupedParamsSchema({ params: pathParams, parentName: resolverTsLegacy.resolvePathParamsName(node, pathParams[0]!) }),
|
|
243
|
+
name: resolver.resolvePathParamsName(node, pathParams[0]!),
|
|
247
244
|
})
|
|
248
245
|
: null,
|
|
249
246
|
queryParams.length > 0
|
|
250
247
|
? renderSchemaType({
|
|
251
|
-
node: buildGroupedParamsSchema({ params: queryParams, parentName: resolverTsLegacy.resolveQueryParamsName
|
|
252
|
-
name: resolver.resolveQueryParamsName
|
|
253
|
-
typedName: resolver.resolveQueryParamsTypedName!(node),
|
|
248
|
+
node: buildGroupedParamsSchema({ params: queryParams, parentName: resolverTsLegacy.resolveQueryParamsName(node, queryParams[0]!) }),
|
|
249
|
+
name: resolver.resolveQueryParamsName(node, queryParams[0]!),
|
|
254
250
|
})
|
|
255
251
|
: null,
|
|
256
252
|
headerParams.length > 0
|
|
257
253
|
? renderSchemaType({
|
|
258
|
-
node: buildGroupedParamsSchema({ params: headerParams, parentName: resolverTsLegacy.resolveHeaderParamsName
|
|
259
|
-
name: resolver.resolveHeaderParamsName
|
|
260
|
-
typedName: resolver.resolveHeaderParamsTypedName!(node),
|
|
254
|
+
node: buildGroupedParamsSchema({ params: headerParams, parentName: resolverTsLegacy.resolveHeaderParamsName(node, headerParams[0]!) }),
|
|
255
|
+
name: resolver.resolveHeaderParamsName(node, headerParams[0]!),
|
|
261
256
|
})
|
|
262
257
|
: null,
|
|
263
258
|
]
|
|
@@ -265,13 +260,11 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
265
260
|
const legacyResponsesType = renderSchemaType({
|
|
266
261
|
node: buildLegacyResponsesSchemaNode({ node, resolver }),
|
|
267
262
|
name: resolver.resolveResponsesName(node),
|
|
268
|
-
typedName: resolver.resolveResponsesTypedName(node),
|
|
269
263
|
})
|
|
270
264
|
|
|
271
265
|
const legacyResponseType = renderSchemaType({
|
|
272
266
|
node: buildLegacyResponseUnionSchemaNode({ node, resolver }),
|
|
273
267
|
name: resolver.resolveResponseName(node),
|
|
274
|
-
typedName: resolver.resolveResponseTypedName(node),
|
|
275
268
|
})
|
|
276
269
|
|
|
277
270
|
return (
|
|
@@ -290,8 +283,8 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
290
283
|
</File>
|
|
291
284
|
)
|
|
292
285
|
},
|
|
293
|
-
Schema({ node, adapter, options, config }) {
|
|
294
|
-
const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group,
|
|
286
|
+
Schema({ node, adapter, options, config, resolver }) {
|
|
287
|
+
const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, transformers = [] } = options
|
|
295
288
|
|
|
296
289
|
const root = path.resolve(config.root, config.output.path)
|
|
297
290
|
const mode = getMode(path.resolve(root, output.path))
|
|
@@ -309,12 +302,10 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
309
302
|
|
|
310
303
|
const isEnumSchema = !!narrowSchema(node, schemaTypes.enum)
|
|
311
304
|
|
|
312
|
-
const
|
|
313
|
-
ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyTypedName(node, enumTypeSuffix) : resolver.resolveTypedName(node.name)
|
|
305
|
+
const name = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyName(node, enumTypeSuffix) : resolver.resolveName(node.name)
|
|
314
306
|
|
|
315
307
|
const type = {
|
|
316
|
-
name
|
|
317
|
-
typedName,
|
|
308
|
+
name,
|
|
318
309
|
file: resolver.resolveFile({ name: node.name, extname: '.ts' }, { root, output, group }),
|
|
319
310
|
} as const
|
|
320
311
|
|
|
@@ -332,7 +323,6 @@ export const typeGeneratorLegacy = defineGenerator<PluginTs>({
|
|
|
332
323
|
))}
|
|
333
324
|
<Type
|
|
334
325
|
name={type.name}
|
|
335
|
-
typedName={type.typedName}
|
|
336
326
|
node={transformedNode}
|
|
337
327
|
enumType={enumType}
|
|
338
328
|
enumTypeSuffix={enumTypeSuffix}
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
+
export { Enum } from './components/Enum.tsx'
|
|
2
|
+
export { Type } from './components/Type.tsx'
|
|
3
|
+
|
|
4
|
+
export { typeGenerator } from './generators/typeGenerator.tsx'
|
|
5
|
+
|
|
1
6
|
export { pluginTs, pluginTsName } from './plugin.ts'
|
|
2
|
-
|
|
7
|
+
|
|
8
|
+
export { functionPrinter } from './printers/functionPrinter.ts'
|
|
9
|
+
export { printerTs } from './printers/printerTs.ts'
|
|
10
|
+
|
|
11
|
+
export { resolverTs } from './resolvers/resolverTs.ts'
|
|
12
|
+
export { resolverTsLegacy } from './resolvers/resolverTsLegacy.ts'
|
|
13
|
+
|
|
14
|
+
export type { PluginTs, ResolverTs } from './types.ts'
|
package/src/plugin.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import { camelCase } from '@internals/utils'
|
|
2
3
|
import { walk } from '@kubb/ast'
|
|
3
|
-
import { createPlugin, getBarrelFiles, renderOperation, renderSchema } from '@kubb/core'
|
|
4
|
-
import {
|
|
4
|
+
import { createPlugin, type Group, getBarrelFiles, getPreset, renderOperation, renderSchema } from '@kubb/core'
|
|
5
|
+
import { presets } from './presets.ts'
|
|
5
6
|
import type { PluginTs } from './types.ts'
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -45,7 +46,9 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
45
46
|
generators: userGenerators = [],
|
|
46
47
|
} = options
|
|
47
48
|
|
|
48
|
-
const
|
|
49
|
+
const preset = getPreset({
|
|
50
|
+
preset: compatibilityPreset,
|
|
51
|
+
presets: presets,
|
|
49
52
|
resolvers: userResolvers,
|
|
50
53
|
transformers: userTransformers,
|
|
51
54
|
generators: userGenerators,
|
|
@@ -56,40 +59,54 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
56
59
|
|
|
57
60
|
return {
|
|
58
61
|
name: pluginTsName,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
get resolver() {
|
|
63
|
+
return preset.resolver
|
|
64
|
+
},
|
|
65
|
+
get options() {
|
|
66
|
+
return {
|
|
67
|
+
output,
|
|
68
|
+
optionalType,
|
|
69
|
+
group: group
|
|
70
|
+
? ({
|
|
71
|
+
...options.group,
|
|
72
|
+
name: (ctx) => {
|
|
73
|
+
if (options.group?.type === 'path') {
|
|
74
|
+
return `${ctx.group.split('/')[1]}`
|
|
75
|
+
}
|
|
76
|
+
return `${camelCase(ctx.group)}Controller`
|
|
77
|
+
},
|
|
78
|
+
} as Group)
|
|
79
|
+
: undefined,
|
|
80
|
+
arrayType,
|
|
81
|
+
enumType,
|
|
82
|
+
enumTypeSuffix,
|
|
83
|
+
enumKeyCasing,
|
|
84
|
+
syntaxType,
|
|
85
|
+
paramsCasing,
|
|
86
|
+
transformers: preset.transformers,
|
|
87
|
+
}
|
|
71
88
|
},
|
|
72
89
|
resolvePath(baseName, pathMode, options) {
|
|
73
90
|
if (!resolvePathWarning) {
|
|
74
|
-
this.
|
|
91
|
+
this.events.emit('warn', 'Do not use resolvePath for pluginTs, use resolverTs.resolvePath instead')
|
|
75
92
|
resolvePathWarning = true
|
|
76
93
|
}
|
|
77
94
|
|
|
78
|
-
return resolver.resolvePath(
|
|
95
|
+
return this.plugin.resolver.resolvePath(
|
|
79
96
|
{ baseName, pathMode, tag: options?.group?.tag, path: options?.group?.path },
|
|
80
|
-
{ root: path.resolve(this.config.root, this.config.output.path), output, group },
|
|
97
|
+
{ root: path.resolve(this.config.root, this.config.output.path), output, group: this.plugin.options.group },
|
|
81
98
|
)
|
|
82
99
|
},
|
|
83
100
|
resolveName(name, type) {
|
|
84
101
|
if (!resolveNameWarning) {
|
|
85
|
-
this.
|
|
102
|
+
this.events.emit('warn', 'Do not use resolveName for pluginTs, use resolverTs.default instead')
|
|
86
103
|
resolveNameWarning = true
|
|
87
104
|
}
|
|
88
105
|
|
|
89
|
-
return resolver.default(name, type)
|
|
106
|
+
return this.plugin.resolver.default(name, type)
|
|
90
107
|
},
|
|
91
108
|
async install() {
|
|
92
|
-
const { config, fabric, plugin, adapter, rootNode, driver, openInStudio } = this
|
|
109
|
+
const { config, fabric, plugin, adapter, rootNode, driver, openInStudio, resolver } = this
|
|
93
110
|
|
|
94
111
|
const root = path.resolve(config.root, config.output.path)
|
|
95
112
|
|
|
@@ -102,7 +119,7 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
102
119
|
await walk(rootNode, {
|
|
103
120
|
depth: 'shallow',
|
|
104
121
|
async schema(schemaNode) {
|
|
105
|
-
const writeTasks = generators.map(async (generator) => {
|
|
122
|
+
const writeTasks = preset.generators.map(async (generator) => {
|
|
106
123
|
if (generator.type === 'react' && generator.version === '2') {
|
|
107
124
|
const options = resolver.resolveOptions(schemaNode, { options: plugin.options, exclude, include, override })
|
|
108
125
|
|
|
@@ -112,6 +129,7 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
112
129
|
|
|
113
130
|
await renderSchema(schemaNode, {
|
|
114
131
|
options,
|
|
132
|
+
resolver,
|
|
115
133
|
adapter,
|
|
116
134
|
config,
|
|
117
135
|
fabric,
|
|
@@ -125,7 +143,7 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
125
143
|
await Promise.all(writeTasks)
|
|
126
144
|
},
|
|
127
145
|
async operation(operationNode) {
|
|
128
|
-
const writeTasks = generators.map(async (generator) => {
|
|
146
|
+
const writeTasks = preset.generators.map(async (generator) => {
|
|
129
147
|
if (generator.type === 'react' && generator.version === '2') {
|
|
130
148
|
const options = resolver.resolveOptions(operationNode, { options: plugin.options, exclude, include, override })
|
|
131
149
|
|
|
@@ -135,6 +153,7 @@ export const pluginTs = createPlugin<PluginTs>((options) => {
|
|
|
135
153
|
|
|
136
154
|
await renderOperation(operationNode, {
|
|
137
155
|
options,
|
|
156
|
+
resolver,
|
|
138
157
|
adapter,
|
|
139
158
|
config,
|
|
140
159
|
fabric,
|
package/src/presets.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { resolverTs
|
|
5
|
-
import
|
|
1
|
+
import { definePresets } from '@kubb/core'
|
|
2
|
+
import { typeGenerator } from './generators/typeGenerator.tsx'
|
|
3
|
+
import { typeGeneratorLegacy } from './generators/typeGeneratorLegacy.tsx'
|
|
4
|
+
import { resolverTs } from './resolvers/resolverTs.ts'
|
|
5
|
+
import { resolverTsLegacy } from './resolvers/resolverTsLegacy.ts'
|
|
6
|
+
import type { ResolverTs } from './types.ts'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Built-in preset registry for `@kubb/plugin-ts`.
|
|
@@ -11,33 +12,14 @@ import type { PluginTs, ResolverTs } from './types.ts'
|
|
|
11
12
|
* - `kubbV4` — uses `resolverTsLegacy` and `typeGeneratorLegacy` (Kubb v4 naming conventions).
|
|
12
13
|
*/
|
|
13
14
|
export const presets = definePresets<ResolverTs>({
|
|
14
|
-
default:
|
|
15
|
-
|
|
15
|
+
default: {
|
|
16
|
+
name: 'default',
|
|
17
|
+
resolvers: [resolverTs],
|
|
18
|
+
generators: [typeGenerator],
|
|
19
|
+
},
|
|
20
|
+
kubbV4: {
|
|
21
|
+
name: 'kubbV4',
|
|
22
|
+
resolvers: [resolverTsLegacy],
|
|
23
|
+
generators: [typeGeneratorLegacy],
|
|
24
|
+
},
|
|
16
25
|
})
|
|
17
|
-
|
|
18
|
-
type GetPresetOptions = {
|
|
19
|
-
resolvers: Array<ResolverTs>
|
|
20
|
-
transformers: Array<Visitor>
|
|
21
|
-
generators: Array<Generator<PluginTs>>
|
|
22
|
-
}
|
|
23
|
-
|
|
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) {
|
|
36
|
-
return getCorePreset({
|
|
37
|
-
preset,
|
|
38
|
-
presets,
|
|
39
|
-
resolvers: [resolverTs, ...(resolvers ?? [])],
|
|
40
|
-
transformers,
|
|
41
|
-
generators,
|
|
42
|
-
})
|
|
43
|
-
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type { PrinterFactoryOptions } from '@kubb/ast'
|
|
2
|
+
import { createPrinterFactory } from '@kubb/ast'
|
|
3
|
+
import type { FunctionNode, FunctionNodeType, FunctionParameterNode, FunctionParametersNode, ParameterGroupNode, TypeNode } from '@kubb/ast/types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Maps each function-printer handler key to its concrete node type.
|
|
7
|
+
*/
|
|
8
|
+
export type FunctionNodeByType = {
|
|
9
|
+
functionParameter: FunctionParameterNode
|
|
10
|
+
parameterGroup: ParameterGroupNode
|
|
11
|
+
functionParameters: FunctionParametersNode
|
|
12
|
+
type: TypeNode
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const kindToHandlerKey = {
|
|
16
|
+
FunctionParameter: 'functionParameter',
|
|
17
|
+
ParameterGroup: 'parameterGroup',
|
|
18
|
+
FunctionParameters: 'functionParameters',
|
|
19
|
+
Type: 'type',
|
|
20
|
+
} satisfies Record<string, FunctionNodeType>
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Creates a function-parameter printer factory.
|
|
24
|
+
*
|
|
25
|
+
* Uses `createPrinterFactory` and dispatches handlers by `node.kind`
|
|
26
|
+
* (for function nodes) rather than by `node.type` (for schema nodes).
|
|
27
|
+
*/
|
|
28
|
+
export const defineFunctionPrinter = createPrinterFactory<FunctionNode, FunctionNodeType, FunctionNodeByType>((node) => kindToHandlerKey[node.kind])
|
|
29
|
+
|
|
30
|
+
export type FunctionPrinterOptions = {
|
|
31
|
+
/**
|
|
32
|
+
* Rendering modes supported by `functionPrinter`.
|
|
33
|
+
*
|
|
34
|
+
* | Mode | Output example | Use case |
|
|
35
|
+
* |---------------|---------------------------------------------|---------------------------------|
|
|
36
|
+
* | `declaration` | `id: string, config: Config = {}` | Function parameter declaration |
|
|
37
|
+
* | `call` | `id, { method, url }` | Function call arguments |
|
|
38
|
+
* | `keys` | `{ id, config }` | Key names only (destructuring) |
|
|
39
|
+
* | `values` | `{ id: id, config: config }` | Key/value object entries |
|
|
40
|
+
*/
|
|
41
|
+
mode: 'declaration' | 'call' | 'keys' | 'values'
|
|
42
|
+
/**
|
|
43
|
+
* Optional transformation applied to every parameter name before printing.
|
|
44
|
+
*/
|
|
45
|
+
transformName?: (name: string) => string
|
|
46
|
+
/**
|
|
47
|
+
* Optional transformation applied to every type string before printing.
|
|
48
|
+
*/
|
|
49
|
+
transformType?: (type: string) => string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type DefaultPrinter = PrinterFactoryOptions<'functionParameters', FunctionPrinterOptions, string>
|
|
53
|
+
|
|
54
|
+
function rank(param: FunctionParameterNode | ParameterGroupNode): number {
|
|
55
|
+
if (param.kind === 'ParameterGroup') {
|
|
56
|
+
if (param.default) return 2
|
|
57
|
+
const isOptional = param.optional ?? param.properties.every((p) => p.optional || p.default !== undefined)
|
|
58
|
+
return isOptional ? 1 : 0
|
|
59
|
+
}
|
|
60
|
+
if (param.rest) return 3
|
|
61
|
+
if (param.default) return 2
|
|
62
|
+
return param.optional ? 1 : 0
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function sortParams(params: ReadonlyArray<FunctionParameterNode | ParameterGroupNode>): Array<FunctionParameterNode | ParameterGroupNode> {
|
|
66
|
+
return [...params].sort((a, b) => rank(a) - rank(b))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function sortChildParams(params: Array<FunctionParameterNode>): Array<FunctionParameterNode> {
|
|
70
|
+
return [...params].sort((a, b) => rank(a) - rank(b))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Default function-signature printer.
|
|
75
|
+
* Covers the four standard output modes used across Kubb plugins.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* const printer = functionPrinter({ mode: 'declaration' })
|
|
80
|
+
*
|
|
81
|
+
* const sig = createFunctionParameters({
|
|
82
|
+
* params: [
|
|
83
|
+
* createFunctionParameter({ name: 'petId', type: 'string', optional: false }),
|
|
84
|
+
* createFunctionParameter({ name: 'config', type: 'Config', optional: false, default: '{}' }),
|
|
85
|
+
* ],
|
|
86
|
+
* })
|
|
87
|
+
*
|
|
88
|
+
* printer.print(sig) // → "petId: string, config: Config = {}"
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export const functionPrinter = defineFunctionPrinter<DefaultPrinter>((options) => ({
|
|
92
|
+
name: 'functionParameters',
|
|
93
|
+
options,
|
|
94
|
+
nodes: {
|
|
95
|
+
type(node) {
|
|
96
|
+
if (node.variant === 'member') {
|
|
97
|
+
return `${node.base}['${node.key}']`
|
|
98
|
+
}
|
|
99
|
+
if (node.variant === 'struct') {
|
|
100
|
+
const parts = node.properties.map((p) => {
|
|
101
|
+
const typeStr = this.transform(p.type)
|
|
102
|
+
return p.optional ? `${p.name}?: ${typeStr}` : `${p.name}: ${typeStr}`
|
|
103
|
+
})
|
|
104
|
+
return `{ ${parts.join('; ')} }`
|
|
105
|
+
}
|
|
106
|
+
if (node.variant === 'reference') {
|
|
107
|
+
return node.name
|
|
108
|
+
}
|
|
109
|
+
return null
|
|
110
|
+
},
|
|
111
|
+
functionParameter(node) {
|
|
112
|
+
const { mode, transformName, transformType } = this.options
|
|
113
|
+
const name = transformName ? transformName(node.name) : node.name
|
|
114
|
+
|
|
115
|
+
const rawType = node.type ? this.transform(node.type) : undefined
|
|
116
|
+
const type = rawType != null && transformType ? transformType(rawType) : rawType
|
|
117
|
+
|
|
118
|
+
if (mode === 'keys' || mode === 'values') {
|
|
119
|
+
return node.rest ? `...${name}` : name
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (mode === 'call') {
|
|
123
|
+
return node.rest ? `...${name}` : name
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (node.rest) {
|
|
127
|
+
return type ? `...${name}: ${type}` : `...${name}`
|
|
128
|
+
}
|
|
129
|
+
if (type) {
|
|
130
|
+
if (node.optional) return `${name}?: ${type}`
|
|
131
|
+
return node.default ? `${name}: ${type} = ${node.default}` : `${name}: ${type}`
|
|
132
|
+
}
|
|
133
|
+
return node.default ? `${name} = ${node.default}` : name
|
|
134
|
+
},
|
|
135
|
+
parameterGroup(node) {
|
|
136
|
+
const { mode, transformName, transformType } = this.options
|
|
137
|
+
const sorted = sortChildParams(node.properties)
|
|
138
|
+
const isOptional = node.optional ?? sorted.every((p) => p.optional || p.default !== undefined)
|
|
139
|
+
|
|
140
|
+
if (node.inline) {
|
|
141
|
+
return sorted
|
|
142
|
+
.map((p) => this.transform(p))
|
|
143
|
+
.filter(Boolean)
|
|
144
|
+
.join(', ')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (mode === 'keys' || mode === 'values') {
|
|
148
|
+
const keys = sorted.map((p) => p.name).join(', ')
|
|
149
|
+
return `{ ${keys} }`
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (mode === 'call') {
|
|
153
|
+
const keys = sorted.map((p) => p.name).join(', ')
|
|
154
|
+
return `{ ${keys} }`
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const names = sorted.map((p) => {
|
|
158
|
+
const n = transformName ? transformName(p.name) : p.name
|
|
159
|
+
|
|
160
|
+
return n
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
const nameStr = names.length ? `{ ${names.join(', ')} }` : undefined
|
|
164
|
+
if (!nameStr) return null
|
|
165
|
+
|
|
166
|
+
let typeAnnotation: string | undefined = node.type ? (this.transform(node.type) ?? undefined) : undefined
|
|
167
|
+
if (!typeAnnotation) {
|
|
168
|
+
const typeParts = sorted
|
|
169
|
+
.filter((p) => p.type)
|
|
170
|
+
.map((p) => {
|
|
171
|
+
const rawT = p.type ? this.transform(p.type) : undefined
|
|
172
|
+
const t = rawT != null && transformType ? transformType(rawT) : rawT
|
|
173
|
+
return p.optional || p.default !== undefined ? `${p.name}?: ${t}` : `${p.name}: ${t}`
|
|
174
|
+
})
|
|
175
|
+
typeAnnotation = typeParts.length ? `{ ${typeParts.join('; ')} }` : undefined
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (typeAnnotation) {
|
|
179
|
+
if (isOptional) return `${nameStr}: ${typeAnnotation} = ${node.default ?? '{}'}`
|
|
180
|
+
return node.default ? `${nameStr}: ${typeAnnotation} = ${node.default}` : `${nameStr}: ${typeAnnotation}`
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return node.default ? `${nameStr} = ${node.default}` : nameStr
|
|
184
|
+
},
|
|
185
|
+
functionParameters(node) {
|
|
186
|
+
const sorted = sortParams(node.params)
|
|
187
|
+
|
|
188
|
+
return sorted
|
|
189
|
+
.map((p) => this.transform(p))
|
|
190
|
+
.filter(Boolean)
|
|
191
|
+
.join(', ')
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
}))
|
|
@@ -37,7 +37,7 @@ type TsOptions = {
|
|
|
37
37
|
* When set, `printer.print(node)` produces a full `type Name = …` declaration.
|
|
38
38
|
* When omitted, `printer.print(node)` returns the raw type node.
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
name?: string
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* JSDoc `@description` comment added to the generated type or interface declaration.
|
|
@@ -272,7 +272,7 @@ export const printerTs = definePrinter<TsPrinter>((options) => {
|
|
|
272
272
|
|
|
273
273
|
const resolvedName =
|
|
274
274
|
ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) && this.options.enumTypeSuffix
|
|
275
|
-
? this.options.resolver.
|
|
275
|
+
? this.options.resolver.resolveEnumKeyName(node as unknown as SchemaNode, this.options.enumTypeSuffix)
|
|
276
276
|
: this.options.resolver.default(node.name, 'type')
|
|
277
277
|
|
|
278
278
|
return factory.createTypeReferenceNode(resolvedName, undefined)
|
|
@@ -360,16 +360,16 @@ export const printerTs = definePrinter<TsPrinter>((options) => {
|
|
|
360
360
|
type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
-
// Without
|
|
364
|
-
const {
|
|
365
|
-
if (!
|
|
363
|
+
// Without name, return the type node as-is (no declaration wrapping).
|
|
364
|
+
const { name, syntaxType = 'type', description, keysToOmit } = this.options
|
|
365
|
+
if (!name) {
|
|
366
366
|
return safePrint(type)
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
const useTypeGeneration = syntaxType === 'type' || type.kind === factory.syntaxKind.union || !!keysToOmit?.length
|
|
370
370
|
|
|
371
371
|
const typeNode = factory.createTypeDeclaration({
|
|
372
|
-
name
|
|
372
|
+
name,
|
|
373
373
|
isExportable: true,
|
|
374
374
|
type: keysToOmit?.length
|
|
375
375
|
? factory.createOmitDeclaration({
|