@kubb/plugin-client 5.0.0-alpha.9 → 5.0.0-beta.15

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 (62) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +27 -7
  3. package/dist/clients/axios.cjs +10 -3
  4. package/dist/clients/axios.cjs.map +1 -1
  5. package/dist/clients/axios.d.ts +5 -4
  6. package/dist/clients/axios.js +9 -2
  7. package/dist/clients/axios.js.map +1 -1
  8. package/dist/clients/fetch.cjs +5 -2
  9. package/dist/clients/fetch.cjs.map +1 -1
  10. package/dist/clients/fetch.d.ts +3 -2
  11. package/dist/clients/fetch.js +5 -2
  12. package/dist/clients/fetch.js.map +1 -1
  13. package/dist/index.cjs +1830 -97
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +330 -4
  16. package/dist/index.js +1816 -95
  17. package/dist/index.js.map +1 -1
  18. package/dist/templates/clients/axios.source.cjs +1 -1
  19. package/dist/templates/clients/axios.source.js +1 -1
  20. package/dist/templates/clients/fetch.source.cjs +1 -1
  21. package/dist/templates/clients/fetch.source.js +1 -1
  22. package/extension.yaml +779 -0
  23. package/package.json +62 -85
  24. package/src/clients/axios.ts +19 -4
  25. package/src/clients/fetch.ts +10 -2
  26. package/src/components/ClassClient.tsx +46 -145
  27. package/src/components/Client.tsx +109 -139
  28. package/src/components/Operations.tsx +10 -10
  29. package/src/components/StaticClassClient.tsx +46 -142
  30. package/src/components/Url.tsx +38 -50
  31. package/src/components/WrapperClient.tsx +11 -7
  32. package/src/functionParams.ts +118 -0
  33. package/src/generators/classClientGenerator.tsx +143 -172
  34. package/src/generators/clientGenerator.tsx +83 -81
  35. package/src/generators/groupedClientGenerator.tsx +50 -52
  36. package/src/generators/operationsGenerator.tsx +11 -18
  37. package/src/generators/staticClassClientGenerator.tsx +172 -184
  38. package/src/index.ts +9 -2
  39. package/src/plugin.ts +115 -145
  40. package/src/resolvers/resolverClient.ts +38 -0
  41. package/src/types.ts +128 -44
  42. package/src/utils.ts +156 -0
  43. package/dist/StaticClassClient-By-aMAe4.cjs +0 -677
  44. package/dist/StaticClassClient-By-aMAe4.cjs.map +0 -1
  45. package/dist/StaticClassClient-CCn9g9eF.js +0 -636
  46. package/dist/StaticClassClient-CCn9g9eF.js.map +0 -1
  47. package/dist/components.cjs +0 -7
  48. package/dist/components.d.ts +0 -216
  49. package/dist/components.js +0 -2
  50. package/dist/generators-BYUJaeZP.js +0 -723
  51. package/dist/generators-BYUJaeZP.js.map +0 -1
  52. package/dist/generators-DTxD9FDY.cjs +0 -753
  53. package/dist/generators-DTxD9FDY.cjs.map +0 -1
  54. package/dist/generators.cjs +0 -7
  55. package/dist/generators.d.ts +0 -517
  56. package/dist/generators.js +0 -2
  57. package/dist/types-DBQdg-BV.d.ts +0 -169
  58. package/src/components/index.ts +0 -5
  59. package/src/generators/index.ts +0 -5
  60. package/templates/clients/axios.ts +0 -70
  61. package/templates/clients/fetch.ts +0 -93
  62. package/templates/config.ts +0 -43
package/extension.yaml ADDED
@@ -0,0 +1,779 @@
1
+ $schema: https://kubb.dev/schemas/extension.json
2
+ kind: plugin
3
+ id: plugin-client
4
+ name: Client
5
+ description: Generate type-safe HTTP clients (Axios, Fetch) from OpenAPI specifications for making API requests.
6
+ category: client
7
+ type: official
8
+ npmPackage: '@kubb/plugin-client'
9
+ docsPath: /plugins/plugin-client
10
+ repo: https://github.com/kubb-labs/plugins
11
+ maintainers:
12
+ - name: Stijn Van Hulle
13
+ github: stijnvanhulle
14
+ compatibility:
15
+ kubb: '>=5.0.0'
16
+ node: '>=22'
17
+ tags:
18
+ - api-client
19
+ - axios
20
+ - fetch
21
+ - http-client
22
+ - codegen
23
+ - openapi
24
+ dependencies:
25
+ - plugin-ts
26
+ resources:
27
+ documentation: https://kubb.dev/plugins/plugin-client
28
+ repository: https://github.com/kubb-labs/plugins
29
+ issues: https://github.com/kubb-labs/plugins/issues
30
+ changelog: https://github.com/kubb-labs/plugins/blob/main/packages/plugin-client/CHANGELOG.md
31
+ codesandbox: https://codesandbox.io/p/github/kubb-labs/plugins/main/examples/client
32
+ featured: true
33
+ icon:
34
+ light: https://kubb.dev/feature/axios.svg
35
+ intro: |
36
+ # @kubb/plugin-client
37
+
38
+ Generate API client code for handling API requests.
39
+
40
+ By default, this plugin uses [Axios](https://axios-http.com/docs/intro), but you can add your own client. See [Use of Fetch](https://kubb.dev/plugins/plugin-client#importpath) for an example.
41
+ options:
42
+ - name: output
43
+ type: Output
44
+ required: false
45
+ default: "{ path: 'clients', barrel: { type: 'named' } }"
46
+ description: Specify the export location for the files and define the behavior of the output.
47
+ properties:
48
+ - name: path
49
+ type: string
50
+ required: true
51
+ description: Output directory or file for the generated code, relative to the global `output.path`.
52
+ tip: |
53
+ if `output.path` is a file, `group` cannot be used.
54
+ default: "'clients'"
55
+ - name: barrel
56
+ type: "{ type: 'named' | 'all', nested?: boolean } | false"
57
+ required: false
58
+ 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.'
60
+ examples:
61
+ - name: all
62
+ files:
63
+ - lang: typescript
64
+ code: |
65
+ export * from './gen/petService.ts'
66
+ twoslash: false
67
+ - name: named
68
+ files:
69
+ - lang: typescript
70
+ code: |
71
+ export { PetService } from './gen/petService.ts'
72
+ twoslash: false
73
+ - name: nested
74
+ files:
75
+ - name: kubb.config.ts
76
+ lang: typescript
77
+ code: |
78
+ output: {
79
+ path: './gen',
80
+ barrel: { type: 'named', nested: true },
81
+ }
82
+ twoslash: false
83
+ - name: 'false'
84
+ files:
85
+ - lang: typescript
86
+ code: ''
87
+ twoslash: false
88
+ - name: banner
89
+ type: 'string | ((node: RootNode) => string)'
90
+ 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.
92
+ - name: footer
93
+ type: 'string | ((node: RootNode) => string)'
94
+ 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.
96
+ - name: override
97
+ type: boolean
98
+ required: false
99
+ default: 'false'
100
+ description: Whether Kubb overrides existing external files that can be generated if they already exist.
101
+ - name: contentType
102
+ type: "'application/json' | (string & {})"
103
+ required: false
104
+ description: |
105
+ Define which content type to use.
106
+
107
+ By default, Kubb uses the first JSON-valid media type.
108
+ - name: group
109
+ type: Group
110
+ required: false
111
+ description: |
112
+ Grouping combines files in a folder based on a specific `type`.
113
+ examples:
114
+ - name: kubb.config.ts
115
+ files:
116
+ - lang: typescript
117
+ code: |
118
+ group: {
119
+ type: 'tag',
120
+ name({ group }) {
121
+ return `${group}Controller`
122
+ }
123
+ }
124
+ twoslash: false
125
+ body: |
126
+ With the configuration above, the generator emits:
127
+
128
+ ```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
140
+ ```
141
+ properties:
142
+ - name: type
143
+ type: "'tag'"
144
+ required: true
145
+ description: Specify the property to group files by. Required when `group` is defined.
146
+ 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`
150
+ - name: name
151
+ type: '(context: GroupContext) => string'
152
+ required: false
153
+ default: (ctx) => `${ctx.group}Controller`
154
+ description: Return the name of a group based on the group name. Used for the file and identifier generation.
155
+ - name: importPath
156
+ type: string
157
+ required: false
158
+ description: Path to the client used for API calls. Supports both relative and absolute paths.
159
+ details:
160
+ - title: When to use `importPath`
161
+ body: |
162
+ Use `importPath` when you want to:
163
+
164
+ - **Customize the HTTP client**: Provide your own client implementation with custom configurations (e.g., baseURL, headers, interceptors)
165
+ - **Add authentication**: Include authentication tokens or other security mechanisms in your client
166
+ - **Override default behavior**: Replace the default Kubb client with your own implementation
167
+ - title: Default behavior
168
+ body: |
169
+ When `importPath` is not specified:
170
+
171
+ - If `bundle: false` (default): Uses `@kubb/plugin-client/clients/${client}` where client is either `axios` or `fetch`.
172
+ - If `bundle: true`: Bundles the client into `.kubb/fetch.ts`.
173
+ - title: Import structure
174
+ body: 'Generated code imports the client as a default import and the runtime types as named type imports:'
175
+ codeBlock:
176
+ lang: typescript
177
+ code: |-
178
+ /**
179
+ * Generated by Kubb (https://kubb.dev/).
180
+ * Do not edit manually.
181
+ */
182
+ import client from '${client.importPath}'
183
+ import type { RequestConfig, ResponseErrorConfig } from '${client.importPath}'
184
+ // ... rest of generated file
185
+ important: |
186
+ 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 types — if any is missing, TypeScript will report an unresolvable import error.
187
+ codeBlock:
188
+ lang: typescript
189
+ title: client.ts
190
+ code: |
191
+ export type RequestConfig<TData = unknown> = {
192
+ url?: string
193
+ method: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE'
194
+ params?: object
195
+ data?: TData | FormData
196
+ responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'
197
+ signal?: AbortSignal
198
+ headers?: HeadersInit
199
+ }
200
+
201
+ export type ResponseConfig<TData = unknown> = {
202
+ data: TData
203
+ status: number
204
+ statusText: string
205
+ }
206
+
207
+ export type ResponseErrorConfig<TError = unknown> = TError
208
+
209
+ // The Client type alias is required when using query plugins
210
+ export type Client = <TData, _TError = unknown, TVariables = unknown>(
211
+ config: RequestConfig<TVariables>
212
+ ) => Promise<ResponseConfig<TData>>
213
+
214
+ export const client: Client = async (config) => { /* ... */ }
215
+ export default client
216
+ examples:
217
+ - name: kubb.config.ts
218
+ files:
219
+ - lang: typescript
220
+ code: |
221
+ import { defineConfig } from 'kubb'
222
+ import { pluginClient } from '@kubb/plugin-client'
223
+
224
+ export default defineConfig({
225
+ // ...
226
+ plugins: [
227
+ pluginClient({
228
+ importPath: './src/client.ts', // Path to your custom client
229
+ }),
230
+ ],
231
+ })
232
+ twoslash: false
233
+ tip: |
234
+ Learn more about defining a custom client [here](https://kubb.dev/plugins/plugin-client#importpath).
235
+ - name: operations
236
+ type: boolean
237
+ required: false
238
+ default: 'false'
239
+ description: Create an `operations.ts` file with all operations grouped by methods.
240
+ - name: dataReturnType
241
+ type: "'data' | 'full'"
242
+ required: false
243
+ default: "'data'"
244
+ description: |
245
+ Return type used when calling the client.
246
+
247
+ - `'data'` returns `ResponseConfig['data']`.
248
+ - `'full'` returns the full `ResponseConfig`.
249
+ examples:
250
+ - name: data
251
+ files:
252
+ - lang: typescript
253
+ code: |
254
+ export async function getPetById<TData>(
255
+ petId: GetPetByIdPathParams,
256
+ ): Promise<ResponseConfig<TData>['data']> {
257
+ ...
258
+ }
259
+ twoslash: false
260
+ - name: full
261
+ files:
262
+ - lang: typescript
263
+ code: |
264
+ export async function getPetById<TData>(
265
+ petId: GetPetByIdPathParams,
266
+ ): Promise<ResponseConfig<TData>> {
267
+ ...
268
+ }
269
+ twoslash: false
270
+ - name: urlType
271
+ type: "'export' | false"
272
+ required: false
273
+ default: 'false'
274
+ description: Export URLs that are used by every operation.
275
+ body: |
276
+ - `'export'` will make them part of your barrel file.
277
+ - `false` will not make them exportable.
278
+ codeBlock:
279
+ lang: typescript
280
+ code: |
281
+ export function getGetPetByIdUrl(petId: GetPetByIdPathParams['petId']) {
282
+ return `/pet/${petId}` as const
283
+ }
284
+ - name: paramsType
285
+ type: "'object' | 'inline'"
286
+ required: false
287
+ default: "'inline'"
288
+ description: Defines how parameters are passed to generated functions. Switch between object-style parameters and inline parameters.
289
+ tip: |
290
+ When `paramsType` is set to `'object'`, `pathParams` will also be set to `'object'`.
291
+ body: |
292
+ - `'object'` returns params and pathParams as an object.
293
+ - `'inline'` returns params as comma-separated params.
294
+ examples:
295
+ - name: object
296
+ files:
297
+ - lang: typescript
298
+ code: |
299
+ export async function deletePet(
300
+ {
301
+ petId,
302
+ headers,
303
+ }: {
304
+ petId: DeletePetPathParams['petId']
305
+ headers?: DeletePetHeaderParams
306
+ },
307
+ config: Partial<RequestConfig> = {},
308
+ ) {
309
+ ...
310
+ }
311
+ twoslash: false
312
+ - name: inline
313
+ files:
314
+ - lang: typescript
315
+ code: |
316
+ export async function deletePet(
317
+ petId: DeletePetPathParams['petId'],
318
+ headers?: DeletePetHeaderParams,
319
+ config: Partial<RequestConfig> = {}
320
+ ){
321
+ ...
322
+ }
323
+ twoslash: false
324
+ - name: paramsCasing
325
+ type: "'camelcase'"
326
+ required: false
327
+ description: Transform parameter names to a specific casing format for path, query, and header parameters in generated client code.
328
+ important: |
329
+ 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.
330
+ body: |
331
+ - `'camelcase'` transforms parameter names to camelCase.
332
+ examples:
333
+ - name: With paramsCasing camelcase
334
+ files:
335
+ - lang: typescript
336
+ code: |
337
+ // Function parameters use camelCase
338
+ export async function deletePet(
339
+ petId: DeletePetPathParams['petId'], // ✓ camelCase
340
+ headers?: DeletePetHeaderParams,
341
+ config: Partial<RequestConfig> = {}
342
+ ) {
343
+ // Automatically maps back to original name for the API
344
+ const pet_id = petId
345
+
346
+ return fetch({
347
+ method: 'DELETE',
348
+ url: `/pet/${pet_id}`, // Uses original API parameter name
349
+ ...
350
+ })
351
+ }
352
+ twoslash: false
353
+ - name: Without paramsCasing
354
+ files:
355
+ - lang: typescript
356
+ code: |
357
+ // Parameters use original API naming
358
+ export async function deletePet(
359
+ pet_id: DeletePetPathParams['pet_id'], // Original naming
360
+ headers?: DeletePetHeaderParams,
361
+ config: Partial<RequestConfig> = {}
362
+ ) {
363
+ return fetch({
364
+ method: 'DELETE',
365
+ url: `/pet/${pet_id}`,
366
+ ...
367
+ })
368
+ }
369
+ twoslash: false
370
+ tip: |
371
+ 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.
372
+ - name: pathParamsType
373
+ type: "'object' | 'inline'"
374
+ required: false
375
+ default: "'inline'"
376
+ description: Defines how pathParams are passed to generated functions.
377
+ body: |
378
+ - `'object'` returns pathParams as an object.
379
+ - `'inline'` returns pathParams as comma-separated params.
380
+ examples:
381
+ - name: object
382
+ files:
383
+ - lang: typescript
384
+ code: |
385
+ export async function getPetById(
386
+ { petId }: GetPetByIdPathParams,
387
+ ) {
388
+ ...
389
+ }
390
+ twoslash: false
391
+ - name: inline
392
+ files:
393
+ - lang: typescript
394
+ code: |
395
+ export async function getPetById(
396
+ petId: GetPetByIdPathParams,
397
+ ) {
398
+ ...
399
+ }
400
+ twoslash: false
401
+ - name: parser
402
+ type: "'client' | 'zod'"
403
+ required: false
404
+ default: "'client'"
405
+ description: Parser used before returning data.
406
+ body: |
407
+ - `'zod'` uses `@kubb/plugin-zod` to parse data.
408
+ - `'client'` returns data without parsing.
409
+ - name: client
410
+ type: "'axios' | 'fetch'"
411
+ required: false
412
+ default: "'axios'"
413
+ description: Client used for HTTP calls.
414
+ body: |
415
+ - `'axios'` uses `@kubb/plugin-client/templates/axios` to fetch data.
416
+ - `'fetch'` uses `@kubb/plugin-client/templates/fetch` to fetch data.
417
+ - name: clientType
418
+ type: "'function' | 'class' | 'staticClass'"
419
+ required: false
420
+ default: "'function'"
421
+ description: |
422
+ Defines the client code generation style.
423
+
424
+ - `'function'` generates standalone functions for each operation.
425
+ - `'class'` generates a class with instance methods for each operation.
426
+ - `'staticClass'` generates a class with static methods for each operation. Use this style to call methods like `Pet.getPetById(...)` without instantiating the class.
427
+ warning: |
428
+ When using `clientType: 'class'` or `clientType: 'staticClass'`, these are not compatible with query plugins like `@kubb/plugin-react-query` or `@kubb/plugin-vue-query`. These plugins are designed to work with function-based clients. If you need to use both class-based or static-class clients and query hooks, configure separate `pluginClient` instances: one with `clientType: 'class'` or `clientType: 'staticClass'` for your needs, and another with `clientType: 'function'` (or omit it for the default) that the query plugins will reference.
429
+ examples:
430
+ - name: staticClass
431
+ files:
432
+ - name: kubb.config.ts
433
+ lang: typescript
434
+ code: |
435
+ import { defineConfig } from 'kubb'
436
+ import { pluginClient } from '@kubb/plugin-client'
437
+ import { pluginTs } from '@kubb/plugin-ts'
438
+
439
+ export default defineConfig({
440
+ input: { path: './petStore.yaml' },
441
+ output: { path: './src/gen' },
442
+ plugins: [
443
+ pluginTs(),
444
+ pluginClient({
445
+ output: { path: './clients' },
446
+ clientType: 'staticClass',
447
+ group: { type: 'tag' },
448
+ }),
449
+ ],
450
+ })
451
+ twoslash: false
452
+ - name: Pet.ts
453
+ lang: typescript
454
+ code: |
455
+ import fetch from '@kubb/plugin-client/clients/fetch'
456
+ import type { GetPetByIdQueryResponse, GetPetByIdPathParams, GetPetById400, GetPetById404 } from '../../../models/ts/petController/GetPetById.js'
457
+ import type { AddPetMutationRequest, AddPetMutationResponse, AddPet405 } from '../../../models/ts/petController/AddPet.js'
458
+ import type { RequestConfig, ResponseErrorConfig } from '@kubb/plugin-client/clients/fetch'
459
+
460
+ export class Pet {
461
+ static #client: typeof fetch = fetch
462
+
463
+ /**
464
+ * @description Returns a single pet
465
+ * @summary Find pet by ID
466
+ * {@link /pet/:petId}
467
+ */
468
+ static async getPetById(
469
+ { petId }: { petId: GetPetByIdPathParams['petId'] },
470
+ config: Partial<RequestConfig> & { client?: typeof fetch } = {}
471
+ ) {
472
+ const request = this.#client || fetch
473
+ const { client: _request = this.#client, ...requestConfig } = config
474
+ const res = await request<GetPetByIdQueryResponse, ResponseErrorConfig<GetPetById400 | GetPetById404>, unknown>({
475
+ method: 'GET',
476
+ url: `/pet/${petId}`,
477
+ ...requestConfig,
478
+ })
479
+ return res.data
480
+ }
481
+ }
482
+ twoslash: false
483
+ - name: usage.ts
484
+ lang: typescript
485
+ code: |
486
+ import { Pet } from './gen/clients/Pet'
487
+
488
+ const pet = await Pet.getPetById({ petId: 1 })
489
+ twoslash: false
490
+ - name: class
491
+ files:
492
+ - name: kubb.config.ts
493
+ lang: typescript
494
+ code: |
495
+ import { defineConfig } from 'kubb'
496
+ import { pluginClient } from '@kubb/plugin-client'
497
+ import { pluginTs } from '@kubb/plugin-ts'
498
+
499
+ export default defineConfig({
500
+ input: { path: './petStore.yaml' },
501
+ output: { path: './src/gen' },
502
+ plugins: [
503
+ pluginTs(),
504
+ pluginClient({
505
+ output: { path: './clients' },
506
+ clientType: 'class',
507
+ group: { type: 'tag' },
508
+ }),
509
+ ],
510
+ })
511
+ twoslash: false
512
+ - name: Pet.ts
513
+ lang: typescript
514
+ code: |
515
+ import fetch from '@kubb/plugin-client/clients/fetch'
516
+ import type { GetPetByIdQueryResponse, GetPetByIdPathParams, GetPetById400, GetPetById404 } from '../../../models/ts/petController/GetPetById.js'
517
+ import type { RequestConfig, ResponseErrorConfig } from '@kubb/plugin-client/clients/fetch'
518
+
519
+ export class Pet {
520
+ #client: typeof fetch
521
+
522
+ constructor(config: Partial<RequestConfig> & { client?: typeof fetch } = {}) {
523
+ this.#client = config.client || fetch
524
+ }
525
+
526
+ async getPetById(
527
+ { petId }: { petId: GetPetByIdPathParams['petId'] },
528
+ config: Partial<RequestConfig> & { client?: typeof fetch } = {}
529
+ ) {
530
+ const { client: request = this.#client, ...requestConfig } = config
531
+ const res = await request<GetPetByIdQueryResponse, ResponseErrorConfig<GetPetById400 | GetPetById404>, unknown>({
532
+ method: 'GET',
533
+ url: `/pet/${petId}`,
534
+ ...requestConfig,
535
+ })
536
+ return res.data
537
+ }
538
+ }
539
+ twoslash: false
540
+ - name: usage.ts
541
+ lang: typescript
542
+ code: |
543
+ import { Pet } from './gen/clients/Pet'
544
+
545
+ const petClient = new Pet()
546
+ const pet = await petClient.getPetById({ petId: 1 })
547
+ twoslash: false
548
+ - name: wrapper
549
+ type: '{ className: string }'
550
+ required: false
551
+ description: Generate a wrapper class that composes all tag-based client classes into a single entry point.
552
+ properties:
553
+ - name: className
554
+ type: string
555
+ required: true
556
+ description: Name of the generated wrapper class.
557
+ examples:
558
+ - name: wrapper.className
559
+ files:
560
+ - name: kubb.config.ts
561
+ lang: typescript
562
+ code: |
563
+ import { defineConfig } from 'kubb'
564
+ import { pluginClient } from '@kubb/plugin-client'
565
+ import { pluginTs } from '@kubb/plugin-ts'
566
+
567
+ export default defineConfig({
568
+ input: { path: './petStore.yaml' },
569
+ output: { path: './src/gen' },
570
+ plugins: [
571
+ pluginTs(),
572
+ pluginClient({
573
+ output: { path: './clients' },
574
+ clientType: 'class',
575
+ group: { type: 'tag' },
576
+ wrapper: { className: 'PetStoreClient' },
577
+ }),
578
+ ],
579
+ })
580
+ twoslash: false
581
+ - name: PetStoreClient.ts
582
+ lang: typescript
583
+ code: |
584
+ import type { Client, RequestConfig } from './.kubb/fetch.js'
585
+ import { Pet } from './petController/Pet.js'
586
+ import { Store } from './storeController/Store.js'
587
+ import { User } from './userController/User.js'
588
+
589
+ export class PetStoreClient {
590
+ readonly pet: Pet
591
+ readonly store: Store
592
+ readonly user: User
593
+
594
+ constructor(config: Partial<RequestConfig> & { client?: Client } = {}) {
595
+ this.pet = new Pet(config)
596
+ this.store = new Store(config)
597
+ this.user = new User(config)
598
+ }
599
+ }
600
+ twoslash: false
601
+ - name: usage.ts
602
+ lang: typescript
603
+ code: |
604
+ import { PetStoreClient } from './gen/clients/PetStoreClient'
605
+
606
+ const client = new PetStoreClient({ baseURL: 'https://petstore.swagger.io/v2' })
607
+
608
+ const pets = await client.pet.findPetsByTags({ tags: ['available'] })
609
+ const user = await client.user.getUserByName({ username: 'john' })
610
+ twoslash: false
611
+ - name: bundle
612
+ type: boolean
613
+ required: false
614
+ default: 'false'
615
+ description: Controls whether the HTTP client runtime is copied into the generated `.kubb` directory.
616
+ body: |
617
+ - `true` adds a `.kubb/fetch.ts` file containing the selected client template (fetch or axios). Generated clients remain self-contained.
618
+ - `false` keeps generated clients slim by importing the shared runtime from `@kubb/plugin-client/clients/{client}`.
619
+ - Override this behavior by providing a custom `client.importPath`.
620
+ - name: baseURL
621
+ type: string
622
+ required: false
623
+ 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).
624
+ - name: include
625
+ type: Array<Include>
626
+ required: false
627
+ description: Array containing include parameters to include tags, operations, methods, paths, or content types.
628
+ codeBlock:
629
+ lang: typescript
630
+ title: Include
631
+ code: |
632
+ export type Include = {
633
+ type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
634
+ pattern: string | RegExp
635
+ }
636
+ - name: exclude
637
+ type: Array<Exclude>
638
+ required: false
639
+ description: Array containing exclude parameters to exclude or skip tags, operations, methods, paths, or content types.
640
+ codeBlock:
641
+ lang: typescript
642
+ title: Exclude
643
+ code: |
644
+ export type Exclude = {
645
+ type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
646
+ pattern: string | RegExp
647
+ }
648
+ - name: override
649
+ type: Array<Override>
650
+ required: false
651
+ description: Array containing override parameters to override `options` based on tags, operations, methods, paths, or content types.
652
+ codeBlock:
653
+ lang: typescript
654
+ title: Override
655
+ code: |
656
+ export type Override = {
657
+ type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
658
+ pattern: string | RegExp
659
+ options: PluginOptions
660
+ }
661
+ - name: generators
662
+ type: Array<Generator<PluginClient>>
663
+ required: false
664
+ experimental: true
665
+ description: |
666
+ Define additional generators next to the built-in generators.
667
+
668
+ See [Generators](https://kubb.dev/docs/5.x/guides/creating-plugins) for more information on how to use generators.
669
+ - name: transformers
670
+ type: Visitor
671
+ required: false
672
+ description: |
673
+ A single AST visitor applied to every node before code is printed. Each method you provide replaces the corresponding built-in one. When a method returns `null` or `undefined`, the preset transformer's result is used as the fallback — so you only need to supply the methods you want to change.
674
+
675
+ Visitor methods receive the node and a context object. Return a modified node to replace it, or return `undefined`/`void` to leave it unchanged.
676
+ examples:
677
+ - name: Strip descriptions before printing
678
+ files:
679
+ - lang: typescript
680
+ code: |
681
+ import { pluginTs } from '@kubb/plugin-ts'
682
+
683
+ pluginTs({
684
+ transformer: {
685
+ schema(node) {
686
+ return { ...node, description: undefined }
687
+ },
688
+ },
689
+ })
690
+ twoslash: false
691
+ - name: Prefix every operationId
692
+ files:
693
+ - lang: typescript
694
+ code: |
695
+ import { pluginTs } from '@kubb/plugin-ts'
696
+
697
+ pluginTs({
698
+ transformer: {
699
+ operation(node) {
700
+ return { ...node, operationId: `api_${node.operationId}` }
701
+ },
702
+ },
703
+ })
704
+ twoslash: false
705
+ tip: |
706
+ Use `transformer` to rewrite node properties before printing. For output naming customization, use `resolver` instead.
707
+ - name: resolver
708
+ type: Partial<ResolverClient> & ThisType<ResolverClient>
709
+ required: false
710
+ description: Override individual resolver methods to customize generated names. Any method you omit falls back to the preset resolver. Use `this.default(...)` to call the preset's implementation.
711
+ codeBlock:
712
+ lang: typescript
713
+ code: |
714
+ import { pluginClient } from '@kubb/plugin-client'
715
+
716
+ pluginClient({
717
+ resolver: {
718
+ resolveName(name) {
719
+ return `${this.default(name)}Client`
720
+ },
721
+ },
722
+ })
723
+ - name: transformer
724
+ type: Visitor
725
+ required: false
726
+ experimental: true
727
+ description: Apply an AST `Visitor` to transform operation nodes before they are printed.
728
+ codeBlock:
729
+ lang: typescript
730
+ code: |
731
+ import { pluginClient } from '@kubb/plugin-client'
732
+
733
+ pluginClient({
734
+ transformer: {
735
+ operation(node) {
736
+ return { ...node, operationId: `api_${node.operationId}` }
737
+ },
738
+ },
739
+ })
740
+ examples:
741
+ - name: kubb.config.ts
742
+ files:
743
+ - lang: typescript
744
+ code: |
745
+ import { defineConfig } from 'kubb'
746
+ import { pluginTs } from '@kubb/plugin-ts'
747
+ import { pluginClient } from '@kubb/plugin-client'
748
+
749
+ export default defineConfig({
750
+ input: { path: './petStore.yaml' },
751
+ output: { path: './src/gen' },
752
+ plugins: [
753
+ pluginTs(),
754
+ pluginClient({
755
+ output: {
756
+ path: './clients/axios',
757
+ barrel: { type: 'named' },
758
+ banner: '/* eslint-disable no-alert, no-console */',
759
+ footer: '',
760
+ },
761
+ group: {
762
+ type: 'tag',
763
+ name: ({ group }) => `${group}Service`,
764
+ },
765
+ resolver: {
766
+ resolveName(name) {
767
+ return `${this.default(name)}Client`
768
+ },
769
+ },
770
+ operations: true,
771
+ parser: 'client',
772
+ exclude: [{ type: 'tag', pattern: 'store' }],
773
+ pathParamsType: 'object',
774
+ dataReturnType: 'full',
775
+ client: 'axios',
776
+ }),
777
+ ],
778
+ })
779
+ twoslash: false