@kubb/plugin-react-query 3.0.0-alpha.3 → 3.0.0-alpha.31

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 (81) hide show
  1. package/README.md +13 -4
  2. package/dist/chunk-C2H3KPHM.cjs +658 -0
  3. package/dist/chunk-C2H3KPHM.cjs.map +1 -0
  4. package/dist/chunk-J7NSRJSY.js +661 -0
  5. package/dist/chunk-J7NSRJSY.js.map +1 -0
  6. package/dist/chunk-M5RJDPKE.cjs +670 -0
  7. package/dist/chunk-M5RJDPKE.cjs.map +1 -0
  8. package/dist/chunk-Y3DM2P6L.js +647 -0
  9. package/dist/chunk-Y3DM2P6L.js.map +1 -0
  10. package/dist/components.cjs +39 -14
  11. package/dist/components.cjs.map +1 -1
  12. package/dist/components.d.cts +161 -7
  13. package/dist/components.d.ts +161 -7
  14. package/dist/components.js +2 -14
  15. package/dist/components.js.map +1 -1
  16. package/dist/generators.cjs +25 -0
  17. package/dist/generators.cjs.map +1 -0
  18. package/dist/generators.d.cts +14 -0
  19. package/dist/generators.d.ts +14 -0
  20. package/dist/generators.js +4 -0
  21. package/dist/generators.js.map +1 -0
  22. package/dist/index.cjs +75 -155
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +1 -5
  25. package/dist/index.d.ts +1 -5
  26. package/dist/index.js +58 -145
  27. package/dist/index.js.map +1 -1
  28. package/dist/types-oaGq_oPb.d.cts +169 -0
  29. package/dist/types-oaGq_oPb.d.ts +169 -0
  30. package/package.json +22 -17
  31. package/src/components/InfiniteQuery.tsx +129 -0
  32. package/src/components/InfiniteQueryOptions.tsx +130 -0
  33. package/src/components/Mutation.tsx +138 -322
  34. package/src/components/MutationKey.tsx +48 -0
  35. package/src/components/Query.tsx +91 -598
  36. package/src/components/QueryKey.tsx +51 -178
  37. package/src/components/QueryOptions.tsx +72 -466
  38. package/src/components/SuspenseQuery.tsx +129 -0
  39. package/src/components/index.ts +4 -1
  40. package/src/generators/__snapshots__/clientDataReturnTypeFull.ts +51 -0
  41. package/src/generators/__snapshots__/clientGetImportPath.ts +51 -0
  42. package/src/generators/__snapshots__/clientPostImportPath.ts +44 -0
  43. package/src/generators/__snapshots__/findByTags.ts +51 -0
  44. package/src/generators/__snapshots__/findByTagsPathParamsObject.ts +51 -0
  45. package/src/generators/__snapshots__/findByTagsWithCustomQueryKey.ts +51 -0
  46. package/src/generators/__snapshots__/findByTagsWithZod.ts +51 -0
  47. package/src/generators/__snapshots__/findInfiniteByTags.ts +57 -0
  48. package/src/generators/__snapshots__/findInfiniteByTagsCursor.ts +57 -0
  49. package/src/generators/__snapshots__/getAsMutation.ts +31 -0
  50. package/src/generators/__snapshots__/postAsQuery.ts +50 -0
  51. package/src/generators/__snapshots__/updatePetById.ts +44 -0
  52. package/src/generators/__snapshots__/updatePetByIdPathParamsObject.ts +46 -0
  53. package/src/generators/index.ts +4 -0
  54. package/src/generators/infiniteQueryGenerator.tsx +124 -0
  55. package/src/generators/mutationGenerator.tsx +108 -0
  56. package/src/generators/queryGenerator.tsx +121 -0
  57. package/src/generators/suspenseQueryGenerator.tsx +120 -0
  58. package/src/plugin.ts +58 -83
  59. package/src/types.ts +50 -107
  60. package/dist/chunk-5IL6M74X.js +0 -1504
  61. package/dist/chunk-5IL6M74X.js.map +0 -1
  62. package/dist/chunk-JFX7DCS7.cjs +0 -1504
  63. package/dist/chunk-JFX7DCS7.cjs.map +0 -1
  64. package/dist/index-C9fwRDH7.d.cts +0 -579
  65. package/dist/index-C9fwRDH7.d.ts +0 -579
  66. package/src/OperationGenerator.tsx +0 -86
  67. package/src/__snapshots__/mutateAsQuery/updatePetWithForm.ts +0 -64
  68. package/src/__snapshots__/pathParamsTypeInline/getPetById.ts +0 -57
  69. package/src/__snapshots__/pathParamsTypeObject/getPetById.ts +0 -63
  70. package/src/__snapshots__/queryOptions/getPetById.ts +0 -37
  71. package/src/__snapshots__/queryWithoutQueryOptions/getPetById.ts +0 -47
  72. package/src/__snapshots__/upload/UploadFile.ts +0 -67
  73. package/src/__snapshots__/uploadMutation/UploadFile.ts +0 -44
  74. package/src/__snapshots__/variablesTypeMutate/deletePet.ts +0 -21
  75. package/src/components/Operations.tsx +0 -74
  76. package/src/components/QueryImports.tsx +0 -167
  77. package/src/components/SchemaType.tsx +0 -55
  78. package/src/components/__snapshots__/gen/showPetById.ts +0 -57
  79. package/src/components/__snapshots__/gen/useCreatePets.ts +0 -46
  80. package/src/components/__snapshots__/gen/useCreatePetsMutate.ts +0 -47
  81. package/src/utils.ts +0 -96
@@ -1,487 +1,93 @@
1
- import { PackageManager } from '@kubb/core'
2
- import transformers from '@kubb/core/transformers'
3
- import { FunctionParams, URLPath } from '@kubb/core/utils'
4
- import { useOperation, useOperationManager } from '@kubb/plugin-oas/hooks'
5
- import { getASTParams } from '@kubb/plugin-oas/utils'
6
- import { Function, useApp } from '@kubb/react'
7
- import { pluginZodName } from '@kubb/plugin-zod'
1
+ import { getPathParams } from '@kubb/plugin-oas/utils'
2
+ import { File, Function, FunctionParams } from '@kubb/react'
8
3
 
9
- import { isRequired } from '@kubb/oas'
10
- import type { HttpMethod } from '@kubb/oas'
11
4
  import type { ReactNode } from 'react'
12
- import type { Infinite, PluginReactQuery, Suspense } from '../types.ts'
13
- import { pluginTsName } from '@kubb/plugin-ts'
14
- import { reactQueryDepRegex } from '../utils.ts'
15
5
 
16
- type TemplateProps = {
17
- /**
18
- * Name of the function
19
- */
6
+ import { isOptional } from '@kubb/oas'
7
+ import { Client } from '@kubb/plugin-client/components'
8
+ import type { OperationSchemas } from '@kubb/plugin-oas'
9
+ import type { PluginReactQuery } from '../types.ts'
10
+ import { QueryKey } from './QueryKey.tsx'
11
+
12
+ type Props = {
20
13
  name: string
21
- /**
22
- * Parameters/options/props that need to be used
23
- */
24
- params: string
25
- /**
26
- * Generics that needs to be added for TypeScript
27
- */
28
- generics?: string
29
- /**
30
- * ReturnType(see async for adding Promise type)
31
- */
32
- returnType?: string
33
- /**
34
- * Options for JSdocs
35
- */
36
- JSDoc?: {
37
- comments: string[]
38
- }
39
- hook: {
40
- queryKey: string
41
- children?: string
42
- }
43
- client: {
44
- generics: string
45
- method: HttpMethod
46
- path: URLPath
47
- withQueryParams: boolean
48
- withPathParams: boolean
49
- withData: boolean
50
- withHeaders: boolean
51
- contentType: string
52
- }
53
- infinite: Infinite | false
54
- dataReturnType: NonNullable<PluginReactQuery['options']['dataReturnType']>
55
- parser: string | undefined
14
+ clientName: string
15
+ queryKeyName: string
16
+ typeSchemas: OperationSchemas
17
+ pathParamsType: PluginReactQuery['resolvedOptions']['pathParamsType']
56
18
  }
57
19
 
58
- function Template({ name, params, generics, returnType, JSDoc, hook, client, infinite, dataReturnType, parser }: TemplateProps): ReactNode {
59
- const isV5 = new PackageManager().isValidSync(reactQueryDepRegex, '>=5')
60
- const isFormData = client.contentType === 'multipart/form-data'
61
- const headers = [
62
- client.contentType !== 'application/json' ? `'Content-Type': '${client.contentType}'` : undefined,
63
- client.withHeaders ? '...headers' : undefined,
64
- ]
65
- .filter(Boolean)
66
- .join(', ')
67
-
68
- const clientOptions = [
69
- `method: "${client.method}"`,
70
- `url: ${client.path.template}`,
71
- client.withQueryParams && !infinite ? 'params' : undefined,
72
- client.withData && !isFormData ? 'data' : undefined,
73
- client.withData && isFormData ? 'data: formData' : undefined,
74
- headers.length ? `headers: { ${headers}, ...options.headers }` : undefined,
75
- '...options',
76
- client.withQueryParams && !!infinite
77
- ? `params: {
78
- ...params,
79
- ['${infinite.queryParam}']: pageParam,
80
- ...(options.params || {}),
81
- }`
82
- : undefined,
83
- ].filter(Boolean)
20
+ type GetParamsProps = {
21
+ pathParamsType: PluginReactQuery['resolvedOptions']['pathParamsType']
22
+ typeSchemas: OperationSchemas
23
+ }
84
24
 
85
- const queryOptions = [
86
- isV5 && !!infinite ? `initialPageParam: ${infinite.initialPageParam}` : undefined,
87
- isV5 && !!infinite && !!infinite.cursorParam ? `getNextPageParam: (lastPage) => lastPage['${infinite.cursorParam}']` : undefined,
88
- isV5 && !!infinite && !!infinite.cursorParam ? `getPreviousPageParam: (firstPage) => firstPage['${infinite.cursorParam}']` : undefined,
89
- isV5 && !!infinite && !infinite.cursorParam && dataReturnType === 'full'
90
- ? 'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage.data) && lastPage.data.length === 0 ? undefined : lastPageParam + 1'
25
+ function getParams({ pathParamsType, typeSchemas }: GetParamsProps) {
26
+ return FunctionParams.factory({
27
+ pathParams: {
28
+ mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
29
+ children: getPathParams(typeSchemas.pathParams, { typed: true }),
30
+ },
31
+ data: typeSchemas.request?.name
32
+ ? {
33
+ type: typeSchemas.request?.name,
34
+ optional: isOptional(typeSchemas.request?.schema),
35
+ }
91
36
  : undefined,
92
- isV5 && !!infinite && !infinite.cursorParam && dataReturnType === 'data'
93
- ? 'getNextPageParam: (lastPage, _allPages, lastPageParam) => Array.isArray(lastPage) && lastPage.length === 0 ? undefined : lastPageParam + 1'
37
+ params: typeSchemas.queryParams?.name
38
+ ? {
39
+ type: typeSchemas.queryParams?.name,
40
+ optional: isOptional(typeSchemas.queryParams?.schema),
41
+ }
94
42
  : undefined,
95
- isV5 && !!infinite && !infinite.cursorParam
96
- ? 'getPreviousPageParam: (_firstPage, _allPages, firstPageParam) => firstPageParam <= 1 ? undefined : firstPageParam - 1'
43
+ headers: typeSchemas.headerParams?.name
44
+ ? {
45
+ type: typeSchemas.headerParams?.name,
46
+ optional: isOptional(typeSchemas.headerParams?.schema),
47
+ }
97
48
  : undefined,
98
- ].filter(Boolean)
99
-
100
- const resolvedClientOptions = `${transformers.createIndent(4)}${clientOptions.join(`,\n${transformers.createIndent(4)}`)}`
101
- const resolvedQueryOptions = `${transformers.createIndent(4)}${queryOptions.join(`,\n${transformers.createIndent(4)}`)}`
102
-
103
- let returnRes = parser ? `return ${parser}(res.data)` : 'return res.data'
104
-
105
- if (dataReturnType === 'full') {
106
- returnRes = parser ? `return {...res, data: ${parser}(res.data)}` : 'return res'
107
- }
108
-
109
- const formData = isFormData
110
- ? `
111
- const formData = new FormData()
112
- if(data) {
113
- Object.keys(data).forEach((key) => {
114
- const value = data[key];
115
- if (typeof key === "string" && (typeof value === "string" || value instanceof Blob)) {
116
- formData.append(key, value);
117
- }
118
- })
119
- }
120
- `
121
- : undefined
122
-
123
- if (infinite) {
124
- if (isV5) {
125
- return (
126
- <Function name={name} export params={params} JSDoc={JSDoc}>
127
- {`
128
- const queryKey = ${hook.queryKey}
129
-
130
- return infiniteQueryOptions({
131
- queryKey,
132
- queryFn: async ({ pageParam }) => {
133
- ${hook.children || ''}
134
- ${formData || ''}
135
- const res = await client<${client.generics}>({
136
- ${resolvedClientOptions}
137
- })
138
-
139
- ${returnRes}
140
- },
141
- ${resolvedQueryOptions}
142
- })
143
-
144
- `}
145
- </Function>
146
- )
147
- }
148
-
149
- return (
150
- <Function name={name} export generics={generics} returnType={returnType} params={params} JSDoc={JSDoc}>
151
- {`
152
- const queryKey = ${hook.queryKey}
153
-
154
- return {
155
- queryKey,
156
- queryFn: async ({ pageParam }) => {
157
- ${hook.children || ''}
158
- ${formData || ''}
159
- const res = await client<${client.generics}>({
160
- ${resolvedClientOptions}
161
- })
162
-
163
- ${returnRes}
164
- },
165
- ${resolvedQueryOptions}
166
- }
167
-
168
- `}
169
- </Function>
170
- )
171
- }
172
-
173
- if (isV5) {
174
- return (
175
- <Function name={name} export params={params} JSDoc={JSDoc}>
176
- {`
177
- const queryKey = ${hook.queryKey}
178
-
179
- return queryOptions({
180
- queryKey,
181
- queryFn: async () => {
182
- ${hook.children || ''}
183
- ${formData || ''}
184
- const res = await client<${client.generics}>({
185
- ${resolvedClientOptions}
186
- })
187
-
188
- ${returnRes}
189
- },
190
- ${resolvedQueryOptions}
191
- })
192
-
193
- `}
194
- </Function>
195
- )
196
- }
197
-
198
- return (
199
- <Function name={name} export generics={generics} returnType={returnType} params={params} JSDoc={JSDoc}>
200
- {`
201
- const queryKey = ${hook.queryKey}
202
-
203
- return {
204
- queryKey,
205
- queryFn: async () => {
206
- ${hook.children || ''}
207
- ${formData || ''}
208
- const res = await client<${client.generics}>({
209
- ${resolvedClientOptions}
210
- })
211
-
212
- ${returnRes}
213
- },
214
- ${resolvedQueryOptions}
215
- }
216
-
217
- `}
218
- </Function>
219
- )
220
- }
221
-
222
- type FrameworkProps = TemplateProps & {
223
- context: {
224
- factory: {
225
- name: string
226
- }
227
- queryKey: string
228
- }
229
- }
230
-
231
- const defaultTemplates = {
232
- get react() {
233
- return function (props: FrameworkProps): ReactNode {
234
- return <Template {...props} />
235
- }
236
- },
237
- get solid() {
238
- return function (props: FrameworkProps): ReactNode {
239
- return <Template {...props} />
240
- }
241
- },
242
- get svelte() {
243
- return function (props: FrameworkProps): ReactNode {
244
- return <Template {...props} />
245
- }
246
- },
247
- get vue() {
248
- return function ({ client, context, ...rest }: FrameworkProps): ReactNode {
249
- const { factory, queryKey } = context
250
-
251
- const {
252
- plugin: {
253
- options: { pathParamsType },
254
- },
255
- } = useApp<PluginReactQuery>()
256
-
257
- const { getSchemas } = useOperationManager()
258
- const operation = useOperation()
259
-
260
- const schemas = getSchemas(operation, { pluginKey: [pluginTsName], type: 'type' })
261
- const params = new FunctionParams()
262
- const queryKeyParams = new FunctionParams()
263
-
264
- params.add([
265
- ...(pathParamsType === 'object'
266
- ? [
267
- getASTParams(schemas.pathParams, {
268
- typed: true,
269
- override: (item) => ({
270
- ...item,
271
- name: item.name ? `ref${transformers.pascalCase(item.name)}` : undefined,
272
- type: `MaybeRef<${item.type}>`,
273
- }),
274
- }),
275
- ]
276
- : getASTParams(schemas.pathParams, {
277
- typed: true,
278
- override: (item) => ({
279
- ...item,
280
- name: item.name ? `ref${transformers.pascalCase(item.name)}` : undefined,
281
- type: `MaybeRef<${item.type}>`,
282
- }),
283
- })),
284
- {
285
- name: 'refParams',
286
- type: `MaybeRef<${schemas.queryParams?.name}>`,
287
- enabled: client.withQueryParams,
288
- required: isRequired(schemas.queryParams?.schema),
289
- },
290
- {
291
- name: 'refHeaders',
292
- type: `MaybeRef<${schemas.headerParams?.name}>`,
293
- enabled: client.withHeaders,
294
- required: isRequired(schemas.headerParams?.schema),
295
- },
296
- {
297
- name: 'refData',
298
- type: `MaybeRef<${schemas.request?.name}>`,
299
- enabled: client.withData,
300
- required: isRequired(schemas.request?.schema),
301
- },
302
- {
303
- name: 'options',
304
- type: `${factory.name}['client']['parameters']`,
305
- default: '{}',
306
- },
307
- ])
308
-
309
- queryKeyParams.add([
310
- ...(pathParamsType === 'object'
311
- ? [
312
- getASTParams(schemas.pathParams, {
313
- override: (item) => ({
314
- ...item,
315
- name: item.name ? `ref${transformers.pascalCase(item.name)}` : undefined,
316
- }),
317
- }),
318
- ]
319
- : getASTParams(schemas.pathParams, {
320
- override: (item) => ({
321
- ...item,
322
- name: item.name ? `ref${transformers.pascalCase(item.name)}` : undefined,
323
- }),
324
- })),
325
- {
326
- name: 'refParams',
327
- enabled: client.withQueryParams,
328
- required: isRequired(schemas.queryParams?.schema),
329
- },
330
- {
331
- name: 'refData',
332
- enabled: client.withData,
333
- required: isRequired(schemas.request?.schema),
334
- },
335
- ])
336
-
337
- const unrefs = params.items
338
- .filter((item) => item.enabled)
339
- .map((item) => {
340
- return item.name ? `const ${transformers.camelCase(item.name.replace('ref', ''))} = unref(${item.name})` : undefined
341
- })
342
- .join('\n')
343
-
344
- const hook = {
345
- queryKey: `${queryKey}(${queryKeyParams.toString()})`,
346
- children: unrefs,
347
- }
348
-
349
- return <Template {...rest} params={params.toString()} hook={hook} client={client} />
350
- }
351
- },
352
- } as const
353
-
354
- type Props = {
355
- infinite: Infinite | false
356
- suspense: Suspense | false
357
- factory: {
358
- name: string
359
- }
360
- resultType: string
361
- /**
362
- * This will make it possible to override the default behaviour.
363
- */
364
- Template?: React.ComponentType<FrameworkProps>
365
- dataReturnType: NonNullable<PluginReactQuery['options']['dataReturnType']>
366
- }
367
-
368
- export function QueryOptions({ factory, infinite, suspense, resultType, dataReturnType, Template = defaultTemplates.react }: Props): ReactNode {
369
- const {
370
- pluginManager,
371
- plugin: {
372
- key: pluginKey,
373
- options: { parser, pathParamsType, queryOptions },
49
+ config: {
50
+ type: typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>>` : 'Partial<RequestConfig>',
51
+ default: '{}',
374
52
  },
375
- } = useApp<PluginReactQuery>()
376
-
377
- const { getSchemas } = useOperationManager()
378
- const operation = useOperation()
379
-
380
- const contentType = operation.getContentType()
381
- const schemas = getSchemas(operation, { pluginKey: [pluginTsName], type: 'type' })
382
- const zodSchemas = getSchemas(operation, { pluginKey: [pluginZodName], type: 'function' })
53
+ })
54
+ }
383
55
 
384
- const queryKey = pluginManager.resolveName({
385
- name: [factory.name, infinite ? 'Infinite' : undefined, suspense ? 'Suspense' : undefined, 'QueryKey'].filter(Boolean).join(''),
386
- pluginKey,
56
+ export function QueryOptions({ name, clientName, typeSchemas, pathParamsType, queryKeyName }: Props): ReactNode {
57
+ const params = getParams({ pathParamsType, typeSchemas })
58
+ const clientParams = Client.getParams({
59
+ typeSchemas,
60
+ pathParamsType,
387
61
  })
388
- const queryOptionsName = pluginManager.resolveName({
389
- name: [factory.name, infinite ? 'Infinite' : undefined, suspense ? 'Suspense' : undefined, 'QueryOptions'].filter(Boolean).join(''),
390
- pluginKey,
62
+ const queryKeyParams = QueryKey.getParams({
63
+ pathParamsType,
64
+ typeSchemas,
391
65
  })
392
66
 
393
- const generics = new FunctionParams()
394
- const params = new FunctionParams()
395
- const queryKeyParams = new FunctionParams()
396
-
397
- const clientGenerics = [`${factory.name}['data']`, `${factory.name}['error']`]
398
- // suspense is having 4 generics instead of 5, TQueryData is not needed because data will always be defined
399
- const resultGenerics = suspense
400
- ? [`${factory.name}['response']`, `${factory.name}["error"]`, 'TData']
401
- : [`${factory.name}['response']`, `${factory.name}["error"]`, 'TData', 'TQueryData']
402
-
403
- const client = {
404
- withQueryParams: !!schemas.queryParams?.name,
405
- withData: !!schemas.request?.name,
406
- withPathParams: !!schemas.pathParams?.name,
407
- withHeaders: !!schemas.headerParams?.name,
408
- method: operation.method,
409
- path: new URLPath(operation.path),
410
- generics: clientGenerics.toString(),
411
- contentType,
412
- }
413
-
414
- generics.add([
415
- { type: 'TData', default: `${factory.name}["response"]` },
416
- suspense ? undefined : { type: 'TQueryData', default: `${factory.name}["response"]` },
417
- ])
418
-
419
- params.add([
420
- ...(pathParamsType === 'object' ? [getASTParams(schemas.pathParams, { typed: true })] : getASTParams(schemas.pathParams, { typed: true })),
421
- {
422
- name: 'params',
423
- type: `${factory.name}['queryParams']`,
424
- enabled: client.withQueryParams,
425
- required: isRequired(schemas.queryParams?.schema),
426
- },
427
- {
428
- name: 'headers',
429
- type: `${factory.name}['headerParams']`,
430
- enabled: client.withHeaders,
431
- required: isRequired(schemas.headerParams?.schema),
432
- },
433
- {
434
- name: 'data',
435
- type: `${factory.name}['request']`,
436
- enabled: client.withData,
437
- required: isRequired(schemas.request?.schema),
438
- },
439
- {
440
- name: 'options',
441
- type: `${factory.name}['client']['parameters']`,
442
- default: '{}',
443
- },
444
- ])
445
-
446
- queryKeyParams.add([
447
- ...(pathParamsType === 'object' ? [getASTParams(schemas.pathParams)] : getASTParams(schemas.pathParams)),
448
- {
449
- name: 'params',
450
- enabled: client.withQueryParams,
451
- required: isRequired(schemas.queryParams?.schema),
452
- },
453
- {
454
- name: 'data',
455
- enabled: client.withData,
456
- required: isRequired(schemas.request?.schema),
457
- },
458
- ])
459
-
460
- const hook = {
461
- queryKey: `${queryKey}(${queryKeyParams.toString()})`,
462
- }
67
+ const enabled = Object.entries(queryKeyParams.flatParams)
68
+ .map(([key, item]) => (item && !item.optional ? key : undefined))
69
+ .filter(Boolean)
70
+ .join('&& ')
463
71
 
464
- if (!queryOptions) {
465
- return null
466
- }
72
+ const enabledText = enabled ? `enabled: !!(${enabled})` : ''
467
73
 
468
74
  return (
469
- <Template
470
- name={queryOptionsName}
471
- params={params.toString()}
472
- generics={generics.toString()}
473
- returnType={`WithRequired<${resultType}<${resultGenerics.join(', ')}>, 'queryKey'>`}
474
- client={client}
475
- hook={hook}
476
- infinite={infinite}
477
- dataReturnType={dataReturnType}
478
- parser={parser === 'zod' ? `${zodSchemas.response.name}.parse` : undefined}
479
- context={{
480
- factory,
481
- queryKey,
482
- }}
483
- />
75
+ <File.Source name={name} isExportable isIndexable>
76
+ <Function name={name} export params={params.toConstructor()}>
77
+ {`
78
+ const queryKey = ${queryKeyName}(${queryKeyParams.toCall()})
79
+ return queryOptions({
80
+ ${enabledText}
81
+ queryKey,
82
+ queryFn: async ({ signal }) => {
83
+ config.signal = signal
84
+ return ${clientName}(${clientParams.toCall({})})
85
+ },
86
+ })
87
+ `}
88
+ </Function>
89
+ </File.Source>
484
90
  )
485
91
  }
486
92
 
487
- QueryOptions.templates = defaultTemplates
93
+ QueryOptions.getParams = getParams
@@ -0,0 +1,129 @@
1
+ import { File, Function, FunctionParams } from '@kubb/react'
2
+
3
+ import { type Operation, isOptional } from '@kubb/oas'
4
+ import type { OperationSchemas } from '@kubb/plugin-oas'
5
+ import { getComments, getPathParams } from '@kubb/plugin-oas/utils'
6
+ import type { ReactNode } from 'react'
7
+ import type { PluginReactQuery } from '../types.ts'
8
+ import { QueryKey } from './QueryKey.tsx'
9
+ import { QueryOptions } from './QueryOptions.tsx'
10
+
11
+ type Props = {
12
+ /**
13
+ * Name of the function
14
+ */
15
+ name: string
16
+ queryOptionsName: string
17
+ queryKeyName: string
18
+ queryKeyTypeName: string
19
+ typeSchemas: OperationSchemas
20
+ operation: Operation
21
+ pathParamsType: PluginReactQuery['resolvedOptions']['pathParamsType']
22
+ dataReturnType: PluginReactQuery['resolvedOptions']['client']['dataReturnType']
23
+ }
24
+
25
+ type GetParamsProps = {
26
+ pathParamsType: PluginReactQuery['resolvedOptions']['pathParamsType']
27
+ dataReturnType: PluginReactQuery['resolvedOptions']['client']['dataReturnType']
28
+ typeSchemas: OperationSchemas
29
+ }
30
+
31
+ function getParams({ pathParamsType, dataReturnType, typeSchemas }: GetParamsProps) {
32
+ const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
33
+
34
+ return FunctionParams.factory({
35
+ pathParams: {
36
+ mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
37
+ children: getPathParams(typeSchemas.pathParams, { typed: true }),
38
+ },
39
+ data: typeSchemas.request?.name
40
+ ? {
41
+ type: typeSchemas.request?.name,
42
+ optional: isOptional(typeSchemas.request?.schema),
43
+ }
44
+ : undefined,
45
+ params: typeSchemas.queryParams?.name
46
+ ? {
47
+ type: typeSchemas.queryParams?.name,
48
+ optional: isOptional(typeSchemas.queryParams?.schema),
49
+ }
50
+ : undefined,
51
+ headers: typeSchemas.headerParams?.name
52
+ ? {
53
+ type: typeSchemas.headerParams?.name,
54
+ optional: isOptional(typeSchemas.headerParams?.schema),
55
+ }
56
+ : undefined,
57
+ options: {
58
+ type: `
59
+ {
60
+ query?: Partial<UseSuspenseQueryOptions<${[TData, typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error', 'TData', 'TQueryKey'].join(', ')}>>,
61
+ client?: ${typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>>` : 'Partial<RequestConfig>'}
62
+ }
63
+ `,
64
+ default: '{}',
65
+ },
66
+ })
67
+ }
68
+
69
+ export function SuspenseQuery({
70
+ name,
71
+ queryKeyTypeName,
72
+ queryOptionsName,
73
+ queryKeyName,
74
+ pathParamsType,
75
+ dataReturnType,
76
+ typeSchemas,
77
+ operation,
78
+ }: Props): ReactNode {
79
+ const TData = dataReturnType === 'data' ? typeSchemas.response.name : `ResponseConfig<${typeSchemas.response.name}>`
80
+ const returnType = `UseSuspenseQueryResult<${['TData', typeSchemas.errors?.map((item) => item.name).join(' | ') || 'Error'].join(', ')}> & { queryKey: TQueryKey }`
81
+ const generics = [`TData = ${TData}`, `TQueryData = ${TData}`, `TQueryKey extends QueryKey = ${queryKeyTypeName}`]
82
+
83
+ const queryKeyParams = QueryKey.getParams({
84
+ pathParamsType,
85
+ typeSchemas,
86
+ })
87
+ const queryOptionsParams = QueryOptions.getParams({
88
+ pathParamsType,
89
+ typeSchemas,
90
+ })
91
+ const params = getParams({
92
+ pathParamsType,
93
+ dataReturnType,
94
+ typeSchemas,
95
+ })
96
+
97
+ const queryOptions = `${queryOptionsName}(${queryOptionsParams.toCall()}) as unknown as UseSuspenseQueryOptions`
98
+
99
+ return (
100
+ <File.Source name={name} isExportable isIndexable>
101
+ <Function
102
+ name={name}
103
+ export
104
+ generics={generics.join(', ')}
105
+ params={params.toConstructor()}
106
+ JSDoc={{
107
+ comments: getComments(operation),
108
+ }}
109
+ >
110
+ {`
111
+ const { query: queryOptions, client: config = {} } = options ?? {}
112
+ const queryKey = queryOptions?.queryKey ?? ${queryKeyName}(${queryKeyParams.toCall()})
113
+
114
+ const query = useSuspenseQuery({
115
+ ...${queryOptions},
116
+ queryKey,
117
+ ...queryOptions as unknown as Omit<UseSuspenseQueryOptions, "queryKey">
118
+ }) as ${returnType}
119
+
120
+ query.queryKey = queryKey as TQueryKey
121
+
122
+ return query
123
+ `}
124
+ </Function>
125
+ </File.Source>
126
+ )
127
+ }
128
+
129
+ SuspenseQuery.getParams = getParams
@@ -1,5 +1,8 @@
1
1
  export { Mutation } from './Mutation.tsx'
2
- export { Operations } from './Operations.tsx'
3
2
  export { Query } from './Query.tsx'
4
3
  export { QueryKey } from './QueryKey.tsx'
4
+ export { MutationKey } from './MutationKey.tsx'
5
5
  export { QueryOptions } from './QueryOptions.tsx'
6
+ export { InfiniteQueryOptions } from './InfiniteQueryOptions.tsx'
7
+ export { InfiniteQuery } from './InfiniteQuery.tsx'
8
+ export { SuspenseQuery } from './SuspenseQuery.tsx'