@kubb/plugin-msw 5.0.0-beta.3 → 5.0.0-beta.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +26 -5
  2. package/dist/{components-CLQ77DVn.cjs → components-B1Dsj2WT.cjs} +67 -72
  3. package/dist/components-B1Dsj2WT.cjs.map +1 -0
  4. package/dist/{components-vO0FIb2i.js → components-BxzfyX2u.js} +64 -63
  5. package/dist/components-BxzfyX2u.js.map +1 -0
  6. package/dist/components.cjs +1 -1
  7. package/dist/components.d.ts +5 -5
  8. package/dist/components.js +1 -1
  9. package/dist/{generators-CrmMwWE4.cjs → generators-C5AvweCJ.cjs} +61 -31
  10. package/dist/generators-C5AvweCJ.cjs.map +1 -0
  11. package/dist/{generators-BPJCs1x1.js → generators-srLe3oqm.js} +63 -33
  12. package/dist/generators-srLe3oqm.js.map +1 -0
  13. package/dist/generators.cjs +1 -1
  14. package/dist/generators.d.ts +13 -1
  15. package/dist/generators.js +1 -1
  16. package/dist/index.cjs +90 -15
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +31 -1
  19. package/dist/index.js +90 -15
  20. package/dist/index.js.map +1 -1
  21. package/dist/types-CLAiv8qc.d.ts +103 -0
  22. package/extension.yaml +680 -0
  23. package/package.json +11 -14
  24. package/src/components/Handlers.tsx +1 -1
  25. package/src/components/Mock.tsx +5 -4
  26. package/src/components/MockWithFaker.tsx +5 -4
  27. package/src/components/Response.tsx +1 -1
  28. package/src/generators/handlersGenerator.tsx +18 -12
  29. package/src/generators/mswGenerator.tsx +29 -18
  30. package/src/plugin.ts +34 -18
  31. package/src/resolvers/resolverMsw.ts +19 -3
  32. package/src/types.ts +35 -21
  33. package/src/utils.ts +26 -61
  34. package/dist/components-CLQ77DVn.cjs.map +0 -1
  35. package/dist/components-vO0FIb2i.js.map +0 -1
  36. package/dist/generators-BPJCs1x1.js.map +0 -1
  37. package/dist/generators-CrmMwWE4.cjs.map +0 -1
  38. package/dist/types-Dxu0KMQ4.d.ts +0 -89
package/extension.yaml ADDED
@@ -0,0 +1,680 @@
1
+ $schema: https://kubb.dev/schemas/extension.json
2
+ kind: plugin
3
+ id: plugin-msw
4
+ name: MSW
5
+ description: Generate MSW request handlers from OpenAPI so you can mock the entire API in tests and during local development.
6
+ category: mocks
7
+ type: official
8
+ npmPackage: '@kubb/plugin-msw'
9
+ docsPath: /plugins/plugin-msw
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
+ - msw
19
+ - mock-service-worker
20
+ - api-mocking
21
+ - mocks
22
+ - testing
23
+ - codegen
24
+ - openapi
25
+ dependencies:
26
+ - plugin-ts
27
+ - plugin-faker
28
+ resources:
29
+ documentation: https://kubb.dev/plugins/plugin-msw
30
+ repository: https://github.com/kubb-labs/plugins
31
+ issues: https://github.com/kubb-labs/plugins/issues
32
+ changelog: https://github.com/kubb-labs/plugins/blob/main/packages/plugin-msw/CHANGELOG.md
33
+ codesandbox: https://codesandbox.io/p/github/kubb-labs/plugins/main/examples/msw
34
+ featured: false
35
+ icon:
36
+ light: https://kubb.dev/feature/msw.svg
37
+ intro: |
38
+ # @kubb/plugin-msw
39
+
40
+ Generate [MSW](https://mswjs.io/) handlers from your OpenAPI spec. Drop them into your test setup or service worker to mock the API end-to-end — request path, method, status, and response body all stay in sync with the spec.
41
+
42
+ Combine with `@kubb/plugin-faker` to seed handlers with realistic data, or feed them custom payloads from tests.
43
+ options:
44
+ - name: output
45
+ type: Output
46
+ required: false
47
+ default: "{ path: 'handlers', barrel: { type: 'named' } }"
48
+ description: Where the generated MSW handlers are written and how they are exported.
49
+ properties:
50
+ - name: path
51
+ type: string
52
+ required: true
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'`.
57
+ tip: |
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
87
+ default: "'handlers'"
88
+ - name: barrel
89
+ type: "{ type: 'named' | 'all', nested?: boolean } | false"
90
+ required: false
91
+ default: "{ type: 'named' }"
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.
101
+ examples:
102
+ - name: "'named' (default)"
103
+ files:
104
+ - name: kubb.config.ts
105
+ lang: typescript
106
+ twoslash: false
107
+ code: |
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
122
+ twoslash: false
123
+ code: |
124
+ export { Pet, PetStatus } from './Pet'
125
+ export { Store } from './Store'
126
+ - name: "'all'"
127
+ files:
128
+ - name: kubb.config.ts
129
+ lang: typescript
130
+ twoslash: false
131
+ code: |
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
146
+ twoslash: false
147
+ code: |
148
+ export * from './Pet'
149
+ export * from './Store'
150
+ - name: nested
151
+ files:
152
+ - name: kubb.config.ts
153
+ lang: typescript
154
+ twoslash: false
155
+ code: |
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
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
180
+ - name: 'false'
181
+ files:
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
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.
204
+ - name: banner
205
+ type: 'string | ((node: RootNode) => string)'
206
+ required: false
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
+ })
262
+ - name: footer
263
+ type: 'string | ((node: RootNode) => string)'
264
+ required: false
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
+ })
291
+ - name: override
292
+ type: boolean
293
+ required: false
294
+ default: 'false'
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
+ })
320
+ - name: handlers
321
+ type: boolean
322
+ required: false
323
+ default: 'false'
324
+ description: |
325
+ Emits a `handlers.ts` file that re-exports every generated handler grouped by HTTP method. Drop this file into your MSW `setupServer(...handlers)` or `setupWorker(...handlers)` call.
326
+ examples:
327
+ - name: setup.ts
328
+ files:
329
+ - lang: typescript
330
+ twoslash: false
331
+ code: |
332
+ import { setupServer } from 'msw/node'
333
+ import { handlersGet, handlersPost } from './gen/handlers'
334
+
335
+ export const server = setupServer(...handlersGet, ...handlersPost)
336
+ - name: contentType
337
+ type: "'application/json' | (string & {})"
338
+ required: false
339
+ description: |
340
+ Selects which request/response media type the generator reads from the OpenAPI spec.
341
+
342
+ 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.
343
+ examples:
344
+ - name: JSON API media type
345
+ files:
346
+ - lang: typescript
347
+ twoslash: false
348
+ code: |
349
+ import { defineConfig } from 'kubb'
350
+ import { pluginTs } from '@kubb/plugin-ts'
351
+
352
+ export default defineConfig({
353
+ input: { path: './petStore.yaml' },
354
+ output: { path: './src/gen' },
355
+ plugins: [
356
+ pluginTs({
357
+ contentType: 'application/vnd.api+json',
358
+ }),
359
+ ],
360
+ })
361
+ - name: baseURL
362
+ type: string
363
+ required: false
364
+ description: |
365
+ 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).
366
+
367
+ Set this when the generated client should point at a different environment (staging, production) than the one written in the spec.
368
+ examples:
369
+ - name: Override the spec's server URL
370
+ files:
371
+ - lang: typescript
372
+ twoslash: false
373
+ code: |
374
+ import { defineConfig } from 'kubb'
375
+ import { pluginClient } from '@kubb/plugin-client'
376
+
377
+ export default defineConfig({
378
+ input: { path: './petStore.yaml' },
379
+ output: { path: './src/gen' },
380
+ plugins: [
381
+ pluginClient({
382
+ baseURL: 'https://petstore.swagger.io/v2',
383
+ }),
384
+ ],
385
+ })
386
+ - name: group
387
+ type: Group
388
+ required: false
389
+ description: |
390
+ Splits generated files into subfolders based on the operation's tag, so each tag in your OpenAPI spec gets its own directory.
391
+
392
+ 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.
393
+ tip: |
394
+ 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.
395
+ examples:
396
+ - name: kubb.config.ts
397
+ files:
398
+ - lang: typescript
399
+ twoslash: false
400
+ code: |
401
+ import { defineConfig } from 'kubb'
402
+ import { pluginTs } from '@kubb/plugin-ts'
403
+
404
+ export default defineConfig({
405
+ input: { path: './petStore.yaml' },
406
+ output: { path: './src/gen' },
407
+ plugins: [
408
+ pluginTs({
409
+ group: {
410
+ type: 'tag',
411
+ name: ({ group }) => `${group}Controller`,
412
+ },
413
+ }),
414
+ ],
415
+ })
416
+ body: |
417
+ With the configuration above, the generator emits:
418
+
419
+ ```text
420
+ src/gen/
421
+ ├── petController/
422
+ │ ├── AddPet.ts
423
+ │ └── GetPet.ts
424
+ └── storeController/
425
+ ├── CreateStore.ts
426
+ └── GetStoreById.ts
427
+ ```
428
+ properties:
429
+ - name: type
430
+ type: "'tag'"
431
+ required: true
432
+ description: |
433
+ Property used to assign each operation to a group. Required whenever `group` is set.
434
+
435
+ 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.
436
+ note: |
437
+ `Required: true*` is conditional — only required when the parent `group` option is used. `group` itself stays optional.
438
+ - name: name
439
+ type: '(context: GroupContext) => string'
440
+ required: false
441
+ default: (ctx) => `${ctx.group}Controller`
442
+ description: Function that builds the folder/identifier name from a group key (the operation's first tag).
443
+ - name: parser
444
+ type: "'data' | 'faker'"
445
+ required: false
446
+ default: "'data'"
447
+ description: |
448
+ Source of the response body returned by each generated handler.
449
+
450
+ - `'data'` (default) — handlers return a typed empty/example payload, ready for you to fill in from tests.
451
+ - `'faker'` — handlers return a value produced by `@kubb/plugin-faker`. Requires the Faker plugin in the plugins array.
452
+ examples:
453
+ - name: "'faker'"
454
+ files:
455
+ - lang: typescript
456
+ twoslash: false
457
+ code: |
458
+ import { defineConfig } from 'kubb'
459
+ import { pluginTs } from '@kubb/plugin-ts'
460
+ import { pluginFaker } from '@kubb/plugin-faker'
461
+ import { pluginMsw } from '@kubb/plugin-msw'
462
+
463
+ export default defineConfig({
464
+ input: { path: './petStore.yaml' },
465
+ output: { path: './src/gen' },
466
+ plugins: [
467
+ pluginTs(),
468
+ pluginFaker(),
469
+ pluginMsw({ parser: 'faker' }),
470
+ ],
471
+ })
472
+ - name: include
473
+ type: Array<Include>
474
+ required: false
475
+ description: |
476
+ Restricts generation to operations that match at least one entry in the list. Anything not matched is skipped.
477
+
478
+ Each entry filters by one of:
479
+
480
+ - `tag` — the operation's first tag in the OpenAPI spec.
481
+ - `operationId` — the operation's `operationId`.
482
+ - `path` — the URL pattern (`'/pet/{petId}'`).
483
+ - `method` — HTTP method (`'get'`, `'post'`, ...).
484
+ - `contentType` — the media type of the request body.
485
+
486
+ `pattern` accepts either a string (exact match) or a `RegExp` for fuzzy matches.
487
+ codeBlock:
488
+ lang: typescript
489
+ title: Type definition
490
+ code: |
491
+ export type Include = {
492
+ type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
493
+ pattern: string | RegExp
494
+ }
495
+ examples:
496
+ - name: Only the pet tag
497
+ files:
498
+ - name: kubb.config.ts
499
+ lang: typescript
500
+ twoslash: false
501
+ code: |
502
+ import { defineConfig } from 'kubb'
503
+ import { pluginTs } from '@kubb/plugin-ts'
504
+
505
+ export default defineConfig({
506
+ input: { path: './petStore.yaml' },
507
+ output: { path: './src/gen' },
508
+ plugins: [
509
+ pluginTs({
510
+ include: [
511
+ { type: 'tag', pattern: 'pet' },
512
+ ],
513
+ }),
514
+ ],
515
+ })
516
+ - name: Only GET operations under /pet
517
+ files:
518
+ - name: kubb.config.ts
519
+ lang: typescript
520
+ twoslash: false
521
+ code: |
522
+ import { defineConfig } from 'kubb'
523
+ import { pluginTs } from '@kubb/plugin-ts'
524
+
525
+ export default defineConfig({
526
+ input: { path: './petStore.yaml' },
527
+ output: { path: './src/gen' },
528
+ plugins: [
529
+ pluginTs({
530
+ include: [
531
+ { type: 'method', pattern: 'get' },
532
+ { type: 'path', pattern: /^\/pet/ },
533
+ ],
534
+ }),
535
+ ],
536
+ })
537
+ - name: exclude
538
+ type: Array<Exclude>
539
+ required: false
540
+ description: |
541
+ Skips any operation that matches at least one entry in the list. The opposite of `include`.
542
+
543
+ Each entry filters by one of:
544
+
545
+ - `tag` — the operation's first tag.
546
+ - `operationId` — the operation's `operationId`.
547
+ - `path` — the URL pattern (`'/pet/{petId}'`).
548
+ - `method` — HTTP method (`'get'`, `'post'`, ...).
549
+ - `contentType` — the media type of the request body.
550
+
551
+ `pattern` accepts a plain string or a `RegExp`. When both `include` and `exclude` are set, `exclude` wins.
552
+ codeBlock:
553
+ lang: typescript
554
+ title: Type definition
555
+ code: |
556
+ export type Exclude = {
557
+ type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
558
+ pattern: string | RegExp
559
+ }
560
+ examples:
561
+ - name: Skip everything under the store tag
562
+ files:
563
+ - name: kubb.config.ts
564
+ lang: typescript
565
+ twoslash: false
566
+ code: |
567
+ import { defineConfig } from 'kubb'
568
+ import { pluginTs } from '@kubb/plugin-ts'
569
+
570
+ export default defineConfig({
571
+ input: { path: './petStore.yaml' },
572
+ output: { path: './src/gen' },
573
+ plugins: [
574
+ pluginTs({
575
+ exclude: [
576
+ { type: 'tag', pattern: 'store' },
577
+ ],
578
+ }),
579
+ ],
580
+ })
581
+ - name: Skip a specific operation and all delete methods
582
+ files:
583
+ - name: kubb.config.ts
584
+ lang: typescript
585
+ twoslash: false
586
+ code: |
587
+ import { defineConfig } from 'kubb'
588
+ import { pluginTs } from '@kubb/plugin-ts'
589
+
590
+ export default defineConfig({
591
+ input: { path: './petStore.yaml' },
592
+ output: { path: './src/gen' },
593
+ plugins: [
594
+ pluginTs({
595
+ exclude: [
596
+ { type: 'operationId', pattern: 'deletePet' },
597
+ { type: 'method', pattern: 'delete' },
598
+ ],
599
+ }),
600
+ ],
601
+ })
602
+ - name: override
603
+ type: Array<Override>
604
+ required: false
605
+ description: |
606
+ 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.
607
+
608
+ 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.
609
+
610
+ Entries are evaluated top to bottom. The first matching entry's `options` is merged onto the plugin defaults; later entries do not stack.
611
+ codeBlock:
612
+ lang: typescript
613
+ title: Type definition
614
+ code: |
615
+ export type Override = {
616
+ type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
617
+ pattern: string | RegExp
618
+ options: PluginOptions
619
+ }
620
+ examples:
621
+ - name: Use a different enum style for the user tag
622
+ files:
623
+ - name: kubb.config.ts
624
+ lang: typescript
625
+ twoslash: false
626
+ code: |
627
+ import { defineConfig } from 'kubb'
628
+ import { pluginTs } from '@kubb/plugin-ts'
629
+
630
+ export default defineConfig({
631
+ input: { path: './petStore.yaml' },
632
+ output: { path: './src/gen' },
633
+ plugins: [
634
+ pluginTs({
635
+ enumType: 'asConst',
636
+ override: [
637
+ {
638
+ type: 'tag',
639
+ pattern: 'user',
640
+ options: { enumType: 'literal' },
641
+ },
642
+ ],
643
+ }),
644
+ ],
645
+ })
646
+ - name: generators
647
+ type: Array<Generator<PluginMsw>>
648
+ required: false
649
+ experimental: true
650
+ description: |
651
+ 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.
652
+
653
+ 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).
654
+ warning: |
655
+ Generators are an experimental, low-level API. The signature may change between minor releases.
656
+ examples:
657
+ - name: kubb.config.ts
658
+ files:
659
+ - lang: typescript
660
+ twoslash: false
661
+ code: |
662
+ import { defineConfig } from 'kubb'
663
+ import { pluginMsw } from '@kubb/plugin-msw'
664
+ import { pluginTs } from '@kubb/plugin-ts'
665
+
666
+ export default defineConfig({
667
+ input: { path: './petStore.yaml' },
668
+ output: { path: './src/gen' },
669
+ plugins: [
670
+ pluginTs(),
671
+ pluginMsw({
672
+ output: { path: './mocks' },
673
+ group: {
674
+ type: 'tag',
675
+ name: ({ group }) => `${group}Service`,
676
+ },
677
+ handlers: true,
678
+ }),
679
+ ],
680
+ })