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

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 (48) hide show
  1. package/README.md +34 -83
  2. package/dist/{components-DTGLu4UV.js → components-CDmg-RPi.js} +275 -255
  3. package/dist/components-CDmg-RPi.js.map +1 -0
  4. package/dist/{components-dAKJEn9b.cjs → components-MPBTffPl.cjs} +299 -255
  5. package/dist/components-MPBTffPl.cjs.map +1 -0
  6. package/dist/components.cjs +1 -1
  7. package/dist/components.d.ts +1 -75
  8. package/dist/components.js +1 -1
  9. package/dist/{generators-C_fbcjpG.js → generators-Bma51Uar.js} +301 -261
  10. package/dist/generators-Bma51Uar.js.map +1 -0
  11. package/dist/{generators-CWEQsdO9.cjs → generators-BtsWNz-6.cjs} +299 -259
  12. package/dist/generators-BtsWNz-6.cjs.map +1 -0
  13. package/dist/generators.cjs +1 -1
  14. package/dist/generators.d.ts +41 -1
  15. package/dist/generators.js +1 -1
  16. package/dist/index.cjs +143 -20
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +30 -1
  19. package/dist/index.js +143 -20
  20. package/dist/index.js.map +1 -1
  21. package/dist/types-DiZPLTXl.d.ts +400 -0
  22. package/extension.yaml +1507 -0
  23. package/package.json +16 -18
  24. package/src/components/InfiniteQuery.tsx +19 -13
  25. package/src/components/InfiniteQueryOptions.tsx +29 -47
  26. package/src/components/Mutation.tsx +35 -15
  27. package/src/components/MutationOptions.tsx +14 -13
  28. package/src/components/Query.tsx +9 -10
  29. package/src/components/QueryOptions.tsx +6 -27
  30. package/src/components/SuspenseInfiniteQuery.tsx +19 -13
  31. package/src/components/SuspenseInfiniteQueryOptions.tsx +29 -47
  32. package/src/components/SuspenseQuery.tsx +9 -10
  33. package/src/generators/customHookOptionsFileGenerator.tsx +18 -14
  34. package/src/generators/hookOptionsGenerator.tsx +36 -33
  35. package/src/generators/infiniteQueryGenerator.tsx +46 -64
  36. package/src/generators/mutationGenerator.tsx +42 -50
  37. package/src/generators/queryGenerator.tsx +43 -49
  38. package/src/generators/suspenseInfiniteQueryGenerator.tsx +41 -51
  39. package/src/generators/suspenseQueryGenerator.tsx +44 -62
  40. package/src/plugin.ts +42 -16
  41. package/src/resolvers/resolverReactQuery.ts +102 -6
  42. package/src/types.ts +199 -61
  43. package/src/utils.ts +10 -33
  44. package/dist/components-DTGLu4UV.js.map +0 -1
  45. package/dist/components-dAKJEn9b.cjs.map +0 -1
  46. package/dist/generators-CWEQsdO9.cjs.map +0 -1
  47. package/dist/generators-C_fbcjpG.js.map +0 -1
  48. package/dist/types-DfaFRSBf.d.ts +0 -284
package/package.json CHANGED
@@ -1,25 +1,22 @@
1
1
  {
2
2
  "name": "@kubb/plugin-react-query",
3
- "version": "5.0.0-beta.3",
4
- "description": "React Query hooks generator plugin for Kubb, creating type-safe API client hooks from OpenAPI specifications for React applications.",
3
+ "version": "5.0.0-beta.30",
4
+ "description": "Generate type-safe TanStack Query (React Query) hooks from your OpenAPI specification. Covers useQuery, useMutation, useInfiniteQuery, and queryOptions with full TypeScript support.",
5
5
  "keywords": [
6
- "api-client",
7
- "code-generator",
6
+ "code-generation",
8
7
  "codegen",
9
8
  "data-fetching",
10
9
  "hooks",
11
10
  "kubb",
12
- "oas",
13
11
  "openapi",
14
- "plugins",
15
12
  "react",
16
- "react-hooks",
17
13
  "react-query",
18
- "sdk-generator",
19
14
  "swagger",
15
+ "tanstack",
20
16
  "tanstack-query",
21
- "type-safe",
22
- "typescript"
17
+ "typescript",
18
+ "use-mutation",
19
+ "use-query"
23
20
  ],
24
21
  "license": "MIT",
25
22
  "author": "stijnvanhulle",
@@ -31,7 +28,7 @@
31
28
  "files": [
32
29
  "src",
33
30
  "dist",
34
- "plugin.json",
31
+ "extension.yaml",
35
32
  "!/**/**.test.**",
36
33
  "!/**/__tests__/**",
37
34
  "!/**/__snapshots__/**"
@@ -71,19 +68,20 @@
71
68
  "registry": "https://registry.npmjs.org/"
72
69
  },
73
70
  "dependencies": {
74
- "@kubb/core": "5.0.0-beta.3",
75
- "@kubb/renderer-jsx": "5.0.0-beta.3",
76
- "remeda": "^2.34.0",
77
- "@kubb/plugin-client": "5.0.0-beta.3",
78
- "@kubb/plugin-ts": "5.0.0-beta.3",
79
- "@kubb/plugin-zod": "5.0.0-beta.3"
71
+ "@kubb/core": "5.0.0-beta.29",
72
+ "@kubb/renderer-jsx": "5.0.0-beta.29",
73
+ "remeda": "^2.34.1",
74
+ "@kubb/plugin-client": "5.0.0-beta.30",
75
+ "@kubb/plugin-ts": "5.0.0-beta.30",
76
+ "@kubb/plugin-zod": "5.0.0-beta.30"
80
77
  },
81
78
  "devDependencies": {
79
+ "@internals/shared": "0.0.0",
82
80
  "@internals/tanstack-query": "0.0.0",
83
81
  "@internals/utils": "0.0.0"
84
82
  },
85
83
  "peerDependencies": {
86
- "@kubb/renderer-jsx": "5.0.0-beta.3"
84
+ "@kubb/renderer-jsx": "5.0.0-beta.29"
87
85
  },
88
86
  "size-limit": [
89
87
  {
@@ -1,11 +1,11 @@
1
+ import { getOperationParameters } from '@internals/shared'
1
2
  import { ast } from '@kubb/core'
2
3
  import type { ResolverTs } from '@kubb/plugin-ts'
3
4
  import { functionPrinter } from '@kubb/plugin-ts'
4
5
  import { File, Function } from '@kubb/renderer-jsx'
5
6
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
7
  import type { Infinite, PluginReactQuery } from '../types.ts'
7
- import { getComments, resolveErrorNames } from '../utils.ts'
8
- import { QueryKey } from './QueryKey.tsx'
8
+ import { buildQueryKeyParams, getComments, resolveErrorNames, resolveSuccessNames } from '../utils.ts'
9
9
  import { getQueryOptionsParams } from './QueryOptions.tsx'
10
10
 
11
11
  type Props = {
@@ -27,7 +27,7 @@ type Props = {
27
27
  const declarationPrinter = functionPrinter({ mode: 'declaration' })
28
28
  const callPrinter = functionPrinter({ mode: 'call' })
29
29
 
30
- function getParams(
30
+ function buildInfiniteQueryParamsNode(
31
31
  node: ast.OperationNode,
32
32
  options: {
33
33
  paramsType: PluginReactQuery['resolvedOptions']['paramsType']
@@ -39,7 +39,7 @@ function getParams(
39
39
  },
40
40
  ): ast.FunctionParametersNode {
41
41
  const { paramsType, paramsCasing, pathParamsType, resolver, pageParamGeneric } = options
42
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
42
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null
43
43
 
44
44
  const optionsParam = ast.createFunctionParameter({
45
45
  name: 'options',
@@ -77,7 +77,8 @@ export function InfiniteQuery({
77
77
  queryParam,
78
78
  customOptions,
79
79
  }: Props): KubbReactNode {
80
- const responseName = tsResolver.resolveResponseName(node)
80
+ const successNames = resolveSuccessNames(node, tsResolver)
81
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
81
82
  const errorNames = resolveErrorNames(node, tsResolver)
82
83
 
83
84
  const responseType = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -98,17 +99,17 @@ export function InfiniteQuery({
98
99
  ? 'boolean'
99
100
  : 'unknown'
100
101
 
101
- const rawQueryParams = node.parameters.filter((p) => p.in === 'query')
102
+ const rawQueryParams = getOperationParameters(node).query
102
103
  const queryParamsTypeName =
103
104
  rawQueryParams.length > 0
104
105
  ? (() => {
105
106
  const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]!)
106
107
  const individualName = tsResolver.resolveParamName(node, rawQueryParams[0]!)
107
- return groupName !== individualName ? groupName : undefined
108
+ return groupName !== individualName ? groupName : null
108
109
  })()
109
- : undefined
110
+ : null
110
111
 
111
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : undefined
112
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null
112
113
  const pageParamType = queryParamType ? (isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType) : fallbackPageParamType
113
114
 
114
115
  const returnType = 'UseInfiniteQueryResult<TData, TError> & { queryKey: TQueryKey }'
@@ -120,13 +121,20 @@ export function InfiniteQuery({
120
121
  `TPageParam = ${pageParamType}`,
121
122
  ]
122
123
 
123
- const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
124
+ const queryKeyParamsNode = buildQueryKeyParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
124
125
  const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
125
126
 
126
127
  const queryOptionsParamsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
127
128
  const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? ''
128
129
 
129
- const paramsNode = getParams(node, { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver: tsResolver, pageParamGeneric: 'TPageParam' })
130
+ const paramsNode = buildInfiniteQueryParamsNode(node, {
131
+ paramsType,
132
+ paramsCasing,
133
+ pathParamsType,
134
+ dataReturnType,
135
+ resolver: tsResolver,
136
+ pageParamGeneric: 'TPageParam',
137
+ })
130
138
  const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
131
139
 
132
140
  return (
@@ -152,5 +160,3 @@ export function InfiniteQuery({
152
160
  </File.Source>
153
161
  )
154
162
  }
155
-
156
- InfiniteQuery.getParams = getParams
@@ -1,3 +1,4 @@
1
+ import { getOperationParameters } from '@internals/shared'
1
2
  import { getNestedAccessor } from '@internals/utils'
2
3
  import type { ast } from '@kubb/core'
3
4
  import type { ResolverTs } from '@kubb/plugin-ts'
@@ -5,9 +6,9 @@ import { functionPrinter } from '@kubb/plugin-ts'
5
6
  import { File, Function } from '@kubb/renderer-jsx'
6
7
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
7
8
  import type { Infinite, PluginReactQuery } from '../types.ts'
8
- import { resolveErrorNames } from '../utils.ts'
9
- import { QueryKey } from './QueryKey.tsx'
10
- import { buildEnabledCheck, getQueryOptionsParams } from './QueryOptions.tsx'
9
+ import { buildQueryKeyParams, resolveErrorNames, resolveSuccessNames } from '../utils.ts'
10
+ import { buildEnabledCheck } from '@internals/tanstack-query'
11
+ import { getQueryOptionsParams } from './QueryOptions.tsx'
11
12
 
12
13
  type Props = {
13
14
  name: string
@@ -45,7 +46,8 @@ export function InfiniteQueryOptions({
45
46
  queryParam,
46
47
  queryKeyName,
47
48
  }: Props): KubbReactNode {
48
- const responseName = tsResolver.resolveResponseName(node)
49
+ const successNames = resolveSuccessNames(node, tsResolver)
50
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
49
51
  const queryFnDataType = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
50
52
  const errorNames = resolveErrorNames(node, tsResolver)
51
53
  const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
@@ -65,17 +67,17 @@ export function InfiniteQueryOptions({
65
67
  ? 'boolean'
66
68
  : 'unknown'
67
69
 
68
- const rawQueryParams = node.parameters.filter((p) => p.in === 'query')
70
+ const rawQueryParams = getOperationParameters(node).query
69
71
  const queryParamsTypeName =
70
72
  rawQueryParams.length > 0
71
73
  ? (() => {
72
74
  const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]!)
73
75
  const individualName = tsResolver.resolveParamName(node, rawQueryParams[0]!)
74
- return groupName !== individualName ? groupName : undefined
76
+ return groupName !== individualName ? groupName : null
75
77
  })()
76
- : undefined
78
+ : null
77
79
 
78
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : undefined
80
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null
79
81
  const pageParamType = queryParamType ? (isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType) : fallbackPageParamType
80
82
 
81
83
  const paramsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
@@ -83,43 +85,33 @@ export function InfiniteQueryOptions({
83
85
  const rawParamsCall = callPrinter.print(paramsNode) ?? ''
84
86
  const clientCallStr = rawParamsCall.replace(/\bconfig\b(?=[^,]*$)/, '{ ...config, signal: config.signal ?? signal }')
85
87
 
86
- const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
88
+ const queryKeyParamsNode = buildQueryKeyParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
87
89
  const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
88
90
 
89
91
  const enabledSource = buildEnabledCheck(queryKeyParamsNode)
90
92
  const enabledText = enabledSource ? `enabled: !!(${enabledSource}),` : ''
91
93
 
92
- const hasNewParams = nextParam !== undefined || previousParam !== undefined
94
+ const hasNewParams = nextParam != null || previousParam != null
93
95
 
94
- let getNextPageParamExpr: string | undefined
95
- let getPreviousPageParamExpr: string | undefined
96
-
97
- if (hasNewParams) {
98
- if (nextParam) {
99
- const accessor = getNestedAccessor(nextParam, 'lastPage')
100
- if (accessor) {
101
- getNextPageParamExpr = `getNextPageParam: (lastPage) => ${accessor}`
102
- }
103
- }
104
- if (previousParam) {
105
- const accessor = getNestedAccessor(previousParam, 'firstPage')
106
- if (accessor) {
107
- getPreviousPageParamExpr = `getPreviousPageParam: (firstPage) => ${accessor}`
108
- }
96
+ const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
97
+ if (hasNewParams) {
98
+ const nextAccessor = nextParam ? getNestedAccessor(nextParam, 'lastPage') : null
99
+ const prevAccessor = previousParam ? getNestedAccessor(previousParam, 'firstPage') : null
100
+ return [
101
+ nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null,
102
+ prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null,
103
+ ] as const
109
104
  }
110
- } else if (cursorParam) {
111
- getNextPageParamExpr = `getNextPageParam: (lastPage) => lastPage['${cursorParam}']`
112
- getPreviousPageParamExpr = `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`
113
- } else {
114
- if (dataReturnType === 'full') {
115
- getNextPageParamExpr =
116
- 'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage.data) && lastPage.data.length === 0 ? undefined : lastPageParam + 1'
117
- } else {
118
- getNextPageParamExpr =
119
- 'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1'
105
+ if (cursorParam) {
106
+ return [`getNextPageParam: (lastPage) => lastPage['${cursorParam}']`, `getPreviousPageParam: (firstPage) => firstPage['${cursorParam}']`] as const
120
107
  }
121
- getPreviousPageParamExpr = 'getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1'
122
- }
108
+ return [
109
+ dataReturnType === 'full'
110
+ ? 'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage.data) && lastPage.data.length === 0 ? undefined : lastPageParam + 1'
111
+ : 'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1',
112
+ 'getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1',
113
+ ] as const
114
+ })()
123
115
 
124
116
  const queryOptionsArr = [
125
117
  `initialPageParam: ${typeof initialPageParam === 'string' ? JSON.stringify(initialPageParam) : initialPageParam}`,
@@ -175,13 +167,3 @@ export function InfiniteQueryOptions({
175
167
  </File.Source>
176
168
  )
177
169
  }
178
-
179
- InfiniteQueryOptions.getParams = (
180
- node: ast.OperationNode,
181
- options: {
182
- paramsType: PluginReactQuery['resolvedOptions']['paramsType']
183
- paramsCasing: PluginReactQuery['resolvedOptions']['paramsCasing']
184
- pathParamsType: PluginReactQuery['resolvedOptions']['pathParamsType']
185
- resolver: ResolverTs
186
- },
187
- ) => getQueryOptionsParams(node, options)
@@ -4,8 +4,8 @@ import { functionPrinter } from '@kubb/plugin-ts'
4
4
  import { File, Function } from '@kubb/renderer-jsx'
5
5
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
6
  import type { PluginReactQuery } from '../types.ts'
7
- import { buildMutationArgParams, getComments, resolveErrorNames } from '../utils.ts'
8
- import { MutationOptions } from './MutationOptions.tsx'
7
+ import { buildRequestConfigType, getComments, resolveErrorNames, resolveSuccessNames } from '../utils.ts'
8
+ import { buildMutationConfigParamsNode } from './MutationOptions.tsx'
9
9
 
10
10
  type Props = {
11
11
  name: string
@@ -23,7 +23,22 @@ type Props = {
23
23
  const declarationPrinter = functionPrinter({ mode: 'declaration' })
24
24
  const callPrinter = functionPrinter({ mode: 'call' })
25
25
 
26
- function getParams(
26
+ function createMutationArgParams(
27
+ node: ast.OperationNode,
28
+ options: {
29
+ paramsCasing: PluginReactQuery['resolvedOptions']['paramsCasing']
30
+ resolver: ResolverTs
31
+ },
32
+ ): ast.FunctionParametersNode {
33
+ return ast.createOperationParams(node, {
34
+ paramsType: 'inline',
35
+ pathParamsType: 'inline',
36
+ paramsCasing: options.paramsCasing,
37
+ resolver: options.resolver,
38
+ })
39
+ }
40
+
41
+ function buildMutationParamsNode(
27
42
  node: ast.OperationNode,
28
43
  options: {
29
44
  paramsCasing: PluginReactQuery['resolvedOptions']['paramsCasing']
@@ -32,16 +47,19 @@ function getParams(
32
47
  },
33
48
  ): ast.FunctionParametersNode {
34
49
  const { paramsCasing, dataReturnType, resolver } = options
35
- const responseName = resolver.resolveResponseName(node)
36
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
50
+ const successNames = resolveSuccessNames(node, resolver)
51
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : resolver.resolveResponseName(node)
37
52
  const errorNames = resolveErrorNames(node, resolver)
38
53
 
39
54
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
40
55
  const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
41
56
 
42
- const mutationArgParamsNode = buildMutationArgParams(node, { paramsCasing, resolver })
57
+ const mutationArgParamsNode = createMutationArgParams(node, {
58
+ paramsCasing,
59
+ resolver,
60
+ })
43
61
  const TRequest = mutationArgParamsNode.params.length > 0 ? (declarationPrinter.print(mutationArgParamsNode) ?? '') : ''
44
- const generics = [TData, TError, TRequest ? `{${TRequest}}` : 'void', 'TContext'].join(', ')
62
+ const generics = [TData, TError, TRequest ? `{${TRequest}}` : 'undefined', 'TContext'].join(', ')
45
63
 
46
64
  return ast.createFunctionParameters({
47
65
  params: [
@@ -51,7 +69,7 @@ function getParams(
51
69
  variant: 'reference',
52
70
  name: `{
53
71
  mutation?: UseMutationOptions<${generics}> & { client?: QueryClient },
54
- client?: ${requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }'},
72
+ client?: ${buildRequestConfigType(node, resolver)},
55
73
  }`,
56
74
  }),
57
75
  default: '{}',
@@ -61,21 +79,25 @@ function getParams(
61
79
  }
62
80
 
63
81
  export function Mutation({ name, mutationOptionsName, paramsCasing, dataReturnType, node, tsResolver, mutationKeyName, customOptions }: Props): KubbReactNode {
64
- const responseName = tsResolver.resolveResponseName(node)
82
+ const successNames = resolveSuccessNames(node, tsResolver)
83
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
65
84
  const errorNames = resolveErrorNames(node, tsResolver)
66
85
 
67
86
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
68
87
  const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
69
88
 
70
- const mutationArgParamsNode = buildMutationArgParams(node, { paramsCasing, resolver: tsResolver })
89
+ const mutationArgParamsNode = createMutationArgParams(node, {
90
+ paramsCasing,
91
+ resolver: tsResolver,
92
+ })
71
93
  const TRequest = mutationArgParamsNode.params.length > 0 ? (declarationPrinter.print(mutationArgParamsNode) ?? '') : ''
72
- const generics = [TData, TError, TRequest ? `{${TRequest}}` : 'void', 'TContext'].join(', ')
94
+ const generics = [TData, TError, TRequest ? `{${TRequest}}` : 'undefined', 'TContext'].join(', ')
73
95
  const returnType = `UseMutationResult<${generics}>`
74
96
 
75
- const mutationOptionsConfigNode = MutationOptions.getParams(node, tsResolver)
97
+ const mutationOptionsConfigNode = buildMutationConfigParamsNode(node, tsResolver)
76
98
  const mutationOptionsParamsCall = callPrinter.print(mutationOptionsConfigNode) ?? ''
77
99
 
78
- const paramsNode = getParams(node, { paramsCasing, dataReturnType, resolver: tsResolver })
100
+ const paramsNode = buildMutationParamsNode(node, { paramsCasing, dataReturnType, resolver: tsResolver })
79
101
  const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
80
102
 
81
103
  return (
@@ -99,5 +121,3 @@ export function Mutation({ name, mutationOptionsName, paramsCasing, dataReturnTy
99
121
  </File.Source>
100
122
  )
101
123
  }
102
-
103
- Mutation.getParams = getParams
@@ -4,7 +4,7 @@ import { functionPrinter } from '@kubb/plugin-ts'
4
4
  import { File, Function } from '@kubb/renderer-jsx'
5
5
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
6
  import type { PluginReactQuery } from '../types.ts'
7
- import { buildMutationArgParams, resolveErrorNames } from '../utils.ts'
7
+ import { buildRequestConfigType, resolveErrorNames, resolveSuccessNames } from '../utils.ts'
8
8
 
9
9
  type Props = {
10
10
  name: string
@@ -22,15 +22,14 @@ const declarationPrinter = functionPrinter({ mode: 'declaration' })
22
22
  const callPrinter = functionPrinter({ mode: 'call' })
23
23
  const keysPrinter = functionPrinter({ mode: 'keys' })
24
24
 
25
- function getConfigParam(node: ast.OperationNode, resolver: ResolverTs): ast.FunctionParametersNode {
26
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
25
+ export function buildMutationConfigParamsNode(node: ast.OperationNode, resolver: ResolverTs): ast.FunctionParametersNode {
27
26
  return ast.createFunctionParameters({
28
27
  params: [
29
28
  ast.createFunctionParameter({
30
29
  name: 'config',
31
30
  type: ast.createParamsType({
32
31
  variant: 'reference',
33
- name: requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : 'Partial<RequestConfig> & { client?: Client }',
32
+ name: buildRequestConfigType(node, resolver),
34
33
  }),
35
34
  default: '{}',
36
35
  }),
@@ -49,15 +48,21 @@ export function MutationOptions({
49
48
  pathParamsType,
50
49
  mutationKeyName,
51
50
  }: Props): KubbReactNode {
52
- const responseName = tsResolver.resolveResponseName(node)
51
+ const successNames = resolveSuccessNames(node, tsResolver)
52
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
53
53
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
54
54
  const errorNames = resolveErrorNames(node, tsResolver)
55
55
  const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
56
56
 
57
- const configParamsNode = getConfigParam(node, tsResolver)
57
+ const configParamsNode = buildMutationConfigParamsNode(node, tsResolver)
58
58
  const paramsSignature = declarationPrinter.print(configParamsNode) ?? ''
59
59
 
60
- const mutationArgParamsNode = buildMutationArgParams(node, { paramsCasing, resolver: tsResolver })
60
+ const mutationArgParamsNode = ast.createOperationParams(node, {
61
+ paramsType: 'inline',
62
+ pathParamsType: 'inline',
63
+ paramsCasing,
64
+ resolver: tsResolver,
65
+ })
61
66
  const hasMutationParams = mutationArgParamsNode.params.length > 0
62
67
 
63
68
  const TRequest = hasMutationParams ? (declarationPrinter.print(mutationArgParamsNode) ?? '') : ''
@@ -73,9 +78,7 @@ export function MutationOptions({
73
78
  name: 'config',
74
79
  type: ast.createParamsType({
75
80
  variant: 'reference',
76
- name: node.requestBody?.content?.[0]?.schema
77
- ? `Partial<RequestConfig<${tsResolver.resolveDataName(node)}>> & { client?: Client }`
78
- : 'Partial<RequestConfig> & { client?: Client }',
81
+ name: buildRequestConfigType(node, tsResolver),
79
82
  }),
80
83
  default: '{}',
81
84
  }),
@@ -88,7 +91,7 @@ export function MutationOptions({
88
91
  <Function name={name} export params={paramsSignature} generics={['TContext = unknown']}>
89
92
  {`
90
93
  const mutationKey = ${mutationKeyName}()
91
- return mutationOptions<${TData}, ${TError}, ${TRequest ? `{${TRequest}}` : 'void'}, TContext>({
94
+ return mutationOptions<${TData}, ${TError}, ${TRequest ? `{${TRequest}}` : 'undefined'}, TContext>({
92
95
  mutationKey,
93
96
  mutationFn: async(${hasMutationParams ? `{ ${argKeysStr} }` : '_'}) => {
94
97
  return ${clientName}(${clientCallStr})
@@ -99,5 +102,3 @@ export function MutationOptions({
99
102
  </File.Source>
100
103
  )
101
104
  }
102
-
103
- MutationOptions.getParams = getConfigParam
@@ -4,8 +4,7 @@ import { functionPrinter } from '@kubb/plugin-ts'
4
4
  import { File, Function } from '@kubb/renderer-jsx'
5
5
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
6
  import type { PluginReactQuery } from '../types.ts'
7
- import { getComments, resolveErrorNames } from '../utils.ts'
8
- import { QueryKey } from './QueryKey.tsx'
7
+ import { buildQueryKeyParams, getComments, resolveErrorNames, resolveSuccessNames } from '../utils.ts'
9
8
  import { getQueryOptionsParams } from './QueryOptions.tsx'
10
9
 
11
10
  type Props = {
@@ -25,7 +24,7 @@ type Props = {
25
24
  const declarationPrinter = functionPrinter({ mode: 'declaration' })
26
25
  const callPrinter = functionPrinter({ mode: 'call' })
27
26
 
28
- function getParams(
27
+ function buildQueryParamsNode(
29
28
  node: ast.OperationNode,
30
29
  options: {
31
30
  paramsType: PluginReactQuery['resolvedOptions']['paramsType']
@@ -36,8 +35,9 @@ function getParams(
36
35
  },
37
36
  ): ast.FunctionParametersNode {
38
37
  const { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver } = options
39
- const responseName = resolver.resolveResponseName(node)
40
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
38
+ const successNames = resolveSuccessNames(node, resolver)
39
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : resolver.resolveResponseName(node)
40
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null
41
41
  const errorNames = resolveErrorNames(node, resolver)
42
42
 
43
43
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -77,7 +77,8 @@ export function Query({
77
77
  tsResolver,
78
78
  customOptions,
79
79
  }: Props): KubbReactNode {
80
- const responseName = tsResolver.resolveResponseName(node)
80
+ const successNames = resolveSuccessNames(node, tsResolver)
81
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
81
82
  const errorNames = resolveErrorNames(node, tsResolver)
82
83
 
83
84
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -85,13 +86,13 @@ export function Query({
85
86
  const returnType = `UseQueryResult<${'TData'}, ${TError}> & { queryKey: TQueryKey }`
86
87
  const generics = [`TData = ${TData}`, `TQueryData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`]
87
88
 
88
- const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
89
+ const queryKeyParamsNode = buildQueryKeyParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
89
90
  const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
90
91
 
91
92
  const queryOptionsParamsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
92
93
  const queryOptionsParamsCall = callPrinter.print(queryOptionsParamsNode) ?? ''
93
94
 
94
- const paramsNode = getParams(node, { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver: tsResolver })
95
+ const paramsNode = buildQueryParamsNode(node, { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver: tsResolver })
95
96
  const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
96
97
 
97
98
  return (
@@ -117,5 +118,3 @@ export function Query({
117
118
  </File.Source>
118
119
  )
119
120
  }
120
-
121
- Query.getParams = getParams
@@ -3,9 +3,9 @@ import type { ResolverTs } from '@kubb/plugin-ts'
3
3
  import { functionPrinter } from '@kubb/plugin-ts'
4
4
  import { File, Function } from '@kubb/renderer-jsx'
5
5
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
+ import { buildEnabledCheck } from '@internals/tanstack-query'
6
7
  import type { PluginReactQuery } from '../types.ts'
7
- import { resolveErrorNames } from '../utils.ts'
8
- import { QueryKey } from './QueryKey.tsx'
8
+ import { buildQueryKeyParams, resolveErrorNames, resolveSuccessNames } from '../utils.ts'
9
9
 
10
10
  type Props = {
11
11
  name: string
@@ -32,7 +32,7 @@ export function getQueryOptionsParams(
32
32
  },
33
33
  ): ast.FunctionParametersNode {
34
34
  const { paramsType, paramsCasing, pathParamsType, resolver } = options
35
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
35
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null
36
36
 
37
37
  return ast.createOperationParams(node, {
38
38
  paramsType,
@@ -52,26 +52,6 @@ export function getQueryOptionsParams(
52
52
  })
53
53
  }
54
54
 
55
- export function buildEnabledCheck(paramsNode: ast.FunctionParametersNode): string {
56
- const required: string[] = []
57
- for (const param of paramsNode.params) {
58
- if ('kind' in param && (param as ast.ParameterGroupNode).kind === 'ParameterGroup') {
59
- const group = param as ast.ParameterGroupNode
60
- for (const child of group.properties) {
61
- if (!child.optional && child.default === undefined) {
62
- required.push(child.name)
63
- }
64
- }
65
- } else {
66
- const fp = param as ast.FunctionParameterNode
67
- if (!fp.optional && fp.default === undefined) {
68
- required.push(fp.name)
69
- }
70
- }
71
- }
72
- return required.join(' && ')
73
- }
74
-
75
55
  export function QueryOptions({
76
56
  name,
77
57
  clientName,
@@ -83,7 +63,8 @@ export function QueryOptions({
83
63
  pathParamsType,
84
64
  queryKeyName,
85
65
  }: Props): KubbReactNode {
86
- const responseName = tsResolver.resolveResponseName(node)
66
+ const successNames = resolveSuccessNames(node, tsResolver)
67
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
87
68
  const errorNames = resolveErrorNames(node, tsResolver)
88
69
 
89
70
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -94,7 +75,7 @@ export function QueryOptions({
94
75
  const rawParamsCall = callPrinter.print(paramsNode) ?? ''
95
76
  const clientCallStr = rawParamsCall.replace(/\bconfig\b(?=[^,]*$)/, '{ ...config, signal: config.signal ?? signal }')
96
77
 
97
- const queryKeyParamsNode = QueryKey.getParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
78
+ const queryKeyParamsNode = buildQueryKeyParams(node, { pathParamsType, paramsCasing, resolver: tsResolver })
98
79
  const queryKeyParamsCall = callPrinter.print(queryKeyParamsNode) ?? ''
99
80
 
100
81
  const enabledSource = buildEnabledCheck(queryKeyParamsNode)
@@ -117,5 +98,3 @@ export function QueryOptions({
117
98
  </File.Source>
118
99
  )
119
100
  }
120
-
121
- QueryOptions.getParams = getQueryOptionsParams