@kubb/core 5.0.0-alpha.5 → 5.0.0-alpha.51

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 (71) hide show
  1. package/README.md +3 -2
  2. package/dist/PluginDriver-6E8zd8MW.cjs +1086 -0
  3. package/dist/PluginDriver-6E8zd8MW.cjs.map +1 -0
  4. package/dist/PluginDriver-D6wQFD4r.js +983 -0
  5. package/dist/PluginDriver-D6wQFD4r.js.map +1 -0
  6. package/dist/index.cjs +1013 -1829
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +279 -265
  9. package/dist/index.js +1003 -1799
  10. package/dist/index.js.map +1 -1
  11. package/dist/mocks.cjs +138 -0
  12. package/dist/mocks.cjs.map +1 -0
  13. package/dist/mocks.d.ts +74 -0
  14. package/dist/mocks.js +133 -0
  15. package/dist/mocks.js.map +1 -0
  16. package/dist/types-DfEv9d_c.d.ts +1721 -0
  17. package/package.json +51 -57
  18. package/src/FileManager.ts +133 -0
  19. package/src/FileProcessor.ts +86 -0
  20. package/src/Kubb.ts +154 -101
  21. package/src/PluginDriver.ts +418 -0
  22. package/src/constants.ts +43 -47
  23. package/src/createAdapter.ts +25 -0
  24. package/src/createKubb.ts +614 -0
  25. package/src/createRenderer.ts +57 -0
  26. package/src/createStorage.ts +58 -0
  27. package/src/defineGenerator.ts +88 -100
  28. package/src/defineLogger.ts +13 -3
  29. package/src/defineParser.ts +45 -0
  30. package/src/definePlugin.ts +68 -7
  31. package/src/defineResolver.ts +521 -0
  32. package/src/devtools.ts +14 -14
  33. package/src/index.ts +12 -17
  34. package/src/mocks.ts +171 -0
  35. package/src/renderNode.ts +35 -0
  36. package/src/storages/fsStorage.ts +40 -11
  37. package/src/storages/memoryStorage.ts +4 -3
  38. package/src/types.ts +575 -205
  39. package/src/utils/TreeNode.ts +47 -9
  40. package/src/utils/diagnostics.ts +4 -1
  41. package/src/utils/getBarrelFiles.ts +94 -16
  42. package/src/utils/isInputPath.ts +10 -0
  43. package/src/utils/packageJSON.ts +99 -0
  44. package/dist/PluginManager-vZodFEMe.d.ts +0 -1056
  45. package/dist/chunk-ByKO4r7w.cjs +0 -38
  46. package/dist/hooks.cjs +0 -60
  47. package/dist/hooks.cjs.map +0 -1
  48. package/dist/hooks.d.ts +0 -56
  49. package/dist/hooks.js +0 -56
  50. package/dist/hooks.js.map +0 -1
  51. package/src/BarrelManager.ts +0 -74
  52. package/src/PackageManager.ts +0 -180
  53. package/src/PluginManager.ts +0 -667
  54. package/src/PromiseManager.ts +0 -40
  55. package/src/build.ts +0 -419
  56. package/src/config.ts +0 -56
  57. package/src/defineAdapter.ts +0 -22
  58. package/src/defineStorage.ts +0 -56
  59. package/src/errors.ts +0 -1
  60. package/src/hooks/index.ts +0 -4
  61. package/src/hooks/useKubb.ts +0 -46
  62. package/src/hooks/useMode.ts +0 -11
  63. package/src/hooks/usePlugin.ts +0 -11
  64. package/src/hooks/usePluginManager.ts +0 -11
  65. package/src/utils/FunctionParams.ts +0 -155
  66. package/src/utils/executeStrategies.ts +0 -81
  67. package/src/utils/formatters.ts +0 -56
  68. package/src/utils/getConfigs.ts +0 -30
  69. package/src/utils/getPlugins.ts +0 -23
  70. package/src/utils/linters.ts +0 -25
  71. package/src/utils/resolveOptions.ts +0 -93
package/src/types.ts CHANGED
@@ -1,40 +1,15 @@
1
1
  import type { AsyncEventEmitter, PossiblePromise } from '@internals/utils'
2
- import type { RootNode, SchemaNode } from '@kubb/ast/types'
3
- import type { Fabric as FabricType, KubbFile } from '@kubb/fabric-core/types'
2
+ import type { FileNode, HttpMethod, ImportNode, InputNode, Node, SchemaNode, Visitor } from '@kubb/ast'
4
3
  import type { DEFAULT_STUDIO_URL, logLevel } from './constants.ts'
5
- import type { DefineStorage } from './defineStorage.ts'
6
- import type { KubbEvents } from './Kubb.ts'
7
- import type { PluginManager } from './PluginManager.ts'
4
+ import type { RendererFactory } from './createRenderer.ts'
5
+ import type { Storage } from './createStorage.ts'
6
+ import type { Generator } from './defineGenerator.ts'
7
+ import type { Parser } from './defineParser.ts'
8
+ import type { Plugin } from './definePlugin.ts'
9
+ import type { KubbHooks } from './Kubb.ts'
10
+ import type { PluginDriver } from './PluginDriver.ts'
8
11
 
9
- export type { Printer, PrinterFactoryOptions } from '@kubb/ast/types'
10
-
11
- declare global {
12
- namespace Kubb {
13
- interface PluginContext {}
14
- }
15
- }
16
-
17
- /**
18
- * Config used in `kubb.config.ts`
19
- *
20
- * @example
21
- * import { defineConfig } from '@kubb/core'
22
- * export default defineConfig({
23
- * ...
24
- * })
25
- */
26
- export type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins'> & {
27
- /**
28
- * The project root directory, which can be either an absolute path or a path relative to the location of your `kubb.config.ts` file.
29
- * @default process.cwd()
30
- */
31
- root?: string
32
- /**
33
- * An array of Kubb plugins used for generation. Each plugin may have additional configurable options (defined within the plugin itself). If a plugin relies on another plugin, an error will occur if the required dependency is missing. Refer to “pre” for more details.
34
- */
35
- // inject needs to be omitted because else we have a clash with the PluginManager instance
36
- plugins?: Array<Omit<UnknownUserPlugin, 'inject'>>
37
- }
12
+ export type { Renderer, RendererFactory } from './createRenderer.ts'
38
13
 
39
14
  export type InputPath = {
40
15
  /**
@@ -50,7 +25,7 @@ export type InputData = {
50
25
  data: string | unknown
51
26
  }
52
27
 
53
- type Input = InputPath | InputData | Array<InputPath>
28
+ type Input = InputPath | InputData
54
29
 
55
30
  /**
56
31
  * The raw source passed to an adapter's `parse` function.
@@ -65,18 +40,25 @@ export type AdapterSource = { type: 'path'; path: string } | { type: 'data'; dat
65
40
  * - `TName` — unique string identifier (e.g. `'oas'`, `'asyncapi'`)
66
41
  * - `TOptions` — raw user-facing options passed to the adapter factory
67
42
  * - `TResolvedOptions` — defaults applied; what the adapter stores as `options`
43
+ * - `TDocument` — type of the raw source document exposed by the adapter after `parse()`
68
44
  */
69
- export type AdapterFactoryOptions<TName extends string = string, TOptions extends object = object, TResolvedOptions extends object = TOptions> = {
45
+ export type AdapterFactoryOptions<
46
+ TName extends string = string,
47
+ TOptions extends object = object,
48
+ TResolvedOptions extends object = TOptions,
49
+ TDocument = unknown,
50
+ > = {
70
51
  name: TName
71
52
  options: TOptions
72
53
  resolvedOptions: TResolvedOptions
54
+ document: TDocument
73
55
  }
74
56
 
75
57
  /**
76
- * An adapter converts a source file or data into a `@kubb/ast` `RootNode`.
58
+ * An adapter converts a source file or data into a `@kubb/ast` `InputNode`.
77
59
  *
78
60
  * Adapters are the single entry-point for different schema formats
79
- * (OpenAPI, AsyncAPI, Drizzle, …) and produce the universal `RootNode`
61
+ * (OpenAPI, AsyncAPI, Drizzle, …) and produce the universal `InputNode`
80
62
  * that all Kubb plugins consume.
81
63
  *
82
64
  * @example
@@ -91,22 +73,40 @@ export type AdapterFactoryOptions<TName extends string = string, TOptions extend
91
73
  * ```
92
74
  */
93
75
  export type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
94
- /** Human-readable identifier, e.g. `'oas'`, `'drizzle'`, `'asyncapi'`. */
76
+ /**
77
+ * Human-readable identifier, e.g. `'oas'`, `'drizzle'`, `'asyncapi'`.
78
+ */
95
79
  name: TOptions['name']
96
- /** Resolved options (after defaults have been applied). */
80
+ /**
81
+ * Resolved options (after defaults have been applied).
82
+ */
97
83
  options: TOptions['resolvedOptions']
98
- /** Convert the raw source into a universal `RootNode`. */
99
- parse: (source: AdapterSource) => PossiblePromise<RootNode>
100
84
  /**
101
- * Extracts `KubbFile.Import` entries needed by a `SchemaNode` tree.
85
+ * The raw source document produced after the first `parse()` call.
86
+ * `undefined` before parsing; typed by the adapter's `TDocument` generic.
87
+ */
88
+ document: TOptions['document'] | null
89
+ inputNode: InputNode | null
90
+ /**
91
+ * Convert the raw source into a universal `InputNode`.
92
+ */
93
+ parse: (source: AdapterSource) => PossiblePromise<InputNode>
94
+ /**
95
+ * Extracts `ImportNode` entries needed by a `SchemaNode` tree.
102
96
  * Populated after the first `parse()` call. Returns an empty array before that.
103
97
  *
104
98
  * The `resolve` callback receives the collision-corrected schema name and must
105
99
  * return the `{ name, path }` pair for the import, or `undefined` to skip it.
106
100
  */
107
- getImports: (node: SchemaNode, resolve: (schemaName: string) => { name: string; path: string }) => Array<KubbFile.Import>
101
+ getImports: (node: SchemaNode, resolve: (schemaName: string) => { name: string; path: string }) => Array<ImportNode>
108
102
  }
109
103
 
104
+ /**
105
+ * Controls how `index.ts` barrel files are generated.
106
+ * - `'all'` — exports every generated symbol from every file.
107
+ * - `'named'` — exports only explicitly named exports.
108
+ * - `'propagate'` — propagates re-exports from nested barrel files upward.
109
+ */
110
110
  export type BarrelType = 'all' | 'named' | 'propagate'
111
111
 
112
112
  export type DevtoolsOptions = {
@@ -132,31 +132,49 @@ export type Config<TInput = Input> = {
132
132
  */
133
133
  root: string
134
134
  /**
135
- * Adapter that converts the input file into a `@kubb/ast` `RootNode` — the universal
135
+ * An array of parsers used to convert generated files to strings.
136
+ * Each parser handles specific file extensions (e.g. `.ts`, `.tsx`).
137
+ *
138
+ * A catch-all fallback parser is always appended last for any unhandled extension.
139
+ *
140
+ * When omitted, `parserTs` from `@kubb/parser-ts` is used automatically as the
141
+ * default (requires `@kubb/parser-ts` to be installed as an optional dependency).
142
+ * @default [parserTs] — from `@kubb/parser-ts`
143
+ * @example
144
+ * ```ts
145
+ * import { parserTs, tsxParser } from '@kubb/parser-ts'
146
+ * export default defineConfig({
147
+ * parsers: [parserTs, tsxParser],
148
+ * })
149
+ * ```
150
+ */
151
+ parsers: Array<Parser>
152
+ /**
153
+ * Adapter that converts the input file into a `@kubb/ast` `InputNode` — the universal
136
154
  * intermediate representation consumed by all Kubb plugins.
137
155
  *
138
- * - Omit (or pass `undefined`) to use the built-in OpenAPI/Swagger adapter.
139
- * - Use `@kubb/adapter-oas` for explicit OpenAPI configuration (validate, contentType, …).
156
+ * - Use `@kubb/adapter-oas` for OpenAPI / Swagger.
140
157
  * - Use `@kubb/adapter-drizzle` or `@kubb/adapter-asyncapi` for other formats.
141
158
  *
142
159
  * @example
143
160
  * ```ts
144
- * import { drizzleAdapter } from '@kubb/adapter-drizzle'
161
+ * import { adapterOas } from '@kubb/adapter-oas'
145
162
  * export default defineConfig({
146
- * adapter: drizzleAdapter(),
147
- * input: { path: './src/schema.ts' },
163
+ * adapter: adapterOas(),
164
+ * input: { path: './petStore.yaml' },
148
165
  * })
149
166
  * ```
150
167
  */
151
- adapter?: Adapter
168
+ adapter: Adapter
152
169
  /**
153
- * You can use either `input.path` or `input.data`, depending on your specific needs.
170
+ * Source file or data to generate code from.
171
+ * Use `input.path` for a file on disk or `input.data` for an inline string or object.
154
172
  */
155
173
  input: TInput
156
174
  output: {
157
175
  /**
158
- * The path where all generated files receives exported.
159
- * This can be an absolute path or a path relative to the specified root option.
176
+ * Output directory for generated files.
177
+ * Accepts an absolute path or a path relative to `root`.
160
178
  */
161
179
  path: string
162
180
  /**
@@ -172,32 +190,32 @@ export type Config<TInput = Input> = {
172
190
  /**
173
191
  * Storage backend for generated files.
174
192
  * Defaults to `fsStorage()` — the built-in filesystem driver.
175
- * Accepts any object implementing the {@link DefineStorage} interface.
193
+ * Accepts any object implementing the {@link Storage} interface.
176
194
  * Keys are root-relative paths (e.g. `src/gen/api/getPets.ts`).
177
195
  * @default fsStorage()
178
196
  * @example
179
197
  * ```ts
180
- * import { defineStorage, fsStorage } from '@kubb/core'
181
- * storage: defineStorage(fsStorage())
198
+ * import { memoryStorage } from '@kubb/core'
199
+ * storage: memoryStorage()
182
200
  * ```
183
201
  */
184
- storage?: DefineStorage
202
+ storage?: Storage
185
203
  /**
186
204
  * Specifies the formatting tool to be used.
187
- * - 'auto' automatically detects and uses biome or prettier (in that order of preference).
205
+ * - 'auto' automatically detects and uses oxfmt, biome, or prettier (in that order of preference).
206
+ * - 'oxfmt' uses Oxfmt for code formatting.
188
207
  * - 'prettier' uses Prettier for code formatting.
189
208
  * - 'biome' uses Biome for code formatting.
190
- * - 'oxfmt' uses Oxfmt for code formatting.
191
209
  * - false disables code formatting.
192
210
  * @default 'prettier'
193
211
  */
194
212
  format?: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false
195
213
  /**
196
214
  * Specifies the linter that should be used to analyze the code.
197
- * - 'auto' automatically detects and uses biome, oxlint, or eslint (in that order of preference).
215
+ * - 'auto' automatically detects and uses oxlint, biome, or eslint (in that order of preference).
216
+ * - 'oxlint' uses Oxlint for linting.
198
217
  * - 'eslint' uses ESLint for linting.
199
218
  * - 'biome' uses Biome for linting.
200
- * - 'oxlint' uses Oxlint for linting.
201
219
  * - false disables linting.
202
220
  * @default 'auto'
203
221
  */
@@ -206,12 +224,12 @@ export type Config<TInput = Input> = {
206
224
  * Overrides the extension for generated imports and exports. By default, each plugin adds an extension.
207
225
  * @default { '.ts': '.ts'}
208
226
  */
209
- extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>
227
+ extension?: Record<FileNode['extname'], FileNode['extname'] | ''>
210
228
  /**
211
229
  * Configures how `index.ts` files are created, including disabling barrel file generation. Each plugin has its own `barrelType` option; this setting controls the root barrel file (e.g., `src/gen/index.ts`).
212
230
  * @default 'named'
213
231
  */
214
- barrelType?: Exclude<BarrelType, 'propagate'> | false
232
+ barrelType?: 'all' | 'named' | false
215
233
  /**
216
234
  * Adds a default banner to the start of every generated file indicating it was generated by Kubb.
217
235
  * - 'simple' adds banner with link to Kubb.
@@ -229,11 +247,28 @@ export type Config<TInput = Input> = {
229
247
  override?: boolean
230
248
  }
231
249
  /**
232
- * An array of Kubb plugins that used in the generation.
233
- * Each plugin may include additional configurable options(defined in the plugin itself).
234
- * If a plugin depends on another plugin, an error is returned if the required dependency is missing. See pre for more details.
250
+ * An array of Kubb plugins used for code generation.
251
+ * Each plugin may declare additional configurable options.
252
+ * If a plugin depends on another, an error is thrown when the dependency is missing.
253
+ * Use `dependencies` on the plugin to declare execution order.
235
254
  */
236
- plugins?: Array<Plugin>
255
+ plugins: Array<Plugin>
256
+ /**
257
+ * Project-wide renderer factory. All plugins and generators that do not declare their own
258
+ * `renderer` ultimately fall back to this value.
259
+ *
260
+ * The resolution chain is: `generator.renderer` → `plugin.renderer` → `config.renderer` → `undefined` (raw `FileNode[]` mode).
261
+ *
262
+ * @example
263
+ * ```ts
264
+ * import { jsxRenderer } from '@kubb/renderer-jsx'
265
+ * export default defineConfig({
266
+ * renderer: jsxRenderer,
267
+ * plugins: [pluginTs(), pluginZod()],
268
+ * })
269
+ * ```
270
+ */
271
+ renderer?: RendererFactory
237
272
  /**
238
273
  * Devtools configuration for Kubb Studio integration.
239
274
  */
@@ -260,6 +295,63 @@ export type Config<TInput = Input> = {
260
295
 
261
296
  // plugin
262
297
 
298
+ /**
299
+ * A type/string-pattern filter used for `include`, `exclude`, and `override` matching.
300
+ */
301
+ type PatternFilter = {
302
+ type: string
303
+ pattern: string | RegExp
304
+ }
305
+
306
+ /**
307
+ * A pattern filter paired with partial option overrides to apply when the pattern matches.
308
+ */
309
+ type PatternOverride<TOptions> = PatternFilter & {
310
+ options: Omit<Partial<TOptions>, 'override'>
311
+ }
312
+
313
+ /**
314
+ * Context passed to `resolver.resolveOptions` to apply include/exclude/override filtering
315
+ * for a given operation or schema node.
316
+ */
317
+ /**
318
+ * Resolves filtered options for a given operation or schema node.
319
+ *
320
+ * @internal
321
+ */
322
+ export type ResolveOptionsContext<TOptions> = {
323
+ options: TOptions
324
+ exclude?: Array<PatternFilter>
325
+ include?: Array<PatternFilter>
326
+ override?: Array<PatternOverride<TOptions>>
327
+ }
328
+
329
+ /**
330
+ * Base constraint for all plugin resolver objects.
331
+ *
332
+ * `default`, `resolveOptions`, `resolvePath`, and `resolveFile` are injected automatically
333
+ * by `defineResolver` — plugin authors may override them but never need to implement them
334
+ * from scratch.
335
+ *
336
+ * @example
337
+ * ```ts
338
+ * type MyResolver = Resolver & {
339
+ * resolveName(node: SchemaNode): string
340
+ * resolveTypedName(node: SchemaNode): string
341
+ * }
342
+ * ```
343
+ */
344
+ export type Resolver = {
345
+ name: string
346
+ pluginName: Plugin['name']
347
+ default(name: string, type?: 'file' | 'function' | 'type' | 'const'): string
348
+ resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null
349
+ resolvePath(params: ResolverPathParams, context: ResolverContext): string
350
+ resolveFile(params: ResolverFileParams, context: ResolverContext): FileNode
351
+ resolveBanner(node: InputNode | null, context: ResolveBannerContext): string | undefined
352
+ resolveFooter(node: InputNode | null, context: ResolveBannerContext): string | undefined
353
+ }
354
+
263
355
  export type PluginFactoryOptions<
264
356
  /**
265
357
  * Name to be used for the plugin.
@@ -281,171 +373,179 @@ export type PluginFactoryOptions<
281
373
  * When calling `resolvePath` you can specify better types.
282
374
  */
283
375
  TResolvePathOptions extends object = object,
376
+ /**
377
+ * Resolver object that encapsulates the naming and path-resolution helpers used by this plugin.
378
+ * Use `defineResolver` to define the resolver object and export it alongside the plugin.
379
+ */
380
+ TResolver extends Resolver = Resolver,
284
381
  > = {
285
382
  name: TName
286
383
  options: TOptions
287
384
  resolvedOptions: TResolvedOptions
288
385
  context: TContext
289
386
  resolvePathOptions: TResolvePathOptions
387
+ resolver: TResolver
290
388
  }
291
389
 
292
- export type GetPluginFactoryOptions<TPlugin extends UserPlugin> = TPlugin extends UserPlugin<infer X> ? X : never
390
+ /**
391
+ * Internal representation of a plugin after normalization.
392
+ * Extends the user-facing `Plugin` with runtime fields populated during `kubb:plugin:setup`.
393
+ * Not part of the public API — use `Plugin` for external-facing interactions.
394
+ * @internal
395
+ */
396
+ export type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & {
397
+ options: TOptions['resolvedOptions'] & {
398
+ output: Output
399
+ include?: Array<Include>
400
+ exclude: Array<Exclude>
401
+ override: Array<Override<TOptions['resolvedOptions']>>
402
+ }
403
+ resolver: TOptions['resolver']
404
+ transformer?: Visitor
405
+ renderer?: RendererFactory
406
+ generators?: Array<Generator>
407
+ apply?: (config: Config) => boolean
408
+ version?: string
409
+ }
293
410
 
294
- export type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
411
+ /**
412
+ * Partial version of {@link Config} intended for user-facing config entry points.
413
+ *
414
+ * Fields that have sensible defaults (`root`, `plugins`, `parsers`, `adapter`) are optional.
415
+ */
416
+ export type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins' | 'parsers' | 'adapter'> & {
295
417
  /**
296
- * Unique name used for the plugin
297
- * The name of the plugin follows the format scope:foo-bar or foo-bar, adding scope: can avoid naming conflicts with other plugins.
298
- * @example @kubb/typescript
418
+ * The project root directory, which can be either an absolute path or a path relative to the location of your `kubb.config.ts` file.
419
+ * @default process.cwd()
299
420
  */
300
- name: TOptions['name']
421
+ root?: string
301
422
  /**
302
- * Options set for a specific plugin(see kubb.config.js), passthrough of options.
423
+ * An array of parsers used to convert generated files to strings.
424
+ * Each parser handles specific file extensions (e.g. `.ts`, `.tsx`).
425
+ *
426
+ * A catch-all fallback parser is always appended last for any unhandled extension.
303
427
  */
304
- options: TOptions['resolvedOptions']
428
+ parsers?: Array<Parser>
305
429
  /**
306
- * Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin is executed after these plugins.
307
- * Can be used to validate dependent plugins.
430
+ * Adapter that converts the input file into a `@kubb/ast` `InputNode`.
308
431
  */
309
- pre?: Array<string>
432
+ adapter?: Adapter
310
433
  /**
311
- * Specifies the succeeding plugins for the current plugin. You can pass an array of succeeding plugin names, and the current plugin is executed before these plugins.
434
+ * An array of Kubb plugins used for code generation.
435
+ * Each entry is a hook-style plugin created with `definePlugin`.
312
436
  */
313
- post?: Array<string>
314
- inject?: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => TOptions['context']
437
+ plugins?: Array<Plugin>
315
438
  }
316
439
 
317
- export type UserPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = UserPlugin<TOptions> & PluginLifecycle<TOptions>
318
-
319
- export type UnknownUserPlugin = UserPlugin<PluginFactoryOptions<any, any, any, any, any>>
320
-
321
- export type Plugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
440
+ export type ResolveNameParams = {
441
+ name: string
442
+ pluginName?: string
322
443
  /**
323
- * Unique name used for the plugin
324
- * @example @kubb/typescript
444
+ * Specifies the type of entity being named.
445
+ * - `'file'` — customizes the name of the created file (camelCase).
446
+ * - `'function'` — customizes the exported function names (camelCase).
447
+ * - `'type'` — customizes TypeScript type names (PascalCase).
448
+ * - `'const'` — customizes variable names (camelCase).
325
449
  */
326
- name: TOptions['name']
450
+ type?: 'file' | 'function' | 'type' | 'const'
451
+ }
452
+ /**
453
+ * Context object passed as the second argument to generator `schema`, `operation`, and
454
+ * `operations` methods.
455
+ *
456
+ * Generators are only invoked from `runPluginAstHooks`, which already guards against a
457
+ * missing adapter. This type reflects that guarantee — `ctx.adapter` and `ctx.inputNode`
458
+ * are always defined, so no runtime checks or casts are needed inside generator bodies.
459
+ *
460
+ * `ctx.options` carries the per-node resolved options for `schema`/`operation` calls
461
+ * (after exclude/include/override filtering) and the plugin-level options for `operations`.
462
+ */
463
+ export type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
464
+ config: Config
327
465
  /**
328
- * Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin is executed after these plugins.
329
- * Can be used to validate dependent plugins.
466
+ * Absolute path to the output directory for the current plugin.
467
+ * Shorthand for `path.resolve(config.root, config.output.path)`.
330
468
  */
331
- pre?: Array<string>
469
+ root: string
332
470
  /**
333
- * Specifies the succeeding plugins for the current plugin. You can pass an array of succeeding plugin names, and the current plugin is executed before these plugins.
471
+ * Returns the output mode for the given output config.
472
+ * Returns `'single'` when `output.path` has a file extension, `'split'` otherwise.
334
473
  */
335
- post?: Array<string>
474
+ getMode: (output: { path: string }) => 'single' | 'split'
475
+ driver: PluginDriver
336
476
  /**
337
- * Options set for a specific plugin(see kubb.config.js), passthrough of options.
477
+ * Get a plugin by name. Returns the plugin typed via `Kubb.PluginRegistry` when
478
+ * the name is a registered key, otherwise returns the generic `Plugin`.
338
479
  */
339
- options: TOptions['resolvedOptions']
340
-
341
- install: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => PossiblePromise<void>
480
+ getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined
481
+ getPlugin(name: string): Plugin | undefined
342
482
  /**
343
- * Define a context that can be used by other plugins, see `PluginManager' where we convert from `UserPlugin` to `Plugin`(used when calling `definePlugin`).
483
+ * Like `getPlugin` but throws a descriptive error when the plugin is not found.
344
484
  */
345
- inject: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => TOptions['context']
346
- }
347
-
348
- export type PluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & PluginLifecycle<TOptions>
349
-
350
- export type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
485
+ requirePlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]>
486
+ requirePlugin(name: string): Plugin
351
487
  /**
352
- * Start of the lifecycle of a plugin.
353
- * @type hookParallel
488
+ * Get a resolver by plugin name. Returns the resolver typed via `Kubb.PluginRegistry` when
489
+ * the name is a registered key, otherwise returns the generic `Resolver`.
354
490
  */
355
- install?: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => PossiblePromise<void>
491
+ getResolver<TName extends keyof Kubb.PluginRegistry>(name: TName): Kubb.PluginRegistry[TName]['resolver']
492
+ getResolver(name: string): Resolver
356
493
  /**
357
- * Resolve to a Path based on a baseName(example: `./Pet.ts`) and directory(example: `./models`).
358
- * Options can als be included.
359
- * @type hookFirst
360
- * @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
494
+ * Add files only when they do not exist yet.
361
495
  */
362
- resolvePath?: (this: PluginContext<TOptions>, baseName: KubbFile.BaseName, mode?: KubbFile.Mode, options?: TOptions['resolvePathOptions']) => KubbFile.Path
496
+ addFile: (...file: Array<FileNode>) => Promise<void>
363
497
  /**
364
- * Resolve to a name based on a string.
365
- * Useful when converting to PascalCase or camelCase.
366
- * @type hookFirst
367
- * @example ('pet') => 'Pet'
498
+ * Merge multiple sources into the same output file.
368
499
  */
369
- resolveName?: (this: PluginContext<TOptions>, name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
370
- }
371
-
372
- export type PluginLifecycleHooks = keyof PluginLifecycle
373
-
374
- export type PluginParameter<H extends PluginLifecycleHooks> = Parameters<Required<PluginLifecycle>[H]>
375
-
376
- export type ResolvePathParams<TOptions = object> = {
377
- pluginName?: string
378
- baseName: KubbFile.BaseName
379
- mode?: KubbFile.Mode
500
+ upsertFile: (...file: Array<FileNode>) => Promise<void>
501
+ hooks: AsyncEventEmitter<KubbHooks>
380
502
  /**
381
- * Options to be passed to 'resolvePath' 3th parameter
503
+ * The current plugin.
382
504
  */
383
- options?: TOptions
384
- }
385
-
386
- export type ResolveNameParams = {
387
- name: string
388
- pluginName?: string
505
+ plugin: Plugin<TOptions>
389
506
  /**
390
- * Specifies the type of entity being named.
391
- * - 'file' customizes the name of the created file (uses camelCase).
392
- * - 'function' customizes the exported function names (uses camelCase).
393
- * - 'type' customizes TypeScript types (uses PascalCase).
394
- * - 'const' customizes variable names (uses camelCase).
395
- * @default undefined
507
+ * Resolver for the current plugin.
396
508
  */
397
- type?: 'file' | 'function' | 'type' | 'const'
398
- }
399
-
400
- export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
401
- fabric: FabricType
402
- config: Config
403
- pluginManager: PluginManager
509
+ resolver: TOptions['resolver']
404
510
  /**
405
- * Only add when the file does not exist yet
511
+ * Composed transformer for the current plugin.
406
512
  */
407
- addFile: (...file: Array<KubbFile.File>) => Promise<void>
513
+ transformer: Visitor | undefined
408
514
  /**
409
- * merging multiple sources into the same output file
515
+ * Emit a warning via the build event system.
410
516
  */
411
- upsertFile: (...file: Array<KubbFile.File>) => Promise<void>
412
- events: AsyncEventEmitter<KubbEvents>
413
- mode: KubbFile.Mode
517
+ warn: (message: string) => void
414
518
  /**
415
- * Current plugin
519
+ * Emit an error via the build event system.
416
520
  */
417
- plugin: Plugin<TOptions>
418
-
521
+ error: (error: string | Error) => void
419
522
  /**
420
- * Opens the Kubb Studio URL for the current `rootNode` in the default browser.
421
- * Falls back to printing the URL if the browser cannot be launched.
422
- * No-ops silently when no adapter has set a `rootNode`.
523
+ * Emit an info message via the build event system.
524
+ */
525
+ info: (message: string) => void
526
+ /**
527
+ * Opens the Kubb Studio URL for the current `inputNode` in the default browser.
423
528
  */
424
529
  openInStudio: (options?: DevtoolsOptions) => Promise<void>
425
- } & (
426
- | {
427
- /**
428
- * Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
429
- * Returns `undefined` when no adapter was set (legacy OAS-only usage).
430
- */
431
- rootNode: RootNode
432
- /**
433
- * Return the adapter from `@kubb/ast`
434
- */
435
- adapter: Adapter
436
- }
437
- | {
438
- rootNode?: never
439
- adapter?: never
440
- }
441
- ) &
442
- Kubb.PluginContext
530
+ /**
531
+ * The adapter from `@kubb/ast`.
532
+ */
533
+ adapter: Adapter
534
+ /**
535
+ * The universal `@kubb/ast` `InputNode` produced by the configured adapter.
536
+ */
537
+ inputNode: InputNode
538
+ /**
539
+ * Per-node resolved options (after exclude/include/override filtering).
540
+ */
541
+ options: TOptions['resolvedOptions']
542
+ }
443
543
  /**
444
- * Specify the export location for the files and define the behavior of the output
544
+ * Configure generated file output location and behavior.
445
545
  */
446
- export type Output<TOptions> = {
546
+ export type Output<_TOptions = unknown> = {
447
547
  /**
448
- * Path to the output folder or file that will contain the generated code
548
+ * Path to the output folder or file that will contain generated code.
449
549
  */
450
550
  path: string
451
551
  /**
@@ -454,13 +554,15 @@ export type Output<TOptions> = {
454
554
  */
455
555
  barrelType?: BarrelType | false
456
556
  /**
457
- * Add a banner text in the beginning of every file
557
+ * Text or function appended at the start of every generated file.
558
+ * When a function, receives the current `InputNode` and must return a string.
458
559
  */
459
- banner?: string | ((options: TOptions) => string)
560
+ banner?: string | ((node?: InputNode) => string)
460
561
  /**
461
- * Add a footer text in the beginning of every file
562
+ * Text or function appended at the end of every generated file.
563
+ * When a function, receives the current `InputNode` and must return a string.
462
564
  */
463
- footer?: string | ((options: TOptions) => string)
565
+ footer?: string | ((node?: InputNode) => string)
464
566
  /**
465
567
  * Whether to override existing external files if they already exist.
466
568
  * @default false
@@ -468,22 +570,18 @@ export type Output<TOptions> = {
468
570
  override?: boolean
469
571
  }
470
572
 
471
- type GroupContext = {
472
- group: string
473
- }
474
-
475
573
  export type Group = {
476
574
  /**
477
- * Defines the type where to group the files.
478
- * - 'tag' groups files by OpenAPI tags.
479
- * - 'path' groups files by OpenAPI paths.
480
- * @default undefined
575
+ * Determines how files are grouped into subdirectories.
576
+ * - `'tag'` groups files by OpenAPI tags.
577
+ * - `'path'` groups files by OpenAPI paths.
481
578
  */
482
579
  type: 'tag' | 'path'
483
580
  /**
484
- * Return the name of a group based on the group name, this used for the file and name generation
581
+ * Returns the subdirectory name for a given group value.
582
+ * Defaults to `${camelCase(group)}Controller` for tags and the first path segment for paths.
485
583
  */
486
- name?: (context: GroupContext) => string
584
+ name?: (context: { group: string }) => string
487
585
  }
488
586
 
489
587
  export type LoggerOptions = {
@@ -494,19 +592,291 @@ export type LoggerOptions = {
494
592
  }
495
593
 
496
594
  /**
497
- * Shared context passed to all plugins, parsers, and Fabric internals.
595
+ * Shared context passed to all plugins, parsers, and other internals.
498
596
  */
499
- export interface LoggerContext extends AsyncEventEmitter<KubbEvents> {}
500
-
501
- type Install<TOptions = unknown> = (context: LoggerContext, options?: TOptions) => void | Promise<void>
597
+ export type LoggerContext = AsyncEventEmitter<KubbHooks>
502
598
 
503
599
  export type Logger<TOptions extends LoggerOptions = LoggerOptions> = {
504
600
  name: string
505
- install: Install<TOptions>
601
+ install: (context: LoggerContext, options?: TOptions) => void | Promise<void>
602
+ }
603
+
604
+ export type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Logger<TOptions>
605
+
606
+ export type { Storage } from './createStorage.ts'
607
+ export type { Generator } from './defineGenerator.ts'
608
+ export type { Plugin } from './definePlugin.ts'
609
+ export type { Kubb, KubbHooks } from './Kubb.ts'
610
+
611
+ /**
612
+ * Context passed to a hook-style plugin's `kubb:plugin:setup` handler.
613
+ * Provides methods to register generators, configure the resolver, transformer,
614
+ * and renderer, as well as access to the current build configuration.
615
+ */
616
+ export type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
617
+ /**
618
+ * Register a generator on this plugin. Generators are invoked during the AST walk
619
+ * (schema/operation/operations) exactly like generators declared statically on `createPlugin`.
620
+ */
621
+ addGenerator<TElement = unknown>(generator: Generator<TFactory, TElement>): void
622
+ /**
623
+ * Set or partially override the resolver for this plugin.
624
+ * The resolver controls file naming and path resolution for generated files.
625
+ *
626
+ * When `TFactory` is a concrete `PluginFactoryOptions` (e.g. `PluginClient`),
627
+ * the resolver parameter is typed to the plugin's own resolver type (e.g. `ResolverClient`).
628
+ */
629
+ setResolver(resolver: Partial<TFactory['resolver']>): void
630
+ /**
631
+ * Set the AST transformer (visitor) for this plugin.
632
+ * The transformer pre-processes nodes before they reach the generators.
633
+ */
634
+ setTransformer(visitor: Visitor): void
635
+ /**
636
+ * Set the renderer factory for this plugin.
637
+ * Used to process JSX elements returned by generators.
638
+ */
639
+ setRenderer(renderer: RendererFactory): void
640
+ /**
641
+ * Set the resolved options for the build loop. These options are merged into the
642
+ * normalized plugin's `options` object (which includes `output`, `exclude`, `override`).
643
+ *
644
+ * Call this in `kubb:plugin:setup` to provide the resolved options that generators
645
+ * and the build loop need (e.g., `enumType`, `optionalType`, `group`).
646
+ */
647
+ setOptions(options: TFactory['resolvedOptions']): void
648
+ /**
649
+ * Inject a raw file into the build output, bypassing the normal generation pipeline.
650
+ */
651
+ injectFile(
652
+ file: Pick<FileNode, 'baseName' | 'path'> & {
653
+ sources?: FileNode['sources']
654
+ },
655
+ ): void
656
+ /**
657
+ * Merge a partial config update into the current build configuration.
658
+ */
659
+ updateConfig(config: Partial<Config>): void
660
+ /**
661
+ * The resolved build configuration at the time of setup.
662
+ */
663
+ config: Config
664
+ /**
665
+ * The plugin's own options as passed by the user.
666
+ */
667
+ options: TFactory['options']
668
+ }
669
+
670
+ /**
671
+ * Context passed to a hook-style plugin's `kubb:build:start` handler.
672
+ * Fires immediately before the plugin execution loop begins.
673
+ */
674
+ export type KubbBuildStartContext = {
675
+ config: Config
676
+ adapter: Adapter
677
+ inputNode: InputNode
678
+ /**
679
+ * Get a plugin by name. Returns the plugin typed via `Kubb.PluginRegistry` when
680
+ * the name is a registered key, otherwise returns the generic `Plugin`.
681
+ */
682
+ getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined
683
+ getPlugin(name: string): Plugin | undefined
684
+ }
685
+
686
+ /**
687
+ * Context passed to a hook-style plugin's `kubb:build:end` handler.
688
+ * Fires after all files have been written to disk.
689
+ */
690
+ export type KubbBuildEndContext = {
691
+ files: Array<FileNode>
692
+ config: Config
693
+ outputDir: string
694
+ }
695
+
696
+ type ByTag = {
697
+ type: 'tag'
698
+ pattern: string | RegExp
699
+ }
700
+
701
+ type ByOperationId = {
702
+ type: 'operationId'
703
+ pattern: string | RegExp
704
+ }
705
+
706
+ type ByPath = {
707
+ type: 'path'
708
+ pattern: string | RegExp
709
+ }
710
+
711
+ type ByMethod = {
712
+ type: 'method'
713
+ pattern: HttpMethod | RegExp
714
+ }
715
+ // TODO implement as alternative for ByMethod
716
+ // type ByMethods = {
717
+ // type: 'methods'
718
+ // pattern: Array<HttpMethod>
719
+ // }
720
+
721
+ type BySchemaName = {
722
+ type: 'schemaName'
723
+ pattern: string | RegExp
724
+ }
725
+
726
+ type ByContentType = {
727
+ type: 'contentType'
728
+ pattern: string | RegExp
729
+ }
730
+
731
+ /**
732
+ * A pattern filter that prevents matching nodes from being generated.
733
+ * Match by `tag`, `operationId`, `path`, `method`, `contentType`, or `schemaName`.
734
+ */
735
+ export type Exclude = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName
736
+
737
+ /**
738
+ * A pattern filter that restricts generation to only matching nodes.
739
+ * Match by `tag`, `operationId`, `path`, `method`, `contentType`, or `schemaName`.
740
+ */
741
+ export type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName
742
+
743
+ /**
744
+ * A pattern filter paired with partial option overrides applied when the pattern matches.
745
+ * Match by `tag`, `operationId`, `path`, `method`, `schemaName`, or `contentType`.
746
+ */
747
+ export type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
748
+ //TODO should be options: Omit<Partial<TOptions>, 'override'>
749
+ options: Partial<TOptions>
750
+ }
751
+
752
+ /**
753
+ * File-specific parameters for `Resolver.resolvePath`.
754
+ *
755
+ * Pass alongside a `ResolverContext` to identify which file to resolve.
756
+ * Provide `tag` for tag-based grouping or `path` for path-based grouping.
757
+ *
758
+ * @example
759
+ * ```ts
760
+ * resolver.resolvePath(
761
+ * { baseName: 'petTypes.ts', tag: 'pets' },
762
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
763
+ * )
764
+ * // → '/src/types/petsController/petTypes.ts'
765
+ * ```
766
+ */
767
+ export type ResolverPathParams = {
768
+ baseName: FileNode['baseName']
769
+ pathMode?: 'single' | 'split'
770
+ /**
771
+ * Tag value used when `group.type === 'tag'`.
772
+ */
773
+ tag?: string
774
+ /**
775
+ * Path value used when `group.type === 'path'`.
776
+ */
777
+ path?: string
778
+ }
779
+
780
+ /**
781
+ * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
782
+ *
783
+ * Describes where on disk output is rooted, which output config is active, and the optional
784
+ * grouping strategy that controls subdirectory layout.
785
+ *
786
+ * @example
787
+ * ```ts
788
+ * const context: ResolverContext = {
789
+ * root: config.root,
790
+ * output,
791
+ * group,
792
+ * }
793
+ * ```
794
+ */
795
+ export type ResolverContext = {
796
+ root: string
797
+ output: Output
798
+ group?: Group
799
+ /**
800
+ * Plugin name used to populate `meta.pluginName` on the resolved file.
801
+ */
802
+ pluginName?: string
803
+ }
804
+
805
+ /**
806
+ * File-specific parameters for `Resolver.resolveFile`.
807
+ *
808
+ * Pass alongside a `ResolverContext` to fully describe the file to resolve.
809
+ * `tag` and `path` are used only when a matching `group` is present in the context.
810
+ *
811
+ * @example
812
+ * ```ts
813
+ * resolver.resolveFile(
814
+ * { name: 'listPets', extname: '.ts', tag: 'pets' },
815
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
816
+ * )
817
+ * // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
818
+ * ```
819
+ */
820
+ export type ResolverFileParams = {
821
+ name: string
822
+ extname: FileNode['extname']
823
+ /**
824
+ * Tag value used when `group.type === 'tag'`.
825
+ */
826
+ tag?: string
827
+ /**
828
+ * Path value used when `group.type === 'path'`.
829
+ */
830
+ path?: string
831
+ }
832
+
833
+ /**
834
+ * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
835
+ *
836
+ * `output` is optional — not every plugin configures a banner/footer.
837
+ * `config` carries the global Kubb config, used to derive the default Kubb banner.
838
+ *
839
+ * @example
840
+ * ```ts
841
+ * resolver.resolveBanner(inputNode, { output: { banner: '// generated' }, config })
842
+ * // → '// generated'
843
+ * ```
844
+ */
845
+ export type ResolveBannerContext = {
846
+ output?: Pick<Output, 'banner' | 'footer'>
847
+ config: Config
506
848
  }
507
849
 
508
- export type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Omit<Logger<TOptions>, 'logLevel'>
850
+ /**
851
+ * CLI options derived from command-line flags.
852
+ */
853
+ export type CLIOptions = {
854
+ /**
855
+ * Path to `kubb.config.js`.
856
+ */
857
+ config?: string
858
+ /**
859
+ * Enable watch mode for input files.
860
+ */
861
+ watch?: boolean
862
+ /**
863
+ * Logging verbosity for CLI usage.
864
+ * @default 'silent'
865
+ */
866
+ logLevel?: 'silent' | 'info' | 'debug'
867
+ }
868
+
869
+ /**
870
+ * All accepted forms of a Kubb configuration.
871
+ *
872
+ * Config is always `@kubb/core` {@link Config}.
873
+ * - `PossibleConfig` accepts `Config`/`Config[]`/promise or a no-arg config factory.
874
+ * - `PossibleConfig<TCliOptions>` accepts the same config forms or a config factory receiving `TCliOptions`.
875
+ */
876
+ export type PossibleConfig<TCliOptions = undefined> =
877
+ | PossiblePromise<Config | Config[]>
878
+ | ((...args: [TCliOptions] extends [undefined] ? [] : [TCliOptions]) => PossiblePromise<Config | Config[]>)
509
879
 
510
- export type { CoreGeneratorV2, Generator, ReactGeneratorV2 } from './defineGenerator.ts'
511
- export type { DefineStorage } from './defineStorage.ts'
512
- export type { KubbEvents } from './Kubb.ts'
880
+ export type { BuildOutput } from './createKubb.ts'
881
+ export type { Parser } from './defineParser.ts'
882
+ export type { FileMetaBase } from './utils/getBarrelFiles.ts'