@kubb/plugin-vue-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 (46) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +1 -3
  3. package/dist/components-D1UhYFgY.js +1277 -0
  4. package/dist/components-D1UhYFgY.js.map +1 -0
  5. package/dist/components-qfOFRSoM.cjs +1367 -0
  6. package/dist/components-qfOFRSoM.cjs.map +1 -0
  7. package/dist/components.cjs +1 -1
  8. package/dist/components.d.ts +118 -109
  9. package/dist/components.js +1 -1
  10. package/dist/generators-C4gs_P1i.cjs +726 -0
  11. package/dist/generators-C4gs_P1i.cjs.map +1 -0
  12. package/dist/generators-CbnIVBgY.js +709 -0
  13. package/dist/generators-CbnIVBgY.js.map +1 -0
  14. package/dist/generators.cjs +1 -1
  15. package/dist/generators.d.ts +5 -472
  16. package/dist/generators.js +1 -1
  17. package/dist/index.cjs +106 -121
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +102 -121
  21. package/dist/index.js.map +1 -1
  22. package/dist/types-nVDTfuS1.d.ts +194 -0
  23. package/package.json +61 -64
  24. package/src/components/InfiniteQuery.tsx +104 -153
  25. package/src/components/InfiniteQueryOptions.tsx +122 -162
  26. package/src/components/Mutation.tsx +110 -136
  27. package/src/components/Query.tsx +102 -151
  28. package/src/components/QueryKey.tsx +68 -58
  29. package/src/components/QueryOptions.tsx +147 -139
  30. package/src/generators/infiniteQueryGenerator.tsx +165 -170
  31. package/src/generators/mutationGenerator.tsx +117 -124
  32. package/src/generators/queryGenerator.tsx +138 -136
  33. package/src/index.ts +1 -1
  34. package/src/plugin.ts +124 -175
  35. package/src/resolvers/resolverVueQuery.ts +19 -0
  36. package/src/types.ts +68 -48
  37. package/src/utils.ts +37 -0
  38. package/dist/components-Yjoe78Y7.cjs +0 -1119
  39. package/dist/components-Yjoe78Y7.cjs.map +0 -1
  40. package/dist/components-_AMBl0g-.js +0 -1029
  41. package/dist/components-_AMBl0g-.js.map +0 -1
  42. package/dist/generators-CR34GjVu.js +0 -661
  43. package/dist/generators-CR34GjVu.js.map +0 -1
  44. package/dist/generators-DH8VkK1q.cjs +0 -678
  45. package/dist/generators-DH8VkK1q.cjs.map +0 -1
  46. package/dist/types-CgDFUvfZ.d.ts +0 -211
@@ -1,139 +1,107 @@
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'
6
- import type { PluginVueQuery } from '../types.ts'
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 type { Infinite, PluginVueQuery } from '../types.ts'
7
+ import { getComments, resolveErrorNames } from '../utils.ts'
7
8
  import { QueryKey } from './QueryKey.tsx'
8
- import { QueryOptions } from './QueryOptions.tsx'
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
19
- operation: Operation
16
+ node: ast.OperationNode
17
+ tsResolver: ResolverTs
20
18
  paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
21
19
  paramsType: PluginVueQuery['resolvedOptions']['paramsType']
22
20
  pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
23
21
  dataReturnType: PluginVueQuery['resolvedOptions']['client']['dataReturnType']
22
+ initialPageParam: Infinite['initialPageParam']
23
+ queryParam?: Infinite['queryParam']
24
24
  }
25
25
 
26
- type GetParamsProps = {
27
- paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
28
- paramsType: PluginVueQuery['resolvedOptions']['paramsType']
29
- pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
30
- dataReturnType: PluginVueQuery['resolvedOptions']['client']['dataReturnType']
31
- typeSchemas: OperationSchemas
32
- }
26
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
27
+ const callPrinter = functionPrinter({ mode: 'call' })
33
28
 
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'}>`
37
-
38
- if (paramsType === 'object') {
39
- const pathParams = getPathParams(typeSchemas.pathParams, {
40
- typed: true,
41
- casing: paramsCasing,
42
- override(item) {
43
- return {
44
- ...item,
45
- type: `MaybeRefOrGetter<${item.type}>`,
46
- }
47
- },
48
- })
49
- const children = {
50
- ...pathParams,
51
- data: typeSchemas.request?.name
52
- ? {
53
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
54
- optional: isOptional(typeSchemas.request?.schema),
55
- }
56
- : undefined,
57
- params: typeSchemas.queryParams?.name
58
- ? {
59
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
60
- optional: isOptional(typeSchemas.queryParams?.schema),
61
- }
62
- : undefined,
63
- headers: typeSchemas.headerParams?.name
64
- ? {
65
- type: `MaybeRefOrGetter<${typeSchemas.headerParams?.name}>`,
66
- optional: isOptional(typeSchemas.headerParams?.schema),
67
- }
68
- : undefined,
69
- }
29
+ function getParams(
30
+ node: ast.OperationNode,
31
+ options: {
32
+ paramsType: PluginVueQuery['resolvedOptions']['paramsType']
33
+ paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
34
+ pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
35
+ dataReturnType: PluginVueQuery['resolvedOptions']['client']['dataReturnType']
36
+ resolver: ResolverTs
37
+ },
38
+ ): ast.FunctionParametersNode {
39
+ const { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver } = options
40
+ const responseName = resolver.resolveResponseName(node)
41
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
42
+ const errorNames = resolveErrorNames(node, resolver)
70
43
 
71
- // Check if all children are optional or undefined
72
- const allChildrenAreOptional = Object.values(children).every((child) => !child || child.optional)
73
-
74
- return FunctionParams.factory({
75
- data: {
76
- mode: 'object',
77
- children,
78
- default: allChildrenAreOptional ? '{}' : undefined,
79
- },
80
- options: {
81
- type: `
82
- {
83
- query?: Partial<UseInfiniteQueryOptions<${[TData, TError, 'TQueryData', 'TQueryKey', 'TQueryData'].join(', ')}>> & { client?: QueryClient },
84
- client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'}
85
- }
86
- `,
87
- default: '{}',
88
- },
89
- })
90
- }
44
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
45
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
91
46
 
92
- return FunctionParams.factory({
93
- pathParams: typeSchemas.pathParams?.name
94
- ? {
95
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
96
- children: getPathParams(typeSchemas.pathParams, {
97
- typed: true,
98
- casing: paramsCasing,
99
- override(item) {
100
- return {
101
- ...item,
102
- type: `MaybeRefOrGetter<${item.type}>`,
103
- }
104
- },
105
- }),
106
- default: getDefaultValue(typeSchemas.pathParams?.schema),
107
- }
108
- : undefined,
109
- data: typeSchemas.request?.name
110
- ? {
111
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
112
- optional: isOptional(typeSchemas.request?.schema),
113
- }
114
- : undefined,
115
- params: typeSchemas.queryParams?.name
116
- ? {
117
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
118
- optional: isOptional(typeSchemas.queryParams?.schema),
119
- }
120
- : undefined,
121
- headers: typeSchemas.headerParams?.name
122
- ? {
123
- type: `MaybeRefOrGetter<${typeSchemas.headerParams?.name}>`,
124
- optional: isOptional(typeSchemas.headerParams?.schema),
125
- }
126
- : undefined,
127
- options: {
128
- type: `
129
- {
47
+ const optionsParam = ast.createFunctionParameter({
48
+ name: 'options',
49
+ type: ast.createParamsType({
50
+ variant: 'reference',
51
+ name: `{
130
52
  query?: Partial<UseInfiniteQueryOptions<${[TData, TError, 'TQueryData', 'TQueryKey', 'TQueryData'].join(', ')}>> & { client?: QueryClient },
131
- client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'}
53
+ client?: ${requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'}
54
+ }`,
55
+ }),
56
+ default: '{}',
57
+ })
58
+
59
+ const baseParams = ast.createOperationParams(node, {
60
+ paramsType,
61
+ pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
62
+ paramsCasing,
63
+ resolver,
64
+ extraParams: [optionsParam],
65
+ })
66
+
67
+ return wrapOperationParamsWithMaybeRef(baseParams)
132
68
  }
133
- `,
134
- default: '{}',
135
- },
69
+
70
+ function wrapOperationParamsWithMaybeRef(paramsNode: ast.FunctionParametersNode): ast.FunctionParametersNode {
71
+ const wrappedParams = paramsNode.params.map((param) => {
72
+ if ('kind' in param && (param as ast.ParameterGroupNode).kind === 'ParameterGroup') {
73
+ const group = param as ast.ParameterGroupNode
74
+ return {
75
+ ...group,
76
+ properties: group.properties.map((p) => ({
77
+ ...p,
78
+ type: p.type ? ast.createParamsType({ variant: 'reference', name: `MaybeRefOrGetter<${printType(p.type)}>` }) : p.type,
79
+ })),
80
+ }
81
+ }
82
+ const fp = param as ast.FunctionParameterNode
83
+ if (fp.name === 'options') return fp
84
+ return {
85
+ ...fp,
86
+ type: fp.type ? ast.createParamsType({ variant: 'reference', name: `MaybeRefOrGetter<${printType(fp.type)}>` }) : fp.type,
87
+ }
136
88
  })
89
+ return ast.createFunctionParameters({ params: wrappedParams })
90
+ }
91
+
92
+ function printType(typeNode: ast.ParamsTypeNode | undefined): string {
93
+ if (!typeNode) return 'unknown'
94
+ if (typeNode.variant === 'reference') return typeNode.name
95
+ if (typeNode.variant === 'member') return `${typeNode.base}['${typeNode.key}']`
96
+ if (typeNode.variant === 'struct') {
97
+ const parts = typeNode.properties.map((p) => {
98
+ const typeStr = printType(p.type)
99
+ const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.name) ? p.name : JSON.stringify(p.name)
100
+ return p.optional ? `${key}?: ${typeStr}` : `${key}: ${typeStr}`
101
+ })
102
+ return `{ ${parts.join('; ')} }`
103
+ }
104
+ return 'unknown'
137
105
  }
138
106
 
139
107
  export function InfiniteQuery({
@@ -142,56 +110,39 @@ export function InfiniteQuery({
142
110
  queryOptionsName,
143
111
  queryKeyName,
144
112
  paramsType,
145
- pathParamsType,
146
113
  paramsCasing,
114
+ pathParamsType,
147
115
  dataReturnType,
148
- typeSchemas,
149
- operation,
150
- }: Props): FabricReactNode {
151
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
152
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
116
+ node,
117
+ tsResolver,
118
+ }: Props): KubbReactNode {
119
+ const responseName = tsResolver.resolveResponseName(node)
120
+ const errorNames = resolveErrorNames(node, tsResolver)
121
+
122
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
123
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
153
124
  const returnType = `UseInfiniteQueryReturnType<${['TData', TError].join(', ')}> & { queryKey: TQueryKey }`
154
125
  const generics = [`TData = InfiniteData<${TData}>`, `TQueryData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`]
155
126
 
156
- const queryKeyParams = QueryKey.getParams({
157
- pathParamsType,
158
- typeSchemas,
159
- paramsCasing,
160
- })
161
- const queryOptionsParams = QueryOptions.getParams({
162
- paramsType,
163
- pathParamsType,
164
- typeSchemas,
165
- paramsCasing,
166
- })
167
- const params = getParams({
168
- paramsCasing,
169
- paramsType,
170
- pathParamsType,
171
- dataReturnType,
172
- typeSchemas,
173
- })
127
+ const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
128
+ const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
129
+
130
+ const queryOptionsParamsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
131
+ const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? ''
174
132
 
175
- const queryOptions = `${queryOptionsName}(${queryOptionsParams.toCall()})`
133
+ const paramsNode = getParams(node, { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver: tsResolver })
134
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
176
135
 
177
136
  return (
178
137
  <File.Source name={name} isExportable isIndexable>
179
- <Function
180
- name={name}
181
- export
182
- generics={generics.join(', ')}
183
- params={params.toConstructor()}
184
- JSDoc={{
185
- comments: getComments(operation),
186
- }}
187
- >
138
+ <Function name={name} export generics={generics.join(', ')} params={paramsSignature} JSDoc={{ comments: getComments(node) }}>
188
139
  {`
189
140
  const { query: queryConfig = {}, client: config = {} } = options ?? {}
190
141
  const { client: queryClient, ...resolvedOptions } = queryConfig
191
- const queryKey = (resolvedOptions && 'queryKey' in resolvedOptions ? toValue(resolvedOptions.queryKey) : undefined) ?? ${queryKeyName}(${queryKeyParams.toCall()})
142
+ const queryKey = (resolvedOptions && 'queryKey' in resolvedOptions ? toValue(resolvedOptions.queryKey) : undefined) ?? ${queryKeyName}(${queryKeyParamsCall})
192
143
 
193
144
  const query = useInfiniteQuery({
194
- ...${queryOptions},
145
+ ...${queryOptionsName}(${queryOptionsParamsCall}),
195
146
  ...resolvedOptions,
196
147
  queryKey
197
148
  } as unknown as UseInfiniteQueryOptions<${TData}, ${TError}, ${TData}, TQueryKey, ${TData}>, toValue(queryClient)) as ${returnType}
@@ -1,18 +1,20 @@
1
1
  import { getNestedAccessor } from '@internals/utils'
2
- import { getDefaultValue, isOptional } from '@kubb/oas'
3
- import { Client } from '@kubb/plugin-client/components'
4
- import type { OperationSchemas } from '@kubb/plugin-oas'
5
- import { getPathParams } from '@kubb/plugin-oas/utils'
6
- import { File, Function, FunctionParams } from '@kubb/react-fabric'
7
- import type { FabricReactNode } from '@kubb/react-fabric/types'
2
+ import type { ast } from '@kubb/core'
3
+ import type { ResolverTs } from '@kubb/plugin-ts'
4
+ import { functionPrinter } from '@kubb/plugin-ts'
5
+ import { File, Function } from '@kubb/renderer-jsx'
6
+ import type { KubbReactNode } from '@kubb/renderer-jsx/types'
8
7
  import type { Infinite, PluginVueQuery } from '../types.ts'
8
+ import { resolveErrorNames } from '../utils.ts'
9
9
  import { QueryKey } from './QueryKey.tsx'
10
+ import { buildEnabledCheck, getQueryOptionsParams } from './QueryOptions.tsx'
10
11
 
11
12
  type Props = {
12
13
  name: string
13
14
  clientName: string
14
15
  queryKeyName: string
15
- typeSchemas: OperationSchemas
16
+ node: ast.OperationNode
17
+ tsResolver: ResolverTs
16
18
  paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
17
19
  paramsType: PluginVueQuery['resolvedOptions']['paramsType']
18
20
  pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
@@ -24,105 +26,8 @@ type Props = {
24
26
  queryParam: Infinite['queryParam']
25
27
  }
26
28
 
27
- type GetParamsProps = {
28
- paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
29
- paramsType: PluginVueQuery['resolvedOptions']['paramsType']
30
- pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
31
- typeSchemas: OperationSchemas
32
- }
33
-
34
- function getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas }: GetParamsProps) {
35
- if (paramsType === 'object') {
36
- const children = {
37
- ...getPathParams(typeSchemas.pathParams, {
38
- typed: true,
39
- casing: paramsCasing,
40
- override(item) {
41
- return {
42
- ...item,
43
- type: `MaybeRefOrGetter<${item.type}>`,
44
- }
45
- },
46
- }),
47
- data: typeSchemas.request?.name
48
- ? {
49
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
50
- optional: isOptional(typeSchemas.request?.schema),
51
- }
52
- : undefined,
53
- params: typeSchemas.queryParams?.name
54
- ? {
55
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
56
- optional: isOptional(typeSchemas.queryParams?.schema),
57
- }
58
- : undefined,
59
- headers: typeSchemas.headerParams?.name
60
- ? {
61
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
62
- optional: isOptional(typeSchemas.headerParams?.schema),
63
- }
64
- : undefined,
65
- }
66
-
67
- // Check if all children are optional or undefined
68
- const allChildrenAreOptional = Object.values(children).every((child) => !child || child.optional)
69
-
70
- return FunctionParams.factory({
71
- data: {
72
- mode: 'object',
73
- children,
74
- default: allChildrenAreOptional ? '{}' : undefined,
75
- },
76
- config: {
77
- type: typeSchemas.request?.name
78
- ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }`
79
- : 'Partial<RequestConfig> & { client?: Client }',
80
- default: '{}',
81
- },
82
- })
83
- }
84
-
85
- return FunctionParams.factory({
86
- pathParams: {
87
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
88
- children: getPathParams(typeSchemas.pathParams, {
89
- typed: true,
90
- casing: paramsCasing,
91
- override(item) {
92
- return {
93
- ...item,
94
- type: `MaybeRefOrGetter<${item.type}>`,
95
- }
96
- },
97
- }),
98
- default: getDefaultValue(typeSchemas.pathParams?.schema),
99
- },
100
- data: typeSchemas.request?.name
101
- ? {
102
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
103
- optional: isOptional(typeSchemas.request?.schema),
104
- }
105
- : undefined,
106
- params: typeSchemas.queryParams?.name
107
- ? {
108
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
109
- optional: isOptional(typeSchemas.queryParams?.schema),
110
- }
111
- : undefined,
112
- headers: typeSchemas.headerParams?.name
113
- ? {
114
- type: `MaybeRefOrGetter<${typeSchemas.headerParams?.name}>`,
115
- optional: isOptional(typeSchemas.headerParams?.schema),
116
- }
117
- : undefined,
118
- config: {
119
- type: typeSchemas.request?.name
120
- ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }`
121
- : 'Partial<RequestConfig> & { client?: Client }',
122
- default: '{}',
123
- },
124
- })
125
- }
29
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
30
+ const callPrinter = functionPrinter({ mode: 'call' })
126
31
 
127
32
  export function InfiniteQueryOptions({
128
33
  name,
@@ -131,39 +36,65 @@ export function InfiniteQueryOptions({
131
36
  cursorParam,
132
37
  nextParam,
133
38
  previousParam,
134
- typeSchemas,
135
- paramsType,
39
+ node,
40
+ tsResolver,
136
41
  paramsCasing,
42
+ paramsType,
137
43
  dataReturnType,
138
44
  pathParamsType,
139
45
  queryParam,
140
46
  queryKeyName,
141
- }: Props): FabricReactNode {
142
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
143
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
144
-
145
- const params = getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas })
146
- const clientParams = Client.getParams({
147
- paramsType,
148
- paramsCasing,
149
- typeSchemas,
150
- pathParamsType,
151
- isConfigurable: true,
152
- })
153
- const queryKeyParams = QueryKey.getParams({
154
- paramsCasing,
155
- pathParamsType,
156
- typeSchemas,
157
- })
47
+ }: Props): KubbReactNode {
48
+ const responseName = tsResolver.resolveResponseName(node)
49
+ const queryFnDataType = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
50
+ const errorNames = resolveErrorNames(node, tsResolver)
51
+ const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
52
+
53
+ const isInitialPageParamDefined = initialPageParam !== undefined && initialPageParam !== null
54
+ const fallbackPageParamType =
55
+ typeof initialPageParam === 'number'
56
+ ? 'number'
57
+ : typeof initialPageParam === 'string'
58
+ ? initialPageParam.includes(' as ')
59
+ ? (() => {
60
+ const parts = initialPageParam.split(' as ')
61
+ return parts[parts.length - 1] ?? 'unknown'
62
+ })()
63
+ : 'string'
64
+ : typeof initialPageParam === 'boolean'
65
+ ? 'boolean'
66
+ : 'unknown'
67
+
68
+ const rawQueryParams = node.parameters.filter((p) => p.in === 'query')
69
+ const queryParamsTypeName =
70
+ rawQueryParams.length > 0
71
+ ? (() => {
72
+ const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]!)
73
+ const individualName = tsResolver.resolveParamName(node, rawQueryParams[0]!)
74
+ return groupName !== individualName ? groupName : undefined
75
+ })()
76
+ : undefined
77
+
78
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : undefined
79
+ const pageParamType = queryParamType ? (isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType) : fallbackPageParamType
80
+
81
+ const paramsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
82
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
83
+ const rawParamsCall = callPrinter.print(paramsNode) ?? ''
84
+ const clientCallStr = rawParamsCall.replace(/\bconfig\b(?=[^,]*$)/, '{ ...config, signal: config.signal ?? signal }')
85
+
86
+ const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
87
+ const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
88
+
89
+ const enabledSource = buildEnabledCheck(queryKeyParamsNode)
90
+ const enabledText = enabledSource ? `enabled: () => !!(${enabledSource}),` : ''
158
91
 
159
- // Determine if we should use the new nextParam/previousParam or fall back to legacy cursorParam behavior
160
92
  const hasNewParams = nextParam !== undefined || previousParam !== undefined
161
93
 
162
94
  let getNextPageParamExpr: string | undefined
163
95
  let getPreviousPageParamExpr: string | undefined
164
96
 
165
97
  if (hasNewParams) {
166
- // Use the new nextParam and previousParam
167
98
  if (nextParam) {
168
99
  const accessor = getNestedAccessor(nextParam, 'lastPage')
169
100
  if (accessor) {
@@ -177,11 +108,9 @@ export function InfiniteQueryOptions({
177
108
  }
178
109
  }
179
110
  } else if (cursorParam) {
180
- // Legacy behavior: use cursorParam for both next and previous
181
111
  getNextPageParamExpr = `getNextPageParam: (lastPage) => lastPage['${cursorParam}']`
182
112
  getPreviousPageParamExpr = `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`
183
113
  } else {
184
- // Fallback behavior: page-based pagination
185
114
  if (dataReturnType === 'full') {
186
115
  getNextPageParamExpr =
187
116
  'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage.data) && lastPage.data.length === 0 ? undefined : lastPageParam + 1'
@@ -192,53 +121,54 @@ export function InfiniteQueryOptions({
192
121
  getPreviousPageParamExpr = 'getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1'
193
122
  }
194
123
 
195
- const queryOptions = [
124
+ const queryOptionsArr = [
196
125
  `initialPageParam: ${typeof initialPageParam === 'string' ? JSON.stringify(initialPageParam) : initialPageParam}`,
197
126
  getNextPageParamExpr,
198
127
  getPreviousPageParamExpr,
199
128
  ].filter(Boolean)
200
129
 
201
130
  const infiniteOverrideParams =
202
- queryParam && typeSchemas.queryParams?.name
131
+ queryParam && queryParamsTypeName
203
132
  ? `
204
- if (!params) {
205
- params = { }
206
- }
207
- params['${queryParam}'] = pageParam as unknown as ${typeSchemas.queryParams?.name}['${queryParam}']`
133
+ params = {
134
+ ...(params ?? {}),
135
+ ['${queryParam}']: pageParam as unknown as ${queryParamsTypeName}['${queryParam}'],
136
+ } as ${queryParamsTypeName}`
208
137
  : ''
209
138
 
210
- const enabled = Object.entries(queryKeyParams.flatParams)
211
- .map(([key, item]) => {
212
- // Only include if the parameter exists and is NOT optional
213
- // This ensures we only check required parameters
214
- return item && !item.optional && !item.default ? key : undefined
215
- })
216
- .filter(Boolean)
217
- .join('&& ')
218
-
219
- const enabledText = enabled ? `enabled: !!(${enabled}),` : ''
139
+ if (infiniteOverrideParams) {
140
+ return (
141
+ <File.Source name={name} isExportable isIndexable>
142
+ <Function name={name} export params={paramsSignature}>
143
+ {`
144
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
145
+ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, QueryKey, ${pageParamType}>({
146
+ ${enabledText}
147
+ queryKey,
148
+ queryFn: async ({ signal, pageParam }) => {
149
+ ${infiniteOverrideParams}
150
+ return ${clientName}(${addToValueCalls(clientCallStr)})
151
+ },
152
+ ${queryOptionsArr.join(',\n')}
153
+ })
154
+ `}
155
+ </Function>
156
+ </File.Source>
157
+ )
158
+ }
220
159
 
221
160
  return (
222
161
  <File.Source name={name} isExportable isIndexable>
223
- <Function name={name} export params={params.toConstructor()}>
162
+ <Function name={name} export params={paramsSignature}>
224
163
  {`
225
- const queryKey = ${queryKeyName}(${queryKeyParams.toCall()})
226
- return infiniteQueryOptions<${TData}, ${TError}, ${TData}, typeof queryKey, number>({
164
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
165
+ return infiniteQueryOptions<${queryFnDataType}, ${errorType}, InfiniteData<${queryFnDataType}>, QueryKey, ${pageParamType}>({
227
166
  ${enabledText}
228
167
  queryKey,
229
- queryFn: async ({ signal, pageParam }) => {
230
- ${infiniteOverrideParams}
231
- return ${clientName}(${clientParams.toCall({
232
- transformName(name) {
233
- if (name === 'config') {
234
- return '{ ...config, signal: config.signal ?? signal }'
235
- }
236
-
237
- return `toValue(${name})`
238
- },
239
- })})
240
- },
241
- ${queryOptions.join(',\n')}
168
+ queryFn: async ({ signal }) => {
169
+ return ${clientName}(${addToValueCalls(clientCallStr)})
170
+ },
171
+ ${queryOptionsArr.join(',\n')}
242
172
  })
243
173
  `}
244
174
  </Function>
@@ -246,4 +176,34 @@ export function InfiniteQueryOptions({
246
176
  )
247
177
  }
248
178
 
249
- InfiniteQueryOptions.getParams = getParams
179
+ function addToValueCalls(callStr: string): string {
180
+ // Step 1: Transform shorthand object params like { petId } → { petId: toValue(petId) }
181
+ let result = callStr.replace(/\{\s*([\w,\s]+)\s*\}(?=\s*,)/g, (match, inner: string) => {
182
+ if (inner.includes(':') || inner.includes('...')) return match
183
+ const keys = inner
184
+ .split(',')
185
+ .map((k: string) => k.trim())
186
+ .filter(Boolean)
187
+ const wrapped = keys.map((k: string) => `${k}: toValue(${k})`).join(', ')
188
+ return `{ ${wrapped} }`
189
+ })
190
+
191
+ // Step 2: Handle standalone identifiers like `data, params`
192
+ result = result.replace(/(?<![{.:?])\b(\w+)\b(?=\s*,)/g, (match, name: string) => {
193
+ if (name === 'config' || name === 'signal' || name === 'undefined') return match
194
+ if (match.includes('toValue(')) return match
195
+ return `toValue(${name})`
196
+ })
197
+
198
+ return result
199
+ }
200
+
201
+ InfiniteQueryOptions.getParams = (
202
+ node: ast.OperationNode,
203
+ options: {
204
+ paramsType: PluginVueQuery['resolvedOptions']['paramsType']
205
+ paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
206
+ pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
207
+ resolver: ResolverTs
208
+ },
209
+ ) => getQueryOptionsParams(node, options)