@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.
- package/README.md +34 -83
- package/dist/{components-DTGLu4UV.js → components-CDmg-RPi.js} +275 -255
- package/dist/components-CDmg-RPi.js.map +1 -0
- package/dist/{components-dAKJEn9b.cjs → components-MPBTffPl.cjs} +299 -255
- package/dist/components-MPBTffPl.cjs.map +1 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.ts +1 -75
- package/dist/components.js +1 -1
- package/dist/{generators-C_fbcjpG.js → generators-Bma51Uar.js} +301 -261
- package/dist/generators-Bma51Uar.js.map +1 -0
- package/dist/{generators-CWEQsdO9.cjs → generators-BtsWNz-6.cjs} +299 -259
- package/dist/generators-BtsWNz-6.cjs.map +1 -0
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +41 -1
- package/dist/generators.js +1 -1
- package/dist/index.cjs +143 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +143 -20
- package/dist/index.js.map +1 -1
- package/dist/types-DiZPLTXl.d.ts +400 -0
- package/extension.yaml +1507 -0
- package/package.json +16 -18
- package/src/components/InfiniteQuery.tsx +19 -13
- package/src/components/InfiniteQueryOptions.tsx +29 -47
- package/src/components/Mutation.tsx +35 -15
- package/src/components/MutationOptions.tsx +14 -13
- package/src/components/Query.tsx +9 -10
- package/src/components/QueryOptions.tsx +6 -27
- package/src/components/SuspenseInfiniteQuery.tsx +19 -13
- package/src/components/SuspenseInfiniteQueryOptions.tsx +29 -47
- package/src/components/SuspenseQuery.tsx +9 -10
- package/src/generators/customHookOptionsFileGenerator.tsx +18 -14
- package/src/generators/hookOptionsGenerator.tsx +36 -33
- package/src/generators/infiniteQueryGenerator.tsx +46 -64
- package/src/generators/mutationGenerator.tsx +42 -50
- package/src/generators/queryGenerator.tsx +43 -49
- package/src/generators/suspenseInfiniteQueryGenerator.tsx +41 -51
- package/src/generators/suspenseQueryGenerator.tsx +44 -62
- package/src/plugin.ts +42 -16
- package/src/resolvers/resolverReactQuery.ts +102 -6
- package/src/types.ts +199 -61
- package/src/utils.ts +10 -33
- package/dist/components-DTGLu4UV.js.map +0 -1
- package/dist/components-dAKJEn9b.cjs.map +0 -1
- package/dist/generators-CWEQsdO9.cjs.map +0 -1
- package/dist/generators-C_fbcjpG.js.map +0 -1
- package/dist/types-DfaFRSBf.d.ts +0 -284
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import {
|
|
2
|
+
import { getOperationParameters, resolveOperationTypeNames } from '@internals/shared'
|
|
3
|
+
import { resolveZodSchemaNames } from '@internals/tanstack-query'
|
|
4
|
+
import { defineGenerator } from '@kubb/core'
|
|
3
5
|
import { Client, pluginClientName } from '@kubb/plugin-client'
|
|
4
6
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
7
|
import { pluginZodName } from '@kubb/plugin-zod'
|
|
6
|
-
import { File,
|
|
8
|
+
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
7
9
|
import { difference } from 'remeda'
|
|
8
10
|
import { InfiniteQuery, InfiniteQueryOptions, QueryKey } from '../components'
|
|
9
11
|
import type { PluginReactQuery } from '../types'
|
|
10
|
-
import { transformName } from '../utils.ts'
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Built-in generator for `useInfiniteQuery` hooks. Enabled when
|
|
15
|
+
* `pluginReactQuery({ infinite: { ... } })`. Emits one `useFooInfiniteQuery`
|
|
16
|
+
* hook per query operation, wiring the configured `nextParam` /
|
|
17
|
+
* `previousParam` paths into TanStack Query's cursor-based pagination.
|
|
18
|
+
*/
|
|
12
19
|
export const infiniteQueryGenerator = defineGenerator<PluginReactQuery>({
|
|
13
20
|
name: 'react-infinite-query',
|
|
14
|
-
renderer:
|
|
21
|
+
renderer: jsxRendererSync,
|
|
15
22
|
operation(node, ctx) {
|
|
16
|
-
const {
|
|
17
|
-
const {
|
|
18
|
-
output,
|
|
19
|
-
query,
|
|
20
|
-
mutation,
|
|
21
|
-
infinite,
|
|
22
|
-
paramsCasing,
|
|
23
|
-
paramsType,
|
|
24
|
-
pathParamsType,
|
|
25
|
-
parser,
|
|
26
|
-
client: clientOptions,
|
|
27
|
-
group,
|
|
28
|
-
transformers,
|
|
29
|
-
customOptions,
|
|
30
|
-
} = ctx.options
|
|
23
|
+
const { config, driver, resolver, root } = ctx
|
|
24
|
+
const { output, query, mutation, infinite, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options
|
|
31
25
|
|
|
32
26
|
const pluginTs = driver.getPlugin(pluginTsName)
|
|
33
27
|
if (!pluginTs) return null
|
|
@@ -38,13 +32,13 @@ export const infiniteQueryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
38
32
|
mutation !== false &&
|
|
39
33
|
!isQuery &&
|
|
40
34
|
difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase())
|
|
41
|
-
const infiniteOptions = infinite && typeof infinite === 'object' ? infinite :
|
|
35
|
+
const infiniteOptions = infinite && typeof infinite === 'object' ? infinite : null
|
|
42
36
|
|
|
43
37
|
if (!isQuery || isMutation || !infiniteOptions) return null
|
|
44
38
|
|
|
45
39
|
// Validate queryParam exists in operation's query parameters
|
|
46
40
|
const normalizeKey = (key: string) => key.replace(/\?$/, '')
|
|
47
|
-
const queryParamKeys = node
|
|
41
|
+
const queryParamKeys = getOperationParameters(node).query.map((p) => p.name)
|
|
48
42
|
const hasQueryParam = infiniteOptions.queryParam ? queryParamKeys.some((k) => normalizeKey(k) === infiniteOptions.queryParam) : false
|
|
49
43
|
// cursorParam validation against response schema keys is skipped in v5 (complex schema inspection)
|
|
50
44
|
const hasCursorParam = !infiniteOptions.cursorParam || true
|
|
@@ -53,53 +47,43 @@ export const infiniteQueryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
53
47
|
|
|
54
48
|
const importPath = query ? query.importPath : '@tanstack/react-query'
|
|
55
49
|
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const queryKeyTypeName = transformName(`${capitalize(baseName)}InfiniteQueryKey`, 'type', transformers)
|
|
62
|
-
const clientBaseName = transformName(`${baseName}Infinite`, 'function', transformers)
|
|
50
|
+
const queryName = resolver.resolveInfiniteQueryName(node)
|
|
51
|
+
const queryOptionsName = resolver.resolveInfiniteQueryOptionsName(node)
|
|
52
|
+
const queryKeyName = resolver.resolveInfiniteQueryKeyName(node)
|
|
53
|
+
const queryKeyTypeName = resolver.resolveInfiniteQueryKeyTypeName(node)
|
|
54
|
+
const clientBaseName = resolver.resolveInfiniteClientName(node)
|
|
63
55
|
|
|
64
56
|
const meta = {
|
|
65
|
-
file: resolver.resolveFile(
|
|
57
|
+
file: resolver.resolveFile(
|
|
58
|
+
{ name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
59
|
+
{ root, output, group: group ?? undefined },
|
|
60
|
+
),
|
|
66
61
|
fileTs: tsResolver.resolveFile(
|
|
67
62
|
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
68
|
-
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
|
|
63
|
+
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group ?? undefined },
|
|
69
64
|
),
|
|
70
65
|
}
|
|
71
66
|
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
81
|
-
...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
82
|
-
...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
83
|
-
...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode)),
|
|
84
|
-
].filter((name): name is string => !!name && name !== queryKeyTypeName)
|
|
85
|
-
|
|
86
|
-
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
|
|
87
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
|
|
67
|
+
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
|
|
68
|
+
paramsCasing,
|
|
69
|
+
exclude: [queryKeyTypeName],
|
|
70
|
+
order: 'body-response-first',
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
|
|
74
|
+
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
|
|
88
75
|
const fileZod = zodResolver
|
|
89
76
|
? zodResolver.resolveFile(
|
|
90
77
|
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
91
|
-
{ root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
|
|
78
|
+
{ root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group ?? undefined },
|
|
92
79
|
)
|
|
93
|
-
:
|
|
94
|
-
const zodSchemaNames =
|
|
95
|
-
zodResolver && parser === 'zod'
|
|
96
|
-
? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : undefined].filter(Boolean)
|
|
97
|
-
: []
|
|
80
|
+
: null
|
|
81
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
|
|
98
82
|
|
|
99
83
|
const clientPlugin = driver.getPlugin(pluginClientName)
|
|
100
84
|
const hasClientPlugin = clientPlugin?.name === pluginClientName
|
|
101
85
|
const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
|
|
102
|
-
const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) :
|
|
86
|
+
const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null
|
|
103
87
|
|
|
104
88
|
const clientFile = shouldUseClientPlugin
|
|
105
89
|
? clientResolver?.resolveFile(
|
|
@@ -107,10 +91,10 @@ export const infiniteQueryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
107
91
|
{
|
|
108
92
|
root,
|
|
109
93
|
output: clientPlugin?.options?.output ?? output,
|
|
110
|
-
group: clientPlugin?.options?.group,
|
|
94
|
+
group: clientPlugin?.options?.group ?? undefined,
|
|
111
95
|
},
|
|
112
96
|
)
|
|
113
|
-
:
|
|
97
|
+
: null
|
|
114
98
|
|
|
115
99
|
const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientBaseName) : clientBaseName
|
|
116
100
|
|
|
@@ -119,29 +103,27 @@ export const infiniteQueryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
119
103
|
baseName={meta.file.baseName}
|
|
120
104
|
path={meta.file.path}
|
|
121
105
|
meta={meta.file.meta}
|
|
122
|
-
banner={resolver.resolveBanner(
|
|
123
|
-
footer={resolver.resolveFooter(
|
|
106
|
+
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
107
|
+
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
124
108
|
>
|
|
125
|
-
{
|
|
126
|
-
<File.Import name={zodSchemaNames as string[]} root={meta.file.path} path={fileZod.path} />
|
|
127
|
-
)}
|
|
109
|
+
{fileZod && zodSchemaNames.length > 0 && <File.Import name={zodSchemaNames} root={meta.file.path} path={fileZod.path} />}
|
|
128
110
|
{clientOptions.importPath ? (
|
|
129
111
|
<>
|
|
130
|
-
{!shouldUseClientPlugin && <File.Import name={'
|
|
112
|
+
{!shouldUseClientPlugin && <File.Import name={'client'} path={clientOptions.importPath} />}
|
|
131
113
|
<File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={clientOptions.importPath} isTypeOnly />
|
|
132
114
|
{clientOptions.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={clientOptions.importPath} isTypeOnly />}
|
|
133
115
|
</>
|
|
134
116
|
) : (
|
|
135
117
|
<>
|
|
136
|
-
{!shouldUseClientPlugin && <File.Import name={['
|
|
118
|
+
{!shouldUseClientPlugin && <File.Import name={['client']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} />}
|
|
137
119
|
<File.Import
|
|
138
120
|
name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
|
|
139
121
|
root={meta.file.path}
|
|
140
|
-
path={path.resolve(root, '.kubb/
|
|
122
|
+
path={path.resolve(root, '.kubb/client.ts')}
|
|
141
123
|
isTypeOnly
|
|
142
124
|
/>
|
|
143
125
|
{clientOptions.dataReturnType === 'full' && (
|
|
144
|
-
<File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/
|
|
126
|
+
<File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} isTypeOnly />
|
|
145
127
|
)}
|
|
146
128
|
</>
|
|
147
129
|
)}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import {
|
|
2
|
+
import { resolveOperationTypeNames } from '@internals/shared'
|
|
3
|
+
import { resolveZodSchemaNames } from '@internals/tanstack-query'
|
|
4
|
+
import { defineGenerator } from '@kubb/core'
|
|
3
5
|
import { Client, pluginClientName } from '@kubb/plugin-client'
|
|
4
6
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
7
|
import { pluginZodName } from '@kubb/plugin-zod'
|
|
6
|
-
import { File,
|
|
8
|
+
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
7
9
|
import { difference } from 'remeda'
|
|
8
10
|
import { Mutation, MutationKey, MutationOptions } from '../components'
|
|
9
11
|
import type { PluginReactQuery } from '../types'
|
|
10
|
-
import { transformName } from '../utils.ts'
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Built-in generator for `useMutation` hooks. Emits one `useFooMutation` hook
|
|
15
|
+
* per POST/PUT/DELETE operation (configurable via `mutation.methods`) plus
|
|
16
|
+
* the matching `fooMutationKey` / `fooMutationOptions` helpers.
|
|
17
|
+
*/
|
|
12
18
|
export const mutationGenerator = defineGenerator<PluginReactQuery>({
|
|
13
19
|
name: 'react-query-mutation',
|
|
14
|
-
renderer:
|
|
20
|
+
renderer: jsxRendererSync,
|
|
15
21
|
operation(node, ctx) {
|
|
16
|
-
const {
|
|
17
|
-
const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group,
|
|
22
|
+
const { config, driver, resolver, root } = ctx
|
|
23
|
+
const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options
|
|
18
24
|
|
|
19
25
|
const pluginTs = driver.getPlugin(pluginTsName)
|
|
20
26
|
if (!pluginTs) return null
|
|
@@ -30,53 +36,39 @@ export const mutationGenerator = defineGenerator<PluginReactQuery>({
|
|
|
30
36
|
|
|
31
37
|
const importPath = mutation ? mutation.importPath : '@tanstack/react-query'
|
|
32
38
|
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const mutationKeyName = transformName(`${baseName}MutationKey`, 'const', transformers)
|
|
39
|
-
const clientName = transformName(baseName, 'function', transformers)
|
|
39
|
+
const mutationHookName = resolver.resolveMutationName(node)
|
|
40
|
+
const mutationTypeName = resolver.resolveMutationTypeName(node)
|
|
41
|
+
const mutationOptionsName = resolver.resolveMutationOptionsName(node)
|
|
42
|
+
const mutationKeyName = resolver.resolveMutationKeyName(node)
|
|
43
|
+
const clientName = resolver.resolveClientName(node)
|
|
40
44
|
|
|
41
45
|
const meta = {
|
|
42
|
-
file: resolver.resolveFile(
|
|
46
|
+
file: resolver.resolveFile(
|
|
47
|
+
{ name: mutationHookName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
48
|
+
{ root, output, group: group ?? undefined },
|
|
49
|
+
),
|
|
43
50
|
fileTs: tsResolver.resolveFile(
|
|
44
51
|
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
45
|
-
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
|
|
52
|
+
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group ?? undefined },
|
|
46
53
|
),
|
|
47
54
|
}
|
|
48
55
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const importedTypeNames = [
|
|
55
|
-
node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : undefined,
|
|
56
|
-
tsResolver.resolveResponseName(node),
|
|
57
|
-
...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
58
|
-
...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
59
|
-
...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
60
|
-
...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode)),
|
|
61
|
-
].filter((name): name is string => !!name)
|
|
62
|
-
|
|
63
|
-
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
|
|
64
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
|
|
56
|
+
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing, order: 'body-response-first' })
|
|
57
|
+
|
|
58
|
+
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
|
|
59
|
+
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
|
|
65
60
|
const fileZod = zodResolver
|
|
66
61
|
? zodResolver.resolveFile(
|
|
67
62
|
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
68
|
-
{ root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
|
|
63
|
+
{ root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group ?? undefined },
|
|
69
64
|
)
|
|
70
|
-
:
|
|
71
|
-
const zodSchemaNames =
|
|
72
|
-
zodResolver && parser === 'zod'
|
|
73
|
-
? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : undefined].filter(Boolean)
|
|
74
|
-
: []
|
|
65
|
+
: null
|
|
66
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
|
|
75
67
|
|
|
76
68
|
const clientPlugin = driver.getPlugin(pluginClientName)
|
|
77
69
|
const hasClientPlugin = clientPlugin?.name === pluginClientName
|
|
78
70
|
const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
|
|
79
|
-
const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) :
|
|
71
|
+
const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null
|
|
80
72
|
|
|
81
73
|
const clientFile = shouldUseClientPlugin
|
|
82
74
|
? clientResolver?.resolveFile(
|
|
@@ -84,10 +76,10 @@ export const mutationGenerator = defineGenerator<PluginReactQuery>({
|
|
|
84
76
|
{
|
|
85
77
|
root,
|
|
86
78
|
output: clientPlugin?.options?.output ?? output,
|
|
87
|
-
group: clientPlugin?.options?.group,
|
|
79
|
+
group: clientPlugin?.options?.group ?? undefined,
|
|
88
80
|
},
|
|
89
81
|
)
|
|
90
|
-
:
|
|
82
|
+
: null
|
|
91
83
|
|
|
92
84
|
const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
|
|
93
85
|
|
|
@@ -96,34 +88,34 @@ export const mutationGenerator = defineGenerator<PluginReactQuery>({
|
|
|
96
88
|
baseName={meta.file.baseName}
|
|
97
89
|
path={meta.file.path}
|
|
98
90
|
meta={meta.file.meta}
|
|
99
|
-
banner={resolver.resolveBanner(
|
|
100
|
-
footer={resolver.resolveFooter(
|
|
91
|
+
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
92
|
+
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
101
93
|
>
|
|
102
|
-
{
|
|
103
|
-
<File.Import name={zodSchemaNames as string[]} root={meta.file.path} path={fileZod.path} />
|
|
104
|
-
)}
|
|
94
|
+
{fileZod && zodSchemaNames.length > 0 && <File.Import name={zodSchemaNames} root={meta.file.path} path={fileZod.path} />}
|
|
105
95
|
{clientOptions.importPath ? (
|
|
106
96
|
<>
|
|
107
|
-
{!shouldUseClientPlugin && <File.Import name={'
|
|
97
|
+
{!shouldUseClientPlugin && <File.Import name={'client'} path={clientOptions.importPath} />}
|
|
108
98
|
<File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={clientOptions.importPath} isTypeOnly />
|
|
109
99
|
{clientOptions.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={clientOptions.importPath} isTypeOnly />}
|
|
110
100
|
</>
|
|
111
101
|
) : (
|
|
112
102
|
<>
|
|
113
|
-
{!shouldUseClientPlugin && <File.Import name={['
|
|
103
|
+
{!shouldUseClientPlugin && <File.Import name={['client']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} />}
|
|
114
104
|
<File.Import
|
|
115
105
|
name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
|
|
116
106
|
root={meta.file.path}
|
|
117
|
-
path={path.resolve(root, '.kubb/
|
|
107
|
+
path={path.resolve(root, '.kubb/client.ts')}
|
|
118
108
|
isTypeOnly
|
|
119
109
|
/>
|
|
120
110
|
{clientOptions.dataReturnType === 'full' && (
|
|
121
|
-
<File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/
|
|
111
|
+
<File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} isTypeOnly />
|
|
122
112
|
)}
|
|
123
113
|
</>
|
|
124
114
|
)}
|
|
125
115
|
{shouldUseClientPlugin && clientFile && <File.Import name={[resolvedClientName]} root={meta.file.path} path={clientFile.path} />}
|
|
126
|
-
{!shouldUseClientPlugin &&
|
|
116
|
+
{!shouldUseClientPlugin && node.requestBody?.content?.some((e) => e.contentType === 'multipart/form-data') && (
|
|
117
|
+
<File.Import name={['buildFormData']} root={meta.file.path} path={path.resolve(root, '.kubb/config.ts')} />
|
|
118
|
+
)}
|
|
127
119
|
{customOptions && <File.Import name={[customOptions.name]} path={customOptions.importPath} />}
|
|
128
120
|
{meta.fileTs && importedTypeNames.length > 0 && (
|
|
129
121
|
<File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import {
|
|
2
|
+
import { resolveOperationTypeNames } from '@internals/shared'
|
|
3
|
+
import { resolveZodSchemaNames } from '@internals/tanstack-query'
|
|
4
|
+
import { defineGenerator } from '@kubb/core'
|
|
3
5
|
import { Client, pluginClientName } from '@kubb/plugin-client'
|
|
4
6
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
7
|
import { pluginZodName } from '@kubb/plugin-zod'
|
|
6
|
-
import { File,
|
|
8
|
+
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
7
9
|
import { difference } from 'remeda'
|
|
8
10
|
import { Query, QueryKey, QueryOptions } from '../components'
|
|
9
11
|
import type { PluginReactQuery } from '../types'
|
|
10
|
-
import { transformName } from '../utils.ts'
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Built-in generator for `useQuery` hooks. Emits one `useFooQuery` hook per
|
|
15
|
+
* GET operation (configurable via `query.methods`) plus the matching
|
|
16
|
+
* `fooQueryKey` / `fooQueryOptions` helpers.
|
|
17
|
+
*/
|
|
12
18
|
export const queryGenerator = defineGenerator<PluginReactQuery>({
|
|
13
19
|
name: 'react-query',
|
|
14
|
-
renderer:
|
|
20
|
+
renderer: jsxRendererSync,
|
|
15
21
|
operation(node, ctx) {
|
|
16
|
-
const {
|
|
17
|
-
const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group,
|
|
22
|
+
const { config, driver, resolver, root } = ctx
|
|
23
|
+
const { output, query, mutation, paramsCasing, paramsType, pathParamsType, parser, client: clientOptions, group, customOptions } = ctx.options
|
|
18
24
|
|
|
19
25
|
const pluginTs = driver.getPlugin(pluginTsName)
|
|
20
26
|
if (!pluginTs) return null
|
|
@@ -31,53 +37,43 @@ export const queryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
31
37
|
|
|
32
38
|
const importPath = query ? query.importPath : '@tanstack/react-query'
|
|
33
39
|
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const queryKeyTypeName = transformName(`${capitalize(baseName)}QueryKey`, 'type', transformers)
|
|
40
|
-
const clientName = transformName(baseName, 'function', transformers)
|
|
40
|
+
const queryName = resolver.resolveQueryName(node)
|
|
41
|
+
const queryOptionsName = resolver.resolveQueryOptionsName(node)
|
|
42
|
+
const queryKeyName = resolver.resolveQueryKeyName(node)
|
|
43
|
+
const queryKeyTypeName = resolver.resolveQueryKeyTypeName(node)
|
|
44
|
+
const clientName = resolver.resolveClientName(node)
|
|
41
45
|
|
|
42
46
|
const meta = {
|
|
43
|
-
file: resolver.resolveFile(
|
|
47
|
+
file: resolver.resolveFile(
|
|
48
|
+
{ name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
49
|
+
{ root, output, group: group ?? undefined },
|
|
50
|
+
),
|
|
44
51
|
fileTs: tsResolver.resolveFile(
|
|
45
52
|
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
46
|
-
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
|
|
53
|
+
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group ?? undefined },
|
|
47
54
|
),
|
|
48
55
|
}
|
|
49
56
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
59
|
-
...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
60
|
-
...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
61
|
-
...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode)),
|
|
62
|
-
].filter((name): name is string => !!name && name !== queryKeyTypeName)
|
|
63
|
-
|
|
64
|
-
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
|
|
65
|
-
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
|
|
57
|
+
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, {
|
|
58
|
+
paramsCasing,
|
|
59
|
+
exclude: [queryKeyTypeName],
|
|
60
|
+
order: 'body-response-first',
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
|
|
64
|
+
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
|
|
66
65
|
const fileZod = zodResolver
|
|
67
66
|
? zodResolver.resolveFile(
|
|
68
67
|
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
69
|
-
{ root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
|
|
68
|
+
{ root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group ?? undefined },
|
|
70
69
|
)
|
|
71
|
-
:
|
|
72
|
-
const zodSchemaNames =
|
|
73
|
-
zodResolver && parser === 'zod'
|
|
74
|
-
? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : undefined].filter(Boolean)
|
|
75
|
-
: []
|
|
70
|
+
: null
|
|
71
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
|
|
76
72
|
|
|
77
73
|
const clientPlugin = driver.getPlugin(pluginClientName)
|
|
78
74
|
const hasClientPlugin = clientPlugin?.name === pluginClientName
|
|
79
75
|
const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
|
|
80
|
-
const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) :
|
|
76
|
+
const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null
|
|
81
77
|
|
|
82
78
|
const clientFile = shouldUseClientPlugin
|
|
83
79
|
? clientResolver?.resolveFile(
|
|
@@ -85,10 +81,10 @@ export const queryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
85
81
|
{
|
|
86
82
|
root,
|
|
87
83
|
output: clientPlugin?.options?.output ?? output,
|
|
88
|
-
group: clientPlugin?.options?.group,
|
|
84
|
+
group: clientPlugin?.options?.group ?? undefined,
|
|
89
85
|
},
|
|
90
86
|
)
|
|
91
|
-
:
|
|
87
|
+
: null
|
|
92
88
|
|
|
93
89
|
const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
|
|
94
90
|
|
|
@@ -97,29 +93,27 @@ export const queryGenerator = defineGenerator<PluginReactQuery>({
|
|
|
97
93
|
baseName={meta.file.baseName}
|
|
98
94
|
path={meta.file.path}
|
|
99
95
|
meta={meta.file.meta}
|
|
100
|
-
banner={resolver.resolveBanner(
|
|
101
|
-
footer={resolver.resolveFooter(
|
|
96
|
+
banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
97
|
+
footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}
|
|
102
98
|
>
|
|
103
|
-
{
|
|
104
|
-
<File.Import name={zodSchemaNames as string[]} root={meta.file.path} path={fileZod.path} />
|
|
105
|
-
)}
|
|
99
|
+
{fileZod && zodSchemaNames.length > 0 && <File.Import name={zodSchemaNames} root={meta.file.path} path={fileZod.path} />}
|
|
106
100
|
{clientOptions.importPath ? (
|
|
107
101
|
<>
|
|
108
|
-
{!shouldUseClientPlugin && <File.Import name={'
|
|
102
|
+
{!shouldUseClientPlugin && <File.Import name={'client'} path={clientOptions.importPath} />}
|
|
109
103
|
<File.Import name={['Client', 'RequestConfig', 'ResponseErrorConfig']} path={clientOptions.importPath} isTypeOnly />
|
|
110
104
|
{clientOptions.dataReturnType === 'full' && <File.Import name={['ResponseConfig']} path={clientOptions.importPath} isTypeOnly />}
|
|
111
105
|
</>
|
|
112
106
|
) : (
|
|
113
107
|
<>
|
|
114
|
-
{!shouldUseClientPlugin && <File.Import name={['
|
|
108
|
+
{!shouldUseClientPlugin && <File.Import name={['client']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} />}
|
|
115
109
|
<File.Import
|
|
116
110
|
name={['Client', 'RequestConfig', 'ResponseErrorConfig']}
|
|
117
111
|
root={meta.file.path}
|
|
118
|
-
path={path.resolve(root, '.kubb/
|
|
112
|
+
path={path.resolve(root, '.kubb/client.ts')}
|
|
119
113
|
isTypeOnly
|
|
120
114
|
/>
|
|
121
115
|
{clientOptions.dataReturnType === 'full' && (
|
|
122
|
-
<File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/
|
|
116
|
+
<File.Import name={['ResponseConfig']} root={meta.file.path} path={path.resolve(root, '.kubb/client.ts')} isTypeOnly />
|
|
123
117
|
)}
|
|
124
118
|
</>
|
|
125
119
|
)}
|