@kubb/plugin-react-query 5.0.0-alpha.8 → 5.0.0-beta.3

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 (52) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +1 -3
  3. package/dist/components-DTGLu4UV.js +1451 -0
  4. package/dist/components-DTGLu4UV.js.map +1 -0
  5. package/dist/components-dAKJEn9b.cjs +1571 -0
  6. package/dist/components-dAKJEn9b.cjs.map +1 -0
  7. package/dist/components.cjs +1 -1
  8. package/dist/components.d.ts +105 -161
  9. package/dist/components.js +1 -1
  10. package/dist/generators-CWEQsdO9.cjs +1502 -0
  11. package/dist/generators-CWEQsdO9.cjs.map +1 -0
  12. package/dist/generators-C_fbcjpG.js +1460 -0
  13. package/dist/generators-C_fbcjpG.js.map +1 -0
  14. package/dist/generators.cjs +1 -1
  15. package/dist/generators.d.ts +9 -476
  16. package/dist/generators.js +1 -1
  17. package/dist/index.cjs +114 -126
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +110 -126
  21. package/dist/index.js.map +1 -1
  22. package/dist/{types-D5S7Ny9r.d.ts → types-DfaFRSBf.d.ts} +100 -86
  23. package/package.json +59 -62
  24. package/src/components/InfiniteQuery.tsx +75 -139
  25. package/src/components/InfiniteQueryOptions.tsx +62 -164
  26. package/src/components/Mutation.tsx +58 -113
  27. package/src/components/MutationOptions.tsx +61 -80
  28. package/src/components/Query.tsx +67 -140
  29. package/src/components/QueryOptions.tsx +75 -135
  30. package/src/components/SuspenseInfiniteQuery.tsx +75 -139
  31. package/src/components/SuspenseInfiniteQueryOptions.tsx +62 -164
  32. package/src/components/SuspenseQuery.tsx +67 -150
  33. package/src/generators/customHookOptionsFileGenerator.tsx +33 -45
  34. package/src/generators/hookOptionsGenerator.tsx +115 -175
  35. package/src/generators/infiniteQueryGenerator.tsx +183 -176
  36. package/src/generators/mutationGenerator.tsx +127 -138
  37. package/src/generators/queryGenerator.tsx +141 -141
  38. package/src/generators/suspenseInfiniteQueryGenerator.tsx +175 -155
  39. package/src/generators/suspenseQueryGenerator.tsx +149 -148
  40. package/src/index.ts +1 -1
  41. package/src/plugin.ts +133 -183
  42. package/src/resolvers/resolverReactQuery.ts +22 -0
  43. package/src/types.ts +67 -45
  44. package/src/utils.ts +40 -0
  45. package/dist/components-BHQT9ZLc.cjs +0 -1634
  46. package/dist/components-BHQT9ZLc.cjs.map +0 -1
  47. package/dist/components-CpyHYGOw.js +0 -1520
  48. package/dist/components-CpyHYGOw.js.map +0 -1
  49. package/dist/generators-DP07m3rH.cjs +0 -1469
  50. package/dist/generators-DP07m3rH.cjs.map +0 -1
  51. package/dist/generators-DkQwKTc2.js +0 -1427
  52. package/dist/generators-DkQwKTc2.js.map +0 -1
@@ -1,191 +1,180 @@
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 { ast, defineGenerator } from '@kubb/core'
3
+ import { Client, pluginClientName } from '@kubb/plugin-client'
8
4
  import { pluginTsName } from '@kubb/plugin-ts'
9
5
  import { pluginZodName } from '@kubb/plugin-zod'
10
- import { File } from '@kubb/react-fabric'
6
+ import { File, jsxRenderer } from '@kubb/renderer-jsx'
11
7
  import { difference } from 'remeda'
12
- import { Mutation, MutationKey } from '../components'
13
- import { MutationOptions } from '../components/MutationOptions.tsx'
8
+ import { Mutation, MutationKey, MutationOptions } from '../components'
14
9
  import type { PluginReactQuery } from '../types'
10
+ import { transformName } from '../utils.ts'
15
11
 
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()
12
+ export const mutationGenerator = defineGenerator<PluginReactQuery>({
13
+ name: 'react-query-mutation',
14
+ renderer: jsxRenderer,
15
+ operation(node, ctx) {
16
+ const { adapter, config, driver, resolver, root } = ctx
17
+ const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, transformers, customOptions } = ctx.options
24
18
 
25
- const oas = useOas()
26
- const { getSchemas, getName, getFile } = useOperationManager(generator)
19
+ const pluginTs = driver.getPlugin(pluginTsName)
20
+ if (!pluginTs) return null
21
+ const tsResolver = driver.getResolver(pluginTsName)
27
22
 
28
- const isQuery = !!options.query && options.query?.methods.some((method) => operation.method === method)
23
+ const isQuery = query === false || (!!query && query.methods.some((method) => node.method.toLowerCase() === method.toLowerCase()))
29
24
  const isMutation =
30
- options.mutation !== false &&
25
+ mutation !== false &&
31
26
  !isQuery &&
32
- difference(options.mutation ? options.mutation.methods : [], options.query ? options.query.methods : []).some((method) => operation.method === method)
27
+ difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase())
33
28
 
34
- const importPath = options.mutation ? options.mutation.importPath : '@tanstack/react-query'
29
+ if (!isMutation) return null
35
30
 
36
- const mutation = {
37
- name: getName(operation, { type: 'function', prefix: 'use' }),
38
- typeName: getName(operation, { type: 'type' }),
39
- file: getFile(operation, { prefix: 'use' }),
40
- }
31
+ const importPath = mutation ? mutation.importPath : '@tanstack/react-query'
41
32
 
42
- const type = {
43
- file: getFile(operation, { pluginName: pluginTsName }),
44
- //todo remove type?
45
- schemas: getSchemas(operation, { pluginName: pluginTsName, type: 'type' }),
46
- }
33
+ const baseName = resolver.resolveName(node.operationId)
34
+ const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1)
35
+ const mutationHookName = transformName(`use${capitalize(baseName)}`, 'function', transformers)
36
+ const mutationTypeName = transformName(`${capitalize(baseName)}`, 'type', transformers)
37
+ const mutationOptionsName = transformName(`${baseName}MutationOptions`, 'function', transformers)
38
+ const mutationKeyName = transformName(`${baseName}MutationKey`, 'const', transformers)
39
+ const clientName = transformName(baseName, 'function', transformers)
47
40
 
48
- const zod = {
49
- file: getFile(operation, { pluginName: pluginZodName }),
50
- schemas: getSchemas(operation, { pluginName: pluginZodName, type: 'function' }),
41
+ const meta = {
42
+ file: resolver.resolveFile({ name: mutationHookName, 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
+ ),
51
47
  }
52
48
 
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
- }
49
+ const casedParams = ast.caseParams(node.parameters, paramsCasing)
50
+ const pathParams = casedParams.filter((p) => p.in === 'path')
51
+ const queryParams = casedParams.filter((p) => p.in === 'query')
52
+ const headerParams = casedParams.filter((p) => p.in === 'header')
67
53
 
68
- const mutationOptions = {
69
- name: getName(operation, { type: 'function', suffix: 'MutationOptions' }),
70
- }
54
+ const importedTypeNames = [
55
+ node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : undefined,
56
+ tsResolver.resolveResponseName(node),
57
+ ...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
58
+ ...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
59
+ ...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
60
+ ...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode)),
61
+ ].filter((name): name is string => !!name)
71
62
 
72
- const mutationKey = {
73
- name: getName(operation, { type: 'const', suffix: 'MutationKey' }),
74
- typeName: getName(operation, { type: 'type', suffix: 'MutationKey' }),
75
- }
63
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
64
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
65
+ const fileZod = zodResolver
66
+ ? zodResolver.resolveFile(
67
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
68
+ { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
69
+ )
70
+ : undefined
71
+ const zodSchemaNames =
72
+ zodResolver && parser === 'zod'
73
+ ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : undefined].filter(Boolean)
74
+ : []
76
75
 
77
- if (!isMutation) {
78
- return null
79
- }
76
+ const clientPlugin = driver.getPlugin(pluginClientName)
77
+ const hasClientPlugin = clientPlugin?.name === pluginClientName
78
+ const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
79
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : undefined
80
+
81
+ const clientFile = shouldUseClientPlugin
82
+ ? clientResolver?.resolveFile(
83
+ { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
84
+ {
85
+ root,
86
+ output: clientPlugin?.options?.output ?? output,
87
+ group: clientPlugin?.options?.group,
88
+ },
89
+ )
90
+ : undefined
91
+
92
+ const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
80
93
 
81
94
  return (
82
95
  <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 })}
96
+ baseName={meta.file.baseName}
97
+ path={meta.file.path}
98
+ meta={meta.file.meta}
99
+ banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
100
+ footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
88
101
  >
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} />
102
+ {parser === 'zod' && fileZod && zodSchemaNames.length > 0 && (
103
+ <File.Import name={zodSchemaNames as string[]} root={meta.file.path} path={fileZod.path} />
91
104
  )}
92
- {options.client.importPath ? (
105
+ {clientOptions.importPath ? (
93
106
  <>
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 />}
107
+ {!shouldUseClientPlugin && <File.Import name={'fetch'} path={clientOptions.importPath} />}
108
+ <File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={clientOptions.importPath} isTypeOnly />
109
+ {clientOptions.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={clientOptions.importPath} isTypeOnly />}
97
110
  </>
98
111
  ) : (
99
112
  <>
100
- {!shouldUseClientPlugin && (
101
- <File.Import name={['fetch']} root={mutation.file.path} path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')} />
102
- )}
113
+ {!shouldUseClientPlugin && <File.Import name={['fetch']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} />}
103
114
  <File.Import
104
115
  name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
105
- root={mutation.file.path}
106
- path={path.resolve(config.root, config.output.path, '.kubb/fetch.ts')}
116
+ root={meta.file.path}
117
+ path={path.resolve(root, '.kubb/fetch.ts')}
107
118
  isTypeOnly
108
119
  />
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
- />
120
+ {clientOptions.dataReturnType === 'full' && (
121
+ <File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/fetch.ts')} isTypeOnly />
116
122
  )}
117
123
  </>
118
124
  )}
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')} />
125
+ {shouldUseClientPlugin && clientFile && <File.Import name={[resolvedClientName]} root={meta.file.path} path={clientFile.path} />}
126
+ {!shouldUseClientPlugin && <File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(root, '.kubb/config.ts')} />}
127
+ {customOptions && <File.Import name={[customOptions.name]} path={customOptions.importPath} />}
128
+ {meta.fileTs && importedTypeNames.length > 0 && (
129
+ <File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />
122
130
  )}
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
131
 
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
- />
132
+ <MutationKey name={mutationKeyName} node={node} pathParamsType={pathParamsType} paramsCasing={paramsCasing} transformer={ctx.options.mutationKey} />
147
133
 
148
134
  {!shouldUseClientPlugin && (
149
135
  <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}
136
+ name={resolvedClientName}
137
+ baseURL={clientOptions.baseURL}
138
+ dataReturnType={clientOptions.dataReturnType || 'data'}
139
+ paramsCasing={clientOptions.paramsCasing || paramsCasing}
140
+ paramsType={paramsType}
141
+ pathParamsType={pathParamsType}
142
+ parser={parser}
143
+ node={node}
144
+ tsResolver={tsResolver}
145
+ zodResolver={zodResolver}
160
146
  />
161
147
  )}
148
+
162
149
  <File.Import name={['mutationOptions']} path={importPath} />
163
150
 
164
151
  <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'}
152
+ name={mutationOptionsName}
153
+ clientName={resolvedClientName}
154
+ mutationKeyName={mutationKeyName}
155
+ node={node}
156
+ tsResolver={tsResolver}
157
+ paramsCasing={paramsCasing}
158
+ paramsType={paramsType}
159
+ pathParamsType={pathParamsType}
160
+ dataReturnType={clientOptions.dataReturnType || 'data'}
173
161
  />
174
- {options.mutation && (
162
+
163
+ {mutation && (
175
164
  <>
176
165
  <File.Import name={['useMutation']} path={importPath} />
177
166
  <File.Import name={['UseMutationOptions', 'UseMutationResult', 'QueryClient']} path={importPath} isTypeOnly />
178
167
  <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}
168
+ name={mutationHookName}
169
+ typeName={mutationTypeName}
170
+ mutationOptionsName={mutationOptionsName}
171
+ mutationKeyName={mutationKeyName}
172
+ node={node}
173
+ tsResolver={tsResolver}
174
+ dataReturnType={clientOptions.dataReturnType || 'data'}
175
+ paramsCasing={paramsCasing}
176
+ pathParamsType={pathParamsType}
177
+ customOptions={customOptions}
189
178
  />
190
179
  </>
191
180
  )}