@kubb/plugin-vue-query 5.0.0-beta.22 → 5.0.0-beta.27

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 (39) hide show
  1. package/dist/{components-CARlYXLX.js → components-B4IlVmNa.js} +58 -43
  2. package/dist/components-B4IlVmNa.js.map +1 -0
  3. package/dist/{components-DycYiYNM.cjs → components-CIedagno.cjs} +58 -43
  4. package/dist/components-CIedagno.cjs.map +1 -0
  5. package/dist/components.cjs +1 -1
  6. package/dist/components.d.ts +3 -3
  7. package/dist/components.js +1 -1
  8. package/dist/{generators-BuDRi6qN.js → generators-Bgcwdua5.js} +46 -30
  9. package/dist/generators-Bgcwdua5.js.map +1 -0
  10. package/dist/{generators-DX8VWz4a.cjs → generators-CuDw35Wp.cjs} +46 -30
  11. package/dist/generators-CuDw35Wp.cjs.map +1 -0
  12. package/dist/generators.cjs +1 -1
  13. package/dist/generators.d.ts +17 -1
  14. package/dist/generators.js +1 -1
  15. package/dist/index.cjs +47 -8
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.ts +29 -1
  18. package/dist/index.js +47 -8
  19. package/dist/index.js.map +1 -1
  20. package/dist/{types-Bkm7bWT3.d.ts → types-D-LjzI_Q.d.ts} +73 -46
  21. package/extension.yaml +779 -255
  22. package/package.json +7 -7
  23. package/src/components/InfiniteQuery.tsx +6 -4
  24. package/src/components/InfiniteQueryOptions.tsx +11 -10
  25. package/src/components/Mutation.tsx +7 -5
  26. package/src/components/Query.tsx +6 -4
  27. package/src/components/QueryKey.tsx +3 -3
  28. package/src/components/QueryOptions.tsx +4 -3
  29. package/src/generators/infiniteQueryGenerator.tsx +19 -10
  30. package/src/generators/mutationGenerator.tsx +17 -9
  31. package/src/generators/queryGenerator.tsx +17 -9
  32. package/src/plugin.ts +32 -4
  33. package/src/resolvers/resolverVueQuery.ts +13 -2
  34. package/src/types.ts +72 -45
  35. package/src/utils.ts +8 -1
  36. package/dist/components-CARlYXLX.js.map +0 -1
  37. package/dist/components-DycYiYNM.cjs.map +0 -1
  38. package/dist/generators-BuDRi6qN.js.map +0 -1
  39. package/dist/generators-DX8VWz4a.cjs.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/plugin-vue-query",
3
- "version": "5.0.0-beta.22",
3
+ "version": "5.0.0-beta.27",
4
4
  "description": "Generate type-safe TanStack Query (Vue Query) composables from your OpenAPI specification. Covers useQuery, useMutation, useInfiniteQuery, and queryOptions with Vue 3 Composition API support.",
5
5
  "keywords": [
6
6
  "code-generation",
@@ -70,12 +70,12 @@
70
70
  "registry": "https://registry.npmjs.org/"
71
71
  },
72
72
  "dependencies": {
73
- "@kubb/core": "5.0.0-beta.22",
74
- "@kubb/renderer-jsx": "5.0.0-beta.22",
73
+ "@kubb/core": "5.0.0-beta.27",
74
+ "@kubb/renderer-jsx": "5.0.0-beta.27",
75
75
  "remeda": "^2.34.1",
76
- "@kubb/plugin-client": "5.0.0-beta.22",
77
- "@kubb/plugin-ts": "5.0.0-beta.22",
78
- "@kubb/plugin-zod": "5.0.0-beta.22"
76
+ "@kubb/plugin-client": "5.0.0-beta.27",
77
+ "@kubb/plugin-ts": "5.0.0-beta.27",
78
+ "@kubb/plugin-zod": "5.0.0-beta.27"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@internals/shared": "0.0.0",
@@ -83,7 +83,7 @@
83
83
  "@internals/utils": "0.0.0"
84
84
  },
85
85
  "peerDependencies": {
86
- "@kubb/renderer-jsx": "5.0.0-beta.22"
86
+ "@kubb/renderer-jsx": "5.0.0-beta.27"
87
87
  },
88
88
  "size-limit": [
89
89
  {
@@ -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 { Infinite, PluginVueQuery } from '../types.ts'
7
- import { getComments, resolveErrorNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
7
+ import { getComments, resolveErrorNames, resolveSuccessNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
8
8
  import { buildQueryKeyParamsNode } from './QueryKey.tsx'
9
9
  import { getQueryOptionsParams } from './QueryOptions.tsx'
10
10
 
@@ -37,8 +37,9 @@ function buildInfiniteQueryParamsNode(
37
37
  },
38
38
  ): ast.FunctionParametersNode {
39
39
  const { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver } = options
40
- const responseName = resolver.resolveResponseName(node)
41
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
40
+ const successNames = resolveSuccessNames(node, resolver)
41
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : resolver.resolveResponseName(node)
42
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null
42
43
  const errorNames = resolveErrorNames(node, resolver)
43
44
 
44
45
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -79,7 +80,8 @@ export function InfiniteQuery({
79
80
  node,
80
81
  tsResolver,
81
82
  }: Props): KubbReactNode {
82
- const responseName = tsResolver.resolveResponseName(node)
83
+ const successNames = resolveSuccessNames(node, tsResolver)
84
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
83
85
  const errorNames = resolveErrorNames(node, tsResolver)
84
86
 
85
87
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -6,7 +6,7 @@ import { functionPrinter } from '@kubb/plugin-ts'
6
6
  import { File, Function } from '@kubb/renderer-jsx'
7
7
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
8
8
  import type { Infinite, PluginVueQuery } from '../types.ts'
9
- import { resolveErrorNames } from '../utils.ts'
9
+ import { resolveErrorNames, resolveSuccessNames } from '../utils.ts'
10
10
  import { buildQueryKeyParamsNode } from './QueryKey.tsx'
11
11
  import { buildEnabledCheck } from '@internals/tanstack-query'
12
12
  import { getQueryOptionsParams } from './QueryOptions.tsx'
@@ -47,7 +47,8 @@ export function InfiniteQueryOptions({
47
47
  queryParam,
48
48
  queryKeyName,
49
49
  }: Props): KubbReactNode {
50
- const responseName = tsResolver.resolveResponseName(node)
50
+ const successNames = resolveSuccessNames(node, tsResolver)
51
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
51
52
  const queryFnDataType = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
52
53
  const errorNames = resolveErrorNames(node, tsResolver)
53
54
  const errorType = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(' | ') : 'Error'}>`
@@ -73,11 +74,11 @@ export function InfiniteQueryOptions({
73
74
  ? (() => {
74
75
  const groupName = tsResolver.resolveQueryParamsName(node, rawQueryParams[0]!)
75
76
  const individualName = tsResolver.resolveParamName(node, rawQueryParams[0]!)
76
- return groupName !== individualName ? groupName : undefined
77
+ return groupName !== individualName ? groupName : null
77
78
  })()
78
- : undefined
79
+ : null
79
80
 
80
- const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : undefined
81
+ const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null
81
82
  const pageParamType = queryParamType ? (isInitialPageParamDefined ? `NonNullable<${queryParamType}>` : queryParamType) : fallbackPageParamType
82
83
 
83
84
  const paramsNode = getQueryOptionsParams(node, { paramsType, paramsCasing, pathParamsType, resolver: tsResolver })
@@ -96,15 +97,15 @@ export function InfiniteQueryOptions({
96
97
  .join(' && ')},`
97
98
  : ''
98
99
 
99
- const hasNewParams = nextParam !== undefined || previousParam !== undefined
100
+ const hasNewParams = nextParam != null || previousParam != null
100
101
 
101
102
  const [getNextPageParamExpr, getPreviousPageParamExpr] = (() => {
102
103
  if (hasNewParams) {
103
- const nextAccessor = nextParam ? getNestedAccessor(nextParam, 'lastPage') : undefined
104
- const prevAccessor = previousParam ? getNestedAccessor(previousParam, 'firstPage') : undefined
104
+ const nextAccessor = nextParam ? getNestedAccessor(nextParam, 'lastPage') : null
105
+ const prevAccessor = previousParam ? getNestedAccessor(previousParam, 'firstPage') : null
105
106
  return [
106
- nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : undefined,
107
- prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : undefined,
107
+ nextAccessor ? `getNextPageParam: (lastPage) => ${nextAccessor}` : null,
108
+ prevAccessor ? `getPreviousPageParam: (firstPage) => ${prevAccessor}` : null,
108
109
  ] as const
109
110
  }
110
111
  if (cursorParam) {
@@ -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 { PluginVueQuery } from '../types.ts'
7
- import { buildRequestConfigType, getComments, resolveErrorNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
7
+ import { buildRequestConfigType, getComments, resolveErrorNames, resolveSuccessNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
8
8
 
9
9
  type Props = {
10
10
  name: string
@@ -47,7 +47,8 @@ function buildMutationParamsNode(
47
47
  },
48
48
  ): ast.FunctionParametersNode {
49
49
  const { paramsCasing, dataReturnType, resolver } = options
50
- const responseName = resolver.resolveResponseName(node)
50
+ const successNames = resolveSuccessNames(node, resolver)
51
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : resolver.resolveResponseName(node)
51
52
  const errorNames = resolveErrorNames(node, resolver)
52
53
 
53
54
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -65,7 +66,7 @@ function buildMutationParamsNode(
65
66
  type: ast.createParamsType({
66
67
  variant: 'reference',
67
68
  name: `{
68
- mutation?: MutationObserverOptions<${[TData, TError, TRequestWrapped ? `{${TRequestWrapped}}` : 'void', 'TContext'].join(', ')}> & { client?: QueryClient },
69
+ mutation?: MutationObserverOptions<${[TData, TError, TRequestWrapped ? `{${TRequestWrapped}}` : 'undefined', 'TContext'].join(', ')}> & { client?: QueryClient },
69
70
  client?: ${buildRequestConfigType(node, resolver)},
70
71
  }`,
71
72
  }),
@@ -86,7 +87,8 @@ export function Mutation({
86
87
  tsResolver,
87
88
  mutationKeyName,
88
89
  }: Props): KubbReactNode {
89
- const responseName = tsResolver.resolveResponseName(node)
90
+ const successNames = resolveSuccessNames(node, tsResolver)
91
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
90
92
  const errorNames = resolveErrorNames(node, tsResolver)
91
93
 
92
94
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -100,7 +102,7 @@ export function Mutation({
100
102
  const TRequest = hasMutationParams ? (declarationPrinter.print(mutationArgParamsNode) ?? '') : ''
101
103
  const argKeysStr = hasMutationParams ? (keysPrinter.print(mutationArgParamsNode) ?? '') : ''
102
104
 
103
- const generics = [TData, TError, TRequest ? `{${TRequest}}` : 'void', 'TContext'].join(', ')
105
+ const generics = [TData, TError, TRequest ? `{${TRequest}}` : 'undefined', 'TContext'].join(', ')
104
106
 
105
107
  const mutationKeyParamsNode = ast.createFunctionParameters({ params: [] })
106
108
  const mutationKeyParamsCall = callPrinter.print(mutationKeyParamsNode) ?? ''
@@ -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 { PluginVueQuery } from '../types.ts'
7
- import { getComments, resolveErrorNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
7
+ import { getComments, resolveErrorNames, resolveSuccessNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
8
8
  import { buildQueryKeyParamsNode } from './QueryKey.tsx'
9
9
  import { getQueryOptionsParams } from './QueryOptions.tsx'
10
10
 
@@ -35,8 +35,9 @@ function buildQueryParamsNode(
35
35
  },
36
36
  ): ast.FunctionParametersNode {
37
37
  const { paramsType, paramsCasing, pathParamsType, dataReturnType, resolver } = options
38
- const responseName = resolver.resolveResponseName(node)
39
- 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
40
41
  const errorNames = resolveErrorNames(node, resolver)
41
42
 
42
43
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -78,7 +79,8 @@ export function Query({
78
79
  node,
79
80
  tsResolver,
80
81
  }: Props): KubbReactNode {
81
- const responseName = tsResolver.resolveResponseName(node)
82
+ const successNames = resolveSuccessNames(node, tsResolver)
83
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
82
84
  const errorNames = resolveErrorNames(node, tsResolver)
83
85
 
84
86
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -14,7 +14,7 @@ type Props = {
14
14
  tsResolver: ResolverTs
15
15
  paramsCasing: 'camelcase' | undefined
16
16
  pathParamsType: 'object' | 'inline'
17
- transformer: Transformer | undefined
17
+ transformer: Transformer | null | undefined
18
18
  }
19
19
 
20
20
  const declarationPrinter = functionPrinter({ mode: 'declaration' })
@@ -26,10 +26,10 @@ export function buildQueryKeyParamsNode(
26
26
  return wrapWithMaybeRefOrGetter(buildQueryKeyParams(node, options))
27
27
  }
28
28
 
29
- export function QueryKey({ name, node, tsResolver, paramsCasing, pathParamsType, typeName, transformer = queryKeyTransformer }: Props): KubbReactNode {
29
+ export function QueryKey({ name, node, tsResolver, paramsCasing, pathParamsType, typeName, transformer }: Props): KubbReactNode {
30
30
  const paramsNode = buildQueryKeyParamsNode(node, { pathParamsType, paramsCasing, resolver: tsResolver })
31
31
  const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
32
- const keys = transformer({
32
+ const keys = (transformer ?? queryKeyTransformer)({
33
33
  node,
34
34
  casing: paramsCasing,
35
35
  })
@@ -5,7 +5,7 @@ import { File, Function } from '@kubb/renderer-jsx'
5
5
  import type { KubbReactNode } from '@kubb/renderer-jsx/types'
6
6
  import { buildEnabledCheck } from '@internals/tanstack-query'
7
7
  import type { PluginVueQuery } from '../types.ts'
8
- import { resolveErrorNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
8
+ import { resolveErrorNames, resolveSuccessNames, wrapWithMaybeRefOrGetter } from '../utils.ts'
9
9
  import { buildQueryKeyParamsNode } from './QueryKey.tsx'
10
10
 
11
11
  type Props = {
@@ -33,7 +33,7 @@ export function getQueryOptionsParams(
33
33
  },
34
34
  ): ast.FunctionParametersNode {
35
35
  const { paramsType, paramsCasing, pathParamsType, resolver } = options
36
- const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : undefined
36
+ const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null
37
37
 
38
38
  const baseParams = ast.createOperationParams(node, {
39
39
  paramsType,
@@ -66,7 +66,8 @@ export function QueryOptions({
66
66
  pathParamsType,
67
67
  queryKeyName,
68
68
  }: Props): KubbReactNode {
69
- const responseName = tsResolver.resolveResponseName(node)
69
+ const successNames = resolveSuccessNames(node, tsResolver)
70
+ const responseName = successNames.length > 0 ? successNames.join(' | ') : tsResolver.resolveResponseName(node)
70
71
  const errorNames = resolveErrorNames(node, tsResolver)
71
72
 
72
73
  const TData = dataReturnType === 'data' ? responseName : `ResponseConfig<${responseName}>`
@@ -10,6 +10,12 @@ import { difference } from 'remeda'
10
10
  import { InfiniteQuery, InfiniteQueryOptions, QueryKey } from '../components'
11
11
  import type { PluginVueQuery } from '../types'
12
12
 
13
+ /**
14
+ * Built-in generator for `useInfiniteQuery` composables. Enabled when
15
+ * `pluginVueQuery({ infinite: { ... } })`. Emits one `useFooInfiniteQuery`
16
+ * composable per query operation, wiring the configured cursor path into
17
+ * TanStack Query's cursor-based pagination.
18
+ */
13
19
  export const infiniteQueryGenerator = defineGenerator<PluginVueQuery>({
14
20
  name: 'vue-query-infinite',
15
21
  renderer: jsxRendererSync,
@@ -26,7 +32,7 @@ export const infiniteQueryGenerator = defineGenerator<PluginVueQuery>({
26
32
  mutation !== false &&
27
33
  !isQuery &&
28
34
  difference(mutation ? mutation.methods : [], query ? query.methods : []).some((method) => node.method.toLowerCase() === method.toLowerCase())
29
- const infiniteOptions = infinite && typeof infinite === 'object' ? infinite : undefined
35
+ const infiniteOptions = infinite && typeof infinite === 'object' ? infinite : null
30
36
 
31
37
  if (!isQuery || isMutation || !infiniteOptions) return null
32
38
 
@@ -48,10 +54,13 @@ export const infiniteQueryGenerator = defineGenerator<PluginVueQuery>({
48
54
  const clientBaseName = resolver.resolveInfiniteClientName(node)
49
55
 
50
56
  const meta = {
51
- file: resolver.resolveFile({ name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
57
+ file: resolver.resolveFile(
58
+ { name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
59
+ { root, output, group: group ?? undefined },
60
+ ),
52
61
  fileTs: tsResolver.resolveFile(
53
62
  { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
54
- { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
63
+ { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group ?? undefined },
55
64
  ),
56
65
  }
57
66
 
@@ -61,20 +70,20 @@ export const infiniteQueryGenerator = defineGenerator<PluginVueQuery>({
61
70
  order: 'body-response-first',
62
71
  })
63
72
 
64
- const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
65
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
73
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
74
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
66
75
  const fileZod = zodResolver
67
76
  ? zodResolver.resolveFile(
68
77
  { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
69
- { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
78
+ { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group ?? undefined },
70
79
  )
71
- : undefined
80
+ : null
72
81
  const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
73
82
 
74
83
  const clientPlugin = driver.getPlugin(pluginClientName)
75
84
  const hasClientPlugin = clientPlugin?.name === pluginClientName
76
85
  const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
77
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : undefined
86
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null
78
87
 
79
88
  const clientFile = shouldUseClientPlugin
80
89
  ? clientResolver?.resolveFile(
@@ -82,10 +91,10 @@ export const infiniteQueryGenerator = defineGenerator<PluginVueQuery>({
82
91
  {
83
92
  root,
84
93
  output: clientPlugin?.options?.output ?? output,
85
- group: clientPlugin?.options?.group,
94
+ group: clientPlugin?.options?.group ?? undefined,
86
95
  },
87
96
  )
88
- : undefined
97
+ : null
89
98
 
90
99
  const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientBaseName) : clientBaseName
91
100
 
@@ -10,6 +10,11 @@ import { difference } from 'remeda'
10
10
  import { Mutation, MutationKey } from '../components'
11
11
  import type { PluginVueQuery } from '../types'
12
12
 
13
+ /**
14
+ * Built-in generator for `useMutation` composables. Emits one
15
+ * `useFooMutation` composable per POST/PUT/DELETE operation (configurable
16
+ * via `mutation.methods`) plus the matching `fooMutationKey` helper.
17
+ */
13
18
  export const mutationGenerator = defineGenerator<PluginVueQuery>({
14
19
  name: 'vue-query-mutation',
15
20
  renderer: jsxRendererSync,
@@ -37,29 +42,32 @@ export const mutationGenerator = defineGenerator<PluginVueQuery>({
37
42
  const clientName = resolver.resolveClientName(node)
38
43
 
39
44
  const meta = {
40
- file: resolver.resolveFile({ name: mutationHookName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
45
+ file: resolver.resolveFile(
46
+ { name: mutationHookName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
47
+ { root, output, group: group ?? undefined },
48
+ ),
41
49
  fileTs: tsResolver.resolveFile(
42
50
  { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
43
- { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
51
+ { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group ?? undefined },
44
52
  ),
45
53
  }
46
54
 
47
55
  const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing, order: 'body-response-first' })
48
56
 
49
- const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
50
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
57
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
58
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
51
59
  const fileZod = zodResolver
52
60
  ? zodResolver.resolveFile(
53
61
  { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
54
- { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
62
+ { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group ?? undefined },
55
63
  )
56
- : undefined
64
+ : null
57
65
  const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
58
66
 
59
67
  const clientPlugin = driver.getPlugin(pluginClientName)
60
68
  const hasClientPlugin = clientPlugin?.name === pluginClientName
61
69
  const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
62
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : undefined
70
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null
63
71
 
64
72
  const clientFile = shouldUseClientPlugin
65
73
  ? clientResolver?.resolveFile(
@@ -67,10 +75,10 @@ export const mutationGenerator = defineGenerator<PluginVueQuery>({
67
75
  {
68
76
  root,
69
77
  output: clientPlugin?.options?.output ?? output,
70
- group: clientPlugin?.options?.group,
78
+ group: clientPlugin?.options?.group ?? undefined,
71
79
  },
72
80
  )
73
- : undefined
81
+ : null
74
82
 
75
83
  const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
76
84
 
@@ -10,6 +10,11 @@ import { difference } from 'remeda'
10
10
  import { Query, QueryKey, QueryOptions } from '../components'
11
11
  import type { PluginVueQuery } from '../types'
12
12
 
13
+ /**
14
+ * Built-in generator for `useQuery` composables. Emits one `useFooQuery`
15
+ * composable per GET operation (configurable via `query.methods`) plus the
16
+ * matching `fooQueryKey` / `fooQueryOptions` helpers.
17
+ */
13
18
  export const queryGenerator = defineGenerator<PluginVueQuery>({
14
19
  name: 'vue-query',
15
20
  renderer: jsxRendererSync,
@@ -38,10 +43,13 @@ export const queryGenerator = defineGenerator<PluginVueQuery>({
38
43
  const clientName = resolver.resolveClientName(node)
39
44
 
40
45
  const meta = {
41
- file: resolver.resolveFile({ name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
46
+ file: resolver.resolveFile(
47
+ { name: queryName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
48
+ { root, output, group: group ?? undefined },
49
+ ),
42
50
  fileTs: tsResolver.resolveFile(
43
51
  { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
44
- { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
52
+ { root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group ?? undefined },
45
53
  ),
46
54
  }
47
55
 
@@ -51,20 +59,20 @@ export const queryGenerator = defineGenerator<PluginVueQuery>({
51
59
  order: 'body-response-first',
52
60
  })
53
61
 
54
- const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : undefined
55
- const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : undefined
62
+ const pluginZod = parser === 'zod' ? driver.getPlugin(pluginZodName) : null
63
+ const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null
56
64
  const fileZod = zodResolver
57
65
  ? zodResolver.resolveFile(
58
66
  { name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
59
- { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group },
67
+ { root, output: pluginZod?.options?.output ?? output, group: pluginZod?.options?.group ?? undefined },
60
68
  )
61
- : undefined
69
+ : null
62
70
  const zodSchemaNames = resolveZodSchemaNames(node, zodResolver)
63
71
 
64
72
  const clientPlugin = driver.getPlugin(pluginClientName)
65
73
  const hasClientPlugin = clientPlugin?.name === pluginClientName
66
74
  const shouldUseClientPlugin = hasClientPlugin && clientOptions.clientType !== 'class'
67
- const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : undefined
75
+ const clientResolver = shouldUseClientPlugin ? driver.getResolver(pluginClientName) : null
68
76
 
69
77
  const clientFile = shouldUseClientPlugin
70
78
  ? clientResolver?.resolveFile(
@@ -72,10 +80,10 @@ export const queryGenerator = defineGenerator<PluginVueQuery>({
72
80
  {
73
81
  root,
74
82
  output: clientPlugin?.options?.output ?? output,
75
- group: clientPlugin?.options?.group,
83
+ group: clientPlugin?.options?.group ?? undefined,
76
84
  },
77
85
  )
78
- : undefined
86
+ : null
79
87
 
80
88
  const resolvedClientName = shouldUseClientPlugin ? (clientResolver?.resolveName(node.operationId) ?? clientName) : clientName
81
89
 
package/src/plugin.ts CHANGED
@@ -13,8 +13,36 @@ import { infiniteQueryGenerator, mutationGenerator, queryGenerator } from './gen
13
13
  import { resolverVueQuery } from './resolvers/resolverVueQuery.ts'
14
14
  import type { PluginVueQuery } from './types.ts'
15
15
 
16
+ /**
17
+ * Canonical plugin name for `@kubb/plugin-vue-query`. Used for driver lookups
18
+ * and cross-plugin dependency references.
19
+ */
16
20
  export const pluginVueQueryName = 'plugin-vue-query' satisfies PluginVueQuery['name']
17
21
 
22
+ /**
23
+ * Generates one TanStack Query composable per OpenAPI operation for Vue's
24
+ * Composition API. Queries become `useFooQuery` (and optionally
25
+ * `useFooInfiniteQuery`); mutations become `useFooMutation`. Each composable
26
+ * is fully typed end to end.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { defineConfig } from 'kubb'
31
+ * import { pluginTs } from '@kubb/plugin-ts'
32
+ * import { pluginVueQuery } from '@kubb/plugin-vue-query'
33
+ *
34
+ * export default defineConfig({
35
+ * input: { path: './petStore.yaml' },
36
+ * output: { path: './src/gen' },
37
+ * plugins: [
38
+ * pluginTs(),
39
+ * pluginVueQuery({
40
+ * output: { path: './hooks' },
41
+ * }),
42
+ * ],
43
+ * })
44
+ * ```
45
+ */
18
46
  export const pluginVueQuery = definePlugin<PluginVueQuery>((options) => {
19
47
  const {
20
48
  output = { path: 'hooks', barrelType: 'named' },
@@ -56,7 +84,7 @@ export const pluginVueQuery = definePlugin<PluginVueQuery>((options) => {
56
84
  return `${camelCase(ctx.group)}Controller`
57
85
  },
58
86
  } satisfies Group)
59
- : undefined
87
+ : null
60
88
 
61
89
  return {
62
90
  name: pluginVueQueryName,
@@ -99,9 +127,9 @@ export const pluginVueQuery = definePlugin<PluginVueQuery>((options) => {
99
127
  ? {
100
128
  queryParam: 'id',
101
129
  initialPageParam: 0,
102
- cursorParam: undefined,
103
- nextParam: undefined,
104
- previousParam: undefined,
130
+ cursorParam: null,
131
+ nextParam: null,
132
+ previousParam: null,
105
133
  ...infinite,
106
134
  }
107
135
  : false,
@@ -7,9 +7,20 @@ function capitalize(name: string): string {
7
7
  }
8
8
 
9
9
  /**
10
- * Naming convention resolver for Vue Query plugin.
10
+ * Default resolver used by `@kubb/plugin-vue-query`. Decides the names and
11
+ * file paths for every generated TanStack Query composable (`useFooQuery`,
12
+ * `useFooMutation`, `useFooInfiniteQuery`) and its companion helpers.
11
13
  *
12
- * Provides default naming helpers using camelCase for functions and file paths.
14
+ * Functions and files use camelCase; composables get the `use` prefix.
15
+ *
16
+ * @example Resolve composable and helper names
17
+ * ```ts
18
+ * import { resolverVueQuery } from '@kubb/plugin-vue-query'
19
+ *
20
+ * resolverVueQuery.resolveQueryName(operationNode) // 'useGetPetById'
21
+ * resolverVueQuery.resolveQueryKeyName(operationNode) // 'getPetByIdQueryKey'
22
+ * resolverVueQuery.resolveQueryOptionsName(operationNode) // 'getPetByIdQueryOptions'
23
+ * ```
13
24
  */
14
25
  export const resolverVueQuery = defineResolver<PluginVueQuery>(() => ({
15
26
  name: 'default',