@kubb/plugin-react-query 5.0.0-alpha.9 → 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 (54) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +34 -85
  3. package/dist/components-Dow6tde8.js +1459 -0
  4. package/dist/components-Dow6tde8.js.map +1 -0
  5. package/dist/components-HwdCDefj.cjs +1603 -0
  6. package/dist/components-HwdCDefj.cjs.map +1 -0
  7. package/dist/components.cjs +1 -1
  8. package/dist/components.d.ts +49 -179
  9. package/dist/components.js +1 -1
  10. package/dist/generators-CcOmnTPa.cjs +1454 -0
  11. package/dist/generators-CcOmnTPa.cjs.map +1 -0
  12. package/dist/generators-yfZr_qfT.js +1412 -0
  13. package/dist/generators-yfZr_qfT.js.map +1 -0
  14. package/dist/generators.cjs +1 -1
  15. package/dist/generators.d.ts +9 -505
  16. package/dist/generators.js +1 -1
  17. package/dist/index.cjs +197 -126
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +193 -126
  21. package/dist/index.js.map +1 -1
  22. package/dist/types-DG_OxOym.d.ts +363 -0
  23. package/extension.yaml +911 -0
  24. package/package.json +59 -64
  25. package/src/components/InfiniteQuery.tsx +79 -138
  26. package/src/components/InfiniteQueryOptions.tsx +55 -166
  27. package/src/components/Mutation.tsx +74 -111
  28. package/src/components/MutationOptions.tsx +61 -80
  29. package/src/components/Query.tsx +66 -142
  30. package/src/components/QueryOptions.tsx +56 -138
  31. package/src/components/SuspenseInfiniteQuery.tsx +79 -138
  32. package/src/components/SuspenseInfiniteQueryOptions.tsx +55 -166
  33. package/src/components/SuspenseQuery.tsx +66 -152
  34. package/src/generators/customHookOptionsFileGenerator.tsx +37 -51
  35. package/src/generators/hookOptionsGenerator.tsx +111 -174
  36. package/src/generators/infiniteQueryGenerator.tsx +158 -178
  37. package/src/generators/mutationGenerator.tsx +112 -139
  38. package/src/generators/queryGenerator.tsx +128 -142
  39. package/src/generators/suspenseInfiniteQueryGenerator.tsx +157 -156
  40. package/src/generators/suspenseQueryGenerator.tsx +126 -152
  41. package/src/index.ts +1 -1
  42. package/src/plugin.ts +134 -187
  43. package/src/resolvers/resolverReactQuery.ts +107 -0
  44. package/src/types.ts +172 -49
  45. package/src/utils.ts +10 -0
  46. package/dist/components-BHQT9ZLc.cjs +0 -1634
  47. package/dist/components-BHQT9ZLc.cjs.map +0 -1
  48. package/dist/components-CpyHYGOw.js +0 -1520
  49. package/dist/components-CpyHYGOw.js.map +0 -1
  50. package/dist/generators-DP07m3rH.cjs +0 -1469
  51. package/dist/generators-DP07m3rH.cjs.map +0 -1
  52. package/dist/generators-DkQwKTc2.js +0 -1427
  53. package/dist/generators-DkQwKTc2.js.map +0 -1
  54. package/dist/types-D5S7Ny9r.d.ts +0 -270
@@ -1,191 +1,164 @@
1
1
  import path from 'node:path'
2
- import { usePluginDriver } from '@kubb/core/hooks'
3
- import { pluginClientName } from '@kubb/plugin-client'
4
- import { Client } from '@kubb/plugin-client/components'
5
- import { createReactGenerator } from '@kubb/plugin-oas/generators'
6
- import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
7
- import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
2
+ import { resolveOperationTypeNames } from '@internals/shared'
3
+ import { resolveZodSchemaNames } from '@internals/tanstack-query'
4
+ import { defineGenerator } from '@kubb/core'
5
+ import { Client, pluginClientName } from '@kubb/plugin-client'
8
6
  import { pluginTsName } from '@kubb/plugin-ts'
9
7
  import { pluginZodName } from '@kubb/plugin-zod'
10
- import { File } from '@kubb/react-fabric'
8
+ import { File, jsxRenderer } from '@kubb/renderer-jsx'
11
9
  import { difference } from 'remeda'
12
- import { Mutation, MutationKey } from '../components'
13
- import { MutationOptions } from '../components/MutationOptions.tsx'
10
+ import { Mutation, MutationKey, MutationOptions } from '../components'
14
11
  import type { PluginReactQuery } from '../types'
15
12
 
16
- export const mutationGenerator = createReactGenerator<PluginReactQuery>({
17
- name: 'react-query',
18
- Operation({ config, plugin, operation, generator }) {
19
- const {
20
- options,
21
- options: { output },
22
- } = plugin
23
- const driver = usePluginDriver()
13
+ export const mutationGenerator = defineGenerator<PluginReactQuery>({
14
+ name: 'react-query-mutation',
15
+ renderer: jsxRenderer,
16
+ operation(node, ctx) {
17
+ const { adapter, config, driver, resolver, root } = ctx
18
+ const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options
24
19
 
25
- const oas = useOas()
26
- const { getSchemas, getName, getFile } = useOperationManager(generator)
20
+ const pluginTs = driver.getPlugin(pluginTsName)
21
+ if (!pluginTs) return null
22
+ const tsResolver = driver.getResolver(pluginTsName)
27
23
 
28
- const isQuery = !!options.query && options.query?.methods.some((method) => operation.method === method)
24
+ const isQuery = query === false || (!!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase()))
29
25
  const isMutation =
30
- options.mutation !== false &&
26
+ mutation !== false &&
31
27
  !isQuery &&
32
- difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method)
28
+ difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase())
33
29
 
34
- const importPath = options.mutation ? options.mutation.importPath : '@tanstack/react-query'
30
+ if (!isMutation) return null
35
31
 
36
- const mutation = {
37
- name: getName(operation, { type: 'function', prefix: 'use' }),
38
- typeName: getName(operation, { type: 'type' }),
39
- file: getFile(operation, { prefix: 'use' }),
40
- }
32
+ const importPath = mutation ? mutation.importPath : '@tanstack/react-query'
41
33
 
42
- const type = {
43
- file: getFile(operation, { pluginName: pluginTsName }),
44
- //todo remove type?
45
- schemas: getSchemas(operation, { pluginName: pluginTsName, type: 'type' }),
46
- }
34
+ const mutationHookName = resolver.resolveMutationName(node)
35
+ const mutationTypeName = resolver.resolveMutationTypeName(node)
36
+ const mutationOptionsName = resolver.resolveMutationOptionsName(node)
37
+ const mutationKeyName = resolver.resolveMutationKeyName(node)
38
+ const clientName = resolver.resolveClientName(node)
47
39
 
48
- const zod = {
49
- file: getFile(operation, { pluginName: pluginZodName }),
50
- schemas: getSchemas(operation, { pluginName: pluginZodName, type: 'function' }),
40
+ const meta = {
41
+ file: resolver.resolveFile({ name: mutationHookName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
42
+ fileTs: tsResolver.resolveFile(
43
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
44
+ { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
45
+ ),
51
46
  }
52
47
 
53
- const hasClientPlugin = !!driver.getPluginByName(pluginClientName)
54
- // Class-based clients are not compatible with query hooks, so we generate inline clients
55
- const shouldUseClientPlugin = hasClientPlugin && options.client.clientType !== 'class'
56
- const client = {
57
- name: shouldUseClientPlugin
58
- ? getName(operation, {
59
- type: 'function',
60
- pluginName: pluginClientName,
61
- })
62
- : getName(operation, {
63
- type: 'function',
64
- }),
65
- file: getFile(operation, { pluginName: pluginClientName }),
66
- }
48
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing, order: 'body-response-first' })
67
49
 
68
- const mutationOptions = {
69
- name: getName(operation, { type: 'function', suffix: 'MutationOptions' }),
70
- }
50
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
51
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
52
+ const fileZod = zodResolver
53
+ ? zodResolver.resolveFile(
54
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
55
+ { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
56
+ )
57
+ : undefined
58
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
71
59
 
72
- const mutationKey = {
73
- name: getName(operation, { type: 'const', suffix: 'MutationKey' }),
74
- typeName: getName(operation, { type: 'type', suffix: 'MutationKey' }),
75
- }
60
+ const clientPlugin = driver.getPlugin(pluginClientName)
61
+ const hasClientPlugin = clientPlugin?.name === pluginClientName
62
+ const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
63
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : undefined
76
64
 
77
- if (!isMutation) {
78
- return null
79
- }
65
+ const clientFile = shouldUseClientPlugin
66
+ ? clientResolver?.resolveFile(
67
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
68
+ {
69
+ root,
70
+ output: clientPlugin?.options?.output ?? output,
71
+ group: clientPlugin?.options?.group,
72
+ },
73
+ )
74
+ : undefined
75
+
76
+ const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
80
77
 
81
78
  return (
82
79
  <File
83
- baseName={mutation.file.baseName}
84
- path={mutation.file.path}
85
- meta={mutation.file.meta}
86
- banner={getBanner({ oas, output, config: driver.config })}
87
- footer={getFooter({ oas, output })}
80
+ baseName={meta.file.baseName}
81
+ path={meta.file.path}
82
+ meta={meta.file.meta}
83
+ banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
84
+ footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
88
85
  >
89
- {options.parser === 'zod' && (
90
- <File.Import name={[zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean)} root={mutation.file.path} path={zod.file.path} />
91
- )}
92
- {options.client.importPath ? (
86
+ {fileZod && zodSchemaNames.length > 0 && <File.Import name={zodSchemaNames} root={meta.file.path} path={fileZod.path} />}
87
+ {clientOptions.importPath ? (
93
88
  <>
94
- {!shouldUseClientPlugin && <File.Import name={'fetch'} path={options.client.importPath} />}
95
- <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={options.client.importPath} isTypeOnly />
96
- {options.client.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={options.client.importPath} isTypeOnly />}
89
+ {!shouldUseClientPlugin && <File.Import name={'fetch'} path={clientOptions.importPath} />}
90
+ <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={clientOptions.importPath} isTypeOnly />
91
+ {clientOptions.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={clientOptions.importPath} isTypeOnly />}
97
92
  </>
98
93
  ) : (
99
94
  <>
100
- {!shouldUseClientPlugin && (
101
- <File.Import name={['fetch']} root={mutation.file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
102
- )}
95
+ {!shouldUseClientPlugin && <File.Import name={['fetch']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} />}
103
96
  <File.Import
104
97
  name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
105
- root={mutation.file.path}
106
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
98
+ root={meta.file.path}
99
+ path={path.resolve(root, '.kubb/fetch.ts')}
107
100
  isTypeOnly
108
101
  />
109
- {options.client.dataReturnType === 'full' && (
110
- <File.Import
111
- name={['ResponseConfig']}
112
- root={mutation.file.path}
113
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
114
- isTypeOnly
115
- />
102
+ {clientOptions.dataReturnType === 'full' && (
103
+ <File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} isTypeOnly />
116
104
  )}
117
105
  </>
118
106
  )}
119
- {shouldUseClientPlugin && <File.Import name={[client.name]} root={mutation.file.path} path={client.file.path} />}
120
- {!shouldUseClientPlugin && (
121
- <File.Import name={['buildFormData']} root={mutation.file.path} path={path.resolve(config.root, config.output.path, '.kubb/config.ts')} />
107
+ {shouldUseClientPlugin && clientFile && <File.Import name={[resolvedClientName]} root={meta.file.path} path={clientFile.path} />}
108
+ {!shouldUseClientPlugin && node.requestBody?.content?.some((e) => e.contentType === 'multipart/form-data') && (
109
+ <File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(root, '.kubb/config.ts')} />
110
+ )}
111
+ {customOptions && <File.Import name={[customOptions.name]} path={customOptions.importPath} />}
112
+ {meta.fileTs && importedTypeNames.length > 0 && (
113
+ <File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />
122
114
  )}
123
- {options.customOptions && <File.Import name={[options.customOptions.name]} path={options.customOptions.importPath} />}
124
- <File.Import
125
- name={[
126
- type.schemas.request?.name,
127
- type.schemas.response.name,
128
- type.schemas.pathParams?.name,
129
- type.schemas.queryParams?.name,
130
- type.schemas.headerParams?.name,
131
- ...(type.schemas.statusCodes?.map((item) => item.name) || []),
132
- ].filter(Boolean)}
133
- root={mutation.file.path}
134
- path={type.file.path}
135
- isTypeOnly
136
- />
137
115
 
138
- <MutationKey
139
- name={mutationKey.name}
140
- typeName={mutationKey.typeName}
141
- operation={operation}
142
- pathParamsType={options.pathParamsType}
143
- typeSchemas={type.schemas}
144
- paramsCasing={options.paramsCasing}
145
- transformer={options.mutationKey}
146
- />
116
+ <MutationKey name={mutationKeyName} node={node} pathParamsType={pathParamsType} paramsCasing={paramsCasing} transformer={ctx.options.mutationKey} />
147
117
 
148
118
  {!shouldUseClientPlugin && (
149
119
  <Client
150
- name={client.name}
151
- baseURL={options.client.baseURL}
152
- operation={operation}
153
- typeSchemas={type.schemas}
154
- zodSchemas={zod.schemas}
155
- dataReturnType={options.client.dataReturnType || 'data'}
156
- paramsCasing={options.client?.paramsCasing || options.paramsCasing}
157
- paramsType={options.paramsType}
158
- pathParamsType={options.pathParamsType}
159
- parser={options.parser}
120
+ name={resolvedClientName}
121
+ baseURL={clientOptions.baseURL}
122
+ dataReturnType={clientOptions.dataReturnType || 'data'}
123
+ paramsCasing={clientOptions.paramsCasing || paramsCasing}
124
+ paramsType={paramsType}
125
+ pathParamsType={pathParamsType}
126
+ parser={parser}
127
+ node={node}
128
+ tsResolver={tsResolver}
129
+ zodResolver={zodResolver}
160
130
  />
161
131
  )}
132
+
162
133
  <File.Import name={['mutationOptions']} path={importPath} />
163
134
 
164
135
  <MutationOptions
165
- name={mutationOptions.name}
166
- clientName={client.name}
167
- mutationKeyName={mutationKey.name}
168
- typeSchemas={type.schemas}
169
- paramsCasing={options.paramsCasing}
170
- paramsType={options.paramsType}
171
- pathParamsType={options.pathParamsType}
172
- dataReturnType={options.client.dataReturnType || 'data'}
136
+ name={mutationOptionsName}
137
+ clientName={resolvedClientName}
138
+ mutationKeyName={mutationKeyName}
139
+ node={node}
140
+ tsResolver={tsResolver}
141
+ paramsCasing={paramsCasing}
142
+ paramsType={paramsType}
143
+ pathParamsType={pathParamsType}
144
+ dataReturnType={clientOptions.dataReturnType || 'data'}
173
145
  />
174
- {options.mutation && (
146
+
147
+ {mutation && (
175
148
  <>
176
149
  <File.Import name={['useMutation']} path={importPath} />
177
150
  <File.Import name={['UseMutationOptions', 'UseMutationResult', 'QueryClient']} path={importPath} isTypeOnly />
178
151
  <Mutation
179
- name={mutation.name}
180
- mutationOptionsName={mutationOptions.name}
181
- typeName={mutation.typeName}
182
- typeSchemas={type.schemas}
183
- operation={operation}
184
- dataReturnType={options.client.dataReturnType || 'data'}
185
- paramsCasing={options.paramsCasing}
186
- pathParamsType={options.pathParamsType}
187
- mutationKeyName={mutationKey.name}
188
- customOptions={options.customOptions}
152
+ name={mutationHookName}
153
+ typeName={mutationTypeName}
154
+ mutationOptionsName={mutationOptionsName}
155
+ mutationKeyName={mutationKeyName}
156
+ node={node}
157
+ tsResolver={tsResolver}
158
+ dataReturnType={clientOptions.dataReturnType || 'data'}
159
+ paramsCasing={paramsCasing}
160
+ pathParamsType={pathParamsType}
161
+ customOptions={customOptions}
189
162
  />
190
163
  </>
191
164
  )}
@@ -1,190 +1,176 @@
1
1
  import path from 'node:path'
2
- import { usePluginDriver } from '@kubb/core/hooks'
3
- import { pluginClientName } from '@kubb/plugin-client'
4
- import { Client } from '@kubb/plugin-client/components'
5
- import { createReactGenerator } from '@kubb/plugin-oas/generators'
6
- import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
7
- import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
2
+ import { resolveOperationTypeNames } from '@internals/shared'
3
+ import { resolveZodSchemaNames } from '@internals/tanstack-query'
4
+ import { defineGenerator } from '@kubb/core'
5
+ import { Client, pluginClientName } from '@kubb/plugin-client'
8
6
  import { pluginTsName } from '@kubb/plugin-ts'
9
7
  import { pluginZodName } from '@kubb/plugin-zod'
10
- import { File } from '@kubb/react-fabric'
8
+ import { File, jsxRenderer } from '@kubb/renderer-jsx'
11
9
  import { difference } from 'remeda'
12
10
  import { Query, QueryKey, QueryOptions } from '../components'
13
11
  import type { PluginReactQuery } from '../types'
14
12
 
15
- export const queryGenerator = createReactGenerator<PluginReactQuery>({
13
+ export const queryGenerator = defineGenerator<PluginReactQuery>({
16
14
  name: 'react-query',
17
- Operation({ config, plugin, operation, generator }) {
18
- const {
19
- options,
20
- options: { output },
21
- } = plugin
22
- const driver = usePluginDriver()
23
-
24
- const oas = useOas()
25
- const { getSchemas, getName, getFile } = useOperationManager(generator)
26
-
27
- const isQuery = typeof options.query === 'boolean' ? true : options.query?.methods.some((method) => operation.method === method)
28
- const isMutation = difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some(
29
- (method) => operation.method === method,
30
- )
15
+ renderer: jsxRenderer,
16
+ operation(node, ctx) {
17
+ const { adapter, config, driver, resolver, root } = ctx
18
+ const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options
31
19
 
32
- const importPath = options.query ? options.query.importPath : '@tanstack/react-query'
20
+ const pluginTs = driver.getPlugin(pluginTsName)
21
+ if (!pluginTs) return null
22
+ const tsResolver = driver.getResolver(pluginTsName)
33
23
 
34
- const query = {
35
- name: getName(operation, { type: 'function', prefix: 'use' }),
36
- typeName: getName(operation, { type: 'type' }),
37
- file: getFile(operation, { prefix: 'use' }),
38
- }
24
+ // query: false means "this IS a query op, but skip the useQuery hook"
25
+ const isQuery = query === false || (!!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase()))
26
+ const isMutation =
27
+ mutation !== false &&
28
+ !isQuery &&
29
+ difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase())
39
30
 
40
- const hasClientPlugin = !!driver.getPluginByName(pluginClientName)
41
- // Class-based clients are not compatible with query hooks, so we generate inline clients
42
- const shouldUseClientPlugin = hasClientPlugin && options.client.clientType !== 'class'
43
- const client = {
44
- name: shouldUseClientPlugin
45
- ? getName(operation, {
46
- type: 'function',
47
- pluginName: pluginClientName,
48
- })
49
- : getName(operation, {
50
- type: 'function',
51
- }),
52
- file: getFile(operation, { pluginName: pluginClientName }),
53
- }
31
+ if (!isQuery || isMutation) return null
54
32
 
55
- const queryOptions = {
56
- name: getName(operation, { type: 'function', suffix: 'QueryOptions' }),
57
- }
33
+ const importPath = query ? query.importPath : '@tanstack/react-query'
58
34
 
59
- const queryKey = {
60
- name: getName(operation, { type: 'const', suffix: 'QueryKey' }),
61
- typeName: getName(operation, { type: 'type', suffix: 'QueryKey' }),
62
- }
35
+ const queryName = resolver.resolveQueryName(node)
36
+ const queryOptionsName = resolver.resolveQueryOptionsName(node)
37
+ const queryKeyName = resolver.resolveQueryKeyName(node)
38
+ const queryKeyTypeName = resolver.resolveQueryKeyTypeName(node)
39
+ const clientName = resolver.resolveClientName(node)
63
40
 
64
- const type = {
65
- file: getFile(operation, { pluginName: pluginTsName }),
66
- //todo remove type?
67
- schemas: getSchemas(operation, {
68
- pluginName: pluginTsName,
69
- type: 'type',
70
- }),
41
+ const meta = {
42
+ file: resolver.resolveFile({ name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
43
+ fileTs: tsResolver.resolveFile(
44
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
45
+ { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
46
+ ),
71
47
  }
72
48
 
73
- const zod = {
74
- // grouping is coming from react-query instead of zod option, we need to pass the options of zod instead
75
- file: getFile(operation, { pluginName: pluginZodName }),
76
- schemas: getSchemas(operation, {
77
- pluginName: pluginZodName,
78
- type: 'function',
79
- }),
80
- }
49
+ const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
50
+ paramsCasing,
51
+ exclude: [queryKeyTypeName],
52
+ order: 'body-response-first',
53
+ })
81
54
 
82
- if (!isQuery || isMutation) {
83
- return null
84
- }
55
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
56
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
57
+ const fileZod = zodResolver
58
+ ? zodResolver.resolveFile(
59
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
60
+ { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
61
+ )
62
+ : undefined
63
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
64
+
65
+ const clientPlugin = driver.getPlugin(pluginClientName)
66
+ const hasClientPlugin = clientPlugin?.name === pluginClientName
67
+ const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
68
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : undefined
69
+
70
+ const clientFile = shouldUseClientPlugin
71
+ ? clientResolver?.resolveFile(
72
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
73
+ {
74
+ root,
75
+ output: clientPlugin?.options?.output ?? output,
76
+ group: clientPlugin?.options?.group,
77
+ },
78
+ )
79
+ : undefined
80
+
81
+ const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
85
82
 
86
83
  return (
87
84
  <File
88
- baseName={query.file.baseName}
89
- path={query.file.path}
90
- meta={query.file.meta}
91
- banner={getBanner({ oas, output, config: driver.config })}
92
- footer={getFooter({ oas, output })}
85
+ baseName={meta.file.baseName}
86
+ path={meta.file.path}
87
+ meta={meta.file.meta}
88
+ banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
89
+ footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
93
90
  >
94
- {options.parser === 'zod' && (
95
- <File.Import name={[zod.schemas.response.name, zod.schemas.request?.name].filter(Boolean)} root={query.file.path} path={zod.file.path} />
96
- )}
97
- {options.client.importPath ? (
91
+ {fileZod && zodSchemaNames.length > 0 && <File.Import name={zodSchemaNames} root={meta.file.path} path={fileZod.path} />}
92
+ {clientOptions.importPath ? (
98
93
  <>
99
- {!shouldUseClientPlugin && <File.Import name={'fetch'} path={options.client.importPath} />}
100
- <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={options.client.importPath} isTypeOnly />
101
- {options.client.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={options.client.importPath} isTypeOnly />}
94
+ {!shouldUseClientPlugin && <File.Import name={'fetch'} path={clientOptions.importPath} />}
95
+ <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={clientOptions.importPath} isTypeOnly />
96
+ {clientOptions.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={clientOptions.importPath} isTypeOnly />}
102
97
  </>
103
98
  ) : (
104
99
  <>
105
- {!shouldUseClientPlugin && (
106
- <File.Import name={['fetch']} root={query.file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
107
- )}
100
+ {!shouldUseClientPlugin && <File.Import name={['fetch']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} />}
108
101
  <File.Import
109
102
  name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
110
- root={query.file.path}
111
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
103
+ root={meta.file.path}
104
+ path={path.resolve(root, '.kubb/fetch.ts')}
112
105
  isTypeOnly
113
106
  />
114
- {options.client.dataReturnType === 'full' && (
115
- <File.Import name={['ResponseConfig']} root={query.file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} isTypeOnly />
107
+ {clientOptions.dataReturnType === 'full' && (
108
+ <File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} isTypeOnly />
116
109
  )}
117
110
  </>
118
111
  )}
119
-
120
- {shouldUseClientPlugin && <File.Import name={[client.name]} root={query.file.path} path={client.file.path} />}
121
- {!shouldUseClientPlugin && (
122
- <File.Import name={['buildFormData']} root={query.file.path} path={path.resolve(config.root, config.output.path, '.kubb/config.ts')} />
112
+ {shouldUseClientPlugin && clientFile && <File.Import name={[resolvedClientName]} root={meta.file.path} path={clientFile.path} />}
113
+ {!shouldUseClientPlugin && <File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(root, '.kubb/config.ts')} />}
114
+ {customOptions && <File.Import name={[customOptions.name]} path={customOptions.importPath} />}
115
+ {meta.fileTs && importedTypeNames.length > 0 && (
116
+ <File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />
123
117
  )}
124
- {options.customOptions && <File.Import name={[options.customOptions.name]} path={options.customOptions.importPath} />}
125
- <File.Import
126
- name={[
127
- type.schemas.request?.name,
128
- type.schemas.response.name,
129
- type.schemas.pathParams?.name,
130
- type.schemas.queryParams?.name,
131
- type.schemas.headerParams?.name,
132
- ...(type.schemas.statusCodes?.map((item) => item.name) || []),
133
- ].filter(Boolean)}
134
- root={query.file.path}
135
- path={type.file.path}
136
- isTypeOnly
137
- />
118
+
138
119
  <QueryKey
139
- name={queryKey.name}
140
- typeName={queryKey.typeName}
141
- operation={operation}
142
- pathParamsType={options.pathParamsType}
143
- typeSchemas={type.schemas}
144
- paramsCasing={options.paramsCasing}
145
- transformer={options.queryKey}
120
+ name={queryKeyName}
121
+ typeName={queryKeyTypeName}
122
+ node={node}
123
+ tsResolver={tsResolver}
124
+ pathParamsType={pathParamsType}
125
+ paramsCasing={paramsCasing}
126
+ transformer={ctx.options.queryKey}
146
127
  />
128
+
147
129
  {!shouldUseClientPlugin && (
148
130
  <Client
149
- name={client.name}
150
- baseURL={options.client.baseURL}
151
- operation={operation}
152
- typeSchemas={type.schemas}
153
- zodSchemas={zod.schemas}
154
- dataReturnType={options.client.dataReturnType || 'data'}
155
- paramsType={options.paramsType}
156
- paramsCasing={options.client?.paramsCasing || options.paramsCasing}
157
- pathParamsType={options.pathParamsType}
158
- parser={options.parser}
131
+ name={resolvedClientName}
132
+ baseURL={clientOptions.baseURL}
133
+ dataReturnType={clientOptions.dataReturnType || 'data'}
134
+ paramsCasing={clientOptions.paramsCasing || paramsCasing}
135
+ paramsType={paramsType}
136
+ pathParamsType={pathParamsType}
137
+ parser={parser}
138
+ node={node}
139
+ tsResolver={tsResolver}
140
+ zodResolver={zodResolver}
159
141
  />
160
142
  )}
143
+
161
144
  <File.Import name={['queryOptions']} path={importPath} />
145
+
162
146
  <QueryOptions
163
- name={queryOptions.name}
164
- clientName={client.name}
165
- queryKeyName={queryKey.name}
166
- typeSchemas={type.schemas}
167
- paramsCasing={options.paramsCasing}
168
- paramsType={options.paramsType}
169
- pathParamsType={options.pathParamsType}
170
- dataReturnType={options.client.dataReturnType || 'data'}
147
+ name={queryOptionsName}
148
+ clientName={resolvedClientName}
149
+ queryKeyName={queryKeyName}
150
+ node={node}
151
+ tsResolver={tsResolver}
152
+ paramsCasing={paramsCasing}
153
+ paramsType={paramsType}
154
+ pathParamsType={pathParamsType}
155
+ dataReturnType={clientOptions.dataReturnType || 'data'}
171
156
  />
172
- {options.query && (
157
+
158
+ {query && (
173
159
  <>
174
160
  <File.Import name={['useQuery']} path={importPath} />
175
- <File.Import name={['QueryKey', 'QueryClient', 'QueryObserverOptions', 'UseQueryResult', 'QueryClient']} path={importPath} isTypeOnly />
161
+ <File.Import name={['QueryKey', 'QueryClient', 'QueryObserverOptions', 'UseQueryResult']} path={importPath} isTypeOnly />
176
162
  <Query
177
- name={query.name}
178
- queryOptionsName={queryOptions.name}
179
- typeSchemas={type.schemas}
180
- paramsCasing={options.paramsCasing}
181
- paramsType={options.paramsType}
182
- pathParamsType={options.pathParamsType}
183
- operation={operation}
184
- dataReturnType={options.client.dataReturnType || 'data'}
185
- queryKeyName={queryKey.name}
186
- queryKeyTypeName={queryKey.typeName}
187
- customOptions={options.customOptions}
163
+ name={queryName}
164
+ queryOptionsName={queryOptionsName}
165
+ queryKeyName={queryKeyName}
166
+ queryKeyTypeName={queryKeyTypeName}
167
+ node={node}
168
+ tsResolver={tsResolver}
169
+ paramsCasing={paramsCasing}
170
+ paramsType={paramsType}
171
+ pathParamsType={pathParamsType}
172
+ dataReturnType={clientOptions.dataReturnType || 'data'}
173
+ customOptions={customOptions}
188
174
  />
189
175
  </>
190
176
  )}