@kubb/plugin-swr 5.0.0-alpha.9 → 5.0.0-beta.33

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 (44) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +33 -26
  3. package/dist/components-ByADeLZO.cjs +1029 -0
  4. package/dist/components-ByADeLZO.cjs.map +1 -0
  5. package/dist/components-CBdpiiay.js +933 -0
  6. package/dist/components-CBdpiiay.js.map +1 -0
  7. package/dist/components.cjs +1 -1
  8. package/dist/components.d.ts +45 -51
  9. package/dist/components.js +1 -1
  10. package/dist/generators-Bb5wNYig.cjs +445 -0
  11. package/dist/generators-Bb5wNYig.cjs.map +1 -0
  12. package/dist/generators-D5kJZsB1.js +434 -0
  13. package/dist/generators-D5kJZsB1.js.map +1 -0
  14. package/dist/generators.cjs +1 -1
  15. package/dist/generators.d.ts +4 -500
  16. package/dist/generators.js +1 -1
  17. package/dist/index.cjs +134 -113
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +130 -113
  21. package/dist/index.js.map +1 -1
  22. package/dist/types-D9jeG3fE.d.ts +220 -0
  23. package/extension.yaml +199 -0
  24. package/package.json +57 -67
  25. package/src/components/Mutation.tsx +106 -227
  26. package/src/components/MutationKey.tsx +25 -1
  27. package/src/components/Query.tsx +75 -140
  28. package/src/components/QueryOptions.tsx +46 -95
  29. package/src/generators/mutationGenerator.tsx +113 -128
  30. package/src/generators/queryGenerator.tsx +125 -137
  31. package/src/index.ts +2 -2
  32. package/src/plugin.ts +117 -170
  33. package/src/resolvers/resolverSwr.ts +56 -0
  34. package/src/types.ts +115 -59
  35. package/src/utils.ts +10 -0
  36. package/dist/components-DRDGvgXG.js +0 -702
  37. package/dist/components-DRDGvgXG.js.map +0 -1
  38. package/dist/components-jd0l9XKn.cjs +0 -780
  39. package/dist/components-jd0l9XKn.cjs.map +0 -1
  40. package/dist/generators-CRSl6u2M.js +0 -399
  41. package/dist/generators-CRSl6u2M.js.map +0 -1
  42. package/dist/generators-D062obA7.cjs +0 -410
  43. package/dist/generators-D062obA7.cjs.map +0 -1
  44. package/dist/types-BIaGRPjD.d.ts +0 -210
@@ -1,130 +1,76 @@
1
- import { isOptional, type Operation } from '@kubb/oas'
2
- import { Client } from '@kubb/plugin-client/components'
3
- import type { OperationSchemas } from '@kubb/plugin-oas'
4
- import { getComments, getPathParams } from '@kubb/plugin-oas/utils'
5
- import { File, Function, FunctionParams, Type } from '@kubb/react-fabric'
6
- import type { FabricReactNode, Params } from '@kubb/react-fabric/types'
1
+ import { ast } from '@kubb/core'
2
+ import type { ResolverTs } from '@kubb/plugin-ts'
3
+ import { functionPrinter } from '@kubb/plugin-ts'
4
+ import { File, Function, Type } from '@kubb/renderer-jsx'
5
+ import type { KubbReactNode } from '@kubb/renderer-jsx/types'
7
6
  import type { PluginSwr } from '../types.ts'
8
- import { MutationKey } from './MutationKey.tsx'
7
+ import { buildRequestConfigType, getComments, resolveErrorNames } from '../utils.ts'
9
8
 
10
9
  type Props = {
11
- /**
12
- * Name of the function
13
- */
14
10
  name: string
15
- typeName: string
16
11
  clientName: string
17
12
  mutationKeyName: string
18
13
  mutationKeyTypeName: string
19
- typeSchemas: OperationSchemas
20
- operation: Operation
14
+ mutationArgTypeName: string
15
+ node: ast.OperationNode
16
+ tsResolver: ResolverTs
21
17
  paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
22
18
  paramsType: PluginSwr['resolvedOptions']['paramsType']
23
- dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
24
- pathParamsType: PluginSwr['resolvedOptions']['pathParamsType']
25
- /**
26
- * When true, mutation parameters are passed via trigger() instead of as hook arguments
27
- * @default false
28
- */
29
- paramsToTrigger?: boolean
30
- }
31
-
32
- type GetParamsProps = {
33
- paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
34
19
  pathParamsType: PluginSwr['resolvedOptions']['pathParamsType']
35
20
  dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
36
- typeSchemas: OperationSchemas
37
- mutationKeyTypeName: string
38
21
  }
39
22
 
40
- // Original getParams - used when paramsToTrigger is false (default)
41
- function getParams({ pathParamsType, paramsCasing, dataReturnType, typeSchemas, mutationKeyTypeName }: GetParamsProps) {
42
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
43
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
44
- const TExtraArg = typeSchemas.request?.name || 'never'
45
-
46
- return FunctionParams.factory({
47
- pathParams: {
48
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
49
- children: getPathParams(typeSchemas.pathParams, { typed: true, casing: paramsCasing }),
50
- },
51
- params: typeSchemas.queryParams?.name
52
- ? {
53
- type: typeSchemas.queryParams?.name,
54
- optional: isOptional(typeSchemas.queryParams?.schema),
55
- }
56
- : undefined,
57
- headers: typeSchemas.headerParams?.name
58
- ? {
59
- type: typeSchemas.headerParams?.name,
60
- optional: isOptional(typeSchemas.headerParams?.schema),
61
- }
62
- : undefined,
63
- options: {
64
- type: `
65
- {
66
- mutation?: SWRMutationConfiguration<${TData}, ${TError}, ${mutationKeyTypeName} | null, ${TExtraArg}> & { throwOnError?: boolean },
67
- client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'},
68
- shouldFetch?: boolean,
69
- }
70
- `,
71
- default: '{}',
72
- },
23
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
24
+ const callPrinter = functionPrinter({ mode: 'call' })
25
+ const keysPrinter = functionPrinter({ mode: 'keys' })
26
+
27
+ function createMutationArgParams(
28
+ node: ast.OperationNode,
29
+ options: {
30
+ paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
31
+ resolver: ResolverTs
32
+ },
33
+ ): ast.FunctionParametersNode {
34
+ return ast.createOperationParams(node, {
35
+ paramsType: 'inline',
36
+ pathParamsType: 'inline',
37
+ paramsCasing: options.paramsCasing,
38
+ resolver: options.resolver,
73
39
  })
74
40
  }
75
41
 
76
- type GetTriggerParamsProps = {
77
- dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
78
- typeSchemas: OperationSchemas
79
- mutationKeyTypeName: string
80
- mutationArgTypeName: string
81
- }
82
-
83
- // New getParams - used when paramsToTrigger is true
84
- function getTriggerParams({ dataReturnType, typeSchemas, mutationKeyTypeName, mutationArgTypeName }: GetTriggerParamsProps) {
85
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
86
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
87
-
88
- return FunctionParams.factory({
89
- options: {
90
- type: `
91
- {
42
+ function buildMutationParamsNode(
43
+ node: ast.OperationNode,
44
+ options: {
45
+ paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
46
+ dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
47
+ mutationKeyTypeName: string
48
+ mutationArgTypeName: string
49
+ resolver: ResolverTs
50
+ },
51
+ ): ast.FunctionParametersNode {
52
+ const { dataReturnType, mutationKeyTypeName, mutationArgTypeName, resolver } = options
53
+ const responseName = resolver.resolveResponseName(node)
54
+ const errorNames = resolveErrorNames(node, resolver)
55
+
56
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
57
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
58
+
59
+ return ast.createFunctionParameters({
60
+ params: [
61
+ ast.createFunctionParameter({
62
+ name: 'options',
63
+ type: ast.createParamsType({
64
+ variant: 'reference',
65
+ name: `{
92
66
  mutation?: SWRMutationConfiguration<${TData}, ${TError}, ${mutationKeyTypeName} | null, ${mutationArgTypeName}> & { throwOnError?: boolean },
93
- client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'},
67
+ client?: ${buildRequestConfigType(node, resolver)},
94
68
  shouldFetch?: boolean,
95
- }
96
- `,
97
- default: '{}',
98
- },
99
- })
100
- }
101
-
102
- type GetMutationParamsProps = {
103
- paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
104
- typeSchemas: OperationSchemas
105
- }
106
-
107
- function getMutationParams({ paramsCasing, typeSchemas }: GetMutationParamsProps) {
108
- return FunctionParams.factory({
109
- ...getPathParams(typeSchemas.pathParams, { typed: true, casing: paramsCasing }),
110
- data: typeSchemas.request?.name
111
- ? {
112
- type: typeSchemas.request?.name,
113
- optional: isOptional(typeSchemas.request?.schema),
114
- }
115
- : undefined,
116
- params: typeSchemas.queryParams?.name
117
- ? {
118
- type: typeSchemas.queryParams?.name,
119
- optional: isOptional(typeSchemas.queryParams?.schema),
120
- }
121
- : undefined,
122
- headers: typeSchemas.headerParams?.name
123
- ? {
124
- type: typeSchemas.headerParams?.name,
125
- optional: isOptional(typeSchemas.headerParams?.schema),
126
- }
127
- : undefined,
69
+ }`,
70
+ }),
71
+ default: '{}',
72
+ }),
73
+ ],
128
74
  })
129
75
  }
130
76
 
@@ -133,144 +79,77 @@ export function Mutation({
133
79
  clientName,
134
80
  mutationKeyName,
135
81
  mutationKeyTypeName,
136
- paramsType,
82
+ mutationArgTypeName,
137
83
  paramsCasing,
84
+ paramsType,
138
85
  pathParamsType,
139
86
  dataReturnType,
140
- typeSchemas,
141
- operation,
142
- paramsToTrigger = false,
143
- }: Props): FabricReactNode {
144
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
145
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
87
+ node,
88
+ tsResolver,
89
+ }: Props): KubbReactNode {
90
+ const responseName = tsResolver.resolveResponseName(node)
91
+ const errorNames = resolveErrorNames(node, tsResolver)
146
92
 
147
- const mutationKeyParams = MutationKey.getParams({
148
- pathParamsType,
149
- typeSchemas,
150
- })
151
-
152
- const clientParams = Client.getParams({
153
- paramsCasing,
154
- paramsType,
155
- typeSchemas,
156
- pathParamsType,
157
- isConfigurable: true,
158
- })
159
-
160
- // Use the new trigger-based approach when paramsToTrigger is true
161
- if (paramsToTrigger) {
162
- // Build the mutation params type (for arg destructuring)
163
- const mutationParams = getMutationParams({
164
- paramsCasing,
165
- typeSchemas,
166
- })
167
-
168
- // Get the arg type name
169
- const mutationArgTypeName = `${mutationKeyTypeName.replace('MutationKey', '')}MutationArg`
170
-
171
- // Check if there are any mutation params (path, data, params, headers)
172
- const hasMutationParams = Object.keys(mutationParams.params).length > 0
173
-
174
- // Build the arg type for useSWRMutation
175
- const argParams = FunctionParams.factory({
176
- data: {
177
- mode: 'object',
178
- children: Object.entries(mutationParams.params).reduce((acc, [key, value]) => {
179
- if (value) {
180
- acc[key] = {
181
- ...value,
182
- type: undefined,
183
- }
184
- }
185
- return acc
186
- }, {} as Params),
187
- },
188
- })
189
-
190
- const params = getTriggerParams({
191
- dataReturnType,
192
- typeSchemas,
193
- mutationKeyTypeName,
194
- mutationArgTypeName,
195
- })
196
-
197
- const generics = [TData, TError, `${mutationKeyTypeName} | null`, mutationArgTypeName].filter(Boolean)
198
-
199
- const mutationArg = mutationParams.toConstructor()
93
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
94
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
200
95
 
201
- return (
202
- <>
203
- <File.Source name={mutationArgTypeName} isExportable isIndexable isTypeOnly>
204
- <Type name={mutationArgTypeName} export>
205
- {hasMutationParams ? `{${mutationArg}}` : 'never'}
206
- </Type>
207
- </File.Source>
208
- <File.Source name={name} isExportable isIndexable>
209
- <Function
210
- name={name}
211
- export
212
- params={params.toConstructor()}
213
- JSDoc={{
214
- comments: getComments(operation),
215
- }}
216
- >
217
- {`
218
- const { mutation: mutationOptions, client: config = {}, shouldFetch = true } = options ?? {}
219
- const mutationKey = ${mutationKeyName}(${mutationKeyParams.toCall()})
220
-
221
- return useSWRMutation<${generics.join(', ')}>(
222
- shouldFetch ? mutationKey : null,
223
- async (_url${hasMutationParams ? `, { arg: ${argParams.toCall()} }` : ''}) => {
224
- return ${clientName}(${clientParams.toCall()})
225
- },
226
- mutationOptions
227
- )
228
- `}
229
- </Function>
230
- </File.Source>
231
- </>
232
- )
233
- }
96
+ const mutationArgParamsNode = createMutationArgParams(node, { paramsCasing, resolver: tsResolver })
97
+ const hasMutationParams = mutationArgParamsNode.params.length > 0
98
+ const argTypeBody = hasMutationParams ? (declarationPrinter.print(mutationArgParamsNode) ?? '') : ''
99
+ const argKeysStr = hasMutationParams ? (keysPrinter.print(mutationArgParamsNode) ?? '') : ''
234
100
 
235
- // Original behavior (default)
236
- const generics = [
237
- TData,
238
- TError,
239
- `${mutationKeyTypeName} | null`,
240
- typeSchemas.request?.name, // TExtraArg - the arg type for useSWRMutation
241
- ].filter(Boolean)
101
+ const generics = [TData, TError, `${mutationKeyTypeName} | null`, mutationArgTypeName]
242
102
 
243
- const params = getParams({
103
+ const paramsNode = buildMutationParamsNode(node, {
244
104
  paramsCasing,
245
- pathParamsType,
246
105
  dataReturnType,
247
- typeSchemas,
248
106
  mutationKeyTypeName,
107
+ mutationArgTypeName,
108
+ resolver: tsResolver,
109
+ })
110
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
111
+
112
+ const clientCallParamsNode = ast.createOperationParams(node, {
113
+ paramsType,
114
+ pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
115
+ paramsCasing,
116
+ resolver: tsResolver,
117
+ extraParams: [
118
+ ast.createFunctionParameter({
119
+ name: 'config',
120
+ type: ast.createParamsType({
121
+ variant: 'reference',
122
+ name: buildRequestConfigType(node, tsResolver),
123
+ }),
124
+ default: '{}',
125
+ }),
126
+ ],
249
127
  })
128
+ const clientCallStr = callPrinter.print(clientCallParamsNode) ?? ''
250
129
 
251
130
  return (
252
- <File.Source name={name} isExportable isIndexable>
253
- <Function
254
- name={name}
255
- export
256
- params={params.toConstructor()}
257
- JSDoc={{
258
- comments: getComments(operation),
259
- }}
260
- >
261
- {`
131
+ <>
132
+ <File.Source name={mutationArgTypeName} isExportable isIndexable isTypeOnly>
133
+ <Type name={mutationArgTypeName} export>
134
+ {hasMutationParams ? `{ ${argTypeBody} }` : 'never'}
135
+ </Type>
136
+ </File.Source>
137
+ <File.Source name={name} isExportable isIndexable>
138
+ <Function name={name} export params={paramsSignature} JSDoc={{ comments: getComments(node) }}>
139
+ {`
262
140
  const { mutation: mutationOptions, client: config = {}, shouldFetch = true } = options ?? {}
263
- const mutationKey = ${mutationKeyName}(${mutationKeyParams.toCall()})
141
+ const mutationKey = ${mutationKeyName}()
264
142
 
265
143
  return useSWRMutation<${generics.join(', ')}>(
266
144
  shouldFetch ? mutationKey : null,
267
- async (_url${typeSchemas.request?.name ? ', { arg: data }' : ''}) => {
268
- return ${clientName}(${clientParams.toCall()})
145
+ async (_url${hasMutationParams ? `, { arg: { ${argKeysStr} } }` : ''}) => {
146
+ return ${clientName}(${clientCallStr})
269
147
  },
270
148
  mutationOptions
271
149
  )
272
150
  `}
273
- </Function>
274
- </File.Source>
151
+ </Function>
152
+ </File.Source>
153
+ </>
275
154
  )
276
155
  }
@@ -1 +1,25 @@
1
- export { MutationKey } from '@internals/tanstack-query'
1
+ import type { Transformer } from '@internals/tanstack-query'
2
+ import { MutationKey as SharedMutationKey } from '@internals/tanstack-query'
3
+ import type { ast } from '@kubb/core'
4
+ import { File, Type } from '@kubb/renderer-jsx'
5
+ import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
+
7
+ type Props = {
8
+ name: string
9
+ typeName: string
10
+ node: ast.OperationNode
11
+ paramsCasing: 'camelcase' | undefined
12
+ pathParamsType: 'object' | 'inline'
13
+ transformer: Transformer | undefined
14
+ }
15
+
16
+ export function MutationKey({ name, typeName, node, paramsCasing, pathParamsType, transformer }: Props): KubbReactNode {
17
+ return (
18
+ <>
19
+ <SharedMutationKey name={name} node={node} paramsCasing={paramsCasing} pathParamsType={pathParamsType} transformer={transformer} />
20
+ <File.Source name={typeName} isExportable isIndexable isTypeOnly>
21
+ <Type export name={typeName}>{`ReturnType<typeof ${name}>`}</Type>
22
+ </File.Source>
23
+ </>
24
+ )
25
+ }
@@ -1,189 +1,124 @@
1
- import { getDefaultValue, isOptional, type Operation } from '@kubb/oas'
2
- import type { OperationSchemas } from '@kubb/plugin-oas'
3
- import { getComments, getPathParams } from '@kubb/plugin-oas/utils'
4
- import { File, Function, FunctionParams } from '@kubb/react-fabric'
5
- import type { FabricReactNode } from '@kubb/react-fabric/types'
1
+ import { ast } from '@kubb/core'
2
+ import type { ResolverTs } from '@kubb/plugin-ts'
3
+ import { functionPrinter } from '@kubb/plugin-ts'
4
+ import { File, Function } from '@kubb/renderer-jsx'
5
+ import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
+ import { getEnabledParamNames, markParamsOptional } from '@internals/tanstack-query'
6
7
  import type { PluginSwr } from '../types.ts'
7
- import { QueryKey } from './QueryKey.tsx'
8
- import { QueryOptions } from './QueryOptions.tsx'
8
+ import { buildQueryKeyParams, getComments, resolveErrorNames } from '../utils.ts'
9
+ import { getQueryOptionsParams } from './QueryOptions.tsx'
9
10
 
10
11
  type Props = {
11
- /**
12
- * Name of the function
13
- */
14
12
  name: string
15
13
  queryOptionsName: string
16
14
  queryKeyName: string
17
15
  queryKeyTypeName: string
18
- typeSchemas: OperationSchemas
16
+ node: ast.OperationNode
17
+ tsResolver: ResolverTs
19
18
  paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
20
19
  paramsType: PluginSwr['resolvedOptions']['paramsType']
21
20
  pathParamsType: PluginSwr['resolvedOptions']['pathParamsType']
22
21
  dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
23
- operation: Operation
24
22
  }
25
23
 
26
- type GetParamsProps = {
27
- paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
28
- paramsType: PluginSwr['resolvedOptions']['paramsType']
29
- pathParamsType: PluginSwr['resolvedOptions']['pathParamsType']
30
- dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
31
- typeSchemas: OperationSchemas
32
- }
24
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
25
+ const callPrinter = functionPrinter({ mode: 'call' })
33
26
 
34
- function getParams({ paramsType, paramsCasing, pathParamsType, dataReturnType, typeSchemas }: GetParamsProps) {
35
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
36
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
27
+ function buildQueryParamsNode(
28
+ node: ast.OperationNode,
29
+ options: {
30
+ paramsType: PluginSwr['resolvedOptions']['paramsType']
31
+ paramsCasing: PluginSwr['resolvedOptions']['paramsCasing']
32
+ pathParamsType: PluginSwr['resolvedOptions']['pathParamsType']
33
+ dataReturnType: PluginSwr['resolvedOptions']['client']['dataReturnType']
34
+ resolver: ResolverTs
35
+ },
36
+ ): ast.FunctionParametersNode {
37
+ const { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver } = options
38
+ const responseName = resolver.resolveResponseName(node)
39
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
40
+ const errorNames = resolveErrorNames(node, resolver)
37
41
 
38
- if (paramsType === 'object') {
39
- const pathParams = getPathParams(typeSchemas.pathParams, { typed: true, casing: paramsCasing })
42
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
43
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
40
44
 
41
- const children = {
42
- ...pathParams,
43
- data: typeSchemas.request?.name
44
- ? {
45
- type: typeSchemas.request?.name,
46
- optional: isOptional(typeSchemas.request?.schema),
47
- }
48
- : undefined,
49
- params: typeSchemas.queryParams?.name
50
- ? {
51
- type: typeSchemas.queryParams?.name,
52
- optional: isOptional(typeSchemas.queryParams?.schema),
53
- }
54
- : undefined,
55
- headers: typeSchemas.headerParams?.name
56
- ? {
57
- type: typeSchemas.headerParams?.name,
58
- optional: isOptional(typeSchemas.headerParams?.schema),
59
- }
60
- : undefined,
61
- }
62
-
63
- // Check if all children are optional or undefined
64
- const allChildrenAreOptional = Object.values(children).every((child) => !child || child.optional)
65
-
66
- return FunctionParams.factory({
67
- data: {
68
- mode: 'object',
69
- children,
70
- default: allChildrenAreOptional ? '{}' : undefined,
71
- },
72
- options: {
73
- type: `
74
- {
75
- query?: Parameters<typeof useSWR<${[TData, TError].join(', ')}>>[2],
76
- client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'},
45
+ const optionsParam = ast.createFunctionParameter({
46
+ name: 'options',
47
+ type: ast.createParamsType({
48
+ variant: 'reference',
49
+ name: `{
50
+ query?: SWRConfiguration<${[TData, TError].join(', ')}>,
51
+ client?: ${requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'},
77
52
  shouldFetch?: boolean,
78
53
  immutable?: boolean
79
- }
80
- `,
81
- default: '{}',
82
- },
83
- })
84
- }
54
+ }`,
55
+ }),
56
+ default: '{}',
57
+ })
85
58
 
86
- return FunctionParams.factory({
87
- pathParams: typeSchemas.pathParams?.name
88
- ? {
89
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
90
- children: getPathParams(typeSchemas.pathParams, { typed: true, casing: paramsCasing }),
91
- default: getDefaultValue(typeSchemas.pathParams?.schema),
92
- }
93
- : undefined,
94
- data: typeSchemas.request?.name
95
- ? {
96
- type: typeSchemas.request?.name,
97
- optional: isOptional(typeSchemas.request?.schema),
98
- }
99
- : undefined,
100
- params: typeSchemas.queryParams?.name
101
- ? {
102
- type: typeSchemas.queryParams?.name,
103
- optional: isOptional(typeSchemas.queryParams?.schema),
104
- }
105
- : undefined,
106
- headers: typeSchemas.headerParams?.name
107
- ? {
108
- type: typeSchemas.headerParams?.name,
109
- optional: isOptional(typeSchemas.headerParams?.schema),
110
- }
111
- : undefined,
112
- options: {
113
- type: `
114
- {
115
- query?: Parameters<typeof useSWR<${[TData, TError].join(', ')}>>[2],
116
- client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'},
117
- shouldFetch?: boolean,
118
- immutable?: boolean
119
- }
120
- `,
121
- default: '{}',
122
- },
59
+ return ast.createOperationParams(node, {
60
+ paramsType,
61
+ pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
62
+ paramsCasing,
63
+ resolver,
64
+ extraParams: [optionsParam],
123
65
  })
124
66
  }
125
67
 
126
68
  export function Query({
127
69
  name,
128
- typeSchemas,
129
- queryKeyName,
130
70
  queryKeyTypeName,
131
71
  queryOptionsName,
132
- operation,
133
- dataReturnType,
72
+ queryKeyName,
134
73
  paramsType,
135
74
  paramsCasing,
136
75
  pathParamsType,
137
- }: Props): FabricReactNode {
138
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
139
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
76
+ dataReturnType,
77
+ node,
78
+ tsResolver,
79
+ }: Props): KubbReactNode {
80
+ const responseName = tsResolver.resolveResponseName(node)
81
+ const errorNames = resolveErrorNames(node, tsResolver)
82
+
83
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
84
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
140
85
  const generics = [TData, TError, `${queryKeyTypeName} | null`]
141
86
 
142
- const queryKeyParams = QueryKey.getParams({
143
- pathParamsType,
144
- typeSchemas,
145
- paramsCasing,
146
- })
147
- const params = getParams({
148
- paramsCasing,
149
- paramsType,
150
- pathParamsType,
151
- dataReturnType,
152
- typeSchemas,
153
- })
87
+ const queryKeyParamsNode = buildQueryKeyParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
88
+ const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
89
+ const enabledNames = getEnabledParamNames(queryKeyParamsNode)
154
90
 
155
- const queryOptionsParams = QueryOptions.getParams({
156
- paramsCasing,
157
- paramsType,
158
- pathParamsType,
159
- typeSchemas,
160
- })
91
+ const queryOptionsParamsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
92
+ const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? ''
93
+
94
+ const paramsNode = markParamsOptional(
95
+ buildQueryParamsNode(node, { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver: tsResolver }),
96
+ enabledNames,
97
+ )
98
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
99
+
100
+ // SWR has no `enabled` option; fold the param-presence check into the null-key gate
101
+ // so passing `undefined` for a required param disables the request (mirrors React Query #60).
102
+ const shouldFetchExpr = enabledNames.length ? `shouldFetch && !!(${enabledNames.join(' && ')})` : 'shouldFetch'
161
103
 
162
104
  return (
163
105
  <File.Source name={name} isExportable isIndexable>
164
- <Function
165
- name={name}
166
- export
167
- params={params.toConstructor()}
168
- JSDoc={{
169
- comments: getComments(operation),
170
- }}
171
- >
106
+ <Function name={name} export params={paramsSignature} JSDoc={{ comments: getComments(node) }}>
172
107
  {`
173
108
  const { query: queryOptions, client: config = {}, shouldFetch = true, immutable } = options ?? {}
174
109
 
175
- const queryKey = ${queryKeyName}(${queryKeyParams.toCall()})
110
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
176
111
 
177
112
  return useSWR<${generics.join(', ')}>(
178
- shouldFetch ? queryKey : null,
113
+ ${shouldFetchExpr} ? queryKey : null,
179
114
  {
180
- ...${queryOptionsName}(${queryOptionsParams.toCall()}),
115
+ ...${queryOptionsName}(${queryOptionsParamsCall}),
181
116
  ...(immutable ? {
182
117
  revalidateIfStale: false,
183
118
  revalidateOnFocus: false,
184
119
  revalidateOnReconnect: false
185
120
  } : { }),
186
- ...queryOptions
121
+ ...queryOptions,
187
122
  }
188
123
  )
189
124
  `}