@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,83 +1,92 @@
1
1
  import { URLPath } from '@internals/utils'
2
- import { isOptional, type Operation } from '@kubb/oas'
3
- import type { OperationSchemas } from '@kubb/plugin-oas'
4
- import { getPathParams } from '@kubb/plugin-oas/utils'
5
- import { File, Function, FunctionParams, Type } from '@kubb/react-fabric'
6
- import type { FabricReactNode } from '@kubb/react-fabric/types'
7
- import type { PluginVueQuery, Transformer } from '../types'
2
+ import { ast } from '@kubb/core'
3
+ import type { ResolverTs } from '@kubb/plugin-ts'
4
+ import { functionPrinter } from '@kubb/plugin-ts'
5
+ import { File, Function, Type } from '@kubb/renderer-jsx'
6
+ import type { KubbReactNode } from '@kubb/renderer-jsx/types'
7
+ import type { Transformer } from '../types.ts'
8
+ import { buildQueryKeyParams } from '../utils.ts'
8
9
 
9
10
  type Props = {
10
11
  name: string
11
12
  typeName: string
12
- typeSchemas: OperationSchemas
13
- operation: Operation
14
- paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
15
- pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
13
+ node: ast.OperationNode
14
+ tsResolver: ResolverTs
15
+ paramsCasing: 'camelcase' | undefined
16
+ pathParamsType: 'object' | 'inline'
16
17
  transformer: Transformer | undefined
17
18
  }
18
19
 
19
- type GetParamsProps = {
20
- paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
21
- pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
22
- typeSchemas: OperationSchemas
23
- }
20
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
21
+ const callPrinter = functionPrinter({ mode: 'call' })
24
22
 
25
- function getParams({ pathParamsType, paramsCasing, typeSchemas }: GetParamsProps) {
26
- return FunctionParams.factory({
27
- pathParams: {
28
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
29
- children: getPathParams(typeSchemas.pathParams, {
30
- typed: true,
31
- casing: paramsCasing,
32
- override(item) {
33
- return {
34
- ...item,
35
- type: `MaybeRefOrGetter<${item.type}>`,
36
- }
37
- },
38
- }),
39
- },
40
- data: typeSchemas.request?.name
41
- ? {
42
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
43
- optional: isOptional(typeSchemas.request?.schema),
44
- }
45
- : undefined,
46
- params: typeSchemas.queryParams?.name
47
- ? {
48
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
49
- optional: isOptional(typeSchemas.queryParams?.schema),
50
- }
51
- : undefined,
23
+ function wrapWithMaybeRefOrGetter(paramsNode: ast.FunctionParametersNode): ast.FunctionParametersNode {
24
+ const wrappedParams = paramsNode.params.map((param) => {
25
+ if ('kind' in param && (param as ast.ParameterGroupNode).kind === 'ParameterGroup') {
26
+ const group = param as ast.ParameterGroupNode
27
+ return {
28
+ ...group,
29
+ properties: group.properties.map((p) => ({
30
+ ...p,
31
+ type: p.type ? ast.createParamsType({ variant: 'reference', name: `MaybeRefOrGetter<${printType(p.type)}>` }) : p.type,
32
+ })),
33
+ }
34
+ }
35
+ const fp = param as ast.FunctionParameterNode
36
+ return {
37
+ ...fp,
38
+ type: fp.type ? ast.createParamsType({ variant: 'reference', name: `MaybeRefOrGetter<${printType(fp.type)}>` }) : fp.type,
39
+ }
52
40
  })
41
+ return ast.createFunctionParameters({ params: wrappedParams })
42
+ }
43
+
44
+ function printType(typeNode: ast.ParamsTypeNode | undefined): string {
45
+ if (!typeNode) return 'unknown'
46
+ if (typeNode.variant === 'reference') return typeNode.name
47
+ if (typeNode.variant === 'member') return `${typeNode.base}['${typeNode.key}']`
48
+ if (typeNode.variant === 'struct') {
49
+ const parts = typeNode.properties.map((p) => {
50
+ const typeStr = printType(p.type)
51
+ const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.name) ? p.name : JSON.stringify(p.name)
52
+ return p.optional ? `${key}?: ${typeStr}` : `${key}: ${typeStr}`
53
+ })
54
+ return `{ ${parts.join('; ')} }`
55
+ }
56
+ return 'unknown'
57
+ }
58
+
59
+ function getParams(
60
+ node: ast.OperationNode,
61
+ options: { pathParamsType: 'object' | 'inline'; paramsCasing: 'camelcase' | undefined; resolver: ResolverTs },
62
+ ): ast.FunctionParametersNode {
63
+ return wrapWithMaybeRefOrGetter(buildQueryKeyParams(node, options))
53
64
  }
54
65
 
55
- const getTransformer: Transformer = ({ operation, schemas, casing }) => {
56
- const path = new URLPath(operation.path, { casing })
57
- const keys = [
58
- path.toObject({
59
- type: 'path',
60
- stringify: true,
61
- }),
62
- schemas.queryParams?.name ? '...(params ? [params] : [])' : undefined,
63
- schemas.request?.name ? '...(data ? [data] : [])' : undefined,
64
- ].filter(Boolean)
66
+ const getTransformer: Transformer = ({ node, casing }) => {
67
+ const path = new URLPath(node.path, { casing })
68
+ const hasQueryParams = node.parameters.some((p) => p.in === 'query')
69
+ const hasRequestBody = !!node.requestBody?.content?.[0]?.schema
65
70
 
66
- return keys
71
+ return [
72
+ path.toObject({ type: 'path', stringify: true }),
73
+ hasQueryParams ? '...(params ? [params] : [])' : undefined,
74
+ hasRequestBody ? '...(data ? [data] : [])' : undefined,
75
+ ].filter(Boolean) as string[]
67
76
  }
68
77
 
69
- export function QueryKey({ name, typeSchemas, paramsCasing, pathParamsType, operation, typeName, transformer = getTransformer }: Props): FabricReactNode {
70
- const params = getParams({ pathParamsType, typeSchemas, paramsCasing })
78
+ export function QueryKey({ name, node, tsResolver, paramsCasing, pathParamsType, typeName, transformer = getTransformer }: Props): KubbReactNode {
79
+ const paramsNode = getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
80
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
71
81
  const keys = transformer({
72
- operation,
73
- schemas: typeSchemas,
82
+ node,
74
83
  casing: paramsCasing,
75
84
  })
76
85
 
77
86
  return (
78
87
  <>
79
88
  <File.Source name={name} isExportable isIndexable>
80
- <Function.Arrow name={name} export params={params.toConstructor()} singleLine>
89
+ <Function.Arrow name={name} export params={paramsSignature} singleLine>
81
90
  {`[${keys.join(', ')}] as const`}
82
91
  </Function.Arrow>
83
92
  </File.Source>
@@ -92,3 +101,4 @@ export function QueryKey({ name, typeSchemas, paramsCasing, pathParamsType, oper
92
101
 
93
102
  QueryKey.getParams = getParams
94
103
  QueryKey.getTransformer = getTransformer
104
+ QueryKey.callPrinter = callPrinter
@@ -1,179 +1,157 @@
1
- import { getDefaultValue, isOptional } from '@kubb/oas'
2
- import { Client } from '@kubb/plugin-client/components'
3
- import type { OperationSchemas } from '@kubb/plugin-oas'
4
- import { getPathParams } from '@kubb/plugin-oas/utils'
5
- import { File, Function, FunctionParams } from '@kubb/react-fabric'
6
- 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'
7
6
  import type { PluginVueQuery } from '../types.ts'
7
+ import { resolveErrorNames } from '../utils.ts'
8
8
  import { QueryKey } from './QueryKey.tsx'
9
9
 
10
10
  type Props = {
11
11
  name: string
12
12
  clientName: string
13
13
  queryKeyName: string
14
- typeSchemas: OperationSchemas
14
+ node: ast.OperationNode
15
+ tsResolver: ResolverTs
15
16
  paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
16
17
  paramsType: PluginVueQuery['resolvedOptions']['paramsType']
17
18
  pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
18
19
  dataReturnType: PluginVueQuery['resolvedOptions']['client']['dataReturnType']
19
20
  }
20
21
 
21
- type GetParamsProps = {
22
- paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
23
- paramsType: PluginVueQuery['resolvedOptions']['paramsType']
24
- pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
25
- typeSchemas: OperationSchemas
26
- }
22
+ const declarationPrinter = functionPrinter({ mode: 'declaration' })
23
+ const callPrinter = functionPrinter({ mode: 'call' })
24
+
25
+ export function getQueryOptionsParams(
26
+ node: ast.OperationNode,
27
+ options: {
28
+ paramsType: PluginVueQuery['resolvedOptions']['paramsType']
29
+ paramsCasing: PluginVueQuery['resolvedOptions']['paramsCasing']
30
+ pathParamsType: PluginVueQuery['resolvedOptions']['pathParamsType']
31
+ resolver: ResolverTs
32
+ },
33
+ ): ast.FunctionParametersNode {
34
+ const { paramsType, paramsCasing, pathParamsType, resolver } = options
35
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
27
36
 
28
- function getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas }: GetParamsProps) {
29
- if (paramsType === 'object') {
30
- const children = {
31
- ...getPathParams(typeSchemas.pathParams, {
32
- typed: true,
33
- casing: paramsCasing,
34
- override(item) {
35
- return {
36
- ...item,
37
- type: `MaybeRefOrGetter<${item.type}>`,
38
- }
39
- },
37
+ const baseParams = ast.createOperationParams(node, {
38
+ paramsType,
39
+ pathParamsType: paramsType === 'object' ? 'object' : pathParamsType === 'object' ? 'object' : 'inline',
40
+ paramsCasing,
41
+ resolver,
42
+ extraParams: [
43
+ ast.createFunctionParameter({
44
+ name: 'config',
45
+ type: ast.createParamsType({
46
+ variant: 'reference',
47
+ name: requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }',
48
+ }),
49
+ default: '{}',
40
50
  }),
41
- data: typeSchemas.request?.name
42
- ? {
43
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
44
- optional: isOptional(typeSchemas.request?.schema),
45
- }
46
- : undefined,
47
- params: typeSchemas.queryParams?.name
48
- ? {
49
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
50
- optional: isOptional(typeSchemas.queryParams?.schema),
51
- }
52
- : undefined,
53
- headers: typeSchemas.headerParams?.name
54
- ? {
55
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
56
- optional: isOptional(typeSchemas.headerParams?.schema),
57
- }
58
- : undefined,
51
+ ],
52
+ })
53
+
54
+ return wrapOperationParamsWithMaybeRef(baseParams)
55
+ }
56
+
57
+ function wrapOperationParamsWithMaybeRef(paramsNode: ast.FunctionParametersNode): ast.FunctionParametersNode {
58
+ const wrappedParams = paramsNode.params.map((param) => {
59
+ if ('kind' in param && (param as ast.ParameterGroupNode).kind === 'ParameterGroup') {
60
+ const group = param as ast.ParameterGroupNode
61
+ return {
62
+ ...group,
63
+ properties: group.properties.map((p) => ({
64
+ ...p,
65
+ type: p.type ? ast.createParamsType({ variant: 'reference', name: `MaybeRefOrGetter<${printType(p.type)}>` }) : p.type,
66
+ })),
67
+ }
68
+ }
69
+ const fp = param as ast.FunctionParameterNode
70
+ // Don't wrap 'config' param — it's not reactive
71
+ if (fp.name === 'config') return fp
72
+ return {
73
+ ...fp,
74
+ type: fp.type ? ast.createParamsType({ variant: 'reference', name: `MaybeRefOrGetter<${printType(fp.type)}>` }) : fp.type,
59
75
  }
76
+ })
77
+ return ast.createFunctionParameters({ params: wrappedParams })
78
+ }
60
79
 
61
- // Check if all children are optional or undefined
62
- const allChildrenAreOptional = Object.values(children).every((child) => !child || child.optional)
63
-
64
- return FunctionParams.factory({
65
- data: {
66
- mode: 'object',
67
- children,
68
- default: allChildrenAreOptional ? '{}' : undefined,
69
- },
70
- config: {
71
- type: typeSchemas.request?.name
72
- ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }`
73
- : 'Partial<RequestConfig> & { client?: Client }',
74
- default: '{}',
75
- },
80
+ function printType(typeNode: ast.ParamsTypeNode | undefined): string {
81
+ if (!typeNode) return 'unknown'
82
+ if (typeNode.variant === 'reference') return typeNode.name
83
+ if (typeNode.variant === 'member') return `${typeNode.base}['${typeNode.key}']`
84
+ if (typeNode.variant === 'struct') {
85
+ const parts = typeNode.properties.map((p) => {
86
+ const typeStr = printType(p.type)
87
+ const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.name) ? p.name : JSON.stringify(p.name)
88
+ return p.optional ? `${key}?: ${typeStr}` : `${key}: ${typeStr}`
76
89
  })
90
+ return `{ ${parts.join('; ')} }`
77
91
  }
92
+ return 'unknown'
93
+ }
78
94
 
79
- return FunctionParams.factory({
80
- pathParams: {
81
- mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
82
- children: getPathParams(typeSchemas.pathParams, {
83
- typed: true,
84
- casing: paramsCasing,
85
- override(item) {
86
- return {
87
- ...item,
88
- type: `MaybeRefOrGetter<${item.type}>`,
89
- }
90
- },
91
- }),
92
- default: getDefaultValue(typeSchemas.pathParams?.schema),
93
- },
94
- data: typeSchemas.request?.name
95
- ? {
96
- type: `MaybeRefOrGetter<${typeSchemas.request?.name}>`,
97
- optional: isOptional(typeSchemas.request?.schema),
98
- }
99
- : undefined,
100
- params: typeSchemas.queryParams?.name
101
- ? {
102
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
103
- optional: isOptional(typeSchemas.queryParams?.schema),
95
+ export function buildEnabledCheck(paramsNode: ast.FunctionParametersNode): string {
96
+ const required: string[] = []
97
+ for (const param of paramsNode.params) {
98
+ if ('kind' in param && (param as ast.ParameterGroupNode).kind === 'ParameterGroup') {
99
+ const group = param as ast.ParameterGroupNode
100
+ for (const child of group.properties) {
101
+ if (!child.optional && child.default === undefined) {
102
+ required.push(child.name)
104
103
  }
105
- : undefined,
106
- headers: typeSchemas.headerParams?.name
107
- ? {
108
- type: `MaybeRefOrGetter<${typeSchemas.queryParams?.name}>`,
109
- optional: isOptional(typeSchemas.headerParams?.schema),
110
- }
111
- : undefined,
112
- config: {
113
- type: typeSchemas.request?.name
114
- ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }`
115
- : 'Partial<RequestConfig> & { client?: Client }',
116
- default: '{}',
117
- },
118
- })
104
+ }
105
+ } else {
106
+ const fp = param as ast.FunctionParameterNode
107
+ if (!fp.optional && fp.default === undefined) {
108
+ required.push(fp.name)
109
+ }
110
+ }
111
+ }
112
+ return required.join(' && ')
119
113
  }
120
114
 
121
115
  export function QueryOptions({
122
116
  name,
123
117
  clientName,
124
118
  dataReturnType,
125
- typeSchemas,
119
+ node,
120
+ tsResolver,
126
121
  paramsCasing,
127
122
  paramsType,
128
123
  pathParamsType,
129
124
  queryKeyName,
130
- }: Props): FabricReactNode {
131
- const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
132
- const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'}>`
125
+ }: Props): KubbReactNode {
126
+ const responseName = tsResolver.resolveResponseName(node)
127
+ const errorNames = resolveErrorNames(node, tsResolver)
133
128
 
134
- const params = getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas })
135
- const clientParams = Client.getParams({
136
- paramsType,
137
- paramsCasing,
138
- typeSchemas,
139
- pathParamsType,
140
- isConfigurable: true,
141
- })
142
- const queryKeyParams = QueryKey.getParams({
143
- pathParamsType,
144
- typeSchemas,
145
- paramsCasing,
146
- })
129
+ const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
130
+ const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
147
131
 
148
- const enabled = Object.entries(queryKeyParams.flatParams)
149
- .map(([key, item]) => {
150
- // Only include if the parameter exists and is NOT optional
151
- // This ensures we only check required parameters
152
- return item && !item.optional && !item.default ? key : undefined
153
- })
154
- .filter(Boolean)
155
- .join('&& ')
132
+ const paramsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
133
+ const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
134
+ const rawParamsCall = callPrinter.print(paramsNode) ?? ''
135
+
136
+ // Transform: wrap non-config params with toValue(), add signal to config
137
+ const clientCallStr = rawParamsCall.replace(/\bconfig\b(?=[^,]*$)/, '{ ...config, signal: config.signal ?? signal }')
138
+
139
+ const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
140
+ const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
156
141
 
157
- const enabledText = enabled ? `enabled: !!(${enabled}),` : ''
142
+ const enabledSource = buildEnabledCheck(queryKeyParamsNode)
143
+ const enabledText = enabledSource ? `enabled: () => !!(${enabledSource}),` : ''
158
144
 
159
145
  return (
160
146
  <File.Source name={name} isExportable isIndexable>
161
- <Function name={name} export params={params.toConstructor()}>
147
+ <Function name={name} export params={paramsSignature}>
162
148
  {`
163
- const queryKey = ${queryKeyName}(${queryKeyParams.toCall()})
164
- return queryOptions<${TData}, ${TError}, ${TData}, typeof queryKey>({
165
- ${enabledText}
166
- queryKey,
167
- queryFn: async ({ signal }) => {
168
- return ${clientName}(${clientParams.toCall({
169
- transformName(name) {
170
- if (name === 'config') {
171
- return '{ ...config, signal: config.signal ?? signal }'
172
- }
173
-
174
- return `toValue(${name})`
175
- },
176
- })})
149
+ const queryKey = ${queryKeyName}(${queryKeyParamsCall})
150
+ return queryOptions<${TData}, ${TError}, ${TData}>({
151
+ ${enabledText}
152
+ queryKey,
153
+ queryFn: async ({ signal }) => {
154
+ return ${clientName}(${addToValueCalls(clientCallStr)})
177
155
  },
178
156
  })
179
157
  `}
@@ -182,4 +160,34 @@ export function QueryOptions({
182
160
  )
183
161
  }
184
162
 
185
- QueryOptions.getParams = getParams
163
+ /**
164
+ * Wraps parameter names with `toValue()` in the client call string,
165
+ * except for 'config'-related params (which are already plain objects).
166
+ *
167
+ * Handles both inline params (`petId, config`) and object shorthand
168
+ * params (`{ petId }, config`) by expanding to `{ petId: toValue(petId) }`.
169
+ */
170
+ function addToValueCalls(callStr: string): string {
171
+ // Step 1: Transform shorthand object params like { petId } → { petId: toValue(petId) }
172
+ let result = callStr.replace(/\{\s*([\w,\s]+)\s*\}(?=\s*,)/g, (match, inner: string) => {
173
+ // Only transform simple shorthand (no colons, no spread)
174
+ if (inner.includes(':') || inner.includes('...')) return match
175
+ const keys = inner
176
+ .split(',')
177
+ .map((k: string) => k.trim())
178
+ .filter(Boolean)
179
+ const wrapped = keys.map((k: string) => `${k}: toValue(${k})`).join(', ')
180
+ return `{ ${wrapped} }`
181
+ })
182
+
183
+ // Step 2: Handle standalone identifiers like `data, params`
184
+ result = result.replace(/(?<![{.:?])\b(\w+)\b(?=\s*,)/g, (match, name: string) => {
185
+ if (name === 'config' || name === 'signal' || name === 'undefined') return match
186
+ if (match.includes('toValue(')) return match
187
+ return `toValue(${name})`
188
+ })
189
+
190
+ return result
191
+ }
192
+
193
+ QueryOptions.getParams = getQueryOptionsParams