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

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 (38) hide show
  1. package/dist/{components-DycYiYNM.cjs → components-CeZrYaZj.cjs} +35 -35
  2. package/dist/components-CeZrYaZj.cjs.map +1 -0
  3. package/dist/{components-CARlYXLX.js → components-CpTXuQiK.js} +35 -35
  4. package/dist/components-CpTXuQiK.js.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-DX8VWz4a.cjs → generators-BSMwPpbh.cjs} +46 -30
  9. package/dist/generators-BSMwPpbh.cjs.map +1 -0
  10. package/dist/{generators-BuDRi6qN.js → generators-Cb5_nhMY.js} +46 -30
  11. package/dist/generators-Cb5_nhMY.js.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 +1 -1
  24. package/src/components/InfiniteQueryOptions.tsx +8 -8
  25. package/src/components/Mutation.tsx +2 -2
  26. package/src/components/Query.tsx +1 -1
  27. package/src/components/QueryKey.tsx +3 -3
  28. package/src/components/QueryOptions.tsx +1 -1
  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/dist/components-CARlYXLX.js.map +0 -1
  36. package/dist/components-DycYiYNM.cjs.map +0 -1
  37. package/dist/generators-BuDRi6qN.js.map +0 -1
  38. package/dist/generators-DX8VWz4a.cjs.map +0 -1
package/extension.yaml CHANGED
@@ -2,7 +2,7 @@ $schema: https://kubb.dev/schemas/extension.json
2
2
  kind: plugin
3
3
  id: plugin-vue-query
4
4
  name: Vue Query
5
- description: Generate Vue Query composables from OpenAPI specifications.
5
+ description: Generate TanStack Query composables for Vue (useQuery, useMutation, useInfiniteQuery) from OpenAPI.
6
6
  category: framework
7
7
  type: official
8
8
  npmPackage: '@kubb/plugin-vue-query'
@@ -37,162 +37,424 @@ icon:
37
37
  intro: |
38
38
  # @kubb/plugin-vue-query
39
39
 
40
- Generate type-safe Vue Query composables from your OpenAPI schema for data fetching, caching, and synchronization.
40
+ Generate one [TanStack Query](https://tanstack.com/query) composable per OpenAPI operation, ready to use inside Vue's Composition API. Queries become `useFooQuery` (and optionally `useFooInfiniteQuery`); mutations become `useFooMutation`. Each composable is fully typed end to end.
41
+
42
+ Pairs with `@kubb/plugin-client` for the HTTP layer and `@kubb/plugin-ts` for types.
41
43
  options:
42
44
  - name: output
43
45
  type: Output
44
46
  required: false
45
47
  default: "{ path: 'hooks', barrel: { type: 'named' } }"
46
- description: Specify the export location for the files and define the behavior of the output.
48
+ description: Where the generated composables are written and how they are exported.
47
49
  properties:
48
50
  - name: path
49
51
  type: string
50
52
  required: true
51
- description: Output directory or file for the generated code, relative to the global `output.path`.
53
+ description: |
54
+ Folder (or single file) where the plugin writes its generated code. The path is resolved against the global `output.path` set on `defineConfig`.
55
+
56
+ Use a folder to keep each generator's output isolated (`'types'`, `'clients'`, `'hooks'`). Use a single file when you want everything in one place, for example `'api.ts'`.
52
57
  tip: |
53
- if `output.path` is a file, `group` cannot be used.
58
+ When `output.path` points to a single file, the `group` option cannot be used because every operation ends up in the same file.
59
+ examples:
60
+ - name: kubb.config.ts
61
+ files:
62
+ - lang: typescript
63
+ twoslash: false
64
+ code: |
65
+ import { defineConfig } from 'kubb'
66
+ import { pluginTs } from '@kubb/plugin-ts'
67
+
68
+ export default defineConfig({
69
+ input: { path: './petStore.yaml' },
70
+ output: { path: './src/gen' },
71
+ plugins: [
72
+ pluginTs({
73
+ output: { path: './types' },
74
+ }),
75
+ ],
76
+ })
77
+ - name: Resulting tree
78
+ files:
79
+ - lang: text
80
+ twoslash: false
81
+ code: |
82
+ src/
83
+ └── gen/
84
+ └── types/
85
+ ├── Pet.ts
86
+ └── Store.ts
54
87
  default: "'hooks'"
55
88
  - name: barrel
56
89
  type: "{ type: 'named' | 'all', nested?: boolean } | false"
57
90
  required: false
58
91
  default: "{ type: 'named' }"
59
- description: 'Configure barrel file export strategy. Use `type` to control named vs. wildcard exports; set `nested: true` to generate hierarchical barrels in subdirectories.'
92
+ description: |
93
+ Controls how the generated `index.ts` (barrel) file re-exports the plugin's output.
94
+
95
+ - `{ type: 'named' }` re-exports each symbol by name. Best for tree-shaking and explicit imports.
96
+ - `{ type: 'all' }` uses `export *`. Smaller barrel file, but exports everything.
97
+ - `{ nested: true }` creates a barrel in every subdirectory, so callers can import from any depth.
98
+ - `false` skips the barrel entirely. The plugin's files are also excluded from the root `index.ts`.
99
+ tip: |
100
+ Pick `'named'` when consumers care about which symbols they import (better tree-shaking, friendlier auto-import). Pick `'all'` when the file count is small and you want a one-line barrel.
60
101
  examples:
61
- - name: all
102
+ - name: "'named' (default)"
62
103
  files:
63
- - lang: typescript
104
+ - name: kubb.config.ts
105
+ lang: typescript
106
+ twoslash: false
64
107
  code: |
65
- export * from './gen/petService.ts'
108
+ import { defineConfig } from 'kubb'
109
+ import { pluginTs } from '@kubb/plugin-ts'
110
+
111
+ export default defineConfig({
112
+ input: { path: './petStore.yaml' },
113
+ output: { path: './src/gen' },
114
+ plugins: [
115
+ pluginTs({
116
+ output: { barrel: { type: 'named' } },
117
+ }),
118
+ ],
119
+ })
120
+ - name: src/gen/types/index.ts
121
+ lang: typescript
66
122
  twoslash: false
67
- - name: named
123
+ code: |
124
+ export { Pet, PetStatus } from './Pet'
125
+ export { Store } from './Store'
126
+ - name: "'all'"
68
127
  files:
69
- - lang: typescript
128
+ - name: kubb.config.ts
129
+ lang: typescript
130
+ twoslash: false
70
131
  code: |
71
- export { PetService } from './gen/petService.ts'
132
+ import { defineConfig } from 'kubb'
133
+ import { pluginTs } from '@kubb/plugin-ts'
134
+
135
+ export default defineConfig({
136
+ input: { path: './petStore.yaml' },
137
+ output: { path: './src/gen' },
138
+ plugins: [
139
+ pluginTs({
140
+ output: { barrel: { type: 'all' } },
141
+ }),
142
+ ],
143
+ })
144
+ - name: src/gen/types/index.ts
145
+ lang: typescript
72
146
  twoslash: false
147
+ code: |
148
+ export * from './Pet'
149
+ export * from './Store'
73
150
  - name: nested
74
151
  files:
75
152
  - name: kubb.config.ts
76
153
  lang: typescript
154
+ twoslash: false
77
155
  code: |
78
- output: {
79
- path: './gen',
80
- barrel: { type: 'named', nested: true },
81
- }
156
+ import { defineConfig } from 'kubb'
157
+ import { pluginTs } from '@kubb/plugin-ts'
158
+
159
+ export default defineConfig({
160
+ input: { path: './petStore.yaml' },
161
+ output: { path: './src/gen' },
162
+ plugins: [
163
+ pluginTs({
164
+ output: { barrel: { type: 'named', nested: true } },
165
+ }),
166
+ ],
167
+ })
168
+ - name: Generated tree
169
+ lang: text
82
170
  twoslash: false
171
+ code: |
172
+ src/gen/types/
173
+ ├── index.ts # re-exports ./petController and ./storeController
174
+ ├── petController/
175
+ │ ├── index.ts # re-exports Pet, Store, ...
176
+ │ └── Pet.ts
177
+ └── storeController/
178
+ ├── index.ts
179
+ └── Store.ts
83
180
  - name: 'false'
84
181
  files:
85
- - lang: typescript
86
- code: ''
182
+ - name: kubb.config.ts
183
+ lang: typescript
184
+ twoslash: false
185
+ code: |
186
+ import { defineConfig } from 'kubb'
187
+ import { pluginTs } from '@kubb/plugin-ts'
188
+
189
+ export default defineConfig({
190
+ input: { path: './petStore.yaml' },
191
+ output: { path: './src/gen' },
192
+ plugins: [
193
+ pluginTs({
194
+ output: { barrel: false },
195
+ }),
196
+ ],
197
+ })
198
+ - name: Result
199
+ lang: text
87
200
  twoslash: false
201
+ code: |
202
+ # No index.ts is generated for this plugin.
203
+ # Its files are also excluded from the root index.ts.
88
204
  - name: banner
89
205
  type: 'string | ((node: RootNode) => string)'
90
206
  required: false
91
- description: Add a banner comment at the top of every generated file. Accepts a static string or a function that receives the `RootNode` and returns a string.
207
+ description: |
208
+ Text prepended to every generated file. Useful for license headers, lint disables, or `@ts-nocheck` directives.
209
+
210
+ Pass a string for a static banner. Pass a function to compute the banner from each file's `RootNode` (the AST root containing path, schema, and operation context).
211
+ examples:
212
+ - name: Static banner
213
+ files:
214
+ - name: kubb.config.ts
215
+ lang: typescript
216
+ twoslash: false
217
+ code: |
218
+ import { defineConfig } from 'kubb'
219
+ import { pluginTs } from '@kubb/plugin-ts'
220
+
221
+ export default defineConfig({
222
+ input: { path: './petStore.yaml' },
223
+ output: { path: './src/gen' },
224
+ plugins: [
225
+ pluginTs({
226
+ output: {
227
+ banner: '/* eslint-disable */\n// @ts-nocheck',
228
+ },
229
+ }),
230
+ ],
231
+ })
232
+ - name: Generated file
233
+ lang: typescript
234
+ twoslash: false
235
+ code: |
236
+ /* eslint-disable */
237
+ // @ts-nocheck
238
+ export type Pet = {
239
+ id: number
240
+ name: string
241
+ }
242
+ - name: Dynamic banner
243
+ files:
244
+ - name: kubb.config.ts
245
+ lang: typescript
246
+ twoslash: false
247
+ code: |
248
+ import { defineConfig } from 'kubb'
249
+ import { pluginTs } from '@kubb/plugin-ts'
250
+
251
+ export default defineConfig({
252
+ input: { path: './petStore.yaml' },
253
+ output: { path: './src/gen' },
254
+ plugins: [
255
+ pluginTs({
256
+ output: {
257
+ banner: (node) => `// Source: ${node.path}\n// Generated at ${new Date().toISOString()}`,
258
+ },
259
+ }),
260
+ ],
261
+ })
92
262
  - name: footer
93
263
  type: 'string | ((node: RootNode) => string)'
94
264
  required: false
95
- description: Add a footer comment at the end of every generated file. Accepts a static string or a function that receives the `RootNode` and returns a string.
265
+ description: |
266
+ Text appended at the end of every generated file. The mirror of `banner` — use it for closing comments, re-enabling lint rules, or marker lines.
267
+
268
+ Pass a string for a static footer, or a function that receives the file's `RootNode` and returns the footer text.
269
+ examples:
270
+ - name: Re-enable lint after a banner disable
271
+ files:
272
+ - name: kubb.config.ts
273
+ lang: typescript
274
+ twoslash: false
275
+ code: |
276
+ import { defineConfig } from 'kubb'
277
+ import { pluginTs } from '@kubb/plugin-ts'
278
+
279
+ export default defineConfig({
280
+ input: { path: './petStore.yaml' },
281
+ output: { path: './src/gen' },
282
+ plugins: [
283
+ pluginTs({
284
+ output: {
285
+ banner: '/* eslint-disable */',
286
+ footer: '/* eslint-enable */',
287
+ },
288
+ }),
289
+ ],
290
+ })
96
291
  - name: override
97
292
  type: boolean
98
293
  required: false
99
294
  default: 'false'
100
- description: Whether Kubb overrides existing external files that can be generated if they already exist.
295
+ description: |
296
+ Allows the plugin to overwrite hand-written files that share a name with a generated file.
297
+
298
+ - `false` (default): Kubb skips a file if it already exists and is not marked as generated. This protects manual edits.
299
+ - `true`: Kubb overwrites any file at the target path, including hand-written ones.
300
+ warning: |
301
+ Enable this only when you are sure the target folder contains nothing you need to keep. Local edits are lost on the next generation.
302
+ examples:
303
+ - name: kubb.config.ts
304
+ files:
305
+ - lang: typescript
306
+ twoslash: false
307
+ code: |
308
+ import { defineConfig } from 'kubb'
309
+ import { pluginTs } from '@kubb/plugin-ts'
310
+
311
+ export default defineConfig({
312
+ input: { path: './petStore.yaml' },
313
+ output: { path: './src/gen' },
314
+ plugins: [
315
+ pluginTs({
316
+ output: { override: true },
317
+ }),
318
+ ],
319
+ })
101
320
  - name: contentType
102
321
  type: "'application/json' | (string & {})"
103
322
  required: false
104
323
  description: |
105
- Define which content type to use.
324
+ Selects which request/response media type the generator reads from the OpenAPI spec.
106
325
 
107
- By default, Kubb uses the first JSON-valid media type.
326
+ When omitted, Kubb picks the first JSON-compatible media type it finds (`application/json`, `application/vnd.api+json`, anything ending in `+json`). Set this when your spec defines multiple media types for the same operation and you want a non-default one.
327
+ examples:
328
+ - name: JSON API media type
329
+ files:
330
+ - lang: typescript
331
+ twoslash: false
332
+ code: |
333
+ import { defineConfig } from 'kubb'
334
+ import { pluginTs } from '@kubb/plugin-ts'
335
+
336
+ export default defineConfig({
337
+ input: { path: './petStore.yaml' },
338
+ output: { path: './src/gen' },
339
+ plugins: [
340
+ pluginTs({
341
+ contentType: 'application/vnd.api+json',
342
+ }),
343
+ ],
344
+ })
108
345
  - name: group
109
346
  type: Group
110
347
  required: false
111
348
  description: |
112
- Grouping combines files in a folder based on a specific `type`.
349
+ Splits generated files into subfolders based on the operation's tag, so each tag in your OpenAPI spec gets its own directory.
350
+
351
+ Without `group`, every file lands in the plugin's `output.path` folder. With `group`, files are bucketed under `{output.path}/{groupName}/`, where `groupName` is derived from the operation's first tag.
352
+ tip: |
353
+ Use `group` to mirror your API's domain structure (pet, store, user) in the generated code. Combine it with `output.barrel: { type: 'named', nested: true }` to get per-tag barrel files.
113
354
  examples:
114
355
  - name: kubb.config.ts
115
356
  files:
116
357
  - lang: typescript
117
- code: |
118
- group: {
119
- type: 'tag',
120
- name({ group }) {
121
- return `${group}Controller`
122
- }
123
- }
124
358
  twoslash: false
359
+ code: |
360
+ import { defineConfig } from 'kubb'
361
+ import { pluginTs } from '@kubb/plugin-ts'
362
+
363
+ export default defineConfig({
364
+ input: { path: './petStore.yaml' },
365
+ output: { path: './src/gen' },
366
+ plugins: [
367
+ pluginTs({
368
+ group: {
369
+ type: 'tag',
370
+ name: ({ group }) => `${group}Controller`,
371
+ },
372
+ }),
373
+ ],
374
+ })
125
375
  body: |
126
376
  With the configuration above, the generator emits:
127
377
 
128
378
  ```text
129
- .
130
- ├── src/
131
- └── petController/
132
- │ ├── addPet.ts
133
- │ │ └── getPet.ts
134
- │ └── storeController/
135
- │ ├── createStore.ts
136
- │ └── getStoreById.ts
137
- ├── petStore.yaml
138
- ├── kubb.config.ts
139
- └── package.json
379
+ src/gen/
380
+ ├── petController/
381
+ ├── AddPet.ts
382
+ └── GetPet.ts
383
+ └── storeController/
384
+ ├── CreateStore.ts
385
+ └── GetStoreById.ts
140
386
  ```
141
387
  properties:
142
388
  - name: type
143
389
  type: "'tag'"
144
390
  required: true
145
- description: Specify the property to group files by. Required when `group` is defined.
391
+ description: |
392
+ Property used to assign each operation to a group. Required whenever `group` is set.
393
+
394
+ Today only `'tag'` is supported: Kubb reads the first tag on the operation (`operation.getTags().at(0)?.name`) and uses it as the group key. Operations without a tag are placed in a default group.
146
395
  note: |
147
- `Required: true*` means this is required only when the `group` option is used. The `group` option itself is optional.
148
- body: |
149
- - `'tag'`: Uses the first tag from `operation.getTags().at(0)?.name`
396
+ `Required: true*` is conditional only required when the parent `group` option is used. `group` itself stays optional.
150
397
  - name: name
151
398
  type: '(context: GroupContext) => string'
152
399
  required: false
153
400
  default: (ctx) => `${ctx.group}Controller`
154
- description: Return the name of a group based on the group name. This is used for file and identifier generation.
401
+ description: Function that builds the folder/identifier name from a group key (the operation's first tag).
155
402
  - name: client
156
403
  type: ClientImportPath & { clientType?, dataReturnType?, baseURL?, bundle?, paramsCasing? }
157
404
  required: false
158
- description: Client configuration for HTTP request generation.
405
+ description: |
406
+ HTTP client used inside every generated composable. Each composable calls into this client to perform the request.
407
+
408
+ Mirrors a subset of `pluginClient` options. Set these here when the Vue composables need different client behavior than the rest of your app.
159
409
  properties:
160
410
  - name: importPath
161
411
  type: string
162
412
  required: false
163
- description: Path to the client used for API calls. Supports both relative and absolute paths.
413
+ description: |
414
+ Path or module specifier of a custom client module. Generated code imports its HTTP runtime from here instead of `@kubb/plugin-client/clients/{client}`.
415
+
416
+ Use this when you need to inject auth headers, add interceptors, change the base URL at runtime, or wrap a different HTTP library (ky, ofetch, ...). Both relative paths (`./src/client.ts`) and bare specifiers (`@my-org/api-client`) work.
164
417
  details:
165
418
  - title: When to use `importPath`
166
419
  body: |
167
- Use `importPath` when you want to:
420
+ Reach for a custom client when you need to:
168
421
 
169
- - **Customize the HTTP client**: Provide your own client implementation with custom configurations (e.g., baseURL, headers, interceptors)
170
- - **Add authentication**: Include authentication tokens or other security mechanisms in your client
171
- - **Override default behavior**: Replace the default Kubb client with your own implementation
422
+ - Add an auth token to every request.
423
+ - Plug in interceptors, retries, or logging.
424
+ - Configure `baseURL` and headers from environment variables.
425
+ - Wrap a library other than `axios`/`fetch`.
172
426
  - title: Default behavior
173
427
  body: |
174
- When `importPath` is not specified:
428
+ Without `importPath`:
175
429
 
176
- - If `bundle: false` (default): Uses `@kubb/plugin-client/clients/${client}` where client is either `axios` or `fetch`.
177
- - If `bundle: true`: Bundles the client into `.kubb/fetch.ts`.
178
- - title: Import structure
179
- body: 'Generated code imports the client as a default import and the runtime types as named type imports:'
430
+ - `bundle: false` (default) generated code imports from `@kubb/plugin-client/clients/{axios|fetch}`.
431
+ - `bundle: true` Kubb writes `.kubb/fetch.ts` (or `.kubb/axios.ts`) and generated code imports from there.
432
+ - title: Required exports
433
+ body: |
434
+ The module pointed to by `importPath` must satisfy the same shape as the built-in client. At minimum:
435
+
436
+ - A default export of the `client` function.
437
+ - A `RequestConfig` type.
438
+ - A `ResponseErrorConfig` type.
439
+
440
+ When used together with a query plugin (`@kubb/plugin-react-query`, `@kubb/plugin-vue-query`), it must also export a `Client` type alias.
441
+ - title: How generated files import it
442
+ body: |
443
+ Generated code imports the client as a default import and the runtime types as named type imports:
180
444
  codeBlock:
181
445
  lang: typescript
182
- code: |-
183
- /**
184
- * Generated by Kubb (https://kubb.dev/).
185
- * Do not edit manually.
186
- */
446
+ code: |
187
447
  import client from '${client.importPath}'
188
448
  import type { RequestConfig, ResponseErrorConfig } from '${client.importPath}'
189
- // ... rest of generated file
449
+ // ... rest of the generated file
190
450
  important: |
191
- When using `importPath` with query plugins such as `@kubb/plugin-react-query` or `@kubb/plugin-vue-query`, the generated hooks also import a `Client` type alongside `RequestConfig` and `ResponseErrorConfig` from the custom module. Your custom client module **must** export all three typesif any is missing, TypeScript will report an unresolvable import error.
451
+ When used with query plugins (`@kubb/plugin-react-query`, `@kubb/plugin-vue-query`), generated hooks also import a `Client` type alias. Your module **must** export `Client`, `RequestConfig`, and `ResponseErrorConfig` — TypeScript will fail the import otherwise.
192
452
  codeBlock:
193
453
  lang: typescript
194
- title: client.ts
454
+ title: src/client.ts
195
455
  code: |
456
+ import axios from 'axios'
457
+
196
458
  export type RequestConfig<TData = unknown> = {
197
459
  url?: string
198
460
  method: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE'
@@ -211,96 +473,191 @@ options:
211
473
 
212
474
  export type ResponseErrorConfig<TError = unknown> = TError
213
475
 
214
- // The Client type alias is required when using query plugins
476
+ // Required when used with @kubb/plugin-react-query or @kubb/plugin-vue-query
215
477
  export type Client = <TData, _TError = unknown, TVariables = unknown>(
216
- config: RequestConfig<TVariables>
478
+ config: RequestConfig<TVariables>,
217
479
  ) => Promise<ResponseConfig<TData>>
218
480
 
219
- export const client: Client = async (config) => { /* ... */ }
481
+ const client: Client = async (config) => {
482
+ const response = await axios.request<TData>({
483
+ ...config,
484
+ headers: {
485
+ Authorization: `Bearer ${process.env.API_TOKEN}`,
486
+ ...config.headers,
487
+ },
488
+ })
489
+
490
+ return response
491
+ }
492
+
220
493
  export default client
221
494
  examples:
222
- - name: kubb.config.ts
495
+ - name: Wire up a custom client
223
496
  files:
224
- - lang: typescript
497
+ - name: kubb.config.ts
498
+ lang: typescript
499
+ twoslash: false
225
500
  code: |
226
501
  import { defineConfig } from 'kubb'
227
502
  import { pluginClient } from '@kubb/plugin-client'
228
503
 
229
504
  export default defineConfig({
230
- // ...
505
+ input: { path: './petStore.yaml' },
506
+ output: { path: './src/gen' },
231
507
  plugins: [
232
508
  pluginClient({
233
- importPath: './src/client.ts', // Path to your custom client
509
+ importPath: './src/client.ts',
234
510
  }),
235
511
  ],
236
512
  })
237
- twoslash: false
238
513
  tip: |
239
- Learn more about defining a custom client [here](https://kubb.dev/plugins/plugin-client#importpath).
514
+ See the [custom client guide](https://kubb.dev/plugins/plugin-client#importpath) for a worked example.
240
515
  - name: dataReturnType
241
516
  type: "'data' | 'full'"
242
517
  required: false
243
518
  default: "'data'"
244
519
  description: |
245
- Return type used when calling the client.
520
+ Shape of the value returned from each generated client function.
246
521
 
247
- - `'data'` returns `ResponseConfig['data']`.
248
- - `'full'` returns the full `ResponseConfig`.
522
+ - `'data'` returns only the response body (`response.data`). Concise and matches what most apps need.
523
+ - `'full'` returns the full response config — body, status code, headers, and the original request. Use this when callers need to inspect headers or status.
249
524
  examples:
250
- - name: data
525
+ - name: "'data' (default)"
251
526
  files:
252
- - lang: typescript
527
+ - name: getPetById.ts
528
+ lang: typescript
529
+ twoslash: false
253
530
  code: |
254
531
  export async function getPetById<TData>(
255
532
  petId: GetPetByIdPathParams,
256
533
  ): Promise<ResponseConfig<TData>['data']> {
257
- ...
534
+ // ...
258
535
  }
536
+ - name: usage.ts
537
+ lang: typescript
259
538
  twoslash: false
260
- - name: full
539
+ code: |
540
+ const pet = await getPetById(1)
541
+ // ^? Pet
542
+ - name: "'full'"
261
543
  files:
262
- - lang: typescript
544
+ - name: getPetById.ts
545
+ lang: typescript
546
+ twoslash: false
263
547
  code: |
264
548
  export async function getPetById<TData>(
265
549
  petId: GetPetByIdPathParams,
266
550
  ): Promise<ResponseConfig<TData>> {
267
- ...
551
+ // ...
268
552
  }
553
+ - name: usage.ts
554
+ lang: typescript
269
555
  twoslash: false
556
+ code: |
557
+ const response = await getPetById(1)
558
+ // ^? ResponseConfig<Pet>
559
+ console.log(response.status, response.headers)
560
+ const pet = response.data
270
561
  - name: baseURL
271
562
  type: string
272
563
  required: false
273
- description: Sets a custom base URL for all generated calls. When not set, the base URL is automatically taken from the OAS spec via the adapter (e.g. the `servers[0].url` field).
564
+ description: |
565
+ Base URL prepended to every request URL in the generated client. When omitted, the URL comes from the OpenAPI spec's `servers[0].url` (or whichever index the adapter is configured to read).
566
+
567
+ Set this when the generated client should point at a different environment (staging, production) than the one written in the spec.
568
+ examples:
569
+ - name: Override the spec's server URL
570
+ files:
571
+ - lang: typescript
572
+ twoslash: false
573
+ code: |
574
+ import { defineConfig } from 'kubb'
575
+ import { pluginClient } from '@kubb/plugin-client'
576
+
577
+ export default defineConfig({
578
+ input: { path: './petStore.yaml' },
579
+ output: { path: './src/gen' },
580
+ plugins: [
581
+ pluginClient({
582
+ baseURL: 'https://petstore.swagger.io/v2',
583
+ }),
584
+ ],
585
+ })
274
586
  - name: clientType
275
587
  type: "'function' | 'class'"
276
588
  required: false
277
589
  default: "'function'"
278
- description: Specify whether to use function-based or class-based clients.
590
+ description: |
591
+ Style of the HTTP client that this plugin imports from `@kubb/plugin-client`.
592
+
593
+ - `'function'` — imports the function client (`getPetById(...)`). Required for query plugins.
594
+ - `'class'` — also generates a wrapper class on top, but only usable inside `@kubb/plugin-client`.
279
595
  warning: |
280
- This plugin is only compatible with `clientType: 'function'` (the default). If `clientType: 'class'` is detected, the plugin will automatically generate its own inline function-based client instead of importing from `@kubb/plugin-client`.
596
+ Query plugins (`@kubb/plugin-react-query`, `@kubb/plugin-vue-query`, `@kubb/plugin-svelte-query`, `@kubb/plugin-solid-query`) work only with `clientType: 'function'`. If you set `clientType: 'class'` here, the plugin falls back to generating its own inline function-based client instead of importing from `@kubb/plugin-client`.
281
597
  - name: bundle
282
598
  type: boolean
283
599
  required: false
284
600
  default: 'false'
285
- description: Controls whether the HTTP client runtime is copied into the generated `.kubb` directory.
286
- body: |
287
- - `true` adds a `.kubb/fetch.ts` file containing the selected client template (fetch or axios). Generated clients remain self-contained.
288
- - `false` keeps generated clients slim by importing the shared runtime from `@kubb/plugin-client/clients/{client}`.
289
- - Override this behavior by providing a custom `client.importPath`.
601
+ description: |
602
+ Copies the HTTP client runtime into the generated output, so the consuming app does not need `@kubb/plugin-client` installed at runtime.
603
+
604
+ - `false` (default) generated files import from `@kubb/plugin-client/clients/{client}`. Smaller diff, but the package must be a runtime dependency.
605
+ - `true` Kubb writes a `.kubb/fetch.ts` (or `.kubb/axios.ts`) file with the client implementation. Generated code imports from that local file and the project no longer pulls `@kubb/plugin-client` at runtime.
606
+ - Setting `client.importPath` overrides both behaviors and uses your custom client instead.
607
+ examples:
608
+ - name: Bundle the runtime
609
+ files:
610
+ - lang: typescript
611
+ twoslash: false
612
+ code: |
613
+ import { defineConfig } from 'kubb'
614
+ import { pluginClient } from '@kubb/plugin-client'
615
+
616
+ export default defineConfig({
617
+ input: { path: './petStore.yaml' },
618
+ output: { path: './src/gen' },
619
+ plugins: [
620
+ pluginClient({
621
+ client: 'fetch',
622
+ bundle: true,
623
+ }),
624
+ ],
625
+ })
290
626
  - name: paramsType
291
627
  type: "'object' | 'inline'"
292
628
  required: false
293
629
  default: "'inline'"
294
- description: Defines how parameters are passed to generated functions. Switch between object-style parameters and inline parameters.
630
+ description: |
631
+ How operation parameters (path, query, headers) are exposed in the generated function signature.
632
+
633
+ - `'inline'` (default) — each parameter is a separate positional argument. Compact for operations with one or two params.
634
+ - `'object'` — every parameter is wrapped in a single object argument. Easier to read for operations with many params and named at the call site.
295
635
  tip: |
296
- When `paramsType` is set to `'object'`, `pathParams` will also be set to `'object'`.
297
- body: |
298
- - `'object'` returns params and pathParams as an object.
299
- - `'inline'` returns params as comma-separated params.
636
+ Setting `paramsType: 'object'` implicitly sets `pathParamsType: 'object'` as well, so call sites are consistent.
300
637
  examples:
301
- - name: object
638
+ - name: "'inline' (default)"
302
639
  files:
303
- - lang: typescript
640
+ - name: Generated client
641
+ lang: typescript
642
+ twoslash: false
643
+ code: |
644
+ export async function deletePet(
645
+ petId: DeletePetPathParams['petId'],
646
+ headers?: DeletePetHeaderParams,
647
+ config: Partial<RequestConfig> = {},
648
+ ) {
649
+ // ...
650
+ }
651
+ - name: Caller
652
+ lang: typescript
653
+ twoslash: false
654
+ code: |
655
+ await deletePet(42)
656
+ - name: "'object'"
657
+ files:
658
+ - name: Generated client
659
+ lang: typescript
660
+ twoslash: false
304
661
  code: |
305
662
  export async function deletePet(
306
663
  {
@@ -312,138 +669,149 @@ options:
312
669
  },
313
670
  config: Partial<RequestConfig> = {},
314
671
  ) {
315
- ...
672
+ // ...
316
673
  }
674
+ - name: Caller
675
+ lang: typescript
317
676
  twoslash: false
318
- - name: inline
319
- files:
320
- - lang: typescript
321
677
  code: |
322
- export async function deletePet(
323
- petId: DeletePetPathParams['petId'],
324
- headers?: DeletePetHeaderParams,
325
- config: Partial<RequestConfig> = {}
326
- ){
327
- ...
328
- }
329
- twoslash: false
678
+ await deletePet({ petId: 42, headers: { 'X-Api-Key': 'secret' } })
330
679
  - name: paramsCasing
331
680
  type: "'camelcase'"
332
681
  required: false
333
- description: Transform parameter names to a specific casing format for path, query, and header parameters in generated client code.
682
+ description: |
683
+ Renames path, query, and header parameters in the generated client to the chosen casing. The HTTP request still uses the original names from the OpenAPI spec — Kubb writes the mapping for you.
684
+
685
+ - `'camelcase'` — turn `pet_id` and `X-Api-Key` into `petId` and `xApiKey` in your TypeScript code. The runtime URL still uses `/pet/{pet_id}` and the header is still sent as `X-Api-Key`.
334
686
  important: |
335
- When using `paramsCasing`, ensure that `@kubb/plugin-ts` also has the same `paramsCasing` setting. This option automatically maps transformed parameter names back to their original API names in HTTP requests.
336
- body: |
337
- - `'camelcase'` transforms parameter names to camelCase.
687
+ Set the same `paramsCasing` on every plugin that touches operation parameters (`@kubb/plugin-ts`, `@kubb/plugin-client`, `@kubb/plugin-react-query`, `@kubb/plugin-faker`, `@kubb/plugin-mcp`). Mismatched casing causes type errors between generated layers.
338
688
  examples:
339
- - name: With paramsCasing camelcase
689
+ - name: "With paramsCasing: 'camelcase'"
340
690
  files:
341
- - lang: typescript
691
+ - name: Generated client
692
+ lang: typescript
693
+ twoslash: false
342
694
  code: |
343
- // Function parameters use camelCase
695
+ // Function takes camelCase parameters
344
696
  export async function deletePet(
345
- petId: DeletePetPathParams['petId'], // ✓ camelCase
697
+ petId: DeletePetPathParams['petId'],
346
698
  headers?: DeletePetHeaderParams,
347
- config: Partial<RequestConfig> = {}
699
+ config: Partial<RequestConfig> = {},
348
700
  ) {
349
- // Automatically maps back to original name for the API
701
+ // ...mapped back to the original API name internally
350
702
  const pet_id = petId
351
703
 
352
704
  return fetch({
353
705
  method: 'DELETE',
354
- url: `/pet/${pet_id}`, // Uses original API parameter name
355
- ...
706
+ url: `/pet/${pet_id}`,
707
+ ...config,
356
708
  })
357
709
  }
710
+ - name: Caller
711
+ lang: typescript
358
712
  twoslash: false
713
+ code: |
714
+ await deletePet(42)
359
715
  - name: Without paramsCasing
360
716
  files:
361
- - lang: typescript
717
+ - name: Generated client
718
+ lang: typescript
719
+ twoslash: false
362
720
  code: |
363
- // Parameters use original API naming
721
+ // Function parameters mirror the OpenAPI spec
364
722
  export async function deletePet(
365
- pet_id: DeletePetPathParams['pet_id'], // Original naming
723
+ pet_id: DeletePetPathParams['pet_id'],
366
724
  headers?: DeletePetHeaderParams,
367
- config: Partial<RequestConfig> = {}
725
+ config: Partial<RequestConfig> = {},
368
726
  ) {
369
727
  return fetch({
370
728
  method: 'DELETE',
371
729
  url: `/pet/${pet_id}`,
372
- ...
730
+ ...config,
373
731
  })
374
732
  }
375
- twoslash: false
376
733
  tip: |
377
- The client automatically generates mapping code to convert camelCase parameter names back to the original API format. You write code with developer-friendly camelCase names, but HTTP requests use the exact parameter names from your OpenAPI specification.
734
+ Callers write friendly camelCase names. The generated client maps them back to whatever the API expects (snake_case path params, kebab-case headers, ...).
378
735
  - name: pathParamsType
379
736
  type: "'object' | 'inline'"
380
737
  required: false
381
738
  default: "'inline'"
382
- description: Defines how pathParams are passed to generated functions.
383
- body: |
384
- - `'object'` returns pathParams as an object.
385
- - `'inline'` returns pathParams as comma-separated params.
739
+ description: |
740
+ How URL path parameters appear in the generated function signature. Affects only path params; query/header params follow `paramsType`.
741
+
742
+ - `'inline'` (default) each path param is a positional argument: `getPetById(petId)`.
743
+ - `'object'` — path params are wrapped in a single object: `getPetById({ petId })`.
386
744
  examples:
387
- - name: object
745
+ - name: "'inline' (default)"
388
746
  files:
389
747
  - lang: typescript
748
+ twoslash: false
390
749
  code: |
391
750
  export async function getPetById(
392
- { petId }: GetPetByIdPathParams,
751
+ petId: GetPetByIdPathParams,
393
752
  ) {
394
- ...
753
+ // ...
395
754
  }
396
- twoslash: false
397
- - name: inline
755
+ - name: "'object'"
398
756
  files:
399
757
  - lang: typescript
758
+ twoslash: false
400
759
  code: |
401
760
  export async function getPetById(
402
- petId: GetPetByIdPathParams,
761
+ { petId }: GetPetByIdPathParams,
403
762
  ) {
404
- ...
763
+ // ...
405
764
  }
406
- twoslash: false
407
765
  - name: parser
408
766
  type: "'client' | 'zod'"
409
767
  required: false
410
768
  default: "'client'"
411
- description: Parser used before returning data.
412
- body: |
413
- - `'zod'` uses `@kubb/plugin-zod` to parse data.
414
- - `'client'` returns data without parsing.
769
+ description: |
770
+ Runtime validator applied to the response body before it is returned to the caller.
771
+
772
+ - `'client'` (default) no validation. The response is cast to the generated TypeScript type and returned as-is. Fastest path, trusts the API.
773
+ - `'zod'` — pipes the response through the Zod schema produced by `@kubb/plugin-zod`. Catches mismatches between spec and API at runtime, at the cost of a parse on every call.
774
+
775
+ Use `'zod'` when you want a defensive boundary against drift between your OpenAPI spec and the live API. Requires `@kubb/plugin-zod` in the plugins list.
776
+ examples:
777
+ - name: Validate responses with Zod
778
+ files:
779
+ - lang: typescript
780
+ twoslash: false
781
+ code: |
782
+ import { defineConfig } from 'kubb'
783
+ import { pluginClient } from '@kubb/plugin-client'
784
+ import { pluginTs } from '@kubb/plugin-ts'
785
+ import { pluginZod } from '@kubb/plugin-zod'
786
+
787
+ export default defineConfig({
788
+ input: { path: './petStore.yaml' },
789
+ output: { path: './src/gen' },
790
+ plugins: [
791
+ pluginTs(),
792
+ pluginZod(),
793
+ pluginClient({
794
+ parser: 'zod',
795
+ }),
796
+ ],
797
+ })
415
798
  - name: infinite
416
799
  type: Infinite | false
417
800
  required: false
418
801
  default: 'false'
419
802
  description: |
420
- Generate an `infiniteQuery` composable for paginated queries. Pass `false` to disable.
803
+ Enables `useInfiniteQuery` composables for cursor- or page-based pagination. Pass an object to configure how the cursor is read from the response; pass `false` (default) to skip.
421
804
  typeDefinition: |
422
805
  type Infinite = {
423
- /**
424
- * Specify the params key used for `pageParam`.
425
- * @default `'id'`
426
- */
806
+ /** Query-param key used as the page cursor. Defaults to `'id'`. */
427
807
  queryParam: string
428
- /**
429
- * Which field of the data will be used, set it to undefined when no cursor is known.
430
- * @deprecated Use `nextParam` and `previousParam` instead for more flexible pagination handling.
431
- */
432
- cursorParam?: string | undefined
433
- /**
434
- * Which field of the data will be used to get the cursor for the next page.
435
- * Supports dot notation (e.g. 'pagination.next.id') or array path (e.g. ['pagination', 'next', 'id']) to access nested fields.
436
- */
437
- nextParam?: string | string[] | undefined
438
- /**
439
- * Which field of the data will be used to get the cursor for the previous page.
440
- * Supports dot notation (e.g. 'pagination.prev.id') or array path (e.g. ['pagination', 'prev', 'id']) to access nested fields.
441
- */
442
- previousParam?: string | string[] | undefined
443
- /**
444
- * The initial value, the value of the first page.
445
- * @default `0`
446
- */
808
+ /** @deprecated Use `nextParam` / `previousParam` instead. */
809
+ cursorParam?: string
810
+ /** Path to the next-page cursor in the response. Dot or array form. */
811
+ nextParam?: string | string[]
812
+ /** Path to the previous-page cursor in the response. Dot or array form. */
813
+ previousParam?: string | string[]
814
+ /** Value of `pageParam` for the first page. Defaults to `0`. */
447
815
  initialPageParam: unknown
448
816
  } | false
449
817
  properties:
@@ -451,49 +819,40 @@ options:
451
819
  type: string
452
820
  required: false
453
821
  default: "'id'"
454
- description: Specify the params key used for `pageParam`.
822
+ description: Name of the query parameter that holds the page cursor.
455
823
  - name: initialPageParam
456
824
  type: unknown
457
825
  required: false
458
826
  default: '0'
459
- description: Specify the initial page param value.
827
+ description: Initial value for `pageParam` on the first fetch.
460
828
  - name: cursorParam
461
829
  type: string | undefined
462
830
  required: false
463
831
  deprecated:
464
- note: '`cursorParam` is deprecated. Use `nextParam` and `previousParam` instead for more flexible pagination handling.'
465
- description: Which field of the data will be used, set it to undefined when no cursor is known.
832
+ note: '`cursorParam` is deprecated. Use `nextParam` and `previousParam` for richer pagination control.'
833
+ description: Path to the cursor field on the response. Leave undefined when the cursor is not known.
466
834
  - name: nextParam
467
835
  type: string | string[] | undefined
468
836
  required: false
469
837
  description: |
470
- Which field of the data will be used to get the cursor for the next page.
471
-
472
- Supports dot notation (e.g. `'pagination.next.id'`) or array path (e.g. `['pagination', 'next', 'id']`) to access nested fields.
838
+ Path to the next-page cursor on the response. Supports dot notation (`'pagination.next.id'`) or array form (`['pagination', 'next', 'id']`).
473
839
  - name: previousParam
474
840
  type: string | string[] | undefined
475
841
  required: false
476
842
  description: |
477
- Which field of the data will be used to get the cursor for the previous page.
478
-
479
- Supports dot notation (e.g. `'pagination.prev.id'`) or array path (e.g. `['pagination', 'prev', 'id']`) to access nested fields.
843
+ Path to the previous-page cursor on the response. Supports dot notation (`'pagination.prev.id'`) or array form.
480
844
  - name: queryKey
481
845
  type: '(props: { operation: Operation; schemas: OperationSchemas }) => unknown[]'
482
846
  required: false
483
847
  description: |
484
- Customize the queryKey that will be used for the query.
848
+ Builds the `queryKey` for each generated composable. Use this to add a version namespace, swap to operation IDs, or shape keys to match an existing invalidation strategy.
485
849
 
486
- The function receives an object with:
487
- - `operation`: The OpenAPI operation object with methods like `getTags()`, `getOperationId()`, etc.
488
- - `schemas`: An object containing operation schemas including `pathParams`, `queryParams`, `request`, `response`, etc.
850
+ The callback receives the OpenAPI `operation` and a `schemas` object containing `pathParams`, `queryParams`, `request`, and `response`.
489
851
  warning: |
490
- When using a string you need to use `JSON.stringify`.
852
+ String values are inlined verbatim into generated code. Wrap any literal string in `JSON.stringify(...)`.
491
853
  details:
492
- - title: Using tags and path parameters
493
- body: |-
494
- Generate a queryKey with operation tags and path parameters:
495
-
496
- For a GET operation with tags `["user"]` and path parameter `username`, this generates:
854
+ - title: Keys from tags and path parameters
855
+ body: "Build a key from the operation's first tag plus its path parameters:"
497
856
  codeBlock:
498
857
  - lang: typescript
499
858
  code: |-
@@ -501,12 +860,13 @@ options:
501
860
  import { pluginVueQuery } from '@kubb/plugin-vue-query'
502
861
 
503
862
  export default defineConfig({
504
- // ...
863
+ input: { path: './petStore.yaml' },
864
+ output: { path: './src/gen' },
505
865
  plugins: [
506
866
  pluginVueQuery({
507
867
  queryKey: ({ operation, schemas }) => {
508
- const tags = operation.getTags().map(tag => JSON.stringify(tag.name))
509
- const pathParams = schemas.pathParams?.keys || []
868
+ const tags = operation.getTags().map((tag) => JSON.stringify(tag.name))
869
+ const pathParams = schemas.pathParams?.keys ?? []
510
870
  return [...tags, ...pathParams]
511
871
  },
512
872
  }),
@@ -514,13 +874,10 @@ options:
514
874
  })
515
875
  - lang: typescript
516
876
  code: |-
517
- export const getUserByNameQueryKey = ({ username }: { username: GetUserByNamePathParams["username"] }) =>
877
+ export const getUserByNameQueryKey = ({ username }: { username: GetUserByNamePathParams['username'] }) =>
518
878
  ['user', username] as const
519
- - title: Using the default transformer
520
- body: |-
521
- You can extend the default queryKey transformer:
522
-
523
- This prepends a version to the default queryKey:
879
+ - title: Extend the default transformer
880
+ body: 'Prepend a version prefix to the default query key:'
524
881
  codeBlock:
525
882
  - lang: typescript
526
883
  code: |-
@@ -529,7 +886,8 @@ options:
529
886
  import { QueryKey } from '@kubb/plugin-vue-query/components'
530
887
 
531
888
  export default defineConfig({
532
- // ...
889
+ input: { path: './petStore.yaml' },
890
+ output: { path: './src/gen' },
533
891
  plugins: [
534
892
  pluginVueQuery({
535
893
  queryKey: (props) => {
@@ -543,8 +901,7 @@ options:
543
901
  code: |-
544
902
  export const findPetsByTagsQueryKey = (params?: FindPetsByTagsQueryParams) =>
545
903
  ['v5', { url: '/pet/findByTags' }, ...(params ? [params] : [])] as const
546
- - title: Using operation ID
547
- body: 'Create a simple queryKey using the operation ID:'
904
+ - title: Key from operationId
548
905
  codeBlock:
549
906
  lang: typescript
550
907
  code: |-
@@ -552,17 +909,15 @@ options:
552
909
  import { pluginVueQuery } from '@kubb/plugin-vue-query'
553
910
 
554
911
  export default defineConfig({
555
- // ...
912
+ input: { path: './petStore.yaml' },
913
+ output: { path: './src/gen' },
556
914
  plugins: [
557
915
  pluginVueQuery({
558
- queryKey: ({ operation }) => {
559
- return [JSON.stringify(operation.getOperationId())]
560
- },
916
+ queryKey: ({ operation }) => [JSON.stringify(operation.getOperationId())],
561
917
  }),
562
918
  ],
563
919
  })
564
- - title: Conditional keys based on parameters
565
- body: 'Include query parameters when they exist:'
920
+ - title: Conditional keys based on params
566
921
  codeBlock:
567
922
  lang: typescript
568
923
  code: |-
@@ -570,18 +925,17 @@ options:
570
925
  import { pluginVueQuery } from '@kubb/plugin-vue-query'
571
926
 
572
927
  export default defineConfig({
573
- // ...
928
+ input: { path: './petStore.yaml' },
929
+ output: { path: './src/gen' },
574
930
  plugins: [
575
931
  pluginVueQuery({
576
932
  queryKey: ({ operation, schemas }) => {
577
- const keys = [JSON.stringify(operation.getOperationId())]
933
+ const keys: unknown[] = [JSON.stringify(operation.getOperationId())]
578
934
 
579
- // Add path parameter values (without quotes, so they reference the variables)
580
935
  if (schemas.pathParams?.keys) {
581
936
  keys.push(...schemas.pathParams.keys)
582
937
  }
583
938
 
584
- // Add query params conditionally (the string gets embedded as code)
585
939
  if (schemas.queryParams?.name) {
586
940
  keys.push('...(params ? [params] : [])')
587
941
  }
@@ -595,9 +949,7 @@ options:
595
949
  type: Query
596
950
  required: false
597
951
  description: |
598
- Override some `useQuery` behaviors.
599
-
600
- To disable the creation of hooks pass `false`, this will result in only creating `queryOptions`.
952
+ Configures the query composables. Pass `false` to skip composable generation and emit only `queryOptions(...)` helpers.
601
953
  typeDefinition: |
602
954
  type Query = {
603
955
  methods: Array<HttpMethod>
@@ -608,22 +960,39 @@ options:
608
960
  type: Array<HttpMethod>
609
961
  required: false
610
962
  default: "['get']"
611
- description: Define which HttpMethods can be used for queries.
963
+ description: |
964
+ HTTP methods treated as queries. Operations using one of these methods generate a `useQuery`-style hook (or `queryOptions` helper) instead of a mutation.
965
+
966
+ Defaults to `['get']`. Add other methods (for example `'head'`) only when your API uses them for cache-friendly reads.
967
+ examples:
968
+ - name: Allow HEAD as a query method
969
+ files:
970
+ - lang: typescript
971
+ twoslash: false
972
+ code: |
973
+ import { defineConfig } from 'kubb'
974
+ import { pluginReactQuery } from '@kubb/plugin-react-query'
975
+
976
+ export default defineConfig({
977
+ input: { path: './petStore.yaml' },
978
+ output: { path: './src/gen' },
979
+ plugins: [
980
+ pluginReactQuery({
981
+ query: { methods: ['get', 'head'] },
982
+ }),
983
+ ],
984
+ })
612
985
  - name: importPath
613
986
  type: string
614
987
  required: false
615
988
  default: "'@tanstack/vue-query'"
616
989
  description: |
617
- Path to the `useQuery` that will be used to do the `useQuery` functionality.
618
-
619
- It will be used as `import { useQuery } from '${hook.importPath}'`. It allows both relative and absolute paths. The path will be applied as is, so relative paths should be based on the file being generated.
990
+ Module specifier used in the `import { useQuery } from '...'` statement at the top of every generated composable file. Useful for routing through your own wrapper.
620
991
  - name: mutation
621
992
  type: Mutation
622
993
  required: false
623
994
  description: |
624
- Override some `useMutation` behaviors.
625
-
626
- To disable queries pass `false`.
995
+ Configures mutation composables. Set to `false` to skip mutation generation.
627
996
  typeDefinition: |
628
997
  type Mutation = {
629
998
  methods: Array<HttpMethod>
@@ -634,110 +1003,266 @@ options:
634
1003
  type: Array<HttpMethod>
635
1004
  required: false
636
1005
  default: "['post', 'put', 'delete']"
637
- description: Define which HttpMethods can be used for mutations.
1006
+ description: |
1007
+ HTTP methods treated as mutations. Operations using one of these methods generate a `useMutation`-style hook instead of a query.
1008
+
1009
+ Defaults to `['post', 'put', 'delete']`. Add `'patch'` if your API uses it for partial updates.
1010
+ examples:
1011
+ - name: Include PATCH as a mutation
1012
+ files:
1013
+ - lang: typescript
1014
+ twoslash: false
1015
+ code: |
1016
+ import { defineConfig } from 'kubb'
1017
+ import { pluginReactQuery } from '@kubb/plugin-react-query'
1018
+
1019
+ export default defineConfig({
1020
+ input: { path: './petStore.yaml' },
1021
+ output: { path: './src/gen' },
1022
+ plugins: [
1023
+ pluginReactQuery({
1024
+ mutation: { methods: ['post', 'put', 'patch', 'delete'] },
1025
+ }),
1026
+ ],
1027
+ })
638
1028
  - name: importPath
639
1029
  type: string
640
1030
  required: false
641
1031
  default: "'@tanstack/vue-query'"
642
1032
  description: |
643
- Path to the `useMutation` that will be used to do the `useMutation` functionality.
644
-
645
- It will be used as `import { useMutation } from '${hook.importPath}'`. It allows both relative and absolute paths. The path will be applied as is, so relative paths should be based on the file being generated.
1033
+ Module specifier used in the `import { useMutation } from '...'` statement at the top of every generated composable file.
646
1034
  - name: mutationKey
647
1035
  type: '(props: { operation: Operation; schemas: OperationSchemas }) => unknown[]'
648
1036
  required: false
649
- description: Customize the mutationKey.
1037
+ description: |
1038
+ Builds the `mutationKey` for each mutation composable. Useful when you batch invalidations or read mutation state via `useMutationState`.
650
1039
  warning: |
651
- When using a string you need to use `JSON.stringify`.
1040
+ String values are inlined verbatim into generated code. Wrap any literal string in `JSON.stringify(...)`.
652
1041
  - name: include
653
1042
  type: Array<Include>
654
1043
  required: false
655
- description: Array containing include parameters to include tags, operations, methods, paths, or content types.
1044
+ description: |
1045
+ Restricts generation to operations that match at least one entry in the list. Anything not matched is skipped.
1046
+
1047
+ Each entry filters by one of:
1048
+
1049
+ - `tag` — the operation's first tag in the OpenAPI spec.
1050
+ - `operationId` — the operation's `operationId`.
1051
+ - `path` — the URL pattern (`'/pet/{petId}'`).
1052
+ - `method` — HTTP method (`'get'`, `'post'`, ...).
1053
+ - `contentType` — the media type of the request body.
1054
+
1055
+ `pattern` accepts either a string (exact match) or a `RegExp` for fuzzy matches.
656
1056
  codeBlock:
657
1057
  lang: typescript
658
- title: Include
1058
+ title: Type definition
659
1059
  code: |
660
1060
  export type Include = {
661
1061
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
662
1062
  pattern: string | RegExp
663
1063
  }
1064
+ examples:
1065
+ - name: Only the pet tag
1066
+ files:
1067
+ - name: kubb.config.ts
1068
+ lang: typescript
1069
+ twoslash: false
1070
+ code: |
1071
+ import { defineConfig } from 'kubb'
1072
+ import { pluginTs } from '@kubb/plugin-ts'
1073
+
1074
+ export default defineConfig({
1075
+ input: { path: './petStore.yaml' },
1076
+ output: { path: './src/gen' },
1077
+ plugins: [
1078
+ pluginTs({
1079
+ include: [
1080
+ { type: 'tag', pattern: 'pet' },
1081
+ ],
1082
+ }),
1083
+ ],
1084
+ })
1085
+ - name: Only GET operations under /pet
1086
+ files:
1087
+ - name: kubb.config.ts
1088
+ lang: typescript
1089
+ twoslash: false
1090
+ code: |
1091
+ import { defineConfig } from 'kubb'
1092
+ import { pluginTs } from '@kubb/plugin-ts'
1093
+
1094
+ export default defineConfig({
1095
+ input: { path: './petStore.yaml' },
1096
+ output: { path: './src/gen' },
1097
+ plugins: [
1098
+ pluginTs({
1099
+ include: [
1100
+ { type: 'method', pattern: 'get' },
1101
+ { type: 'path', pattern: /^\/pet/ },
1102
+ ],
1103
+ }),
1104
+ ],
1105
+ })
664
1106
  - name: exclude
665
1107
  type: Array<Exclude>
666
1108
  required: false
667
- description: Array containing exclude parameters to exclude or skip tags, operations, methods, paths, or content types.
1109
+ description: |
1110
+ Skips any operation that matches at least one entry in the list. The opposite of `include`.
1111
+
1112
+ Each entry filters by one of:
1113
+
1114
+ - `tag` — the operation's first tag.
1115
+ - `operationId` — the operation's `operationId`.
1116
+ - `path` — the URL pattern (`'/pet/{petId}'`).
1117
+ - `method` — HTTP method (`'get'`, `'post'`, ...).
1118
+ - `contentType` — the media type of the request body.
1119
+
1120
+ `pattern` accepts a plain string or a `RegExp`. When both `include` and `exclude` are set, `exclude` wins.
668
1121
  codeBlock:
669
1122
  lang: typescript
670
- title: Exclude
1123
+ title: Type definition
671
1124
  code: |
672
1125
  export type Exclude = {
673
1126
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
674
1127
  pattern: string | RegExp
675
1128
  }
1129
+ examples:
1130
+ - name: Skip everything under the store tag
1131
+ files:
1132
+ - name: kubb.config.ts
1133
+ lang: typescript
1134
+ twoslash: false
1135
+ code: |
1136
+ import { defineConfig } from 'kubb'
1137
+ import { pluginTs } from '@kubb/plugin-ts'
1138
+
1139
+ export default defineConfig({
1140
+ input: { path: './petStore.yaml' },
1141
+ output: { path: './src/gen' },
1142
+ plugins: [
1143
+ pluginTs({
1144
+ exclude: [
1145
+ { type: 'tag', pattern: 'store' },
1146
+ ],
1147
+ }),
1148
+ ],
1149
+ })
1150
+ - name: Skip a specific operation and all delete methods
1151
+ files:
1152
+ - name: kubb.config.ts
1153
+ lang: typescript
1154
+ twoslash: false
1155
+ code: |
1156
+ import { defineConfig } from 'kubb'
1157
+ import { pluginTs } from '@kubb/plugin-ts'
1158
+
1159
+ export default defineConfig({
1160
+ input: { path: './petStore.yaml' },
1161
+ output: { path: './src/gen' },
1162
+ plugins: [
1163
+ pluginTs({
1164
+ exclude: [
1165
+ { type: 'operationId', pattern: 'deletePet' },
1166
+ { type: 'method', pattern: 'delete' },
1167
+ ],
1168
+ }),
1169
+ ],
1170
+ })
676
1171
  - name: override
677
1172
  type: Array<Override>
678
1173
  required: false
679
- description: Array containing override parameters to override `options` based on tags, operations, methods, paths, or content types.
1174
+ description: |
1175
+ Applies a different set of plugin options to operations that match a pattern. Use this when most of your API should follow the global config, but a handful of endpoints need different treatment.
1176
+
1177
+ Each entry has the same `type` and `pattern` shape as `include`/`exclude`, plus an `options` object that overrides the plugin's options for matched operations.
1178
+
1179
+ Entries are evaluated top to bottom. The first matching entry's `options` is merged onto the plugin defaults; later entries do not stack.
680
1180
  codeBlock:
681
1181
  lang: typescript
682
- title: Override
1182
+ title: Type definition
683
1183
  code: |
684
1184
  export type Override = {
685
1185
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
686
1186
  pattern: string | RegExp
687
1187
  options: PluginOptions
688
1188
  }
1189
+ examples:
1190
+ - name: Use a different enum style for the user tag
1191
+ files:
1192
+ - name: kubb.config.ts
1193
+ lang: typescript
1194
+ twoslash: false
1195
+ code: |
1196
+ import { defineConfig } from 'kubb'
1197
+ import { pluginTs } from '@kubb/plugin-ts'
1198
+
1199
+ export default defineConfig({
1200
+ input: { path: './petStore.yaml' },
1201
+ output: { path: './src/gen' },
1202
+ plugins: [
1203
+ pluginTs({
1204
+ enumType: 'asConst',
1205
+ override: [
1206
+ {
1207
+ type: 'tag',
1208
+ pattern: 'user',
1209
+ options: { enumType: 'literal' },
1210
+ },
1211
+ ],
1212
+ }),
1213
+ ],
1214
+ })
689
1215
  - name: generators
690
1216
  type: Array<Generator<PluginVueQuery>>
691
1217
  required: false
692
1218
  experimental: true
693
1219
  description: |
694
- Define additional generators next to the built-in generators.
1220
+ Adds custom generators that run alongside the plugin's built-in generators. Each generator can emit additional files or post-process existing ones using the plugin's AST and options.
695
1221
 
696
- See [Generators](https://kubb.dev/docs/5.x/guides/creating-plugins) for more information on how to use generators.
1222
+ Use this when you need output the plugin does not produce out of the box (a custom client wrapper, an extra index, a metadata file). For end-to-end guidance, see [Creating plugins](https://kubb.dev/docs/5.x/guides/creating-plugins).
1223
+ warning: |
1224
+ Generators are an experimental, low-level API. The signature may change between minor releases.
697
1225
  - name: resolver
698
1226
  type: Partial<ResolverVueQuery>
699
1227
  required: false
700
- description: Override individual resolver methods to customize naming conventions.
1228
+ description: |
1229
+ Overrides naming and path resolution for the generated composables. Supply only the methods you want to change; everything else falls back to the default resolver.
701
1230
  - name: transformer
702
1231
  type: ast.Visitor
703
1232
  required: false
704
- description: Single AST visitor applied to each node before printing.
1233
+ description: |
1234
+ AST visitor applied to operation nodes before code is printed. Use this to rewrite operation IDs, tags, or descriptions across the entire output.
1235
+ notes:
1236
+ - type: tip
1237
+ body: |
1238
+ Reference: [TanStack Query for Vue](https://tanstack.com/query/latest/docs/framework/vue/overview) for cache, retries, and devtools.
705
1239
  examples:
706
1240
  - name: kubb.config.ts
707
1241
  files:
708
1242
  - lang: typescript
1243
+ twoslash: false
709
1244
  code: |
710
1245
  import { defineConfig } from 'kubb'
711
1246
  import { pluginTs } from '@kubb/plugin-ts'
712
1247
  import { pluginVueQuery } from '@kubb/plugin-vue-query'
713
1248
 
714
1249
  export default defineConfig({
715
- input: {
716
- path: './petStore.yaml',
717
- },
718
- output: {
719
- path: './src/gen',
720
- },
1250
+ input: { path: './petStore.yaml' },
1251
+ output: { path: './src/gen' },
721
1252
  plugins: [
722
1253
  pluginTs(),
723
1254
  pluginVueQuery({
724
- output: {
725
- path: './hooks',
726
- },
1255
+ output: { path: './hooks' },
727
1256
  group: {
728
1257
  type: 'tag',
729
1258
  name: ({ group }) => `${group}Hooks`,
730
1259
  },
731
- client: {
732
- dataReturnType: 'full',
733
- },
734
- mutation: {
735
- methods: ['post', 'put', 'delete'],
736
- },
1260
+ client: { dataReturnType: 'full' },
1261
+ mutation: { methods: ['post', 'put', 'delete'] },
737
1262
  infinite: {
738
1263
  queryParam: 'next_page',
739
1264
  initialPageParam: 0,
740
- cursorParam: 'nextCursor',
1265
+ nextParam: 'pagination.next.cursor',
741
1266
  },
742
1267
  query: {
743
1268
  methods: ['get'],
@@ -746,4 +1271,3 @@ examples:
746
1271
  }),
747
1272
  ],
748
1273
  })
749
- twoslash: false