@kubb/plugin-ts 5.0.0-beta.42 → 5.0.0-beta.56

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 DELETED
@@ -1,1080 +0,0 @@
1
- $schema: https://kubb.dev/schemas/extension.json
2
- kind: plugin
3
- id: plugin-ts
4
- name: TypeScript
5
- description: Generate TypeScript types and interfaces from OpenAPI schemas with full type safety end to end.
6
- category: types
7
- type: official
8
- npmPackage: '@kubb/plugin-ts'
9
- docsPath: /plugins/plugin-ts
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
- - typescript
19
- - types
20
- - interfaces
21
- - codegen
22
- - openapi
23
- dependencies: []
24
- resources:
25
- documentation: https://kubb.dev/plugins/plugin-ts
26
- repository: https://github.com/kubb-labs/plugins
27
- issues: https://github.com/kubb-labs/plugins/issues
28
- changelog: https://github.com/kubb-labs/plugins/blob/main/packages/plugin-ts/CHANGELOG.md
29
- codesandbox: https://codesandbox.io/p/github/kubb-labs/plugins/main/examples/typescript
30
- featured: true
31
- icon:
32
- light: https://kubb.dev/feature/typescript.svg
33
- intro: |
34
- # @kubb/plugin-ts
35
-
36
- `@kubb/plugin-ts` turns your OpenAPI schema into TypeScript `type` aliases and `interface` declarations. It is the foundation that every other Kubb plugin builds on — clients, query hooks, mocks, and validators all reference the names this plugin produces.
37
-
38
- Add it once and every request payload, response, path parameter, and enum becomes a compile-time check.
39
-
40
- **See also**
41
-
42
- - [TypeScript](https://www.typescriptlang.org/)
43
- - [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API)
44
- options:
45
- - name: output
46
- type: Output
47
- required: false
48
- default: "{ path: 'types', barrel: { type: 'named' } }"
49
- description: Where the generated `.ts` files are written and how they are exported.
50
- properties:
51
- - name: path
52
- type: string
53
- required: true
54
- description: |
55
- Folder (or single file) where the plugin writes its generated code. The path is resolved against the global `output.path` set on `defineConfig`.
56
-
57
- 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'`.
58
- tip: |
59
- When `output.path` points to a single file, the `group` option cannot be used because every operation ends up in the same file.
60
- examples:
61
- - name: kubb.config.ts
62
- files:
63
- - lang: typescript
64
- twoslash: false
65
- code: |
66
- import { defineConfig } from 'kubb'
67
- import { pluginTs } from '@kubb/plugin-ts'
68
-
69
- export default defineConfig({
70
- input: { path: './petStore.yaml' },
71
- output: { path: './src/gen' },
72
- plugins: [
73
- pluginTs({
74
- output: { path: './types' },
75
- }),
76
- ],
77
- })
78
- - name: Resulting tree
79
- files:
80
- - lang: text
81
- twoslash: false
82
- code: |
83
- src/
84
- └── gen/
85
- └── types/
86
- ├── Pet.ts
87
- └── Store.ts
88
- default: "'types'"
89
- - name: barrel
90
- type: "{ type: 'named' | 'all', nested?: boolean } | false"
91
- required: false
92
- default: "{ type: 'named' }"
93
- description: |
94
- Controls how the generated `index.ts` (barrel) file re-exports the plugin's output.
95
-
96
- - `{ type: 'named' }` re-exports each symbol by name. Best for tree-shaking and explicit imports.
97
- - `{ type: 'all' }` uses `export *`. Smaller barrel file, but exports everything.
98
- - `{ nested: true }` creates a barrel in every subdirectory, so callers can import from any depth.
99
- - `false` skips the barrel entirely. The plugin's files are also excluded from the root `index.ts`.
100
- tip: |
101
- 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.
102
- examples:
103
- - name: "'named' (default)"
104
- files:
105
- - name: kubb.config.ts
106
- lang: typescript
107
- twoslash: false
108
- code: |
109
- import { defineConfig } from 'kubb'
110
- import { pluginTs } from '@kubb/plugin-ts'
111
-
112
- export default defineConfig({
113
- input: { path: './petStore.yaml' },
114
- output: { path: './src/gen' },
115
- plugins: [
116
- pluginTs({
117
- output: { barrel: { type: 'named' } },
118
- }),
119
- ],
120
- })
121
- - name: src/gen/types/index.ts
122
- lang: typescript
123
- twoslash: false
124
- code: |
125
- export { Pet, PetStatus } from './Pet'
126
- export { Store } from './Store'
127
- - name: "'all'"
128
- files:
129
- - name: kubb.config.ts
130
- lang: typescript
131
- twoslash: false
132
- code: |
133
- import { defineConfig } from 'kubb'
134
- import { pluginTs } from '@kubb/plugin-ts'
135
-
136
- export default defineConfig({
137
- input: { path: './petStore.yaml' },
138
- output: { path: './src/gen' },
139
- plugins: [
140
- pluginTs({
141
- output: { barrel: { type: 'all' } },
142
- }),
143
- ],
144
- })
145
- - name: src/gen/types/index.ts
146
- lang: typescript
147
- twoslash: false
148
- code: |
149
- export * from './Pet'
150
- export * from './Store'
151
- - name: nested
152
- files:
153
- - name: kubb.config.ts
154
- lang: typescript
155
- twoslash: false
156
- code: |
157
- import { defineConfig } from 'kubb'
158
- import { pluginTs } from '@kubb/plugin-ts'
159
-
160
- export default defineConfig({
161
- input: { path: './petStore.yaml' },
162
- output: { path: './src/gen' },
163
- plugins: [
164
- pluginTs({
165
- output: { barrel: { type: 'named', nested: true } },
166
- }),
167
- ],
168
- })
169
- - name: Generated tree
170
- lang: text
171
- twoslash: false
172
- code: |
173
- src/gen/types/
174
- ├── index.ts # re-exports ./petController and ./storeController
175
- ├── petController/
176
- │ ├── index.ts # re-exports Pet, Store, ...
177
- │ └── Pet.ts
178
- └── storeController/
179
- ├── index.ts
180
- └── Store.ts
181
- - name: 'false'
182
- files:
183
- - name: kubb.config.ts
184
- lang: typescript
185
- twoslash: false
186
- code: |
187
- import { defineConfig } from 'kubb'
188
- import { pluginTs } from '@kubb/plugin-ts'
189
-
190
- export default defineConfig({
191
- input: { path: './petStore.yaml' },
192
- output: { path: './src/gen' },
193
- plugins: [
194
- pluginTs({
195
- output: { barrel: false },
196
- }),
197
- ],
198
- })
199
- - name: Result
200
- lang: text
201
- twoslash: false
202
- code: |
203
- # No index.ts is generated for this plugin.
204
- # Its files are also excluded from the root index.ts.
205
- - name: banner
206
- type: 'string | ((node: RootNode) => string)'
207
- required: false
208
- description: |
209
- Text prepended to every generated file. Useful for license headers, lint disables, or `@ts-nocheck` directives.
210
-
211
- 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).
212
- examples:
213
- - name: Static banner
214
- files:
215
- - name: kubb.config.ts
216
- lang: typescript
217
- twoslash: false
218
- code: |
219
- import { defineConfig } from 'kubb'
220
- import { pluginTs } from '@kubb/plugin-ts'
221
-
222
- export default defineConfig({
223
- input: { path: './petStore.yaml' },
224
- output: { path: './src/gen' },
225
- plugins: [
226
- pluginTs({
227
- output: {
228
- banner: '/* eslint-disable */\n// @ts-nocheck',
229
- },
230
- }),
231
- ],
232
- })
233
- - name: Generated file
234
- lang: typescript
235
- twoslash: false
236
- code: |
237
- /* eslint-disable */
238
- // @ts-nocheck
239
- export type Pet = {
240
- id: number
241
- name: string
242
- }
243
- - name: Dynamic banner
244
- files:
245
- - name: kubb.config.ts
246
- lang: typescript
247
- twoslash: false
248
- code: |
249
- import { defineConfig } from 'kubb'
250
- import { pluginTs } from '@kubb/plugin-ts'
251
-
252
- export default defineConfig({
253
- input: { path: './petStore.yaml' },
254
- output: { path: './src/gen' },
255
- plugins: [
256
- pluginTs({
257
- output: {
258
- banner: (node) => `// Source: ${node.path}\n// Generated at ${new Date().toISOString()}`,
259
- },
260
- }),
261
- ],
262
- })
263
- - name: footer
264
- type: 'string | ((node: RootNode) => string)'
265
- required: false
266
- description: |
267
- 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.
268
-
269
- Pass a string for a static footer, or a function that receives the file's `RootNode` and returns the footer text.
270
- examples:
271
- - name: Re-enable lint after a banner disable
272
- files:
273
- - name: kubb.config.ts
274
- lang: typescript
275
- twoslash: false
276
- code: |
277
- import { defineConfig } from 'kubb'
278
- import { pluginTs } from '@kubb/plugin-ts'
279
-
280
- export default defineConfig({
281
- input: { path: './petStore.yaml' },
282
- output: { path: './src/gen' },
283
- plugins: [
284
- pluginTs({
285
- output: {
286
- banner: '/* eslint-disable */',
287
- footer: '/* eslint-enable */',
288
- },
289
- }),
290
- ],
291
- })
292
- - name: override
293
- type: boolean
294
- required: false
295
- default: 'false'
296
- description: |
297
- Allows the plugin to overwrite hand-written files that share a name with a generated file.
298
-
299
- - `false` (default): Kubb skips a file if it already exists and is not marked as generated. This protects manual edits.
300
- - `true`: Kubb overwrites any file at the target path, including hand-written ones.
301
- warning: |
302
- Enable this only when you are sure the target folder contains nothing you need to keep. Local edits are lost on the next generation.
303
- examples:
304
- - name: kubb.config.ts
305
- files:
306
- - lang: typescript
307
- twoslash: false
308
- code: |
309
- import { defineConfig } from 'kubb'
310
- import { pluginTs } from '@kubb/plugin-ts'
311
-
312
- export default defineConfig({
313
- input: { path: './petStore.yaml' },
314
- output: { path: './src/gen' },
315
- plugins: [
316
- pluginTs({
317
- output: { override: true },
318
- }),
319
- ],
320
- })
321
- - name: contentType
322
- type: "'application/json' | (string & {})"
323
- required: false
324
- description: |
325
- Selects which request/response media type the generator reads from the OpenAPI spec.
326
-
327
- 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.
328
- examples:
329
- - name: JSON API media type
330
- files:
331
- - lang: typescript
332
- twoslash: false
333
- code: |
334
- import { defineConfig } from 'kubb'
335
- import { pluginTs } from '@kubb/plugin-ts'
336
-
337
- export default defineConfig({
338
- input: { path: './petStore.yaml' },
339
- output: { path: './src/gen' },
340
- plugins: [
341
- pluginTs({
342
- contentType: 'application/vnd.api+json',
343
- }),
344
- ],
345
- })
346
- - name: group
347
- type: Group
348
- required: false
349
- description: |
350
- Splits generated files into subfolders based on the operation's tag, so each tag in your OpenAPI spec gets its own directory.
351
-
352
- 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.
353
- tip: |
354
- 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.
355
- examples:
356
- - name: kubb.config.ts
357
- files:
358
- - lang: typescript
359
- twoslash: false
360
- code: |
361
- import { defineConfig } from 'kubb'
362
- import { pluginTs } from '@kubb/plugin-ts'
363
-
364
- export default defineConfig({
365
- input: { path: './petStore.yaml' },
366
- output: { path: './src/gen' },
367
- plugins: [
368
- pluginTs({
369
- group: {
370
- type: 'tag',
371
- name: ({ group }) => `${group}Controller`,
372
- },
373
- }),
374
- ],
375
- })
376
- body: |
377
- With the configuration above, the generator emits:
378
-
379
- ```text
380
- src/gen/
381
- ├── petController/
382
- │ ├── AddPet.ts
383
- │ └── GetPet.ts
384
- └── storeController/
385
- ├── CreateStore.ts
386
- └── GetStoreById.ts
387
- ```
388
- properties:
389
- - name: type
390
- type: "'tag'"
391
- required: true
392
- description: |
393
- Property used to assign each operation to a group. Required whenever `group` is set.
394
-
395
- 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.
396
- note: |
397
- `Required: true*` is conditional — only required when the parent `group` option is used. `group` itself stays optional.
398
- - name: name
399
- type: '(context: GroupContext) => string'
400
- required: false
401
- default: (ctx) => `${ctx.group}Controller`
402
- description: |
403
- Function that turns a group key (the operation's first tag) into a folder/identifier name.
404
-
405
- The result is used as both the subdirectory name under `output.path` and as a suffix when naming aggregate files.
406
- - name: enumType
407
- type: "'enum' | 'asConst' | 'asPascalConst' | 'constEnum' | 'literal' | 'inlineLiteral'"
408
- required: false
409
- default: "'asConst'"
410
- description: |
411
- How OpenAPI enums are represented in the generated TypeScript.
412
-
413
- - `'asConst'` (default) — `as const` object plus a key/value type. Tree-shakeable, no enum runtime.
414
- - `'asPascalConst'` — same as `asConst`, but the const is named in PascalCase.
415
- - `'enum'` — a regular TypeScript `enum`. Produces JavaScript runtime code.
416
- - `'constEnum'` — a `const enum`. Inlines at compile time; not compatible with `--isolatedModules`.
417
- - `'literal'` — a plain union type (`'dog' | 'cat'`). No runtime value.
418
- - `'inlineLiteral'` — the union is inlined at every usage site instead of giving it a name.
419
- tip: |
420
- `'asConst'` vs `'asPascalConst'` differs only in the casing of the const variable: `petType` vs `PetType`. The type alias is always PascalCase.
421
- examples:
422
- - name: "'enum'"
423
- files:
424
- - lang: typescript
425
- twoslash: false
426
- code: |
427
- enum PetType {
428
- Dog = 'dog',
429
- Cat = 'cat',
430
- }
431
- - name: "'asConst' (default)"
432
- files:
433
- - lang: typescript
434
- twoslash: false
435
- code: |
436
- export const petType = {
437
- Dog: 'dog',
438
- Cat: 'cat',
439
- } as const
440
-
441
- export type PetTypeKey = (typeof petType)[keyof typeof petType]
442
- - name: "'asPascalConst'"
443
- files:
444
- - lang: typescript
445
- twoslash: false
446
- code: |
447
- export const PetType = {
448
- Dog: 'dog',
449
- Cat: 'cat',
450
- } as const
451
-
452
- export type PetTypeKey = (typeof PetType)[keyof typeof PetType]
453
- - name: "'constEnum'"
454
- files:
455
- - lang: typescript
456
- twoslash: false
457
- code: |
458
- const enum PetType {
459
- Dog = 'dog',
460
- Cat = 'cat',
461
- }
462
- - name: "'literal'"
463
- files:
464
- - lang: typescript
465
- twoslash: false
466
- code: |
467
- export type PetType = 'dog' | 'cat'
468
- - name: "'inlineLiteral'"
469
- files:
470
- - lang: typescript
471
- twoslash: false
472
- code: |
473
- // No separate enum type — values are inlined wherever PetType would have been used
474
- export interface Pet {
475
- status?: 'available' | 'pending' | 'sold'
476
- }
477
- body: |
478
- > [!TIP]
479
- > `'inlineLiteral'` produces the cleanest output for small enums — the values appear directly where they are used instead of via a named alias.
480
- - name: enumSuffix
481
- required: false
482
- description: ''
483
- warning: |
484
- Moved to [`adapterOas`](/adapters/adapter-oas#enumSuffix). Use `adapterOas({ enumSuffix })` instead.
485
- - name: enumTypeSuffix
486
- type: string
487
- required: false
488
- default: "'Key'"
489
- description: |
490
- Suffix appended to the type alias generated for enums when `enumType` is `'asConst'` or `'asPascalConst'`.
491
-
492
- The const object name (e.g. `petType`) is unaffected — only the companion type alias is renamed.
493
- examples:
494
- - name: "'Key' (default)"
495
- files:
496
- - lang: typescript
497
- twoslash: false
498
- code: |
499
- export const petType = {
500
- Dog: 'dog',
501
- Cat: 'cat',
502
- } as const
503
-
504
- export type PetTypeKey = (typeof petType)[keyof typeof petType]
505
- - name: "'Value'"
506
- files:
507
- - lang: typescript
508
- twoslash: false
509
- code: |
510
- export const petType = {
511
- Dog: 'dog',
512
- Cat: 'cat',
513
- } as const
514
-
515
- export type PetTypeValue = (typeof petType)[keyof typeof petType]
516
- - name: "'' (no suffix)"
517
- files:
518
- - lang: typescript
519
- twoslash: false
520
- code: |
521
- export const petType = {
522
- Dog: 'dog',
523
- Cat: 'cat',
524
- } as const
525
-
526
- export type PetType = (typeof petType)[keyof typeof petType]
527
- - name: enumKeyCasing
528
- type: "'screamingSnakeCase' | 'snakeCase' | 'pascalCase' | 'camelCase' | 'none'"
529
- required: false
530
- default: "'none'"
531
- description: |
532
- Casing applied to enum key names. By default the key is the raw value from the spec; switch to a project convention when needed.
533
- body: |
534
- | Value | Example key |
535
- | --- | --- |
536
- | `'screamingSnakeCase'` | `ENUM_VALUE` |
537
- | `'snakeCase'` | `enum_value` |
538
- | `'pascalCase'` | `EnumValue` |
539
- | `'camelCase'` | `enumValue` |
540
- | `'none'` (default) | as-is |
541
- - name: dateType
542
- required: false
543
- description: ''
544
- warning: |
545
- Moved to [`adapterOas`](/adapters/adapter-oas#dateType). Use `adapterOas({ dateType })` instead.
546
- - name: integerType
547
- required: false
548
- description: ''
549
- warning: |
550
- Moved to [`adapterOas`](/adapters/adapter-oas#integerType). Use `adapterOas({ integerType })` instead.
551
- - name: syntaxType
552
- type: "'type' | 'interface'"
553
- required: false
554
- default: "'type'"
555
- description: |
556
- Whether object schemas are emitted as `type` aliases or `interface` declarations.
557
-
558
- `type` is the safer default for generated code: declarations are closed, intersections work cleanly, and unions are fine. Pick `interface` when consumers need to use declaration merging (rare for generated code).
559
-
560
- For more background, see [Type vs Interface](https://www.totaltypescript.com/type-vs-interface-which-should-you-use).
561
- examples:
562
- - name: "'type' (default)"
563
- files:
564
- - lang: typescript
565
- twoslash: false
566
- code: |
567
- export type Pet = {
568
- name: string
569
- }
570
- - name: "'interface'"
571
- files:
572
- - lang: typescript
573
- twoslash: false
574
- code: |
575
- export interface Pet {
576
- name: string
577
- }
578
- - name: unknownType
579
- required: false
580
- description: ''
581
- warning: |
582
- Moved to [`adapterOas`](/adapters/adapter-oas#unknownType). Use `adapterOas({ unknownType })` instead.
583
- - name: emptySchemaType
584
- required: false
585
- description: ''
586
- warning: |
587
- Moved to [`adapterOas`](/adapters/adapter-oas#emptySchemaType). Use `adapterOas({ emptySchemaType })` instead.
588
- - name: optionalType
589
- type: "'questionToken' | 'undefined' | 'questionTokenAndUndefined'"
590
- required: false
591
- default: "'questionToken'"
592
- description: |
593
- How optional properties are written in generated types.
594
-
595
- - `'questionToken'` (default) — `type?: string`. The property may be missing.
596
- - `'undefined'` — `type: string | undefined`. The property is required to exist but may be `undefined`.
597
- - `'questionTokenAndUndefined'` — `type?: string | undefined`. Strictest — the property may be missing or explicitly set to `undefined`.
598
- tip: |
599
- Choose `'questionTokenAndUndefined'` when your project enables `"exactOptionalPropertyTypes": true` in `tsconfig.json` — it keeps generated types compatible with that setting.
600
- examples:
601
- - name: "'questionToken' (default)"
602
- files:
603
- - lang: typescript
604
- twoslash: false
605
- code: |
606
- export type Pet = {
607
- type?: string
608
- }
609
- - name: "'undefined'"
610
- files:
611
- - lang: typescript
612
- twoslash: false
613
- code: |
614
- export type Pet = {
615
- type: string | undefined
616
- }
617
- - name: "'questionTokenAndUndefined'"
618
- files:
619
- - lang: typescript
620
- twoslash: false
621
- code: |
622
- export type Pet = {
623
- type?: string | undefined
624
- }
625
- - name: arrayType
626
- type: "'array' | 'generic'"
627
- required: false
628
- default: "'array'"
629
- description: |
630
- Syntax used for array types in generated code.
631
-
632
- - `'array'` (default) — postfix `Type[]`. Slightly shorter.
633
- - `'generic'` — `Array<Type>`. More readable for complex element types (`Array<{ id: number }>`).
634
- examples:
635
- - name: "'array' (default)"
636
- files:
637
- - lang: typescript
638
- twoslash: false
639
- code: |
640
- export type Pet = {
641
- tags: string[]
642
- }
643
- - name: "'generic'"
644
- files:
645
- - lang: typescript
646
- twoslash: false
647
- code: |
648
- export type Pet = {
649
- tags: Array<string>
650
- }
651
- - name: paramsCasing
652
- type: "'camelcase'"
653
- required: false
654
- description: |
655
- Renames properties inside `PathParams`, `QueryParams`, and `HeaderParams` types. Response and request body types are not touched.
656
-
657
- Use this when your OpenAPI parameters use snake_case or kebab-case but you want camelCase in TypeScript.
658
- important: |
659
- Every plugin that references parameters must use the same `paramsCasing` value — `@kubb/plugin-client`, `@kubb/plugin-react-query`, `@kubb/plugin-vue-query`, `@kubb/plugin-faker`, `@kubb/plugin-mcp`. Mismatched casing breaks the generated type chain.
660
- examples:
661
- - name: Without `paramsCasing`
662
- files:
663
- - lang: typescript
664
- twoslash: false
665
- code: |
666
- // OpenAPI spec: step_id, bool_param, X-Custom-Header
667
- export type FindPetsByStatusPathParams = {
668
- step_id: string
669
- }
670
-
671
- export type FindPetsByStatusQueryParams = {
672
- bool_param?: boolean
673
- }
674
-
675
- export type FindPetsByStatusHeaderParams = {
676
- 'X-Custom-Header'?: string
677
- }
678
- - name: "With `paramsCasing: 'camelcase'`"
679
- files:
680
- - lang: typescript
681
- twoslash: false
682
- code: |
683
- export type FindPetsByStatusPathParams = {
684
- stepId: string
685
- }
686
-
687
- export type FindPetsByStatusQueryParams = {
688
- boolParam?: boolean
689
- }
690
-
691
- export type FindPetsByStatusHeaderParams = {
692
- xCustomHeader?: string
693
- }
694
- - name: resolver
695
- type: Partial<ResolverTs> & ThisType<ResolverTs>
696
- required: false
697
- description: |
698
- 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.
699
-
700
- 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.
701
-
702
- 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.
703
- body: |
704
- Each plugin ships with a default resolver:
705
-
706
- | Plugin | Default resolver |
707
- | --- | --- |
708
- | `@kubb/plugin-ts` | `resolverTs` |
709
- | `@kubb/plugin-zod` | `resolverZod` |
710
- | `@kubb/plugin-faker` | `resolverFaker` |
711
- | `@kubb/plugin-cypress` | `resolverCypress` |
712
- | `@kubb/plugin-msw` | `resolverMsw` |
713
- | `@kubb/plugin-mcp` | `resolverMcp` |
714
- | `@kubb/plugin-client` | `resolverClient` |
715
- codeBlock:
716
- lang: typescript
717
- title: Add an Api prefix to every name
718
- code: |
719
- import { defineConfig } from 'kubb'
720
- import { pluginTs } from '@kubb/plugin-ts'
721
-
722
- export default defineConfig({
723
- input: { path: './petStore.yaml' },
724
- output: { path: './src/gen' },
725
- plugins: [
726
- pluginTs({
727
- resolver: {
728
- resolveName(name) {
729
- return `Api${this.default(name, 'function')}`
730
- },
731
- },
732
- }),
733
- ],
734
- })
735
- tip: |
736
- Use `resolver` for naming and file-location tweaks. For changing the AST nodes themselves (e.g. stripping descriptions), use `transformer` instead.
737
- examples:
738
- - name: Add a Custom prefix to every name
739
- files:
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
- resolver: {
752
- resolveName(name) {
753
- return `Custom${this.default(name, 'function')}`
754
- },
755
- },
756
- }),
757
- ],
758
- })
759
- - name: include
760
- type: Array<Include>
761
- required: false
762
- description: |
763
- Restricts generation to operations that match at least one entry in the list. Anything not matched is skipped.
764
-
765
- Each entry filters by one of:
766
-
767
- - `tag` — the operation's first tag in the OpenAPI spec.
768
- - `operationId` — the operation's `operationId`.
769
- - `path` — the URL pattern (`'/pet/{petId}'`).
770
- - `method` — HTTP method (`'get'`, `'post'`, ...).
771
- - `contentType` — the media type of the request body.
772
-
773
- `pattern` accepts either a string (exact match) or a `RegExp` for fuzzy matches.
774
- codeBlock:
775
- lang: typescript
776
- title: Type definition
777
- code: |
778
- export type Include = {
779
- type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
780
- pattern: string | RegExp
781
- }
782
- examples:
783
- - name: Only the pet tag
784
- files:
785
- - name: kubb.config.ts
786
- lang: typescript
787
- twoslash: false
788
- code: |
789
- import { defineConfig } from 'kubb'
790
- import { pluginTs } from '@kubb/plugin-ts'
791
-
792
- export default defineConfig({
793
- input: { path: './petStore.yaml' },
794
- output: { path: './src/gen' },
795
- plugins: [
796
- pluginTs({
797
- include: [
798
- { type: 'tag', pattern: 'pet' },
799
- ],
800
- }),
801
- ],
802
- })
803
- - name: Only GET operations under /pet
804
- files:
805
- - name: kubb.config.ts
806
- lang: typescript
807
- twoslash: false
808
- code: |
809
- import { defineConfig } from 'kubb'
810
- import { pluginTs } from '@kubb/plugin-ts'
811
-
812
- export default defineConfig({
813
- input: { path: './petStore.yaml' },
814
- output: { path: './src/gen' },
815
- plugins: [
816
- pluginTs({
817
- include: [
818
- { type: 'method', pattern: 'get' },
819
- { type: 'path', pattern: /^\/pet/ },
820
- ],
821
- }),
822
- ],
823
- })
824
- - name: exclude
825
- type: Array<Exclude>
826
- required: false
827
- description: |
828
- Skips any operation that matches at least one entry in the list. The opposite of `include`.
829
-
830
- Each entry filters by one of:
831
-
832
- - `tag` — the operation's first tag.
833
- - `operationId` — the operation's `operationId`.
834
- - `path` — the URL pattern (`'/pet/{petId}'`).
835
- - `method` — HTTP method (`'get'`, `'post'`, ...).
836
- - `contentType` — the media type of the request body.
837
-
838
- `pattern` accepts a plain string or a `RegExp`. When both `include` and `exclude` are set, `exclude` wins.
839
- codeBlock:
840
- lang: typescript
841
- title: Type definition
842
- code: |
843
- export type Exclude = {
844
- type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
845
- pattern: string | RegExp
846
- }
847
- examples:
848
- - name: Skip everything under the store tag
849
- files:
850
- - name: kubb.config.ts
851
- lang: typescript
852
- twoslash: false
853
- code: |
854
- import { defineConfig } from 'kubb'
855
- import { pluginTs } from '@kubb/plugin-ts'
856
-
857
- export default defineConfig({
858
- input: { path: './petStore.yaml' },
859
- output: { path: './src/gen' },
860
- plugins: [
861
- pluginTs({
862
- exclude: [
863
- { type: 'tag', pattern: 'store' },
864
- ],
865
- }),
866
- ],
867
- })
868
- - name: Skip a specific operation and all delete methods
869
- files:
870
- - name: kubb.config.ts
871
- lang: typescript
872
- twoslash: false
873
- code: |
874
- import { defineConfig } from 'kubb'
875
- import { pluginTs } from '@kubb/plugin-ts'
876
-
877
- export default defineConfig({
878
- input: { path: './petStore.yaml' },
879
- output: { path: './src/gen' },
880
- plugins: [
881
- pluginTs({
882
- exclude: [
883
- { type: 'operationId', pattern: 'deletePet' },
884
- { type: 'method', pattern: 'delete' },
885
- ],
886
- }),
887
- ],
888
- })
889
- - name: override
890
- type: Array<Override>
891
- required: false
892
- description: |
893
- 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.
894
-
895
- 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.
896
-
897
- Entries are evaluated top to bottom. The first matching entry's `options` is merged onto the plugin defaults; later entries do not stack.
898
- codeBlock:
899
- lang: typescript
900
- title: Type definition
901
- code: |
902
- export type Override = {
903
- type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
904
- pattern: string | RegExp
905
- options: PluginOptions
906
- }
907
- examples:
908
- - name: Use a different enum style for the user tag
909
- files:
910
- - name: kubb.config.ts
911
- lang: typescript
912
- twoslash: false
913
- code: |
914
- import { defineConfig } from 'kubb'
915
- import { pluginTs } from '@kubb/plugin-ts'
916
-
917
- export default defineConfig({
918
- input: { path: './petStore.yaml' },
919
- output: { path: './src/gen' },
920
- plugins: [
921
- pluginTs({
922
- enumType: 'asConst',
923
- override: [
924
- {
925
- type: 'tag',
926
- pattern: 'user',
927
- options: { enumType: 'literal' },
928
- },
929
- ],
930
- }),
931
- ],
932
- })
933
- - name: generators
934
- type: Array<Generator<PluginTs>>
935
- required: false
936
- experimental: true
937
- description: |
938
- 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.
939
-
940
- 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).
941
- warning: |
942
- Generators are an experimental, low-level API. The signature may change between minor releases.
943
- - name: transformer
944
- type: Visitor
945
- required: false
946
- description: |
947
- 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.
948
-
949
- 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.
950
- examples:
951
- - name: Strip descriptions before printing
952
- files:
953
- - name: kubb.config.ts
954
- lang: typescript
955
- twoslash: false
956
- code: |
957
- import { defineConfig } from 'kubb'
958
- import { pluginTs } from '@kubb/plugin-ts'
959
-
960
- export default defineConfig({
961
- input: { path: './petStore.yaml' },
962
- output: { path: './src/gen' },
963
- plugins: [
964
- pluginTs({
965
- transformer: {
966
- schema(node) {
967
- return { ...node, description: undefined }
968
- },
969
- },
970
- }),
971
- ],
972
- })
973
- - name: Prefix every operationId
974
- files:
975
- - name: kubb.config.ts
976
- lang: typescript
977
- twoslash: false
978
- code: |
979
- import { defineConfig } from 'kubb'
980
- import { pluginTs } from '@kubb/plugin-ts'
981
-
982
- export default defineConfig({
983
- input: { path: './petStore.yaml' },
984
- output: { path: './src/gen' },
985
- plugins: [
986
- pluginTs({
987
- transformer: {
988
- operation(node) {
989
- return { ...node, operationId: `api_${node.operationId}` }
990
- },
991
- },
992
- }),
993
- ],
994
- })
995
- tip: |
996
- Use `transformer` to rewrite node properties before printing. For changing the names of generated symbols and files, use `resolver` instead.
997
- note: |
998
- `@kubb/plugin-ts` uses AST visitors for schema/operation node transforms. For renaming generated symbols, use `resolver` instead.
999
- - name: printer
1000
- type: '{ nodes?: PrinterTsNodes }'
1001
- required: false
1002
- description: |
1003
- Replaces the TypeScript node handler for a specific schema type (e.g. `'integer'`, `'date'`, `'string'`). Each handler is a function that builds a TypeScript AST node for that schema type.
1004
-
1005
- Use `this.transform` to recurse into nested schema nodes and `this.options` to read printer options.
1006
- examples:
1007
- - name: Use the JavaScript Date object for date schemas
1008
- files:
1009
- - lang: typescript
1010
- twoslash: false
1011
- code: |
1012
- import ts from 'typescript'
1013
- import { defineConfig } from 'kubb'
1014
- import { pluginTs } from '@kubb/plugin-ts'
1015
-
1016
- export default defineConfig({
1017
- input: { path: './petStore.yaml' },
1018
- output: { path: './src/gen' },
1019
- plugins: [
1020
- pluginTs({
1021
- printer: {
1022
- nodes: {
1023
- date() {
1024
- return ts.factory.createTypeReferenceNode('Date', [])
1025
- },
1026
- },
1027
- },
1028
- }),
1029
- ],
1030
- })
1031
- - name: Use bigint for integers
1032
- files:
1033
- - lang: typescript
1034
- twoslash: false
1035
- code: |
1036
- import ts from 'typescript'
1037
- import { defineConfig } from 'kubb'
1038
- import { pluginTs } from '@kubb/plugin-ts'
1039
-
1040
- export default defineConfig({
1041
- input: { path: './petStore.yaml' },
1042
- output: { path: './src/gen' },
1043
- plugins: [
1044
- pluginTs({
1045
- printer: {
1046
- nodes: {
1047
- integer() {
1048
- return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword)
1049
- },
1050
- },
1051
- },
1052
- }),
1053
- ],
1054
- })
1055
- examples:
1056
- - name: kubb.config.ts
1057
- files:
1058
- - lang: typescript
1059
- twoslash: false
1060
- code: |
1061
- import { defineConfig } from 'kubb'
1062
- import { pluginTs } from '@kubb/plugin-ts'
1063
-
1064
- export default defineConfig({
1065
- input: { path: './petStore.yaml' },
1066
- output: { path: './src/gen' },
1067
- plugins: [
1068
- pluginTs({
1069
- output: { path: './types' },
1070
- exclude: [{ type: 'tag', pattern: 'store' }],
1071
- group: {
1072
- type: 'tag',
1073
- name: ({ group }) => `${group}Controller`,
1074
- },
1075
- enumType: 'asConst',
1076
- optionalType: 'questionTokenAndUndefined',
1077
- paramsCasing: 'camelcase',
1078
- }),
1079
- ],
1080
- })