@kubb/plugin-cypress 5.0.0-beta.4 → 5.0.0-beta.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/extension.yaml CHANGED
@@ -2,18 +2,18 @@ $schema: https://kubb.dev/schemas/extension.json
2
2
  kind: plugin
3
3
  id: plugin-cypress
4
4
  name: Cypress
5
- description: Generate Cypress end-to-end tests from OpenAPI specifications.
5
+ description: Generate typed `cy.request()` wrappers from OpenAPI so end-to-end tests reuse one source of truth for API calls.
6
6
  category: testing
7
7
  type: official
8
- npmPackage: "@kubb/plugin-cypress"
8
+ npmPackage: '@kubb/plugin-cypress'
9
9
  docsPath: /plugins/plugin-cypress
10
10
  repo: https://github.com/kubb-labs/plugins
11
11
  maintainers:
12
12
  - name: Stijn Van Hulle
13
13
  github: stijnvanhulle
14
14
  compatibility:
15
- kubb: ">=5.0.0"
16
- node: ">=22"
15
+ kubb: '>=5.0.0'
16
+ node: '>=22'
17
17
  tags:
18
18
  - cypress
19
19
  - e2e-testing
@@ -35,111 +35,364 @@ icon:
35
35
  intro: |
36
36
  # @kubb/plugin-cypress
37
37
 
38
- Generate typed `cy.request()` wrappers from your OpenAPI schema. Each API operation becomes a reusable function you can call in Cypress tests, with full TypeScript support.
38
+ Generate one typed `cy.request()` wrapper per OpenAPI operation. Each helper has typed path params, body, query, and a typed response so failing API calls in Cypress show up at compile time instead of inside the test runner.
39
+
40
+ Use these helpers in `before`/`beforeEach` hooks to seed data, in custom commands, or in API-only test specs.
39
41
  options:
40
42
  - name: output
41
43
  type: Output
42
44
  required: false
43
- default: "{ path: 'cypress', barrelType: 'named' }"
44
- description: Specify the export location for the files and define the behavior of the output.
45
+ default: "{ path: 'cypress', barrel: { type: 'named' } }"
46
+ description: Where the generated Cypress helpers are written and how they are exported.
45
47
  properties:
46
48
  - name: path
47
49
  type: string
48
50
  required: true
49
- description: Output directory or file for the generated code, relative to the global `output.path`.
51
+ description: |
52
+ Folder (or single file) where the plugin writes its generated code. The path is resolved against the global `output.path` set on `defineConfig`.
53
+
54
+ 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'`.
50
55
  tip: |
51
- if `output.path` is a file, `group` cannot be used.
56
+ When `output.path` points to a single file, the `group` option cannot be used because every operation ends up in the same file.
57
+ examples:
58
+ - name: kubb.config.ts
59
+ files:
60
+ - lang: typescript
61
+ twoslash: false
62
+ code: |
63
+ import { defineConfig } from 'kubb'
64
+ import { pluginTs } from '@kubb/plugin-ts'
65
+
66
+ export default defineConfig({
67
+ input: { path: './petStore.yaml' },
68
+ output: { path: './src/gen' },
69
+ plugins: [
70
+ pluginTs({
71
+ output: { path: './types' },
72
+ }),
73
+ ],
74
+ })
75
+ - name: Resulting tree
76
+ files:
77
+ - lang: text
78
+ twoslash: false
79
+ code: |
80
+ src/
81
+ └── gen/
82
+ └── types/
83
+ ├── Pet.ts
84
+ └── Store.ts
52
85
  default: "'cypress'"
53
- - name: barrelType
54
- type: "'all' | 'named' | 'propagate' | false"
86
+ - name: barrel
87
+ type: "{ type: 'named' | 'all', nested?: boolean } | false"
55
88
  required: false
56
- default: "'named'"
57
- description: Specify what to export and optionally disable barrel-file generation.
89
+ default: "{ type: 'named' }"
90
+ description: |
91
+ Controls how the generated `index.ts` (barrel) file re-exports the plugin's output.
92
+
93
+ - `{ type: 'named' }` re-exports each symbol by name. Best for tree-shaking and explicit imports.
94
+ - `{ type: 'all' }` uses `export *`. Smaller barrel file, but exports everything.
95
+ - `{ nested: true }` creates a barrel in every subdirectory, so callers can import from any depth.
96
+ - `false` skips the barrel entirely. The plugin's files are also excluded from the root `index.ts`.
58
97
  tip: |
59
- Using `propagate` will prevent a plugin from creating a barrel file, but it will still propagate, allowing [`output.barrelType`](https://kubb.dev/docs/5.x/configuration#output-barreltype) to export the specific function or type.
98
+ 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
99
  examples:
61
- - name: all
100
+ - name: "'named' (default)"
62
101
  files:
63
- - lang: typescript
102
+ - name: kubb.config.ts
103
+ lang: typescript
104
+ twoslash: false
64
105
  code: |
65
- export * from './gen/petService.ts'
106
+ import { defineConfig } from 'kubb'
107
+ import { pluginTs } from '@kubb/plugin-ts'
108
+
109
+ export default defineConfig({
110
+ input: { path: './petStore.yaml' },
111
+ output: { path: './src/gen' },
112
+ plugins: [
113
+ pluginTs({
114
+ output: { barrel: { type: 'named' } },
115
+ }),
116
+ ],
117
+ })
118
+ - name: src/gen/types/index.ts
119
+ lang: typescript
66
120
  twoslash: false
67
- - name: named
121
+ code: |
122
+ export { Pet, PetStatus } from './Pet'
123
+ export { Store } from './Store'
124
+ - name: "'all'"
68
125
  files:
69
- - lang: typescript
126
+ - name: kubb.config.ts
127
+ lang: typescript
128
+ twoslash: false
70
129
  code: |
71
- export { PetService } from './gen/petService.ts'
130
+ import { defineConfig } from 'kubb'
131
+ import { pluginTs } from '@kubb/plugin-ts'
132
+
133
+ export default defineConfig({
134
+ input: { path: './petStore.yaml' },
135
+ output: { path: './src/gen' },
136
+ plugins: [
137
+ pluginTs({
138
+ output: { barrel: { type: 'all' } },
139
+ }),
140
+ ],
141
+ })
142
+ - name: src/gen/types/index.ts
143
+ lang: typescript
72
144
  twoslash: false
73
- - name: propagate
145
+ code: |
146
+ export * from './Pet'
147
+ export * from './Store'
148
+ - name: nested
74
149
  files:
75
- - lang: typescript
76
- code: ""
150
+ - name: kubb.config.ts
151
+ lang: typescript
152
+ twoslash: false
153
+ code: |
154
+ import { defineConfig } from 'kubb'
155
+ import { pluginTs } from '@kubb/plugin-ts'
156
+
157
+ export default defineConfig({
158
+ input: { path: './petStore.yaml' },
159
+ output: { path: './src/gen' },
160
+ plugins: [
161
+ pluginTs({
162
+ output: { barrel: { type: 'named', nested: true } },
163
+ }),
164
+ ],
165
+ })
166
+ - name: Generated tree
167
+ lang: text
77
168
  twoslash: false
78
- - name: "false"
169
+ code: |
170
+ src/gen/types/
171
+ ├── index.ts # re-exports ./petController and ./storeController
172
+ ├── petController/
173
+ │ ├── index.ts # re-exports Pet, Store, ...
174
+ │ └── Pet.ts
175
+ └── storeController/
176
+ ├── index.ts
177
+ └── Store.ts
178
+ - name: 'false'
79
179
  files:
80
- - lang: typescript
81
- code: ""
180
+ - name: kubb.config.ts
181
+ lang: typescript
182
+ twoslash: false
183
+ code: |
184
+ import { defineConfig } from 'kubb'
185
+ import { pluginTs } from '@kubb/plugin-ts'
186
+
187
+ export default defineConfig({
188
+ input: { path: './petStore.yaml' },
189
+ output: { path: './src/gen' },
190
+ plugins: [
191
+ pluginTs({
192
+ output: { barrel: false },
193
+ }),
194
+ ],
195
+ })
196
+ - name: Result
197
+ lang: text
82
198
  twoslash: false
199
+ code: |
200
+ # No index.ts is generated for this plugin.
201
+ # Its files are also excluded from the root index.ts.
83
202
  - name: banner
84
- type: "string | ((node: RootNode) => string)"
203
+ type: 'string | ((node: RootNode) => string)'
85
204
  required: false
86
- 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.
205
+ description: |
206
+ Text prepended to every generated file. Useful for license headers, lint disables, or `@ts-nocheck` directives.
207
+
208
+ 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).
209
+ examples:
210
+ - name: Static banner
211
+ files:
212
+ - name: kubb.config.ts
213
+ lang: typescript
214
+ twoslash: false
215
+ code: |
216
+ import { defineConfig } from 'kubb'
217
+ import { pluginTs } from '@kubb/plugin-ts'
218
+
219
+ export default defineConfig({
220
+ input: { path: './petStore.yaml' },
221
+ output: { path: './src/gen' },
222
+ plugins: [
223
+ pluginTs({
224
+ output: {
225
+ banner: '/* eslint-disable */\n// @ts-nocheck',
226
+ },
227
+ }),
228
+ ],
229
+ })
230
+ - name: Generated file
231
+ lang: typescript
232
+ twoslash: false
233
+ code: |
234
+ /* eslint-disable */
235
+ // @ts-nocheck
236
+ export type Pet = {
237
+ id: number
238
+ name: string
239
+ }
240
+ - name: Dynamic banner
241
+ files:
242
+ - name: kubb.config.ts
243
+ lang: typescript
244
+ twoslash: false
245
+ code: |
246
+ import { defineConfig } from 'kubb'
247
+ import { pluginTs } from '@kubb/plugin-ts'
248
+
249
+ export default defineConfig({
250
+ input: { path: './petStore.yaml' },
251
+ output: { path: './src/gen' },
252
+ plugins: [
253
+ pluginTs({
254
+ output: {
255
+ banner: (node) => `// Source: ${node.path}\n// Generated at ${new Date().toISOString()}`,
256
+ },
257
+ }),
258
+ ],
259
+ })
87
260
  - name: footer
88
- type: "string | ((node: RootNode) => string)"
261
+ type: 'string | ((node: RootNode) => string)'
89
262
  required: false
90
- 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.
263
+ description: |
264
+ 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.
265
+
266
+ Pass a string for a static footer, or a function that receives the file's `RootNode` and returns the footer text.
267
+ examples:
268
+ - name: Re-enable lint after a banner disable
269
+ files:
270
+ - name: kubb.config.ts
271
+ lang: typescript
272
+ twoslash: false
273
+ code: |
274
+ import { defineConfig } from 'kubb'
275
+ import { pluginTs } from '@kubb/plugin-ts'
276
+
277
+ export default defineConfig({
278
+ input: { path: './petStore.yaml' },
279
+ output: { path: './src/gen' },
280
+ plugins: [
281
+ pluginTs({
282
+ output: {
283
+ banner: '/* eslint-disable */',
284
+ footer: '/* eslint-enable */',
285
+ },
286
+ }),
287
+ ],
288
+ })
91
289
  - name: override
92
290
  type: boolean
93
291
  required: false
94
- default: "false"
95
- description: Whether Kubb overrides existing external files that can be generated if they already exist.
292
+ default: 'false'
293
+ description: |
294
+ Allows the plugin to overwrite hand-written files that share a name with a generated file.
295
+
296
+ - `false` (default): Kubb skips a file if it already exists and is not marked as generated. This protects manual edits.
297
+ - `true`: Kubb overwrites any file at the target path, including hand-written ones.
298
+ warning: |
299
+ Enable this only when you are sure the target folder contains nothing you need to keep. Local edits are lost on the next generation.
300
+ examples:
301
+ - name: kubb.config.ts
302
+ files:
303
+ - lang: typescript
304
+ twoslash: false
305
+ code: |
306
+ import { defineConfig } from 'kubb'
307
+ import { pluginTs } from '@kubb/plugin-ts'
308
+
309
+ export default defineConfig({
310
+ input: { path: './petStore.yaml' },
311
+ output: { path: './src/gen' },
312
+ plugins: [
313
+ pluginTs({
314
+ output: { override: true },
315
+ }),
316
+ ],
317
+ })
96
318
  - name: resolver
97
319
  type: Partial<ResolverCypress> & ThisType<ResolverCypress>
98
320
  required: false
99
321
  description: |
100
- A single resolver that overrides the naming and path-resolution conventions. Each method you provide replaces the corresponding built-in one. When a method returns `null` or `undefined`, the resolver's result is used as the fallback, so you only need to supply the methods you want to change.
322
+ Overrides how the plugin builds names and paths for generated files and symbols. Use this to add prefixes, suffixes, or to swap the casing strategy without forking the plugin.
323
+
324
+ Only override the methods you want to change. Anything you omit falls back to the plugin's default resolver. A method that returns `null` or `undefined` also falls back.
101
325
 
102
- `this` inside each method is bound to the **full** resolver, so you can call other resolver methods (e.g. `this.default(name, 'function')`) without losing context.
326
+ Inside each method, `this` is bound to the full resolver, so you can call `this.default(name, 'function')` to delegate to the built-in implementation.
103
327
  body: |
104
- Each plugin ships a built-in resolver:
328
+ Each plugin ships with a default resolver:
105
329
 
106
330
  | Plugin | Default resolver |
107
331
  | --- | --- |
108
332
  | `@kubb/plugin-ts` | `resolverTs` |
109
333
  | `@kubb/plugin-zod` | `resolverZod` |
334
+ | `@kubb/plugin-faker` | `resolverFaker` |
110
335
  | `@kubb/plugin-cypress` | `resolverCypress` |
336
+ | `@kubb/plugin-msw` | `resolverMsw` |
111
337
  | `@kubb/plugin-mcp` | `resolverMcp` |
338
+ | `@kubb/plugin-client` | `resolverClient` |
112
339
  codeBlock:
113
340
  lang: typescript
114
- title: Custom resolver (plugin-ts example)
341
+ title: Add an Api prefix to every name
115
342
  code: |
343
+ import { defineConfig } from 'kubb'
116
344
  import { pluginTs } from '@kubb/plugin-ts'
117
345
 
118
- pluginTs({
119
- resolver: {
120
- resolveName(name) {
121
- // Prefix every operation-derived name; falls back for names where
122
- // this returns null/undefined.
123
- return `Api${this.default(name, 'function')}`
124
- },
125
- },
346
+ export default defineConfig({
347
+ input: { path: './petStore.yaml' },
348
+ output: { path: './src/gen' },
349
+ plugins: [
350
+ pluginTs({
351
+ resolver: {
352
+ resolveName(name) {
353
+ return `Api${this.default(name, 'function')}`
354
+ },
355
+ },
356
+ }),
357
+ ],
126
358
  })
127
359
  tip: |
128
- Use `resolver` for fine-grained control over naming conventions.
360
+ Use `resolver` for naming and file-location tweaks. For changing the AST nodes themselves (e.g. stripping descriptions), use `transformer` instead.
129
361
  - name: paramsType
130
362
  type: "'object' | 'inline'"
131
363
  required: false
132
364
  default: "'inline'"
133
- description: Defines how parameters are passed to generated functions. Switch between object-style parameters and inline parameters.
365
+ description: |
366
+ How operation parameters (path, query, headers) are exposed in the generated function signature.
367
+
368
+ - `'inline'` (default) — each parameter is a separate positional argument. Compact for operations with one or two params.
369
+ - `'object'` — every parameter is wrapped in a single object argument. Easier to read for operations with many params and named at the call site.
134
370
  tip: |
135
- When `paramsType` is set to `'object'`, `pathParams` will also be set to `'object'`.
136
- body: |
137
- - `'object'` returns params and pathParams as an object.
138
- - `'inline'` returns params as comma-separated params.
371
+ Setting `paramsType: 'object'` implicitly sets `pathParamsType: 'object'` as well, so call sites are consistent.
139
372
  examples:
140
- - name: object
373
+ - name: "'inline' (default)"
141
374
  files:
142
- - lang: typescript
375
+ - name: Generated client
376
+ lang: typescript
377
+ twoslash: false
378
+ code: |
379
+ export async function deletePet(
380
+ petId: DeletePetPathParams['petId'],
381
+ headers?: DeletePetHeaderParams,
382
+ config: Partial<RequestConfig> = {},
383
+ ) {
384
+ // ...
385
+ }
386
+ - name: Caller
387
+ lang: typescript
388
+ twoslash: false
389
+ code: |
390
+ await deletePet(42)
391
+ - name: "'object'"
392
+ files:
393
+ - name: Generated client
394
+ lang: typescript
395
+ twoslash: false
143
396
  code: |
144
397
  export async function deletePet(
145
398
  {
@@ -151,285 +404,485 @@ options:
151
404
  },
152
405
  config: Partial<RequestConfig> = {},
153
406
  ) {
154
- ...
407
+ // ...
155
408
  }
409
+ - name: Caller
410
+ lang: typescript
156
411
  twoslash: false
157
- - name: inline
158
- files:
159
- - lang: typescript
160
412
  code: |
161
- export async function deletePet(
162
- petId: DeletePetPathParams['petId'],
163
- headers?: DeletePetHeaderParams,
164
- config: Partial<RequestConfig> = {}
165
- ){
166
- ...
167
- }
168
- twoslash: false
413
+ await deletePet({ petId: 42, headers: { 'X-Api-Key': 'secret' } })
169
414
  - name: paramsCasing
170
415
  type: "'camelcase'"
171
416
  required: false
172
- description: Transform parameter names to a specific casing format for path, query, and header parameters in generated client code.
417
+ description: |
418
+ 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.
419
+
420
+ - `'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`.
173
421
  important: |
174
- 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.
175
- body: |
176
- - `'camelcase'` transforms parameter names to camelCase.
422
+ 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.
177
423
  examples:
178
- - name: With paramsCasing camelcase
424
+ - name: "With paramsCasing: 'camelcase'"
179
425
  files:
180
- - lang: typescript
426
+ - name: Generated client
427
+ lang: typescript
428
+ twoslash: false
181
429
  code: |
182
- // Function parameters use camelCase
430
+ // Function takes camelCase parameters
183
431
  export async function deletePet(
184
- petId: DeletePetPathParams['petId'], // ✓ camelCase
432
+ petId: DeletePetPathParams['petId'],
185
433
  headers?: DeletePetHeaderParams,
186
- config: Partial<RequestConfig> = {}
434
+ config: Partial<RequestConfig> = {},
187
435
  ) {
188
- // Automatically maps back to original name for the API
436
+ // ...mapped back to the original API name internally
189
437
  const pet_id = petId
190
438
 
191
- return fetch({
439
+ return client({
192
440
  method: 'DELETE',
193
- url: `/pet/${pet_id}`, // Uses original API parameter name
194
- ...
441
+ url: `/pet/${pet_id}`,
442
+ ...config,
195
443
  })
196
444
  }
445
+ - name: Caller
446
+ lang: typescript
197
447
  twoslash: false
448
+ code: |
449
+ await deletePet(42)
198
450
  - name: Without paramsCasing
199
451
  files:
200
- - lang: typescript
452
+ - name: Generated client
453
+ lang: typescript
454
+ twoslash: false
201
455
  code: |
202
- // Parameters use original API naming
456
+ // Function parameters mirror the OpenAPI spec
203
457
  export async function deletePet(
204
- pet_id: DeletePetPathParams['pet_id'], // Original naming
458
+ pet_id: DeletePetPathParams['pet_id'],
205
459
  headers?: DeletePetHeaderParams,
206
- config: Partial<RequestConfig> = {}
460
+ config: Partial<RequestConfig> = {},
207
461
  ) {
208
- return fetch({
462
+ return client({
209
463
  method: 'DELETE',
210
464
  url: `/pet/${pet_id}`,
211
- ...
465
+ ...config,
212
466
  })
213
467
  }
214
- twoslash: false
215
468
  tip: |
216
- 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.
469
+ Callers write friendly camelCase names. The generated client maps them back to whatever the API expects (snake_case path params, kebab-case headers, ...).
217
470
  - name: pathParamsType
218
471
  type: "'object' | 'inline'"
219
472
  required: false
220
473
  default: "'inline'"
221
- description: Defines how pathParams are passed to generated functions.
222
- body: |
223
- - `'object'` returns pathParams as an object.
224
- - `'inline'` returns pathParams as comma-separated params.
474
+ description: |
475
+ How URL path parameters appear in the generated function signature. Affects only path params; query/header params follow `paramsType`.
476
+
477
+ - `'inline'` (default) each path param is a positional argument: `getPetById(petId)`.
478
+ - `'object'` — path params are wrapped in a single object: `getPetById({ petId })`.
225
479
  examples:
226
- - name: object
480
+ - name: "'inline' (default)"
227
481
  files:
228
482
  - lang: typescript
483
+ twoslash: false
229
484
  code: |
230
485
  export async function getPetById(
231
- { petId }: GetPetByIdPathParams,
486
+ petId: GetPetByIdPathParams,
232
487
  ) {
233
- ...
488
+ // ...
234
489
  }
235
- twoslash: false
236
- - name: inline
490
+ - name: "'object'"
237
491
  files:
238
492
  - lang: typescript
493
+ twoslash: false
239
494
  code: |
240
495
  export async function getPetById(
241
- petId: GetPetByIdPathParams,
496
+ { petId }: GetPetByIdPathParams,
242
497
  ) {
243
- ...
498
+ // ...
244
499
  }
245
- twoslash: false
246
500
  - name: dataReturnType
247
501
  type: "'data' | 'full'"
248
502
  required: false
249
503
  default: "'data'"
250
504
  description: |
251
- Return type used when calling the client.
505
+ Shape of the value returned from each generated client function.
252
506
 
253
- - `'data'` returns `ResponseConfig['data']`.
254
- - `'full'` returns the full `ResponseConfig`.
507
+ - `'data'` returns only the response body (`response.data`). Concise and matches what most apps need.
508
+ - `'full'` returns the full response config — body, status code, headers, and the original request. Use this when callers need to inspect headers or status.
255
509
  examples:
256
- - name: data
510
+ - name: "'data' (default)"
257
511
  files:
258
- - lang: typescript
512
+ - name: getPetById.ts
513
+ lang: typescript
514
+ twoslash: false
259
515
  code: |
260
516
  export async function getPetById<TData>(
261
517
  petId: GetPetByIdPathParams,
262
518
  ): Promise<ResponseConfig<TData>['data']> {
263
- ...
519
+ // ...
264
520
  }
521
+ - name: usage.ts
522
+ lang: typescript
265
523
  twoslash: false
266
- - name: full
524
+ code: |
525
+ const pet = await getPetById(1)
526
+ // ^? Pet
527
+ - name: "'full'"
267
528
  files:
268
- - lang: typescript
529
+ - name: getPetById.ts
530
+ lang: typescript
531
+ twoslash: false
269
532
  code: |
270
533
  export async function getPetById<TData>(
271
534
  petId: GetPetByIdPathParams,
272
535
  ): Promise<ResponseConfig<TData>> {
273
- ...
536
+ // ...
274
537
  }
538
+ - name: usage.ts
539
+ lang: typescript
275
540
  twoslash: false
541
+ code: |
542
+ const response = await getPetById(1)
543
+ // ^? ResponseConfig<Pet>
544
+ console.log(response.status, response.headers)
545
+ const pet = response.data
276
546
  - name: baseURL
277
547
  type: string
278
548
  required: false
279
- 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).
549
+ description: |
550
+ 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).
551
+
552
+ Set this when the generated client should point at a different environment (staging, production) than the one written in the spec.
553
+ examples:
554
+ - name: Override the spec's server URL
555
+ files:
556
+ - lang: typescript
557
+ twoslash: false
558
+ code: |
559
+ import { defineConfig } from 'kubb'
560
+ import { pluginClient } from '@kubb/plugin-client'
561
+
562
+ export default defineConfig({
563
+ input: { path: './petStore.yaml' },
564
+ output: { path: './src/gen' },
565
+ plugins: [
566
+ pluginClient({
567
+ baseURL: 'https://petstore.swagger.io/v2',
568
+ }),
569
+ ],
570
+ })
280
571
  - name: group
281
572
  type: Group
282
573
  required: false
283
574
  description: |
284
- Grouping combines files in a folder based on a specific `type`.
575
+ Splits generated files into subfolders based on the operation's tag, so each tag in your OpenAPI spec gets its own directory.
576
+
577
+ 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.
578
+ tip: |
579
+ 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.
285
580
  examples:
286
581
  - name: kubb.config.ts
287
582
  files:
288
583
  - lang: typescript
289
- code: |
290
- group: {
291
- type: 'tag',
292
- name({ group }) {
293
- return `${group}Controller`
294
- }
295
- }
296
584
  twoslash: false
585
+ code: |
586
+ import { defineConfig } from 'kubb'
587
+ import { pluginTs } from '@kubb/plugin-ts'
588
+
589
+ export default defineConfig({
590
+ input: { path: './petStore.yaml' },
591
+ output: { path: './src/gen' },
592
+ plugins: [
593
+ pluginTs({
594
+ group: {
595
+ type: 'tag',
596
+ name: ({ group }) => `${group}Controller`,
597
+ },
598
+ }),
599
+ ],
600
+ })
297
601
  body: |
298
602
  With the configuration above, the generator emits:
299
603
 
300
604
  ```text
301
- .
302
- ├── src/
303
- └── petController/
304
- │ ├── addPet.ts
305
- │ │ └── getPet.ts
306
- │ └── storeController/
307
- │ ├── createStore.ts
308
- │ └── getStoreById.ts
309
- ├── petStore.yaml
310
- ├── kubb.config.ts
311
- └── package.json
605
+ src/gen/
606
+ ├── petController/
607
+ ├── AddPet.ts
608
+ └── GetPet.ts
609
+ └── storeController/
610
+ ├── CreateStore.ts
611
+ └── GetStoreById.ts
312
612
  ```
313
613
  properties:
314
614
  - name: type
315
615
  type: "'tag'"
316
616
  required: true
317
- description: Specify the property to group files by. Required when `group` is defined.
617
+ description: |
618
+ Property used to assign each operation to a group. Required whenever `group` is set.
619
+
620
+ 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.
318
621
  note: |
319
- `Required: true*` means this is required only when the `group` option is used. The `group` option itself is optional.
320
- body: |
321
- - `'tag'`: Uses the first tag from `operation.getTags().at(0)?.name`
622
+ `Required: true*` is conditional only required when the parent `group` option is used. `group` itself stays optional.
322
623
  - name: name
323
- type: "(context: GroupContext) => string"
624
+ type: '(context: GroupContext) => string'
324
625
  required: false
325
626
  default: (ctx) => `${ctx.group}Requests`
326
- description: Return the name of a group based on the group name. This is used for file and identifier generation.
627
+ description: Function that builds the folder/identifier name from a group key (the operation's first tag).
327
628
  - name: include
328
629
  type: Array<Include>
329
630
  required: false
330
- description: Array containing include parameters to include tags, operations, methods, paths, or content types.
631
+ description: |
632
+ Restricts generation to operations that match at least one entry in the list. Anything not matched is skipped.
633
+
634
+ Each entry filters by one of:
635
+
636
+ - `tag` — the operation's first tag in the OpenAPI spec.
637
+ - `operationId` — the operation's `operationId`.
638
+ - `path` — the URL pattern (`'/pet/{petId}'`).
639
+ - `method` — HTTP method (`'get'`, `'post'`, ...).
640
+ - `contentType` — the media type of the request body.
641
+
642
+ `pattern` accepts either a string (exact match) or a `RegExp` for fuzzy matches.
331
643
  codeBlock:
332
644
  lang: typescript
333
- title: Include
645
+ title: Type definition
334
646
  code: |
335
647
  export type Include = {
336
648
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
337
649
  pattern: string | RegExp
338
650
  }
651
+ examples:
652
+ - name: Only the pet tag
653
+ files:
654
+ - name: kubb.config.ts
655
+ lang: typescript
656
+ twoslash: false
657
+ code: |
658
+ import { defineConfig } from 'kubb'
659
+ import { pluginTs } from '@kubb/plugin-ts'
660
+
661
+ export default defineConfig({
662
+ input: { path: './petStore.yaml' },
663
+ output: { path: './src/gen' },
664
+ plugins: [
665
+ pluginTs({
666
+ include: [
667
+ { type: 'tag', pattern: 'pet' },
668
+ ],
669
+ }),
670
+ ],
671
+ })
672
+ - name: Only GET operations under /pet
673
+ files:
674
+ - name: kubb.config.ts
675
+ lang: typescript
676
+ twoslash: false
677
+ code: |
678
+ import { defineConfig } from 'kubb'
679
+ import { pluginTs } from '@kubb/plugin-ts'
680
+
681
+ export default defineConfig({
682
+ input: { path: './petStore.yaml' },
683
+ output: { path: './src/gen' },
684
+ plugins: [
685
+ pluginTs({
686
+ include: [
687
+ { type: 'method', pattern: 'get' },
688
+ { type: 'path', pattern: /^\/pet/ },
689
+ ],
690
+ }),
691
+ ],
692
+ })
339
693
  - name: exclude
340
694
  type: Array<Exclude>
341
695
  required: false
342
- description: Array containing exclude parameters to exclude or skip tags, operations, methods, paths, or content types.
696
+ description: |
697
+ Skips any operation that matches at least one entry in the list. The opposite of `include`.
698
+
699
+ Each entry filters by one of:
700
+
701
+ - `tag` — the operation's first tag.
702
+ - `operationId` — the operation's `operationId`.
703
+ - `path` — the URL pattern (`'/pet/{petId}'`).
704
+ - `method` — HTTP method (`'get'`, `'post'`, ...).
705
+ - `contentType` — the media type of the request body.
706
+
707
+ `pattern` accepts a plain string or a `RegExp`. When both `include` and `exclude` are set, `exclude` wins.
343
708
  codeBlock:
344
709
  lang: typescript
345
- title: Exclude
710
+ title: Type definition
346
711
  code: |
347
712
  export type Exclude = {
348
713
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
349
714
  pattern: string | RegExp
350
715
  }
716
+ examples:
717
+ - name: Skip everything under the store tag
718
+ files:
719
+ - name: kubb.config.ts
720
+ lang: typescript
721
+ twoslash: false
722
+ code: |
723
+ import { defineConfig } from 'kubb'
724
+ import { pluginTs } from '@kubb/plugin-ts'
725
+
726
+ export default defineConfig({
727
+ input: { path: './petStore.yaml' },
728
+ output: { path: './src/gen' },
729
+ plugins: [
730
+ pluginTs({
731
+ exclude: [
732
+ { type: 'tag', pattern: 'store' },
733
+ ],
734
+ }),
735
+ ],
736
+ })
737
+ - name: Skip a specific operation and all delete methods
738
+ files:
739
+ - name: kubb.config.ts
740
+ lang: typescript
741
+ twoslash: false
742
+ code: |
743
+ import { defineConfig } from 'kubb'
744
+ import { pluginTs } from '@kubb/plugin-ts'
745
+
746
+ export default defineConfig({
747
+ input: { path: './petStore.yaml' },
748
+ output: { path: './src/gen' },
749
+ plugins: [
750
+ pluginTs({
751
+ exclude: [
752
+ { type: 'operationId', pattern: 'deletePet' },
753
+ { type: 'method', pattern: 'delete' },
754
+ ],
755
+ }),
756
+ ],
757
+ })
351
758
  - name: override
352
759
  type: Array<Override>
353
760
  required: false
354
- description: Array containing override parameters to override `options` based on tags, operations, methods, paths, or content types.
761
+ description: |
762
+ 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.
763
+
764
+ 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.
765
+
766
+ Entries are evaluated top to bottom. The first matching entry's `options` is merged onto the plugin defaults; later entries do not stack.
355
767
  codeBlock:
356
768
  lang: typescript
357
- title: Override
769
+ title: Type definition
358
770
  code: |
359
771
  export type Override = {
360
772
  type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
361
773
  pattern: string | RegExp
362
774
  options: PluginOptions
363
775
  }
776
+ examples:
777
+ - name: Use a different enum style for the user tag
778
+ files:
779
+ - name: kubb.config.ts
780
+ lang: typescript
781
+ twoslash: false
782
+ code: |
783
+ import { defineConfig } from 'kubb'
784
+ import { pluginTs } from '@kubb/plugin-ts'
785
+
786
+ export default defineConfig({
787
+ input: { path: './petStore.yaml' },
788
+ output: { path: './src/gen' },
789
+ plugins: [
790
+ pluginTs({
791
+ enumType: 'asConst',
792
+ override: [
793
+ {
794
+ type: 'tag',
795
+ pattern: 'user',
796
+ options: { enumType: 'literal' },
797
+ },
798
+ ],
799
+ }),
800
+ ],
801
+ })
364
802
  - name: generators
365
803
  type: Array<Generator<PluginCypress>>
366
804
  required: false
367
805
  experimental: true
368
806
  description: |
369
- Define additional generators next to the built-in generators.
807
+ 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.
370
808
 
371
- See [Generators](https://kubb.dev/docs/5.x/guides/creating-plugins) for more information on how to use generators.
809
+ 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).
810
+ warning: |
811
+ Generators are an experimental, low-level API. The signature may change between minor releases.
372
812
  - name: transformer
373
813
  type: Visitor
374
814
  required: false
375
815
  description: |
376
- 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.
816
+ Modifies AST nodes before they are printed to source code. Use this when you need to rewrite operation IDs, drop descriptions, or change schema metadata without forking the generator.
377
817
 
378
- Visitor methods receive the node and a context object. Return a modified node to replace it, or return `undefined`/`void` to leave it unchanged.
818
+ Each visitor method (e.g. `schema`, `operation`) receives the node and a context object. Return a new node to replace it, or return `undefined` to leave it untouched. Methods you omit keep the plugin's default behavior.
379
819
  examples:
380
820
  - name: Strip descriptions before printing
381
821
  files:
382
- - lang: typescript
822
+ - name: kubb.config.ts
823
+ lang: typescript
824
+ twoslash: false
383
825
  code: |
826
+ import { defineConfig } from 'kubb'
384
827
  import { pluginTs } from '@kubb/plugin-ts'
385
828
 
386
- pluginTs({
387
- transformer: {
388
- schema(node) {
389
- return { ...node, description: undefined }
390
- },
391
- },
829
+ export default defineConfig({
830
+ input: { path: './petStore.yaml' },
831
+ output: { path: './src/gen' },
832
+ plugins: [
833
+ pluginTs({
834
+ transformer: {
835
+ schema(node) {
836
+ return { ...node, description: undefined }
837
+ },
838
+ },
839
+ }),
840
+ ],
392
841
  })
393
- twoslash: false
394
842
  - name: Prefix every operationId
395
843
  files:
396
- - lang: typescript
844
+ - name: kubb.config.ts
845
+ lang: typescript
846
+ twoslash: false
397
847
  code: |
848
+ import { defineConfig } from 'kubb'
398
849
  import { pluginTs } from '@kubb/plugin-ts'
399
850
 
400
- pluginTs({
401
- transformer: {
402
- operation(node) {
403
- return { ...node, operationId: `api_${node.operationId}` }
404
- },
405
- },
851
+ export default defineConfig({
852
+ input: { path: './petStore.yaml' },
853
+ output: { path: './src/gen' },
854
+ plugins: [
855
+ pluginTs({
856
+ transformer: {
857
+ operation(node) {
858
+ return { ...node, operationId: `api_${node.operationId}` }
859
+ },
860
+ },
861
+ }),
862
+ ],
406
863
  })
407
- twoslash: false
408
864
  tip: |
409
- Use `transformer` to rewrite node properties before printing. For output naming customization, use `resolver` instead.
865
+ Use `transformer` to rewrite node properties before printing. For changing the names of generated symbols and files, use `resolver` instead.
410
866
  examples:
411
867
  - name: kubb.config.ts
412
868
  files:
413
869
  - lang: typescript
870
+ twoslash: false
414
871
  code: |
415
872
  import { defineConfig } from 'kubb'
416
873
  import { pluginTs } from '@kubb/plugin-ts'
417
874
  import { pluginCypress } from '@kubb/plugin-cypress'
418
875
 
419
876
  export default defineConfig({
420
- input: {
421
- path: './petStore.yaml',
422
- },
423
- output: {
424
- path: './src/gen',
425
- },
877
+ input: { path: './petStore.yaml' },
878
+ output: { path: './src/gen' },
426
879
  plugins: [
427
880
  pluginTs(),
428
881
  pluginCypress({
429
882
  output: {
430
883
  path: './cypress',
431
- barrelType: 'named',
432
- banner: '/* eslint-disable no-alert, no-console */',
884
+ barrel: { type: 'named' },
885
+ banner: '/* eslint-disable */',
433
886
  },
434
887
  group: {
435
888
  type: 'tag',
@@ -438,4 +891,18 @@ examples:
438
891
  }),
439
892
  ],
440
893
  })
441
- twoslash: false
894
+ - name: Using a generated helper
895
+ files:
896
+ - lang: typescript
897
+ twoslash: false
898
+ code: |
899
+ import { getPetByIdRequest } from '../gen/cypress/petRequests'
900
+
901
+ describe('Pet API', () => {
902
+ it('returns the pet by id', () => {
903
+ getPetByIdRequest(1).then((response) => {
904
+ expect(response.status).to.eq(200)
905
+ expect(response.body.id).to.eq(1)
906
+ })
907
+ })
908
+ })