@kubb/plugin-client 5.0.0-beta.42 → 5.0.0-beta.64
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/clients/axios.cjs.map +1 -1
- package/dist/clients/axios.js.map +1 -1
- package/dist/clients/fetch.cjs.map +1 -1
- package/dist/clients/fetch.js.map +1 -1
- package/dist/index.cjs +439 -383
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +60 -25
- package/dist/index.js +435 -383
- package/dist/index.js.map +1 -1
- package/dist/templates/clients/axios.source.cjs.map +1 -1
- package/dist/templates/clients/axios.source.js.map +1 -1
- package/dist/templates/clients/fetch.source.cjs.map +1 -1
- package/dist/templates/clients/fetch.source.js.map +1 -1
- package/dist/templates/config.source.cjs.map +1 -1
- package/dist/templates/config.source.js.map +1 -1
- package/package.json +10 -18
- package/extension.yaml +0 -1267
- package/src/clients/axios.ts +0 -113
- package/src/clients/fetch.ts +0 -201
- package/src/components/ClassClient.tsx +0 -137
- package/src/components/Client.tsx +0 -273
- package/src/components/Operations.tsx +0 -29
- package/src/components/StaticClassClient.tsx +0 -129
- package/src/components/Url.tsx +0 -91
- package/src/components/WrapperClient.tsx +0 -33
- package/src/functionParams.ts +0 -118
- package/src/generators/classClientGenerator.tsx +0 -253
- package/src/generators/clientGenerator.tsx +0 -127
- package/src/generators/groupedClientGenerator.tsx +0 -82
- package/src/generators/operationsGenerator.tsx +0 -34
- package/src/generators/staticClassClientGenerator.tsx +0 -232
- package/src/index.ts +0 -9
- package/src/plugin.ts +0 -160
- package/src/resolvers/resolverClient.ts +0 -45
- package/src/templates/clients/axios.source.ts +0 -4
- package/src/templates/clients/fetch.source.ts +0 -4
- package/src/templates/config.source.ts +0 -4
- package/src/types.ts +0 -268
- package/src/utils.ts +0 -159
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import { operationFileEntry, resolveOperationTypeNames } from '@internals/shared'
|
|
3
|
-
import { camelCase } from '@internals/utils'
|
|
4
|
-
import { ast, defineGenerator } from '@kubb/core'
|
|
5
|
-
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
6
|
-
import { pluginTsName } from '@kubb/plugin-ts'
|
|
7
|
-
import type { ResolverZod } from '@kubb/plugin-zod'
|
|
8
|
-
import { pluginZodName } from '@kubb/plugin-zod'
|
|
9
|
-
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
10
|
-
import { ClassClient } from '../components/ClassClient'
|
|
11
|
-
import { WrapperClient } from '../components/WrapperClient'
|
|
12
|
-
import type { PluginClient } from '../types'
|
|
13
|
-
|
|
14
|
-
type OperationData = {
|
|
15
|
-
node: ast.OperationNode
|
|
16
|
-
name: string
|
|
17
|
-
tsResolver: ResolverTs
|
|
18
|
-
zodResolver: ResolverZod | null
|
|
19
|
-
typeFile: ast.FileNode
|
|
20
|
-
zodFile: ast.FileNode | null
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
type Controller = {
|
|
24
|
-
name: string
|
|
25
|
-
propertyName: string
|
|
26
|
-
file: ast.FileNode
|
|
27
|
-
operations: Array<OperationData>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function resolveTypeImportNames(node: ast.OperationNode, tsResolver: ResolverTs): Array<string> {
|
|
31
|
-
return resolveOperationTypeNames(node, tsResolver, { order: 'body-response-first' })
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function resolveZodImportNames(node: ast.OperationNode, zodResolver: ResolverZod): Array<string> {
|
|
35
|
-
const names: Array<string | null | undefined> = [
|
|
36
|
-
zodResolver.resolveResponseName?.(node),
|
|
37
|
-
node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,
|
|
38
|
-
]
|
|
39
|
-
return names.filter((n): n is string => Boolean(n))
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Built-in `operations` generator for `@kubb/plugin-client` when
|
|
44
|
-
* `clientType: 'class'`. Emits one class per tag, with one instance method
|
|
45
|
-
* per operation and a shared constructor for request configuration.
|
|
46
|
-
*/
|
|
47
|
-
export const classClientGenerator = defineGenerator<PluginClient>({
|
|
48
|
-
name: 'classClient',
|
|
49
|
-
renderer: jsxRendererSync,
|
|
50
|
-
operations(nodes, ctx) {
|
|
51
|
-
const { config, driver, resolver, root } = ctx
|
|
52
|
-
const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, sdk } = ctx.options
|
|
53
|
-
const baseURL = ctx.options.baseURL ?? ctx.meta.baseURL
|
|
54
|
-
|
|
55
|
-
const pluginTs = driver.getPlugin(pluginTsName)
|
|
56
|
-
if (!pluginTs) return null
|
|
57
|
-
|
|
58
|
-
const tsResolver = driver.getResolver(pluginTsName)
|
|
59
|
-
const tsPluginOptions = pluginTs.options
|
|
60
|
-
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
|
|
61
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
|
|
62
|
-
|
|
63
|
-
function buildOperationData(node: ast.OperationNode): OperationData {
|
|
64
|
-
const typeFile = tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
65
|
-
root,
|
|
66
|
-
output: tsPluginOptions?.output ?? output,
|
|
67
|
-
group: tsPluginOptions?.group,
|
|
68
|
-
})
|
|
69
|
-
const zodFile =
|
|
70
|
-
zodResolver && pluginZod?.options
|
|
71
|
-
? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
72
|
-
root,
|
|
73
|
-
output: pluginZod.options?.output ?? output,
|
|
74
|
-
group: pluginZod.options?.group ?? undefined,
|
|
75
|
-
})
|
|
76
|
-
: null
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
node: node,
|
|
80
|
-
name: resolver.resolveName(node.operationId),
|
|
81
|
-
tsResolver,
|
|
82
|
-
zodResolver,
|
|
83
|
-
typeFile,
|
|
84
|
-
zodFile,
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const controllers = nodes.reduce((acc, operationNode) => {
|
|
89
|
-
if (!ast.isHttpOperationNode(operationNode)) return acc
|
|
90
|
-
const tag = operationNode.tags[0]
|
|
91
|
-
const groupName = tag ? (group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag)) : resolver.resolveGroupName('Client')
|
|
92
|
-
|
|
93
|
-
if (!tag && !group) {
|
|
94
|
-
const name = resolver.resolveClassName('ApiClient')
|
|
95
|
-
const file = resolver.resolveFile({ name, extname: '.ts' }, { root, output, group: group ?? undefined })
|
|
96
|
-
const operationData = buildOperationData(operationNode)
|
|
97
|
-
const previous = acc.find((item) => item.file.path === file.path)
|
|
98
|
-
|
|
99
|
-
if (previous) {
|
|
100
|
-
previous.operations.push(operationData)
|
|
101
|
-
} else {
|
|
102
|
-
acc.push({ name, propertyName: resolver.resolveClientPropertyName(name), file, operations: [operationData] })
|
|
103
|
-
}
|
|
104
|
-
return acc
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (tag) {
|
|
108
|
-
const name = groupName
|
|
109
|
-
const file = resolver.resolveFile({ name, extname: '.ts', tag }, { root, output, group: group ?? undefined })
|
|
110
|
-
const operationData = buildOperationData(operationNode)
|
|
111
|
-
const previous = acc.find((item) => item.file.path === file.path)
|
|
112
|
-
|
|
113
|
-
if (previous) {
|
|
114
|
-
previous.operations.push(operationData)
|
|
115
|
-
} else {
|
|
116
|
-
acc.push({ name, propertyName: resolver.resolveClientPropertyName(name), file, operations: [operationData] })
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return acc
|
|
121
|
-
}, [] as Array<Controller>)
|
|
122
|
-
|
|
123
|
-
function collectTypeImports(ops: Array<OperationData>) {
|
|
124
|
-
const typeImportsByFile = new Map<string, Set<string>>()
|
|
125
|
-
const typeFilesByPath = new Map<string, ast.FileNode>()
|
|
126
|
-
|
|
127
|
-
ops.forEach((op) => {
|
|
128
|
-
const names = resolveTypeImportNames(op.node, tsResolver)
|
|
129
|
-
if (!typeImportsByFile.has(op.typeFile.path)) {
|
|
130
|
-
typeImportsByFile.set(op.typeFile.path, new Set())
|
|
131
|
-
}
|
|
132
|
-
const imports = typeImportsByFile.get(op.typeFile.path)!
|
|
133
|
-
names.forEach((n) => {
|
|
134
|
-
imports.add(n)
|
|
135
|
-
})
|
|
136
|
-
typeFilesByPath.set(op.typeFile.path, op.typeFile)
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
return { typeImportsByFile, typeFilesByPath }
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function collectZodImports(ops: Array<OperationData>) {
|
|
143
|
-
const zodImportsByFile = new Map<string, Set<string>>()
|
|
144
|
-
const zodFilesByPath = new Map<string, ast.FileNode>()
|
|
145
|
-
|
|
146
|
-
ops.forEach((op) => {
|
|
147
|
-
if (!op.zodFile || !zodResolver) return
|
|
148
|
-
const names = resolveZodImportNames(op.node, zodResolver)
|
|
149
|
-
if (!zodImportsByFile.has(op.zodFile.path)) {
|
|
150
|
-
zodImportsByFile.set(op.zodFile.path, new Set())
|
|
151
|
-
}
|
|
152
|
-
const imports = zodImportsByFile.get(op.zodFile.path)!
|
|
153
|
-
names.forEach((n) => {
|
|
154
|
-
imports.add(n)
|
|
155
|
-
})
|
|
156
|
-
zodFilesByPath.set(op.zodFile.path, op.zodFile)
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
return { zodImportsByFile, zodFilesByPath }
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const files = controllers.map(({ name, file, operations: ops }) => {
|
|
163
|
-
const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops)
|
|
164
|
-
const { zodImportsByFile, zodFilesByPath } =
|
|
165
|
-
parser === 'zod' ? collectZodImports(ops) : { zodImportsByFile: new Map<string, Set<string>>(), zodFilesByPath: new Map<string, ast.FileNode>() }
|
|
166
|
-
const hasFormData = ops.some((op) => op.node.requestBody?.content?.some((e) => e.contentType === 'multipart/form-data') ?? false)
|
|
167
|
-
|
|
168
|
-
return (
|
|
169
|
-
<File
|
|
170
|
-
key={file.path}
|
|
171
|
-
baseName={file.baseName}
|
|
172
|
-
path={file.path}
|
|
173
|
-
meta={file.meta}
|
|
174
|
-
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })}
|
|
175
|
-
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })}
|
|
176
|
-
>
|
|
177
|
-
{importPath ? (
|
|
178
|
-
<>
|
|
179
|
-
<File.Import name={'client'} path={importPath} />
|
|
180
|
-
<File.Import name={['mergeConfig']} path={importPath} />
|
|
181
|
-
<File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={importPath} isTypeOnly />
|
|
182
|
-
</>
|
|
183
|
-
) : (
|
|
184
|
-
<>
|
|
185
|
-
<File.Import name={['client']} root={file.path} path={path.resolve(root, '.kubb/client.ts')} />
|
|
186
|
-
<File.Import name={['mergeConfig']} root={file.path} path={path.resolve(root, '.kubb/client.ts')} />
|
|
187
|
-
<File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} root={file.path} path={path.resolve(root, '.kubb/client.ts')} isTypeOnly />
|
|
188
|
-
</>
|
|
189
|
-
)}
|
|
190
|
-
|
|
191
|
-
{hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(root, '.kubb/config.ts')} />}
|
|
192
|
-
|
|
193
|
-
{Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
|
|
194
|
-
const typeFile = typeFilesByPath.get(filePath)
|
|
195
|
-
if (!typeFile) return null
|
|
196
|
-
const importNames = Array.from(importSet).filter(Boolean)
|
|
197
|
-
if (importNames.length === 0) return null
|
|
198
|
-
return <File.Import key={filePath} name={importNames} root={file.path} path={typeFile.path} isTypeOnly />
|
|
199
|
-
})}
|
|
200
|
-
|
|
201
|
-
{parser === 'zod' &&
|
|
202
|
-
Array.from(zodImportsByFile.entries()).map(([filePath, importSet]) => {
|
|
203
|
-
const zodFile = zodFilesByPath.get(filePath)
|
|
204
|
-
if (!zodFile) return null
|
|
205
|
-
const importNames = Array.from(importSet).filter(Boolean)
|
|
206
|
-
if (importNames.length === 0) return null
|
|
207
|
-
return <File.Import key={filePath} name={importNames} root={file.path} path={zodFile.path} />
|
|
208
|
-
})}
|
|
209
|
-
|
|
210
|
-
<ClassClient
|
|
211
|
-
name={name}
|
|
212
|
-
operations={ops}
|
|
213
|
-
baseURL={baseURL}
|
|
214
|
-
dataReturnType={dataReturnType}
|
|
215
|
-
pathParamsType={pathParamsType}
|
|
216
|
-
paramsCasing={paramsCasing}
|
|
217
|
-
paramsType={paramsType}
|
|
218
|
-
parser={parser}
|
|
219
|
-
/>
|
|
220
|
-
</File>
|
|
221
|
-
)
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
if (sdk) {
|
|
225
|
-
const sdkFile = resolver.resolveFile({ name: sdk.className, extname: '.ts' }, { root, output, group: group ?? undefined })
|
|
226
|
-
|
|
227
|
-
files.push(
|
|
228
|
-
<File
|
|
229
|
-
key={sdkFile.path}
|
|
230
|
-
baseName={sdkFile.baseName}
|
|
231
|
-
path={sdkFile.path}
|
|
232
|
-
meta={sdkFile.meta}
|
|
233
|
-
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: sdkFile.path, baseName: sdkFile.baseName } })}
|
|
234
|
-
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: sdkFile.path, baseName: sdkFile.baseName } })}
|
|
235
|
-
>
|
|
236
|
-
{importPath ? (
|
|
237
|
-
<File.Import name={['Client', 'RequestConfig']} path={importPath} isTypeOnly />
|
|
238
|
-
) : (
|
|
239
|
-
<File.Import name={['Client', 'RequestConfig']} root={sdkFile.path} path={path.resolve(root, '.kubb/client.ts')} isTypeOnly />
|
|
240
|
-
)}
|
|
241
|
-
|
|
242
|
-
{controllers.map(({ name, file }) => (
|
|
243
|
-
<File.Import key={name} name={[name]} root={sdkFile.path} path={file.path} />
|
|
244
|
-
))}
|
|
245
|
-
|
|
246
|
-
<WrapperClient name={sdk.className} controllers={controllers.map(({ name, propertyName }) => ({ className: name, propertyName }))} />
|
|
247
|
-
</File>,
|
|
248
|
-
)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return <>{files}</>
|
|
252
|
-
},
|
|
253
|
-
})
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import { operationFileEntry, resolveOperationTypeNames } from '@internals/shared'
|
|
3
|
-
import { ast, defineGenerator } from '@kubb/core'
|
|
4
|
-
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
|
-
import { pluginZodName } from '@kubb/plugin-zod'
|
|
6
|
-
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
7
|
-
import { Client } from '../components/Client'
|
|
8
|
-
import { Url } from '../components/Url.tsx'
|
|
9
|
-
import type { PluginClient } from '../types'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Built-in operation generator for `@kubb/plugin-client`. Emits one async
|
|
13
|
-
* function per OpenAPI operation, plus the matching URL helper. Used when
|
|
14
|
-
* `clientType: 'function'` (the default).
|
|
15
|
-
*/
|
|
16
|
-
export const clientGenerator = defineGenerator<PluginClient>({
|
|
17
|
-
name: 'client',
|
|
18
|
-
renderer: jsxRendererSync,
|
|
19
|
-
operation(node, ctx) {
|
|
20
|
-
if (!ast.isHttpOperationNode(node)) return null
|
|
21
|
-
const { config, driver, resolver, root } = ctx
|
|
22
|
-
const { output, urlType, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, group } = ctx.options
|
|
23
|
-
const baseURL = ctx.options.baseURL ?? ctx.meta.baseURL
|
|
24
|
-
|
|
25
|
-
const pluginTs = driver.getPlugin(pluginTsName)
|
|
26
|
-
|
|
27
|
-
if (!pluginTs) {
|
|
28
|
-
return null
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const tsResolver = driver.getResolver(pluginTsName)
|
|
32
|
-
|
|
33
|
-
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
|
|
34
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
|
|
35
|
-
|
|
36
|
-
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing })
|
|
37
|
-
|
|
38
|
-
const importedZodNames =
|
|
39
|
-
zodResolver && parser === 'zod'
|
|
40
|
-
? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter(
|
|
41
|
-
(name): name is string => Boolean(name),
|
|
42
|
-
)
|
|
43
|
-
: []
|
|
44
|
-
|
|
45
|
-
const meta = {
|
|
46
|
-
name: resolver.resolveName(node.operationId),
|
|
47
|
-
urlName: resolver.resolveUrlName(node),
|
|
48
|
-
file: resolver.resolveFile(operationFileEntry(node, node.operationId), { root, output, group: group ?? undefined }),
|
|
49
|
-
fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
50
|
-
root,
|
|
51
|
-
output: pluginTs.options?.output ?? output,
|
|
52
|
-
group: pluginTs.options?.group ?? undefined,
|
|
53
|
-
}),
|
|
54
|
-
fileZod:
|
|
55
|
-
zodResolver && pluginZod?.options
|
|
56
|
-
? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
57
|
-
root,
|
|
58
|
-
output: pluginZod.options.output ?? output,
|
|
59
|
-
group: pluginZod.options?.group ?? undefined,
|
|
60
|
-
})
|
|
61
|
-
: null,
|
|
62
|
-
} as const
|
|
63
|
-
|
|
64
|
-
const hasFormData = node.requestBody?.content?.some((e) => e.contentType === 'multipart/form-data') ?? false
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<File
|
|
68
|
-
baseName={meta.file.baseName}
|
|
69
|
-
path={meta.file.path}
|
|
70
|
-
meta={meta.file.meta}
|
|
71
|
-
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
72
|
-
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
73
|
-
>
|
|
74
|
-
{importPath ? (
|
|
75
|
-
<>
|
|
76
|
-
<File.Import name={'client'} path={importPath} />
|
|
77
|
-
<File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={importPath} isTypeOnly />
|
|
78
|
-
</>
|
|
79
|
-
) : (
|
|
80
|
-
<>
|
|
81
|
-
<File.Import name={['client']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} />
|
|
82
|
-
<File.Import
|
|
83
|
-
name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
|
|
84
|
-
root={meta.file.path}
|
|
85
|
-
path={path.resolve(root, '.kubb/client.ts')}
|
|
86
|
-
isTypeOnly
|
|
87
|
-
/>
|
|
88
|
-
</>
|
|
89
|
-
)}
|
|
90
|
-
|
|
91
|
-
{hasFormData && <File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(root, '.kubb/config.ts')} />}
|
|
92
|
-
|
|
93
|
-
{meta.fileZod && importedZodNames.length > 0 && <File.Import name={importedZodNames as Array<string>} root={meta.file.path} path={meta.fileZod.path} />}
|
|
94
|
-
|
|
95
|
-
{meta.fileTs && importedTypeNames.length > 0 && (
|
|
96
|
-
<File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />
|
|
97
|
-
)}
|
|
98
|
-
|
|
99
|
-
<Url
|
|
100
|
-
name={meta.urlName}
|
|
101
|
-
baseURL={baseURL}
|
|
102
|
-
pathParamsType={pathParamsType}
|
|
103
|
-
paramsCasing={paramsCasing}
|
|
104
|
-
paramsType={paramsType}
|
|
105
|
-
node={node}
|
|
106
|
-
tsResolver={tsResolver}
|
|
107
|
-
isIndexable={urlType === 'export'}
|
|
108
|
-
isExportable={urlType === 'export'}
|
|
109
|
-
/>
|
|
110
|
-
|
|
111
|
-
<Client
|
|
112
|
-
name={meta.name}
|
|
113
|
-
urlName={meta.urlName}
|
|
114
|
-
baseURL={baseURL}
|
|
115
|
-
dataReturnType={dataReturnType}
|
|
116
|
-
pathParamsType={pathParamsType}
|
|
117
|
-
paramsCasing={paramsCasing}
|
|
118
|
-
paramsType={paramsType}
|
|
119
|
-
node={node}
|
|
120
|
-
tsResolver={tsResolver}
|
|
121
|
-
zodResolver={zodResolver}
|
|
122
|
-
parser={parser}
|
|
123
|
-
/>
|
|
124
|
-
</File>
|
|
125
|
-
)
|
|
126
|
-
},
|
|
127
|
-
})
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { camelCase } from '@internals/utils'
|
|
2
|
-
import type { ast } from '@kubb/core'
|
|
3
|
-
import { defineGenerator } from '@kubb/core'
|
|
4
|
-
import { File, Function, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
5
|
-
import type { PluginClient } from '../types'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Emits one aggregate file per tag/group when `group` is configured. Each
|
|
9
|
-
* file re-exports every client function for that group, so callers can
|
|
10
|
-
* `import { petController } from './gen/clients'` instead of importing
|
|
11
|
-
* each operation individually.
|
|
12
|
-
*/
|
|
13
|
-
export const groupedClientGenerator = defineGenerator<PluginClient>({
|
|
14
|
-
name: 'groupedClient',
|
|
15
|
-
renderer: jsxRendererSync,
|
|
16
|
-
operations(nodes, ctx) {
|
|
17
|
-
const { config, resolver, root } = ctx
|
|
18
|
-
const { output, group } = ctx.options
|
|
19
|
-
|
|
20
|
-
const controllers = nodes.reduce(
|
|
21
|
-
(acc, operationNode) => {
|
|
22
|
-
if (group?.type === 'tag') {
|
|
23
|
-
const tag = operationNode.tags[0]
|
|
24
|
-
const name = tag ? group?.name?.({ group: camelCase(tag) }) : null
|
|
25
|
-
|
|
26
|
-
if (!tag || !name) {
|
|
27
|
-
return acc
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const file = resolver.resolveFile({ name, extname: '.ts', tag }, { root, output, group: group ?? undefined })
|
|
31
|
-
const clientFile = resolver.resolveFile(
|
|
32
|
-
{ name: operationNode.operationId, extname: '.ts', tag: operationNode.tags[0] ?? 'default', path: operationNode.path },
|
|
33
|
-
{ root, output, group: group ?? undefined },
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
const client = {
|
|
37
|
-
name: resolver.resolveName(operationNode.operationId),
|
|
38
|
-
file: clientFile,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const previous = acc.find((item) => item.file.path === file.path)
|
|
42
|
-
|
|
43
|
-
if (previous) {
|
|
44
|
-
previous.clients.push(client)
|
|
45
|
-
} else {
|
|
46
|
-
acc.push({ name, file, clients: [client] })
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return acc
|
|
51
|
-
},
|
|
52
|
-
[] as Array<{ name: string; file: ast.FileNode; clients: Array<{ name: string; file: ast.FileNode }> }>,
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<>
|
|
57
|
-
{controllers.map(({ name, file, clients }) => {
|
|
58
|
-
return (
|
|
59
|
-
<File
|
|
60
|
-
key={file.path}
|
|
61
|
-
baseName={file.baseName}
|
|
62
|
-
path={file.path}
|
|
63
|
-
meta={file.meta}
|
|
64
|
-
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName, isAggregation: true } })}
|
|
65
|
-
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName, isAggregation: true } })}
|
|
66
|
-
>
|
|
67
|
-
{clients.map((client) => (
|
|
68
|
-
<File.Import key={client.name} name={[client.name]} root={file.path} path={client.file.path} />
|
|
69
|
-
))}
|
|
70
|
-
|
|
71
|
-
<File.Source name={name} isExportable isIndexable>
|
|
72
|
-
<Function export name={name}>
|
|
73
|
-
{`return { ${clients.map((client) => client.name).join(', ')} }`}
|
|
74
|
-
</Function>
|
|
75
|
-
</File.Source>
|
|
76
|
-
</File>
|
|
77
|
-
)
|
|
78
|
-
})}
|
|
79
|
-
</>
|
|
80
|
-
)
|
|
81
|
-
},
|
|
82
|
-
})
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { ast, defineGenerator } from '@kubb/core'
|
|
2
|
-
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
3
|
-
import { Operations } from '../components/Operations'
|
|
4
|
-
import type { PluginClient } from '../types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generates an `operations.ts` file that re-exports every operation grouped
|
|
8
|
-
* by HTTP method. Enabled when `pluginClient({ operations: true })`. Useful
|
|
9
|
-
* for building meta-tooling on top of the generated client (route
|
|
10
|
-
* registries, API explorers).
|
|
11
|
-
*/
|
|
12
|
-
export const operationsGenerator = defineGenerator<PluginClient>({
|
|
13
|
-
name: 'client',
|
|
14
|
-
renderer: jsxRendererSync,
|
|
15
|
-
operations(nodes, ctx) {
|
|
16
|
-
const { config, resolver, root } = ctx
|
|
17
|
-
const { output, group } = ctx.options
|
|
18
|
-
|
|
19
|
-
const name = 'operations'
|
|
20
|
-
const file = resolver.resolveFile({ name, extname: '.ts' }, { root, output, group: group ?? undefined })
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<File
|
|
24
|
-
baseName={file.baseName}
|
|
25
|
-
path={file.path}
|
|
26
|
-
meta={file.meta}
|
|
27
|
-
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })}
|
|
28
|
-
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })}
|
|
29
|
-
>
|
|
30
|
-
<Operations name={name} nodes={nodes.filter(ast.isHttpOperationNode)} />
|
|
31
|
-
</File>
|
|
32
|
-
)
|
|
33
|
-
},
|
|
34
|
-
})
|