@kubb/plugin-client 5.0.0-alpha.8 → 5.0.0-beta.10

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.
Files changed (62) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +27 -7
  3. package/dist/clients/axios.cjs +10 -3
  4. package/dist/clients/axios.cjs.map +1 -1
  5. package/dist/clients/axios.d.ts +5 -4
  6. package/dist/clients/axios.js +9 -2
  7. package/dist/clients/axios.js.map +1 -1
  8. package/dist/clients/fetch.cjs +5 -2
  9. package/dist/clients/fetch.cjs.map +1 -1
  10. package/dist/clients/fetch.d.ts +3 -2
  11. package/dist/clients/fetch.js +5 -2
  12. package/dist/clients/fetch.js.map +1 -1
  13. package/dist/index.cjs +1818 -97
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +330 -4
  16. package/dist/index.js +1804 -95
  17. package/dist/index.js.map +1 -1
  18. package/dist/templates/clients/axios.source.cjs +1 -1
  19. package/dist/templates/clients/axios.source.js +1 -1
  20. package/dist/templates/clients/fetch.source.cjs +1 -1
  21. package/dist/templates/clients/fetch.source.js +1 -1
  22. package/extension.yaml +776 -0
  23. package/package.json +62 -85
  24. package/src/clients/axios.ts +19 -4
  25. package/src/clients/fetch.ts +10 -2
  26. package/src/components/ClassClient.tsx +46 -145
  27. package/src/components/Client.tsx +109 -139
  28. package/src/components/Operations.tsx +10 -10
  29. package/src/components/StaticClassClient.tsx +46 -142
  30. package/src/components/Url.tsx +38 -50
  31. package/src/components/WrapperClient.tsx +11 -7
  32. package/src/functionParams.ts +118 -0
  33. package/src/generators/classClientGenerator.tsx +143 -172
  34. package/src/generators/clientGenerator.tsx +83 -81
  35. package/src/generators/groupedClientGenerator.tsx +50 -52
  36. package/src/generators/operationsGenerator.tsx +11 -18
  37. package/src/generators/staticClassClientGenerator.tsx +172 -184
  38. package/src/index.ts +9 -2
  39. package/src/plugin.ts +115 -145
  40. package/src/resolvers/resolverClient.ts +38 -0
  41. package/src/types.ts +128 -44
  42. package/src/utils.ts +156 -0
  43. package/dist/StaticClassClient-By-aMAe4.cjs +0 -677
  44. package/dist/StaticClassClient-By-aMAe4.cjs.map +0 -1
  45. package/dist/StaticClassClient-CCn9g9eF.js +0 -636
  46. package/dist/StaticClassClient-CCn9g9eF.js.map +0 -1
  47. package/dist/components.cjs +0 -7
  48. package/dist/components.d.ts +0 -216
  49. package/dist/components.js +0 -2
  50. package/dist/generators-BYUJaeZP.js +0 -723
  51. package/dist/generators-BYUJaeZP.js.map +0 -1
  52. package/dist/generators-DTxD9FDY.cjs +0 -753
  53. package/dist/generators-DTxD9FDY.cjs.map +0 -1
  54. package/dist/generators.cjs +0 -7
  55. package/dist/generators.d.ts +0 -488
  56. package/dist/generators.js +0 -2
  57. package/dist/types-DBQdg-BV.d.ts +0 -169
  58. package/src/components/index.ts +0 -5
  59. package/src/generators/index.ts +0 -5
  60. package/templates/clients/axios.ts +0 -70
  61. package/templates/clients/fetch.ts +0 -93
  62. package/templates/config.ts +0 -43
@@ -1,47 +1,41 @@
1
1
  import { camelCase } from '@internals/utils'
2
- import { usePluginDriver } from '@kubb/core/hooks'
3
- import type { KubbFile } from '@kubb/fabric-core/types'
4
- import { createReactGenerator } from '@kubb/plugin-oas/generators'
5
- import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
6
- import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
7
- import { File, Function } from '@kubb/react-fabric'
2
+ import type { ast } from '@kubb/core'
3
+ import { defineGenerator } from '@kubb/core'
4
+ import { File, Function, jsxRenderer } from '@kubb/renderer-jsx'
8
5
  import type { PluginClient } from '../types'
9
6
 
10
- export const groupedClientGenerator = createReactGenerator<PluginClient>({
7
+ export const groupedClientGenerator = defineGenerator<PluginClient>({
11
8
  name: 'groupedClient',
12
- Operations({ operations, generator, plugin }) {
13
- const { options, name: pluginName } = plugin
14
- const driver = usePluginDriver()
9
+ renderer: jsxRenderer,
10
+ operations(nodes, ctx) {
11
+ const { config, resolver, adapter, root } = ctx
12
+ const { output, group } = ctx.options
15
13
 
16
- const oas = useOas()
17
- const { getName, getFile, getGroup } = useOperationManager(generator)
14
+ const controllers = nodes.reduce(
15
+ (acc, operationNode) => {
16
+ if (group?.type === 'tag') {
17
+ const tag = operationNode.tags[0]
18
+ const name = tag ? group?.name?.({ group: camelCase(tag) }) : undefined
18
19
 
19
- const controllers = operations.reduce(
20
- (acc, operation) => {
21
- if (options.group?.type === 'tag') {
22
- const group = getGroup(operation)
23
- const name = group?.tag ? options.group?.name?.({ group: camelCase(group.tag) }) : undefined
24
-
25
- if (!group?.tag || !name) {
20
+ if (!tag || !name) {
26
21
  return acc
27
22
  }
28
23
 
29
- const file = driver.getFile({
30
- name,
31
- extname: '.ts',
32
- pluginName,
33
- options: { group },
34
- })
24
+ const file = resolver.resolveFile({ name, extname: '.ts', tag }, { root, output, group })
25
+ const clientFile = resolver.resolveFile(
26
+ { name: operationNode.operationId, extname: '.ts', tag: operationNode.tags[0] ?? 'default', path: operationNode.path },
27
+ { root, output, group },
28
+ )
35
29
 
36
30
  const client = {
37
- name: getName(operation, { type: 'function' }),
38
- file: getFile(operation),
31
+ name: resolver.resolveName(operationNode.operationId),
32
+ file: clientFile,
39
33
  }
40
34
 
41
- const previousFile = acc.find((item) => item.file.path === file.path)
35
+ const previous = acc.find((item) => item.file.path === file.path)
42
36
 
43
- if (previousFile) {
44
- previousFile.clients.push(client)
37
+ if (previous) {
38
+ previous.clients.push(client)
45
39
  } else {
46
40
  acc.push({ name, file, clients: [client] })
47
41
  }
@@ -49,30 +43,34 @@ export const groupedClientGenerator = createReactGenerator<PluginClient>({
49
43
 
50
44
  return acc
51
45
  },
52
- [] as Array<{ name: string; file: KubbFile.File; clients: Array<{ name: string; file: KubbFile.File }> }>,
46
+ [] as Array<{ name: string; file: ast.FileNode; clients: Array<{ name: string; file: ast.FileNode }> }>,
53
47
  )
54
48
 
55
- return controllers.map(({ name, file, clients }) => {
56
- return (
57
- <File
58
- key={file.path}
59
- baseName={file.baseName}
60
- path={file.path}
61
- meta={file.meta}
62
- banner={getBanner({ oas, output: options.output, config: driver.config })}
63
- footer={getFooter({ oas, output: options.output })}
64
- >
65
- {clients.map((client) => (
66
- <File.Import key={client.name} name={[client.name]} root={file.path} path={client.file.path} />
67
- ))}
49
+ return (
50
+ <>
51
+ {controllers.map(({ name, file, clients }) => {
52
+ return (
53
+ <File
54
+ key={file.path}
55
+ baseName={file.baseName}
56
+ path={file.path}
57
+ meta={file.meta}
58
+ banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
59
+ footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
60
+ >
61
+ {clients.map((client) => (
62
+ <File.Import key={client.name} name={[client.name]} root={file.path} path={client.file.path} />
63
+ ))}
68
64
 
69
- <File.Source name={name} isExportable isIndexable>
70
- <Function export name={name}>
71
- {`return { ${clients.map((client) => client.name).join(', ')} }`}
72
- </Function>
73
- </File.Source>
74
- </File>
75
- )
76
- })
65
+ <File.Source name={name} isExportable isIndexable>
66
+ <Function export name={name}>
67
+ {`return { ${clients.map((client) => client.name).join(', ')} }`}
68
+ </Function>
69
+ </File.Source>
70
+ </File>
71
+ )
72
+ })}
73
+ </>
74
+ )
77
75
  },
78
76
  })
@@ -1,34 +1,27 @@
1
- import { usePluginDriver } from '@kubb/core/hooks'
2
- import { createReactGenerator } from '@kubb/plugin-oas/generators'
3
- import { useOas } from '@kubb/plugin-oas/hooks'
4
- import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
5
- import { File } from '@kubb/react-fabric'
1
+ import { defineGenerator } from '@kubb/core'
2
+ import { File, jsxRenderer } from '@kubb/renderer-jsx'
6
3
  import { Operations } from '../components/Operations'
7
4
  import type { PluginClient } from '../types'
8
5
 
9
- export const operationsGenerator = createReactGenerator<PluginClient>({
6
+ export const operationsGenerator = defineGenerator<PluginClient>({
10
7
  name: 'client',
11
- Operations({ operations, plugin }) {
12
- const {
13
- name: pluginName,
14
- options: { output },
15
- } = plugin
16
- const driver = usePluginDriver()
17
-
18
- const oas = useOas()
8
+ renderer: jsxRenderer,
9
+ operations(nodes, ctx) {
10
+ const { config, resolver, adapter, root } = ctx
11
+ const { output, group } = ctx.options
19
12
 
20
13
  const name = 'operations'
21
- const file = driver.getFile({ name, extname: '.ts', pluginName })
14
+ const file = resolver.resolveFile({ name, extname: '.ts' }, { root, output, group })
22
15
 
23
16
  return (
24
17
  <File
25
18
  baseName={file.baseName}
26
19
  path={file.path}
27
20
  meta={file.meta}
28
- banner={getBanner({ oas, output, config: driver.config })}
29
- footer={getFooter({ oas, output })}
21
+ banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
22
+ footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
30
23
  >
31
- <Operations name={name} operations={operations} />
24
+ <Operations name={name} nodes={nodes} />
32
25
  </File>
33
26
  )
34
27
  },
@@ -1,132 +1,127 @@
1
1
  import path from 'node:path'
2
- import { camelCase, pascalCase } from '@internals/utils'
3
- import { usePluginDriver } from '@kubb/core/hooks'
4
- import type { KubbFile } from '@kubb/fabric-core/types'
5
- import type { Operation } from '@kubb/oas'
6
- import type { OperationSchemas } from '@kubb/plugin-oas'
7
- import { createReactGenerator } from '@kubb/plugin-oas/generators'
8
- import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
9
- import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
2
+ import { resolveOperationTypeNames } from '@internals/shared'
3
+ import { camelCase } from '@internals/utils'
4
+ import type { ast } from '@kubb/core'
5
+ import { defineGenerator } from '@kubb/core'
6
+ import type { ResolverTs } from '@kubb/plugin-ts'
10
7
  import { pluginTsName } from '@kubb/plugin-ts'
8
+ import type { ResolverZod } from '@kubb/plugin-zod'
11
9
  import { pluginZodName } from '@kubb/plugin-zod'
12
- import { File } from '@kubb/react-fabric'
10
+ import { File, jsxRenderer } from '@kubb/renderer-jsx'
13
11
  import { StaticClassClient } from '../components/StaticClassClient'
14
12
  import type { PluginClient } from '../types'
15
13
 
16
14
  type OperationData = {
17
- operation: Operation
15
+ node: ast.OperationNode
18
16
  name: string
19
- typeSchemas: OperationSchemas
20
- zodSchemas: OperationSchemas | undefined
21
- typeFile: KubbFile.File
22
- zodFile: KubbFile.File
17
+ tsResolver: ResolverTs
18
+ zodResolver: ResolverZod | undefined
19
+ typeFile: ast.FileNode
20
+ zodFile: ast.FileNode | undefined
23
21
  }
24
22
 
25
23
  type Controller = {
26
24
  name: string
27
- file: KubbFile.File
25
+ file: ast.FileNode
28
26
  operations: Array<OperationData>
29
27
  }
30
28
 
31
- export const staticClassClientGenerator = createReactGenerator<PluginClient>({
32
- name: 'staticClassClient',
33
- Operations({ operations, generator, plugin, config }) {
34
- const { options, name: pluginName } = plugin
35
- const driver = usePluginDriver()
36
-
37
- const oas = useOas()
38
- const { getName, getFile, getGroup, getSchemas } = useOperationManager(generator)
29
+ function resolveTypeImportNames(node: ast.OperationNode, tsResolver: ResolverTs): Array<string> {
30
+ return resolveOperationTypeNames(node, tsResolver, { order: 'body-response-first' })
31
+ }
39
32
 
40
- function buildOperationData(operation: Operation): OperationData {
41
- const type = {
42
- file: getFile(operation, { pluginName: pluginTsName }),
43
- schemas: getSchemas(operation, { pluginName: pluginTsName, type: 'type' }),
44
- }
33
+ function resolveZodImportNames(node: ast.OperationNode, zodResolver: ResolverZod): Array<string> {
34
+ const names: Array<string | undefined> = [
35
+ zodResolver.resolveResponseName?.(node),
36
+ node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : undefined,
37
+ ]
38
+ return names.filter((n): n is string => Boolean(n))
39
+ }
45
40
 
46
- const zod = {
47
- file: getFile(operation, { pluginName: pluginZodName }),
48
- schemas: getSchemas(operation, { pluginName: pluginZodName, type: 'function' }),
49
- }
41
+ export const staticClassClientGenerator = defineGenerator<PluginClient>({
42
+ name: 'staticClassClient',
43
+ renderer: jsxRenderer,
44
+ operations(nodes, ctx) {
45
+ const { adapter, config, driver, resolver, root } = ctx
46
+ const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath } = ctx.options
47
+ const baseURL = ctx.options.baseURL ?? adapter.inputNode?.meta?.baseURL
48
+
49
+ const pluginTs = driver.getPlugin(pluginTsName)
50
+ if (!pluginTs) return null
51
+
52
+ const tsResolver = driver.getResolver(pluginTsName)
53
+ const tsPluginOptions = pluginTs.options
54
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
55
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
56
+
57
+ function buildOperationData(node: ast.OperationNode): OperationData {
58
+ const typeFile = tsResolver.resolveFile(
59
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
60
+ { root, output: tsPluginOptions?.output ?? output, group: tsPluginOptions?.group },
61
+ )
62
+ const zodFile =
63
+ zodResolver && pluginZod?.options
64
+ ? zodResolver.resolveFile(
65
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
66
+ { root, output: pluginZod.options?.output ?? output, group: pluginZod.options?.group },
67
+ )
68
+ : undefined
50
69
 
51
70
  return {
52
- operation,
53
- name: getName(operation, { type: 'function' }),
54
- typeSchemas: type.schemas,
55
- zodSchemas: zod.schemas,
56
- typeFile: type.file,
57
- zodFile: zod.file,
71
+ node: node,
72
+ name: resolver.resolveName(node.operationId),
73
+ tsResolver,
74
+ zodResolver,
75
+ typeFile,
76
+ zodFile,
58
77
  }
59
78
  }
60
79
 
61
- // Group operations by tag
62
- const controllers = operations.reduce(
63
- (acc, operation) => {
64
- const group = getGroup(operation)
65
- const groupName = group?.tag ? (options.group?.name?.({ group: camelCase(group.tag) }) ?? pascalCase(group.tag)) : 'Client'
66
-
67
- if (!group?.tag && !options.group) {
68
- // If no grouping, put all operations in a single class
69
- const name = 'ApiClient'
70
- const file = driver.getFile({
71
- name,
72
- extname: '.ts',
73
- pluginName,
74
- })
75
-
76
- const operationData = buildOperationData(operation)
77
- const previousFile = acc.find((item) => item.file.path === file.path)
78
-
79
- if (previousFile) {
80
- previousFile.operations.push(operationData)
81
- } else {
82
- acc.push({ name, file, operations: [operationData] })
83
- }
84
- } else if (group?.tag) {
85
- // Group by tag
86
- const name = groupName
87
- const file = driver.getFile({
88
- name,
89
- extname: '.ts',
90
- pluginName,
91
- options: { group },
92
- })
93
-
94
- const operationData = buildOperationData(operation)
95
- const previousFile = acc.find((item) => item.file.path === file.path)
96
-
97
- if (previousFile) {
98
- previousFile.operations.push(operationData)
99
- } else {
100
- acc.push({ name, file, operations: [operationData] })
101
- }
80
+ const controllers = nodes.reduce((acc, operationNode) => {
81
+ const tag = operationNode.tags[0]
82
+ const groupName = tag ? (group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag)) : resolver.resolveGroupName('Client')
83
+
84
+ if (!tag && !group) {
85
+ const name = resolver.resolveClassName('ApiClient')
86
+ const file = resolver.resolveFile({ name, extname: '.ts' }, { root, output, group })
87
+ const operationData = buildOperationData(operationNode)
88
+ const previous = acc.find((item) => item.file.path === file.path)
89
+
90
+ if (previous) {
91
+ previous.operations.push(operationData)
92
+ } else {
93
+ acc.push({ name, file, operations: [operationData] })
102
94
  }
95
+ } else if (tag) {
96
+ const name = groupName
97
+ const file = resolver.resolveFile({ name, extname: '.ts', tag }, { root, output, group })
98
+ const operationData = buildOperationData(operationNode)
99
+ const previous = acc.find((item) => item.file.path === file.path)
100
+
101
+ if (previous) {
102
+ previous.operations.push(operationData)
103
+ } else {
104
+ acc.push({ name, file, operations: [operationData] })
105
+ }
106
+ }
103
107
 
104
- return acc
105
- },
106
- [] as Array<Controller>,
107
- )
108
+ return acc
109
+ }, [] as Array<Controller>)
108
110
 
109
111
  function collectTypeImports(ops: Array<OperationData>) {
110
112
  const typeImportsByFile = new Map<string, Set<string>>()
111
- const typeFilesByPath = new Map<string, KubbFile.File>()
113
+ const typeFilesByPath = new Map<string, ast.FileNode>()
112
114
 
113
115
  ops.forEach((op) => {
114
- const { typeSchemas, typeFile } = op
115
-
116
- if (!typeImportsByFile.has(typeFile.path)) {
117
- typeImportsByFile.set(typeFile.path, new Set())
116
+ const names = resolveTypeImportNames(op.node, tsResolver)
117
+ if (!typeImportsByFile.has(op.typeFile.path)) {
118
+ typeImportsByFile.set(op.typeFile.path, new Set())
118
119
  }
119
- const typeImports = typeImportsByFile.get(typeFile.path)!
120
-
121
- if (typeSchemas.request?.name) typeImports.add(typeSchemas.request.name)
122
- if (typeSchemas.response?.name) typeImports.add(typeSchemas.response.name)
123
- if (typeSchemas.pathParams?.name) typeImports.add(typeSchemas.pathParams.name)
124
- if (typeSchemas.queryParams?.name) typeImports.add(typeSchemas.queryParams.name)
125
- if (typeSchemas.headerParams?.name) typeImports.add(typeSchemas.headerParams.name)
126
- typeSchemas.statusCodes?.forEach((item) => {
127
- if (item?.name) typeImports.add(item.name)
120
+ const imports = typeImportsByFile.get(op.typeFile.path)!
121
+ names.forEach((n) => {
122
+ imports.add(n)
128
123
  })
129
- typeFilesByPath.set(typeFile.path, typeFile)
124
+ typeFilesByPath.set(op.typeFile.path, op.typeFile)
130
125
  })
131
126
 
132
127
  return { typeImportsByFile, typeFilesByPath }
@@ -134,100 +129,93 @@ export const staticClassClientGenerator = createReactGenerator<PluginClient>({
134
129
 
135
130
  function collectZodImports(ops: Array<OperationData>) {
136
131
  const zodImportsByFile = new Map<string, Set<string>>()
137
- const zodFilesByPath = new Map<string, KubbFile.File>()
132
+ const zodFilesByPath = new Map<string, ast.FileNode>()
138
133
 
139
134
  ops.forEach((op) => {
140
- const { zodSchemas, zodFile } = op
141
-
142
- if (!zodImportsByFile.has(zodFile.path)) {
143
- zodImportsByFile.set(zodFile.path, new Set())
135
+ if (!op.zodFile || !zodResolver) return
136
+ const names = resolveZodImportNames(op.node, zodResolver)
137
+ if (!zodImportsByFile.has(op.zodFile.path)) {
138
+ zodImportsByFile.set(op.zodFile.path, new Set())
144
139
  }
145
- const zodImports = zodImportsByFile.get(zodFile.path)!
146
-
147
- if (zodSchemas?.response?.name) zodImports.add(zodSchemas.response.name)
148
- if (zodSchemas?.request?.name) zodImports.add(zodSchemas.request.name)
149
- zodFilesByPath.set(zodFile.path, zodFile)
140
+ const imports = zodImportsByFile.get(op.zodFile.path)!
141
+ names.forEach((n) => {
142
+ imports.add(n)
143
+ })
144
+ zodFilesByPath.set(op.zodFile.path, op.zodFile)
150
145
  })
151
146
 
152
147
  return { zodImportsByFile, zodFilesByPath }
153
148
  }
154
149
 
155
- return controllers.map(({ name, file, operations: ops }) => {
156
- const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops)
157
- const { zodImportsByFile, zodFilesByPath } =
158
- options.parser === 'zod'
159
- ? collectZodImports(ops)
160
- : { zodImportsByFile: new Map<string, Set<string>>(), zodFilesByPath: new Map<string, KubbFile.File>() }
161
- const hasFormData = ops.some((op) => op.operation.getContentType() === 'multipart/form-data')
162
-
163
- return (
164
- <File
165
- key={file.path}
166
- baseName={file.baseName}
167
- path={file.path}
168
- meta={file.meta}
169
- banner={getBanner({ oas, output: options.output, config: driver.config })}
170
- footer={getFooter({ oas, output: options.output })}
171
- >
172
- {options.importPath ? (
173
- <>
174
- <File.Import name={'fetch'} path={options.importPath} />
175
- <File.Import name={['mergeConfig']} path={options.importPath} />
176
- <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={options.importPath} isTypeOnly />
177
- </>
178
- ) : (
179
- <>
180
- <File.Import name={['fetch']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
181
- <File.Import name={['mergeConfig']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
182
- <File.Import
183
- name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
184
- root={file.path}
185
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
186
- isTypeOnly
150
+ return (
151
+ <>
152
+ {controllers.map(({ name, file, operations: ops }) => {
153
+ const { typeImportsByFile, typeFilesByPath } = collectTypeImports(ops)
154
+ const { zodImportsByFile, zodFilesByPath } =
155
+ parser === 'zod' ? collectZodImports(ops) : { zodImportsByFile: new Map<string, Set<string>>(), zodFilesByPath: new Map<string, ast.FileNode>() }
156
+ const hasFormData = ops.some((op) => op.node.requestBody?.content?.some((e) => e.contentType === 'multipart/form-data') ?? false)
157
+
158
+ return (
159
+ <File
160
+ key={file.path}
161
+ baseName={file.baseName}
162
+ path={file.path}
163
+ meta={file.meta}
164
+ banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
165
+ footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
166
+ >
167
+ {importPath ? (
168
+ <>
169
+ <File.Import name={'fetch'} path={importPath} />
170
+ <File.Import name={['mergeConfig']} path={importPath} />
171
+ <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={importPath} isTypeOnly />
172
+ </>
173
+ ) : (
174
+ <>
175
+ <File.Import name={['fetch']} root={file.path} path={path.resolve(root, '.kubb/client.ts')} />
176
+ <File.Import name={['mergeConfig']} root={file.path} path={path.resolve(root, '.kubb/client.ts')} />
177
+ <File.Import
178
+ name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
179
+ root={file.path}
180
+ path={path.resolve(root, '.kubb/client.ts')}
181
+ isTypeOnly
182
+ />
183
+ </>
184
+ )}
185
+
186
+ {hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(root, '.kubb/config.ts')} />}
187
+
188
+ {Array.from(typeImportsByFile.entries()).map(([filePath, importSet]) => {
189
+ const typeFile = typeFilesByPath.get(filePath)
190
+ if (!typeFile) return null
191
+ const importNames = Array.from(importSet).filter(Boolean)
192
+ if (importNames.length === 0) return null
193
+ return <File.Import key={filePath} name={importNames} root={file.path} path={typeFile.path} isTypeOnly />
194
+ })}
195
+
196
+ {parser === 'zod' &&
197
+ Array.from(zodImportsByFile.entries()).map(([filePath, importSet]) => {
198
+ const zodFile = zodFilesByPath.get(filePath)
199
+ if (!zodFile) return null
200
+ const importNames = Array.from(importSet).filter(Boolean)
201
+ if (importNames.length === 0) return null
202
+ return <File.Import key={filePath} name={importNames} root={file.path} path={zodFile.path} />
203
+ })}
204
+
205
+ <StaticClassClient
206
+ name={name}
207
+ operations={ops}
208
+ baseURL={baseURL}
209
+ dataReturnType={dataReturnType}
210
+ pathParamsType={pathParamsType}
211
+ paramsCasing={paramsCasing}
212
+ paramsType={paramsType}
213
+ parser={parser}
187
214
  />
188
- </>
189
- )}
190
-
191
- {hasFormData && <File.Import name={['buildFormData']} root={file.path} path={path.resolve(config.root, config.output.path, '.kubb/config.ts')} />}
192
-
193
- {Array.from(typeImportsByFile.entries()).map(([filePath, imports]) => {
194
- const typeFile = typeFilesByPath.get(filePath)
195
- if (!typeFile) {
196
- return null
197
- }
198
- const importNames = Array.from(imports).filter(Boolean)
199
- if (importNames.length === 0) {
200
- return null
201
- }
202
- return <File.Import key={filePath} name={importNames} root={file.path} path={typeFile.path} isTypeOnly />
203
- })}
204
-
205
- {options.parser === 'zod' &&
206
- Array.from(zodImportsByFile.entries()).map(([filePath, imports]) => {
207
- const zodFile = zodFilesByPath.get(filePath)
208
- if (!zodFile) {
209
- return null
210
- }
211
- const importNames = Array.from(imports).filter(Boolean)
212
- if (importNames.length === 0) {
213
- return null
214
- }
215
-
216
- return <File.Import key={filePath} name={importNames} root={file.path} path={zodFile.path} />
217
- })}
218
-
219
- <StaticClassClient
220
- name={name}
221
- operations={ops}
222
- baseURL={options.baseURL}
223
- dataReturnType={options.dataReturnType}
224
- pathParamsType={options.pathParamsType}
225
- paramsCasing={options.paramsCasing}
226
- paramsType={options.paramsType}
227
- parser={options.parser}
228
- />
229
- </File>
230
- )
231
- })
215
+ </File>
216
+ )
217
+ })}
218
+ </>
219
+ )
232
220
  },
233
221
  })
package/src/index.ts CHANGED
@@ -1,2 +1,9 @@
1
- export { pluginClient, pluginClientName } from './plugin.ts'
2
- export type { ClientImportPath, PluginClient } from './types.ts'
1
+ export { Client } from './components/Client.tsx'
2
+ export { classClientGenerator } from './generators/classClientGenerator.tsx'
3
+ export { clientGenerator } from './generators/clientGenerator.tsx'
4
+ export { groupedClientGenerator } from './generators/groupedClientGenerator.tsx'
5
+ export { operationsGenerator } from './generators/operationsGenerator.tsx'
6
+ export { staticClassClientGenerator } from './generators/staticClassClientGenerator.tsx'
7
+ export { default, pluginClient, pluginClientName } from './plugin.ts'
8
+ export { resolverClient } from './resolvers/resolverClient.ts'
9
+ export type { ClientImportPath, PluginClient, ResolverClient } from './types.ts'