@kubb/plugin-client 5.0.0-alpha.29 → 5.0.0-alpha.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/plugin-client",
3
- "version": "5.0.0-alpha.29",
3
+ "version": "5.0.0-alpha.30",
4
4
  "description": "API client generator plugin for Kubb, creating type-safe HTTP clients (Axios, Fetch) from OpenAPI specifications for making API requests.",
5
5
  "keywords": [
6
6
  "api-client",
@@ -96,10 +96,10 @@
96
96
  "dependencies": {
97
97
  "@kubb/fabric-core": "0.15.1",
98
98
  "@kubb/react-fabric": "0.15.1",
99
- "@kubb/ast": "5.0.0-alpha.29",
100
- "@kubb/core": "5.0.0-alpha.29",
101
- "@kubb/plugin-ts": "5.0.0-alpha.29",
102
- "@kubb/plugin-zod": "5.0.0-alpha.29"
99
+ "@kubb/ast": "5.0.0-alpha.30",
100
+ "@kubb/core": "5.0.0-alpha.30",
101
+ "@kubb/plugin-ts": "5.0.0-alpha.30",
102
+ "@kubb/plugin-zod": "5.0.0-alpha.30"
103
103
  },
104
104
  "devDependencies": {
105
105
  "axios": "^1.14.0",
@@ -1,6 +1,5 @@
1
1
  import path from 'node:path'
2
2
  import { camelCase, pascalCase } from '@internals/utils'
3
- import { transform } from '@kubb/ast'
4
3
  import type { OperationNode } from '@kubb/ast/types'
5
4
  import { defineGenerator } from '@kubb/core'
6
5
  import type { FabricFile } from '@kubb/fabric-core/types'
@@ -47,37 +46,35 @@ function resolveZodImportNames(node: OperationNode, zodResolver: PluginZod['reso
47
46
 
48
47
  export const classClientGenerator = defineGenerator<PluginClient>({
49
48
  name: 'classClient',
50
- type: 'react',
51
- Operations({ nodes, options, config, driver, resolver, adapter, plugin }) {
49
+ operations(nodes, options) {
50
+ const { adapter, config, driver, resolver, root } = this
52
51
  const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, wrapper } = options
53
52
  const baseURL = options.baseURL ?? adapter.rootNode?.meta?.baseURL
54
- const root = path.resolve(config.root, config.output.path)
55
53
 
56
- const pluginTs = driver.getPlugin<PluginTs>(pluginTsName)
54
+ const pluginTs = driver.getPlugin(pluginTsName)
57
55
  if (!pluginTs?.resolver) return null
58
56
 
59
57
  const tsResolver = pluginTs.resolver
60
58
  const tsPluginOptions = pluginTs.options
61
- const pluginZod = parser === 'zod' ? driver.getPlugin<PluginZod>(pluginZodName) : undefined
59
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
62
60
  const zodResolver = pluginZod?.resolver
63
61
 
64
62
  function buildOperationData(node: OperationNode): OperationData {
65
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node
66
63
  const typeFile = tsResolver.resolveFile(
67
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
64
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
68
65
  { root, output: tsPluginOptions?.output ?? output, group: tsPluginOptions?.group },
69
66
  )
70
67
  const zodFile =
71
68
  zodResolver && pluginZod?.options
72
69
  ? zodResolver.resolveFile(
73
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
70
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
74
71
  { root, output: pluginZod.options.output ?? output, group: pluginZod.options.group },
75
72
  )
76
73
  : undefined
77
74
 
78
75
  return {
79
- node: transformedNode,
80
- name: resolver.resolveName(transformedNode.operationId),
76
+ node: node,
77
+ name: resolver.resolveName(node.operationId),
81
78
  tsResolver,
82
79
  zodResolver,
83
80
  typeFile,
@@ -181,18 +178,13 @@ export const classClientGenerator = defineGenerator<PluginClient>({
181
178
  </>
182
179
  ) : (
183
180
  <>
184
- <File.Import name={['fetch']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
185
- <File.Import name={['mergeConfig']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
186
- <File.Import
187
- name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
188
- root={file.path}
189
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
190
- isTypeOnly
191
- />
181
+ <File.Import name={['fetch']} root={file.path} path={path.resolve(root, '.kubb/fetch.ts')} />
182
+ <File.Import name={['mergeConfig']} root={file.path} path={path.resolve(root, '.kubb/fetch.ts')} />
183
+ <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} root={file.path} path={path.resolve(root, '.kubb/fetch.ts')} isTypeOnly />
192
184
  </>
193
185
  )}
194
186
 
195
- {hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/config.ts')} />}
187
+ {hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(root, '.kubb/config.ts')} />}
196
188
 
197
189
  {Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
198
190
  const typeFile = typeFilesByPath.get(filePath)
@@ -240,12 +232,7 @@ export const classClientGenerator = defineGenerator<PluginClient>({
240
232
  {importPath ? (
241
233
  <File.Import name={['Client', 'RequestConfig']} path={importPath} isTypeOnly />
242
234
  ) : (
243
- <File.Import
244
- name={['Client', 'RequestConfig']}
245
- root={wrapperFile.path}
246
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
247
- isTypeOnly
248
- />
235
+ <File.Import name={['Client', 'RequestConfig']} root={wrapperFile.path} path={path.resolve(root, '.kubb/fetch.ts')} isTypeOnly />
249
236
  )}
250
237
 
251
238
  {controllers.map(({ name, file }) => (
@@ -257,6 +244,6 @@ export const classClientGenerator = defineGenerator<PluginClient>({
257
244
  )
258
245
  }
259
246
 
260
- return files
247
+ return <>{files}</>
261
248
  },
262
249
  })
@@ -1,9 +1,7 @@
1
1
  import path from 'node:path'
2
- import { caseParams, transform } from '@kubb/ast'
2
+ import { caseParams } from '@kubb/ast'
3
3
  import { defineGenerator } from '@kubb/core'
4
- import type { PluginTs } from '@kubb/plugin-ts'
5
4
  import { pluginTsName } from '@kubb/plugin-ts'
6
- import type { PluginZod } from '@kubb/plugin-zod'
7
5
  import { pluginZodName } from '@kubb/plugin-zod'
8
6
  import { File } from '@kubb/react-fabric'
9
7
  import { Client } from '../components/Client'
@@ -12,13 +10,12 @@ import type { PluginClient } from '../types'
12
10
 
13
11
  export const clientGenerator = defineGenerator<PluginClient>({
14
12
  name: 'client',
15
- type: 'react',
16
- Operation({ node, adapter, options, config, driver, resolver, plugin }) {
13
+ operation(node, options) {
14
+ const { adapter, config, driver, resolver, root } = this
17
15
  const { output, urlType, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, group } = options
18
16
  const baseURL = options.baseURL ?? adapter.rootNode?.meta?.baseURL
19
- const root = path.resolve(config.root, config.output.path)
20
17
 
21
- const pluginTs = driver.getPlugin<PluginTs>(pluginTsName)
18
+ const pluginTs = driver.getPlugin(pluginTsName)
22
19
 
23
20
  if (!pluginTs?.resolver) {
24
21
  return null
@@ -26,42 +23,34 @@ export const clientGenerator = defineGenerator<PluginClient>({
26
23
 
27
24
  const tsResolver = pluginTs.resolver
28
25
 
29
- const pluginZod = parser === 'zod' ? driver.getPlugin<PluginZod>(pluginZodName) : undefined
26
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
30
27
  const zodResolver = pluginZod?.resolver
31
28
 
32
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node
33
-
34
- const casedParams = caseParams(transformedNode.parameters, paramsCasing)
29
+ const casedParams = caseParams(node.parameters, paramsCasing)
35
30
  const pathParams = casedParams.filter((p) => p.in === 'path')
36
31
  const queryParams = casedParams.filter((p) => p.in === 'query')
37
32
  const headerParams = casedParams.filter((p) => p.in === 'header')
38
33
 
39
34
  const importedTypeNames = [
40
- ...pathParams.map((p) => tsResolver.resolvePathParamsName(transformedNode, p)),
41
- ...queryParams.map((p) => tsResolver.resolveQueryParamsName(transformedNode, p)),
42
- ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(transformedNode, p)),
43
- transformedNode.requestBody?.schema ? tsResolver.resolveDataName(transformedNode) : undefined,
44
- tsResolver.resolveResponseName(transformedNode),
45
- ...transformedNode.responses.map((res) => tsResolver.resolveResponseStatusName(transformedNode, res.statusCode)),
35
+ ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
36
+ ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
37
+ ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
38
+ node.requestBody?.schema ? tsResolver.resolveDataName(node) : undefined,
39
+ tsResolver.resolveResponseName(node),
40
+ ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode)),
46
41
  ].filter(Boolean)
47
42
 
48
43
  const importedZodNames =
49
44
  zodResolver && parser === 'zod'
50
- ? [
51
- zodResolver.resolveResponseName?.(transformedNode),
52
- transformedNode.requestBody?.schema ? zodResolver.resolveDataName?.(transformedNode) : undefined,
53
- ].filter(Boolean)
45
+ ? [zodResolver.resolveResponseName?.(node), node.requestBody?.schema ? zodResolver.resolveDataName?.(node) : undefined].filter(Boolean)
54
46
  : []
55
47
 
56
48
  const meta = {
57
- name: resolver.resolveName(transformedNode.operationId),
58
- urlName: `get${resolver.resolveName(transformedNode.operationId).charAt(0).toUpperCase()}${resolver.resolveName(transformedNode.operationId).slice(1)}Url`,
59
- file: resolver.resolveFile(
60
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
61
- { root, output, group },
62
- ),
49
+ name: resolver.resolveName(node.operationId),
50
+ urlName: `get${resolver.resolveName(node.operationId).charAt(0).toUpperCase()}${resolver.resolveName(node.operationId).slice(1)}Url`,
51
+ file: resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
63
52
  fileTs: tsResolver.resolveFile(
64
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
53
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
65
54
  {
66
55
  root,
67
56
  output: pluginTs.options?.output ?? output,
@@ -71,7 +60,7 @@ export const clientGenerator = defineGenerator<PluginClient>({
71
60
  fileZod:
72
61
  zodResolver && pluginZod?.options
73
62
  ? zodResolver.resolveFile(
74
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
63
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
75
64
  {
76
65
  root,
77
66
  output: pluginZod.options.output ?? output,
@@ -81,7 +70,7 @@ export const clientGenerator = defineGenerator<PluginClient>({
81
70
  : undefined,
82
71
  } as const
83
72
 
84
- const isFormData = transformedNode.requestBody?.contentType === 'multipart/form-data'
73
+ const isFormData = node.requestBody?.contentType === 'multipart/form-data'
85
74
 
86
75
  return (
87
76
  <File
@@ -98,19 +87,17 @@ export const clientGenerator = defineGenerator<PluginClient>({
98
87
  </>
99
88
  ) : (
100
89
  <>
101
- <File.Import name={['fetch']} root={meta.file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
90
+ <File.Import name={['fetch']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} />
102
91
  <File.Import
103
92
  name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
104
93
  root={meta.file.path}
105
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
94
+ path={path.resolve(root, '.kubb/fetch.ts')}
106
95
  isTypeOnly
107
96
  />
108
97
  </>
109
98
  )}
110
99
 
111
- {isFormData && transformedNode.requestBody?.schema && (
112
- <File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(config.root, config.output.path, '.kubb/config.ts')} />
113
- )}
100
+ {isFormData && node.requestBody?.schema && <File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(root, '.kubb/config.ts')} />}
114
101
 
115
102
  {meta.fileZod && importedZodNames.length > 0 && <File.Import name={importedZodNames as string[]} root={meta.file.path} path={meta.fileZod.path} />}
116
103
 
@@ -124,7 +111,7 @@ export const clientGenerator = defineGenerator<PluginClient>({
124
111
  pathParamsType={pathParamsType}
125
112
  paramsCasing={paramsCasing}
126
113
  paramsType={paramsType}
127
- node={transformedNode}
114
+ node={node}
128
115
  tsResolver={tsResolver}
129
116
  isIndexable={urlType === 'export'}
130
117
  isExportable={urlType === 'export'}
@@ -138,7 +125,7 @@ export const clientGenerator = defineGenerator<PluginClient>({
138
125
  pathParamsType={pathParamsType}
139
126
  paramsCasing={paramsCasing}
140
127
  paramsType={paramsType}
141
- node={transformedNode}
128
+ node={node}
142
129
  tsResolver={tsResolver}
143
130
  zodResolver={zodResolver}
144
131
  parser={parser}
@@ -1,6 +1,4 @@
1
- import path from 'node:path'
2
1
  import { camelCase } from '@internals/utils'
3
- import { transform } from '@kubb/ast'
4
2
  import { defineGenerator } from '@kubb/core'
5
3
  import type { FabricFile } from '@kubb/fabric-core/types'
6
4
  import { File, Function } from '@kubb/react-fabric'
@@ -8,10 +6,9 @@ import type { PluginClient } from '../types'
8
6
 
9
7
  export const groupedClientGenerator = defineGenerator<PluginClient>({
10
8
  name: 'groupedClient',
11
- type: 'react',
12
- Operations({ nodes, options, config, resolver, adapter, plugin }) {
9
+ operations(nodes, options) {
10
+ const { config, resolver, adapter, root } = this
13
11
  const { output, group } = options
14
- const root = path.resolve(config.root, config.output.path)
15
12
 
16
13
  const controllers = nodes.reduce(
17
14
  (acc, operationNode) => {
@@ -23,16 +20,14 @@ export const groupedClientGenerator = defineGenerator<PluginClient>({
23
20
  return acc
24
21
  }
25
22
 
26
- const transformedNode = plugin.transformer ? transform(operationNode, plugin.transformer) : operationNode
27
-
28
23
  const file = resolver.resolveFile({ name, extname: '.ts', tag }, { root, output, group })
29
24
  const clientFile = resolver.resolveFile(
30
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
25
+ { name: operationNode.operationId, extname: '.ts', tag: operationNode.tags[0] ?? 'default', path: operationNode.path },
31
26
  { root, output, group },
32
27
  )
33
28
 
34
29
  const client = {
35
- name: resolver.resolveName(transformedNode.operationId),
30
+ name: resolver.resolveName(operationNode.operationId),
36
31
  file: clientFile,
37
32
  }
38
33
 
@@ -50,27 +45,31 @@ export const groupedClientGenerator = defineGenerator<PluginClient>({
50
45
  [] as Array<{ name: string; file: FabricFile.File; clients: Array<{ name: string; file: FabricFile.File }> }>,
51
46
  )
52
47
 
53
- return controllers.map(({ name, file, clients }) => {
54
- return (
55
- <File
56
- key={file.path}
57
- baseName={file.baseName}
58
- path={file.path}
59
- meta={file.meta}
60
- banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
61
- footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
62
- >
63
- {clients.map((client) => (
64
- <File.Import key={client.name} name={[client.name]} root={file.path} path={client.file.path} />
65
- ))}
48
+ return (
49
+ <>
50
+ {controllers.map(({ name, file, clients }) => {
51
+ return (
52
+ <File
53
+ key={file.path}
54
+ baseName={file.baseName}
55
+ path={file.path}
56
+ meta={file.meta}
57
+ banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
58
+ footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
59
+ >
60
+ {clients.map((client) => (
61
+ <File.Import key={client.name} name={[client.name]} root={file.path} path={client.file.path} />
62
+ ))}
66
63
 
67
- <File.Source name={name} isExportable isIndexable>
68
- <Function export name={name}>
69
- {`return { ${clients.map((client) => client.name).join(', ')} }`}
70
- </Function>
71
- </File.Source>
72
- </File>
73
- )
74
- })
64
+ <File.Source name={name} isExportable isIndexable>
65
+ <Function export name={name}>
66
+ {`return { ${clients.map((client) => client.name).join(', ')} }`}
67
+ </Function>
68
+ </File.Source>
69
+ </File>
70
+ )
71
+ })}
72
+ </>
73
+ )
75
74
  },
76
75
  })
@@ -1,4 +1,3 @@
1
- import path from 'node:path'
2
1
  import { defineGenerator } from '@kubb/core'
3
2
  import { File } from '@kubb/react-fabric'
4
3
  import { Operations } from '../components/Operations'
@@ -6,10 +5,9 @@ import type { PluginClient } from '../types'
6
5
 
7
6
  export const operationsGenerator = defineGenerator<PluginClient>({
8
7
  name: 'client',
9
- type: 'react',
10
- Operations({ nodes, options, config, resolver, adapter }) {
8
+ operations(nodes, options) {
9
+ const { config, resolver, adapter, root } = this
11
10
  const { output, group } = options
12
- const root = path.resolve(config.root, config.output.path)
13
11
 
14
12
  const name = 'operations'
15
13
  const file = resolver.resolveFile({ name, extname: '.ts' }, { root, output, group })
@@ -1,6 +1,5 @@
1
1
  import path from 'node:path'
2
2
  import { camelCase, pascalCase } from '@internals/utils'
3
- import { transform } from '@kubb/ast'
4
3
  import type { OperationNode } from '@kubb/ast/types'
5
4
  import { defineGenerator } from '@kubb/core'
6
5
  import type { FabricFile } from '@kubb/fabric-core/types'
@@ -46,37 +45,35 @@ function resolveZodImportNames(node: OperationNode, zodResolver: PluginZod['reso
46
45
 
47
46
  export const staticClassClientGenerator = defineGenerator<PluginClient>({
48
47
  name: 'staticClassClient',
49
- type: 'react',
50
- Operations({ nodes, options, config, driver, resolver, adapter, plugin }) {
48
+ operations(nodes, options) {
49
+ const { adapter, config, driver, resolver, root } = this
51
50
  const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath } = options
52
51
  const baseURL = options.baseURL ?? adapter.rootNode?.meta?.baseURL
53
- const root = path.resolve(config.root, config.output.path)
54
52
 
55
- const pluginTs = driver.getPlugin<PluginTs>(pluginTsName)
53
+ const pluginTs = driver.getPlugin(pluginTsName)
56
54
  if (!pluginTs?.resolver) return null
57
55
 
58
56
  const tsResolver = pluginTs.resolver
59
57
  const tsPluginOptions = pluginTs.options
60
- const pluginZod = parser === 'zod' ? driver.getPlugin<PluginZod>(pluginZodName) : undefined
58
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
61
59
  const zodResolver = pluginZod?.resolver
62
60
 
63
61
  function buildOperationData(node: OperationNode): OperationData {
64
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node
65
62
  const typeFile = tsResolver.resolveFile(
66
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
63
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
67
64
  { root, output: tsPluginOptions?.output ?? output, group: tsPluginOptions?.group },
68
65
  )
69
66
  const zodFile =
70
67
  zodResolver && pluginZod?.options
71
68
  ? zodResolver.resolveFile(
72
- { name: transformedNode.operationId, extname: '.ts', tag: transformedNode.tags[0] ?? 'default', path: transformedNode.path },
69
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
73
70
  { root, output: pluginZod.options.output ?? output, group: pluginZod.options.group },
74
71
  )
75
72
  : undefined
76
73
 
77
74
  return {
78
- node: transformedNode,
79
- name: resolver.resolveName(transformedNode.operationId),
75
+ node: node,
76
+ name: resolver.resolveName(node.operationId),
80
77
  tsResolver,
81
78
  zodResolver,
82
79
  typeFile,
@@ -157,71 +154,75 @@ export const staticClassClientGenerator = defineGenerator<PluginClient>({
157
154
  return { zodImportsByFile, zodFilesByPath }
158
155
  }
159
156
 
160
- return controllers.map(({ name, file, operations: ops }) => {
161
- const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops)
162
- const { zodImportsByFile, zodFilesByPath } =
163
- parser === 'zod' ? collectZodImports(ops) : { zodImportsByFile: new Map<string, Set<string>>(), zodFilesByPath: new Map<string, FabricFile.File>() }
164
- const hasFormData = ops.some((op) => op.node.requestBody?.contentType === 'multipart/form-data')
165
-
166
- return (
167
- <File
168
- key={file.path}
169
- baseName={file.baseName}
170
- path={file.path}
171
- meta={file.meta}
172
- banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
173
- footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
174
- >
175
- {importPath ? (
176
- <>
177
- <File.Import name={'fetch'} path={importPath} />
178
- <File.Import name={['mergeConfig']} path={importPath} />
179
- <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={importPath} isTypeOnly />
180
- </>
181
- ) : (
182
- <>
183
- <File.Import name={['fetch']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
184
- <File.Import name={['mergeConfig']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
185
- <File.Import
186
- name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
187
- root={file.path}
188
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
189
- isTypeOnly
157
+ return (
158
+ <>
159
+ {controllers.map(({ name, file, operations: ops }) => {
160
+ const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops)
161
+ const { zodImportsByFile, zodFilesByPath } =
162
+ parser === 'zod' ? collectZodImports(ops) : { zodImportsByFile: new Map<string, Set<string>>(), zodFilesByPath: new Map<string, FabricFile.File>() }
163
+ const hasFormData = ops.some((op) => op.node.requestBody?.contentType === 'multipart/form-data')
164
+
165
+ return (
166
+ <File
167
+ key={file.path}
168
+ baseName={file.baseName}
169
+ path={file.path}
170
+ meta={file.meta}
171
+ banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
172
+ footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
173
+ >
174
+ {importPath ? (
175
+ <>
176
+ <File.Import name={'fetch'} path={importPath} />
177
+ <File.Import name={['mergeConfig']} path={importPath} />
178
+ <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={importPath} isTypeOnly />
179
+ </>
180
+ ) : (
181
+ <>
182
+ <File.Import name={['fetch']} root={file.path} path={path.resolve(root, '.kubb/fetch.ts')} />
183
+ <File.Import name={['mergeConfig']} root={file.path} path={path.resolve(root, '.kubb/fetch.ts')} />
184
+ <File.Import
185
+ name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
186
+ root={file.path}
187
+ path={path.resolve(root, '.kubb/fetch.ts')}
188
+ isTypeOnly
189
+ />
190
+ </>
191
+ )}
192
+
193
+ {hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(root, '.kubb/config.ts')} />}
194
+
195
+ {Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
196
+ const typeFile = typeFilesByPath.get(filePath)
197
+ if (!typeFile) return null
198
+ const importNames = Array.from(importSet).filter(Boolean)
199
+ if (importNames.length === 0) return null
200
+ return <File.Import key={filePath} name={importNames} root={file.path} path={typeFile.path} isTypeOnly />
201
+ })}
202
+
203
+ {parser === 'zod' &&
204
+ Array.from(zodImportsByFile.entries()).map(([filePath, importSet]) => {
205
+ const zodFile = zodFilesByPath.get(filePath)
206
+ if (!zodFile) return null
207
+ const importNames = Array.from(importSet).filter(Boolean)
208
+ if (importNames.length === 0) return null
209
+ return <File.Import key={filePath} name={importNames} root={file.path} path={zodFile.path} />
210
+ })}
211
+
212
+ <StaticClassClient
213
+ name={name}
214
+ operations={ops}
215
+ baseURL={baseURL}
216
+ dataReturnType={dataReturnType}
217
+ pathParamsType={pathParamsType}
218
+ paramsCasing={paramsCasing}
219
+ paramsType={paramsType}
220
+ parser={parser}
190
221
  />
191
- </>
192
- )}
193
-
194
- {hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/config.ts')} />}
195
-
196
- {Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
197
- const typeFile = typeFilesByPath.get(filePath)
198
- if (!typeFile) return null
199
- const importNames = Array.from(importSet).filter(Boolean)
200
- if (importNames.length === 0) return null
201
- return <File.Import key={filePath} name={importNames} root={file.path} path={typeFile.path} isTypeOnly />
202
- })}
203
-
204
- {parser === 'zod' &&
205
- Array.from(zodImportsByFile.entries()).map(([filePath, importSet]) => {
206
- const zodFile = zodFilesByPath.get(filePath)
207
- if (!zodFile) return null
208
- const importNames = Array.from(importSet).filter(Boolean)
209
- if (importNames.length === 0) return null
210
- return <File.Import key={filePath} name={importNames} root={file.path} path={zodFile.path} />
211
- })}
212
-
213
- <StaticClassClient
214
- name={name}
215
- operations={ops}
216
- baseURL={baseURL}
217
- dataReturnType={dataReturnType}
218
- pathParamsType={pathParamsType}
219
- paramsCasing={paramsCasing}
220
- paramsType={paramsType}
221
- parser={parser}
222
- />
223
- </File>
224
- )
225
- })
222
+ </File>
223
+ )
224
+ })}
225
+ </>
226
+ )
226
227
  },
227
228
  })