@kubb/core 5.0.0-beta.7 → 5.0.0-beta.8

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.
@@ -113,6 +113,116 @@ declare const logLevel: {
113
113
  readonly debug: 5;
114
114
  };
115
115
  //#endregion
116
+ //#region src/createAdapter.d.ts
117
+ /**
118
+ * Source data passed to an adapter's `parse` function.
119
+ * Mirrors the config input shape with paths resolved to absolute.
120
+ */
121
+ type AdapterSource = {
122
+ type: 'path';
123
+ path: string;
124
+ } | {
125
+ type: 'data';
126
+ data: string | unknown;
127
+ } | {
128
+ type: 'paths';
129
+ paths: Array<string>;
130
+ };
131
+ /**
132
+ * Generic type parameters for an adapter definition.
133
+ *
134
+ * - `TName` — unique identifier (e.g. `'oas'`, `'asyncapi'`)
135
+ * - `TOptions` — user-facing options passed to the adapter factory
136
+ * - `TResolvedOptions` — options after defaults applied
137
+ * - `TDocument` — type of the parsed source document
138
+ */
139
+ type AdapterFactoryOptions<TName extends string = string, TOptions extends object = object, TResolvedOptions extends object = TOptions, TDocument = unknown> = {
140
+ name: TName;
141
+ options: TOptions;
142
+ resolvedOptions: TResolvedOptions;
143
+ document: TDocument;
144
+ };
145
+ /**
146
+ * Adapter that converts input files or data into an `InputNode`.
147
+ *
148
+ * Adapters parse different schema formats (OpenAPI, AsyncAPI, Drizzle, etc.) into Kubb's
149
+ * universal intermediate representation that all plugins consume.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * import { adapterOas } from '@kubb/adapter-oas'
154
+ *
155
+ * export default defineConfig({
156
+ * adapter: adapterOas(),
157
+ * input: { path: './openapi.yaml' },
158
+ * plugins: [pluginTs(), pluginZod()],
159
+ * })
160
+ * ```
161
+ */
162
+ type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
163
+ /**
164
+ * Human-readable adapter identifier (e.g. `'oas'`, `'asyncapi'`).
165
+ */
166
+ name: TOptions['name'];
167
+ /**
168
+ * Resolved adapter options after defaults have been applied.
169
+ */
170
+ options: TOptions['resolvedOptions'];
171
+ /**
172
+ * Parsed source document after the first `parse()` call. `null` before parsing.
173
+ */
174
+ document: TOptions['document'] | null;
175
+ inputNode: InputNode | null;
176
+ /**
177
+ * Parse the source into a universal `InputNode`.
178
+ */
179
+ parse: (source: AdapterSource) => PossiblePromise<InputNode>;
180
+ /**
181
+ * Extract `ImportNode` entries for a schema tree.
182
+ * Returns an empty array before the first `parse()` call.
183
+ *
184
+ * The `resolve` callback receives the collision-corrected schema name and must
185
+ * return `{ name, path }` for the import, or `undefined` to skip it.
186
+ */
187
+ getImports: (node: SchemaNode, resolve: (schemaName: string) => {
188
+ name: string;
189
+ path: string;
190
+ }) => Array<ImportNode>;
191
+ /**
192
+ * Validate the document at the given path or URL.
193
+ */
194
+ validate: (input: string, options?: {
195
+ throwOnError?: boolean;
196
+ }) => Promise<void>;
197
+ };
198
+ type AdapterBuilder<T extends AdapterFactoryOptions> = (options: T['options']) => Adapter<T>;
199
+ /**
200
+ * Factory for implementing custom adapters that translate non-OpenAPI specs into Kubb's AST.
201
+ *
202
+ * Use this to support GraphQL schemas, gRPC definitions, AsyncAPI, or custom domain-specific languages.
203
+ * Built-in adapters include `@kubb/adapter-oas` for OpenAPI and Swagger documents.
204
+ *
205
+ * @note Adapters must parse their input format to Kubb's `InputNode` structure.
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * export const myAdapter = createAdapter<MyAdapter>((options) => {
210
+ * return {
211
+ * name: 'my-adapter',
212
+ * options,
213
+ * async parse(source) {
214
+ * // Transform source format to InputNode
215
+ * return { ... }
216
+ * },
217
+ * }
218
+ * })
219
+ *
220
+ * // Instantiate:
221
+ * const adapter = myAdapter({ validate: true })
222
+ * ```
223
+ */
224
+ declare function createAdapter<T extends AdapterFactoryOptions = AdapterFactoryOptions>(build: AdapterBuilder<T>): (options?: T['options']) => Adapter<T>;
225
+ //#endregion
116
226
  //#region src/createRenderer.d.ts
117
227
  /**
118
228
  * Minimal interface any Kubb renderer must satisfy.
@@ -235,1570 +345,1553 @@ type Storage = {
235
345
  */
236
346
  declare function createStorage<TOptions = Record<string, never>>(build: (options: TOptions) => Storage): (options?: TOptions) => Storage;
237
347
  //#endregion
238
- //#region src/defineGenerator.d.ts
348
+ //#region src/devtools.d.ts
349
+ type DevtoolsOptions = {
350
+ /**
351
+ * Open the AST inspector in Kubb Studio (`/ast`). Defaults to the main Studio page.
352
+ * @default false
353
+ */
354
+ ast?: boolean;
355
+ };
356
+ //#endregion
357
+ //#region src/defineLogger.d.ts
358
+ type LoggerOptions = {
359
+ /**
360
+ * Log level for output verbosity.
361
+ * @default 3
362
+ */
363
+ logLevel: (typeof logLevel)[keyof typeof logLevel];
364
+ };
239
365
  /**
240
- * Declares a named generator unit that walks the AST and emits files.
241
- *
242
- * Each method (`schema`, `operation`, `operations`) is called for the matching node type.
243
- * Each method returns `TElement | Array<FileNode> | void`. JSX-based generators require a `renderer` factory.
244
- * Return `Array<FileNode>` directly or call `ctx.upsertFile()` manually and return `void` to bypass rendering.
366
+ * Shared context passed to plugins, parsers, and other internals.
367
+ */
368
+ type LoggerContext = AsyncEventEmitter<KubbHooks>;
369
+ type Logger<TOptions extends LoggerOptions = LoggerOptions, TInstallReturn = void> = {
370
+ name: string;
371
+ install: (context: LoggerContext, options?: TOptions) => TInstallReturn | Promise<TInstallReturn>;
372
+ };
373
+ type UserLogger<TOptions extends LoggerOptions = LoggerOptions, TInstallReturn = void> = Logger<TOptions, TInstallReturn>;
374
+ /**
375
+ * Wraps a logger definition into a typed {@link Logger}.
245
376
  *
246
- * @note Generators are consumed by plugins and registered via `ctx.addGenerator()` in `kubb:plugin:setup`.
377
+ * The optional second type parameter `TInstallReturn` allows loggers to return
378
+ * a value from `install` — for example, a sink factory that the caller can
379
+ * forward to hook execution.
247
380
  *
248
- * @example
381
+ * @example Basic logger
249
382
  * ```ts
250
- * import { defineGenerator } from '@kubb/core'
251
- * import { jsxRenderer } from '@kubb/renderer-jsx'
383
+ * export const myLogger = defineLogger({
384
+ * name: 'my-logger',
385
+ * install(context, options) {
386
+ * context.on('kubb:info', (message) => console.log('ℹ', message))
387
+ * context.on('kubb:error', (error) => console.error('✗', error.message))
388
+ * },
389
+ * })
390
+ * ```
252
391
  *
253
- * export const typeGenerator = defineGenerator({
254
- * name: 'typescript',
255
- * renderer: jsxRenderer,
256
- * schema(node, ctx) {
257
- * const { adapter, resolver, root, options } = ctx
258
- * return <File ...><Type node={node} resolver={resolver} /></File>
392
+ * @example Logger that returns a hook sink factory
393
+ * ```ts
394
+ * export const myLogger = defineLogger<LoggerOptions, HookSinkFactory>({
395
+ * name: 'my-logger',
396
+ * install(context, options) {
397
+ * // register event handlers
398
+ * return (commandWithArgs) => ({ onStdout: console.log })
259
399
  * },
260
400
  * })
261
401
  * ```
262
402
  */
263
- type Generator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown> = {
264
- /**
265
- * Used in diagnostic messages and debug output.
266
- */
267
- name: string;
268
- /**
269
- * Optional renderer factory that produces a {@link Renderer} for each render cycle.
270
- *
271
- * Generators that return renderer elements (e.g. JSX via `@kubb/renderer-jsx`) must set this
272
- * to the matching renderer factory (e.g. `jsxRenderer` from `@kubb/renderer-jsx`).
273
- *
274
- * Generators that only return `Array<FileNode>` or `void` do not need to set this.
275
- *
276
- * Set `renderer: null` to explicitly opt out of rendering even when the parent plugin
277
- * declares a `renderer` (overrides the plugin-level fallback).
278
- *
279
- * @example
280
- * ```ts
281
- * import { jsxRenderer } from '@kubb/renderer-jsx'
282
- * export const myGenerator = defineGenerator<PluginTs>({
283
- * renderer: jsxRenderer,
284
- * schema(node, ctx) { return <File ...>...</File> },
285
- * })
286
- * ```
287
- */
288
- renderer?: RendererFactory<TElement> | null;
289
- /**
290
- * Called for each schema node in the AST walk.
291
- * `ctx` carries the plugin context with `adapter` and `inputNode` guaranteed present,
292
- * plus `ctx.options` with the per-node resolved options (after exclude/include/override).
293
- */
294
- schema?: (node: SchemaNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
295
- /**
296
- * Called for each operation node in the AST walk.
297
- * `ctx` carries the plugin context with `adapter` and `inputNode` guaranteed present,
298
- * plus `ctx.options` with the per-node resolved options (after exclude/include/override).
299
- */
300
- operation?: (node: OperationNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
301
- /**
302
- * Called once after all operations have been walked.
303
- * `ctx` carries the plugin context with `adapter` and `inputNode` guaranteed present,
304
- * plus `ctx.options` with the plugin-level options for the batch call.
305
- */
306
- operations?: (nodes: Array<OperationNode>, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
307
- };
308
- /**
309
- * Defines a generator. Returns the object as-is with correct `this` typings.
310
- * `applyHookResult` handles renderer elements and `File[]` uniformly using
311
- * the generator's declared `renderer` factory.
312
- */
313
- declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown>(generator: Generator<TOptions, TElement>): Generator<TOptions, TElement>;
403
+ declare function defineLogger<Options extends LoggerOptions = LoggerOptions, TInstallReturn = void>(logger: UserLogger<Options, TInstallReturn>): Logger<Options, TInstallReturn>;
314
404
  //#endregion
315
- //#region src/definePlugin.d.ts
405
+ //#region src/defineMiddleware.d.ts
316
406
  /**
317
- * A plugin object produced by `definePlugin`.
318
- * Instead of flat lifecycle methods, it groups all handlers under a `hooks:` property
319
- * (matching Astro's integration naming convention).
320
- *
321
- * @template TFactory - The plugin's `PluginFactoryOptions` type.
407
+ * A middleware instance produced by calling a factory created with `defineMiddleware`.
408
+ * It declares event handlers under a `hooks` object which are registered on the
409
+ * shared emitter after all plugin hooks, so middleware handlers for any event
410
+ * always fire last.
322
411
  */
323
- type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
412
+ type Middleware = {
324
413
  /**
325
- * Unique name for the plugin, following the same naming convention as `createPlugin`.
414
+ * Unique identifier for this middleware.
326
415
  */
327
416
  name: string;
328
417
  /**
329
- * Plugins that must be registered before this plugin executes.
330
- * An error is thrown at startup when any listed dependency is missing.
331
- */
332
- dependencies?: Array<string>;
333
- /**
334
- * Controls the execution order of this plugin relative to others.
335
- *
336
- * - `'pre'` — runs before all normal plugins.
337
- * - `'post'` — runs after all normal plugins.
338
- * - `undefined` (default) — runs in declaration order among normal plugins.
339
- *
340
- * Dependency constraints always take precedence over `enforce`.
341
- */
342
- enforce?: 'pre' | 'post';
343
- /**
344
- * The options passed by the user when calling the plugin factory.
345
- */
346
- options?: TFactory['options'];
347
- /**
348
- * Lifecycle event handlers for this plugin.
418
+ * Lifecycle event handlers for this middleware.
349
419
  * Any event from the global `KubbHooks` map can be subscribed to here.
420
+ * Handlers are registered after all plugin handlers, so they always fire last.
350
421
  */
351
- hooks: { [K in Exclude<keyof KubbHooks, 'kubb:plugin:setup'>]?: (...args: KubbHooks[K]) => void | Promise<void> } & {
352
- 'kubb:plugin:setup'?(ctx: KubbPluginSetupContext<TFactory>): void | Promise<void>;
353
- };
422
+ hooks: { [K in keyof KubbHooks]?: (...args: KubbHooks[K]) => void | Promise<void> };
354
423
  };
355
424
  /**
356
- * Wraps a factory function and returns a typed `Plugin` with lifecycle handlers grouped under `hooks`.
425
+ * Creates a middleware factory using the hook-style `hooks` API.
357
426
  *
358
- * Handlers live in a single `hooks` object (inspired by Astro integrations).
359
- * All lifecycle events from `KubbHooks` are available for subscription.
427
+ * Middleware handlers fire after all plugin handlers for any given event, making them ideal for post-processing, logging, and auditing.
428
+ * Per-build state (such as accumulators) belongs inside the factory closure so each `createKubb` invocation gets its own isolated instance.
360
429
  *
361
- * @note For real plugins, use a `PluginFactoryOptions` type parameter to get type-safe context in `kubb:plugin:setup`.
362
- * Plugin names should follow the convention `plugin-<feature>` (e.g., `plugin-react-query`, `plugin-zod`).
430
+ * @note The factory can accept typed options. See examples for using options and per-build state patterns.
363
431
  *
364
432
  * @example
365
433
  * ```ts
366
- * import { definePlugin } from '@kubb/core'
434
+ * import { defineMiddleware } from '@kubb/core'
367
435
  *
368
- * export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
369
- * name: 'plugin-ts',
436
+ * // Stateless middleware
437
+ * export const logMiddleware = defineMiddleware(() => ({
438
+ * name: 'log-middleware',
370
439
  * hooks: {
371
- * 'kubb:plugin:setup'(ctx) {
372
- * ctx.setResolver(resolverTs)
440
+ * 'kubb:build:end'({ files }) {
441
+ * console.log(`Build complete with ${files.length} files`)
373
442
  * },
374
443
  * },
375
444
  * }))
376
- * ```
377
- */
378
- declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
379
- //#endregion
380
- //#region src/FileManager.d.ts
381
- /**
382
- * In-memory file store for generated files.
383
- *
384
- * Files with the same `path` are merged — sources, imports, and exports are concatenated.
385
- * The `files` getter returns all stored files sorted by path length (shortest first).
386
- *
387
- * @example
388
- * ```ts
389
- * import { FileManager } from '@kubb/core'
390
445
  *
391
- * const manager = new FileManager()
392
- * manager.upsert(myFile)
393
- * console.log(manager.files) // all stored files
446
+ * // Middleware with options and per-build state
447
+ * export const prefixMiddleware = defineMiddleware((options: { prefix: string } = { prefix: '' }) => {
448
+ * const seen = new Set<string>()
449
+ * return {
450
+ * name: 'prefix-middleware',
451
+ * hooks: {
452
+ * 'kubb:plugin:end'({ plugin }) {
453
+ * seen.add(`${options.prefix}${plugin.name}`)
454
+ * },
455
+ * },
456
+ * }
457
+ * })
394
458
  * ```
395
459
  */
396
- declare class FileManager {
397
- #private;
398
- /**
399
- * Adds one or more files. Incoming files with the same path are merged
400
- * (sources/imports/exports concatenated), but existing cache entries are
401
- * replaced — use {@link upsert} when you want to merge into the cache too.
402
- */
403
- add(...files: Array<FileNode>): Array<FileNode>;
404
- /**
405
- * Adds or merges one or more files.
406
- * If a file with the same path already exists in the cache, its
407
- * sources/imports/exports are merged into the incoming file.
408
- */
409
- upsert(...files: Array<FileNode>): Array<FileNode>;
410
- getByPath(path: string): FileNode | null;
411
- deleteByPath(path: string): void;
412
- clear(): void;
413
- /**
414
- * All stored files, sorted by path length (shorter paths first).
415
- */
416
- get files(): Array<FileNode>;
417
- }
460
+ declare function defineMiddleware<TOptions extends object = object>(factory: (options: TOptions) => Middleware): (options?: TOptions) => Middleware;
418
461
  //#endregion
419
- //#region src/PluginDriver.d.ts
420
- type Options = {
421
- hooks: AsyncEventEmitter<KubbHooks>;
462
+ //#region src/defineParser.d.ts
463
+ type PrintOptions = {
464
+ extname?: FileNode['extname'];
422
465
  };
423
- declare class PluginDriver {
424
- #private;
425
- readonly config: Config;
426
- readonly options: Options;
427
- /**
428
- * Returns `'single'` when `fileOrFolder` has a file extension, `'split'` otherwise.
429
- *
430
- * @example
431
- * ```ts
432
- * PluginDriver.getMode('src/gen/types.ts') // 'single'
433
- * PluginDriver.getMode('src/gen/types') // 'split'
434
- * ```
435
- */
436
- static getMode(fileOrFolder: string | undefined | null): 'single' | 'split';
437
- /**
438
- * The universal `@kubb/ast` `InputNode` produced by the adapter, set by
439
- * the build pipeline after the adapter's `parse()` resolves.
440
- */
441
- inputNode: InputNode | undefined;
442
- adapter: Adapter | undefined;
443
- /**
444
- * Central file store for all generated files.
445
- * Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
446
- * add files; this property gives direct read/write access when needed.
447
- */
448
- readonly fileManager: FileManager;
449
- readonly plugins: Map<string, NormalizedPlugin>;
450
- constructor(config: Config, options: Options);
451
- get hooks(): AsyncEventEmitter<KubbHooks>;
452
- /**
453
- * Registers a hook-style plugin's lifecycle handlers on the shared `AsyncEventEmitter`.
454
- *
455
- * For `kubb:plugin:setup`, the registered listener wraps the globally emitted context with a
456
- * plugin-specific one so that `addGenerator`, `setResolver`, `setTransformer`, and
457
- * `setRenderer` all target the correct `normalizedPlugin` entry in the plugins map.
458
- *
459
- * All other hooks are iterated and registered directly as pass-through listeners.
460
- * Any event key present in the global `KubbHooks` interface can be subscribed to.
461
- *
462
- * External tooling can subscribe to any of these events via `hooks.on(...)` to observe
463
- * the plugin lifecycle without modifying plugin behavior.
464
- *
465
- * @internal
466
- */
467
- registerPluginHooks(hookPlugin: Plugin, normalizedPlugin: NormalizedPlugin): void;
468
- /**
469
- * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
470
- * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
471
- *
472
- * Call this once from `safeBuild` before the plugin execution loop begins.
473
- */
474
- emitSetupHooks(): Promise<void>;
475
- /**
476
- * Registers a generator for the given plugin on the shared event emitter.
477
- *
478
- * The generator's `schema`, `operation`, and `operations` methods are registered as
479
- * listeners on `kubb:generate:schema`, `kubb:generate:operation`, and `kubb:generate:operations`
480
- * respectively. Each listener is scoped to the owning plugin via a `ctx.plugin.name` check
481
- * so that generators from different plugins do not cross-fire.
482
- *
483
- * The renderer resolution chain is: `generator.renderer → plugin.renderer → config.renderer`.
484
- * Set `generator.renderer = null` to explicitly opt out of rendering even when the plugin
485
- * declares a renderer.
486
- *
487
- * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
488
- */
489
- registerGenerator(pluginName: string, gen: Generator): void;
490
- /**
491
- * Returns `true` when at least one generator was registered for the given plugin
492
- * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
493
- *
494
- * Used by the build loop to decide whether to walk the AST and emit generator events
495
- * for a plugin that has no static `plugin.generators`.
496
- */
497
- hasRegisteredGenerators(pluginName: string): boolean;
498
- /**
499
- * Unregisters all plugin lifecycle listeners from the shared event emitter.
500
- * Called at the end of a build to prevent listener leaks across repeated builds.
501
- *
502
- * @internal
503
- */
504
- dispose(): void;
505
- /**
506
- * Merges `partial` with the plugin's default resolver and stores the result.
507
- * Also mirrors it onto `plugin.resolver` so callers using `getPlugin(name).resolver`
508
- * get the up-to-date resolver without going through `getResolver()`.
509
- */
510
- setPluginResolver(pluginName: string, partial: Partial<Resolver>): void;
466
+ type Parser<TMeta extends object = any> = {
467
+ name: string;
511
468
  /**
512
- * Returns the resolver for the given plugin.
469
+ * File extensions this parser handles.
470
+ * Use `undefined` to create a catch-all fallback parser.
513
471
  *
514
- * Resolution order: dynamic resolver set via `setPluginResolver` → static resolver on the
515
- * plugin → lazily created default resolver (identity name, no path transforms).
472
+ * @example Handled extensions
473
+ * `['.ts', '.js']`
516
474
  */
517
- getResolver<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Kubb.PluginRegistry[TName]['resolver'];
518
- getResolver<TResolver extends Resolver = Resolver>(pluginName: string): TResolver;
519
- getContext<TOptions extends PluginFactoryOptions>(plugin: NormalizedPlugin<TOptions>): GeneratorContext<TOptions> & Record<string, unknown>;
520
- getPlugin<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
521
- getPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(pluginName: string): Plugin<TOptions> | undefined;
475
+ extNames: Array<FileNode['extname']> | undefined;
522
476
  /**
523
- * Like `getPlugin` but throws a descriptive error when the plugin is not found.
477
+ * Convert a resolved file to a string.
524
478
  */
525
- requirePlugin<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Plugin<Kubb.PluginRegistry[TName]>;
526
- requirePlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(pluginName: string): Plugin<TOptions>;
527
- }
479
+ parse(file: FileNode<TMeta>, options?: PrintOptions): Promise<string> | string;
480
+ };
481
+ /**
482
+ * Defines a parser with type safety. Creates parsers that transform generated files to strings based on their extension.
483
+ *
484
+ * @note Call the returned factory with optional options to instantiate the parser.
485
+ *
486
+ * @example
487
+ * ```ts
488
+ * import { defineParser } from '@kubb/core'
489
+ *
490
+ * export const jsonParser = defineParser({
491
+ * name: 'json',
492
+ * extNames: ['.json'],
493
+ * parse(file) {
494
+ * const { extractStringsFromNodes } = await import('@kubb/ast')
495
+ * return file.sources.map((s) => extractStringsFromNodes(s.nodes ?? [])).join('\n')
496
+ * },
497
+ * })
498
+ * ```
499
+ */
500
+ declare function defineParser<TMeta extends object = any>(parser: Parser<TMeta>): Parser<TMeta>;
528
501
  //#endregion
529
- //#region src/createKubb.d.ts
502
+ //#region src/defineResolver.d.ts
530
503
  /**
531
- * Full output produced by a successful or failed build.
504
+ * Type/string pattern filter for include/exclude/override matching.
532
505
  */
533
- type BuildOutput = {
534
- /**
535
- * Plugins that threw during installation, paired with the caught error.
536
- */
537
- failedPlugins: Set<{
538
- plugin: Plugin;
539
- error: Error;
540
- }>;
541
- files: Array<FileNode>;
542
- driver: PluginDriver;
543
- /**
544
- * Elapsed time in milliseconds for each plugin, keyed by plugin name.
545
- */
546
- pluginTimings: Map<string, number>;
547
- error?: Error;
548
- /**
549
- * Raw generated source, keyed by absolute file path.
550
- */
551
- sources: Map<string, string>;
506
+ type PatternFilter = {
507
+ type: string;
508
+ pattern: string | RegExp;
552
509
  };
553
- type CreateKubbOptions = {
554
- hooks?: AsyncEventEmitter<KubbHooks>;
510
+ /**
511
+ * Pattern filter with partial option overrides applied when the pattern matches.
512
+ */
513
+ type PatternOverride<TOptions> = PatternFilter & {
514
+ options: Omit<Partial<TOptions>, 'override'>;
555
515
  };
556
516
  /**
557
- * Creates a Kubb instance bound to a single config entry.
517
+ * Context for resolving filtered options for a given operation or schema node.
558
518
  *
559
- * Accepts a user-facing config shape and resolves it to a full {@link Config} during
560
- * `setup()`. The instance then holds shared state (`hooks`, `sources`, `driver`, `config`)
561
- * across the `setup → build` lifecycle. Attach event listeners to `kubb.hooks` before
562
- * calling `setup()` or `build()`.
519
+ * @internal
520
+ */
521
+ type ResolveOptionsContext<TOptions> = {
522
+ options: TOptions;
523
+ exclude?: Array<PatternFilter>;
524
+ include?: Array<PatternFilter>;
525
+ override?: Array<PatternOverride<TOptions>>;
526
+ };
527
+ /**
528
+ * Base constraint for all plugin resolver objects.
529
+ *
530
+ * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
531
+ * are injected automatically by `defineResolver` — extend this type to add custom resolution methods.
563
532
  *
564
533
  * @example
565
534
  * ```ts
566
- * const kubb = createKubb(userConfig)
567
- *
568
- * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
569
- * console.log(`${plugin.name} completed in ${duration}ms`)
570
- * })
571
- *
572
- * const { files, failedPlugins } = await kubb.safeBuild()
535
+ * type MyResolver = Resolver & {
536
+ * resolveName(node: SchemaNode): string
537
+ * resolveTypedName(node: SchemaNode): string
538
+ * }
573
539
  * ```
574
540
  */
575
- declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
576
- //#endregion
577
- //#region src/Kubb.d.ts
541
+ type Resolver = {
542
+ name: string;
543
+ pluginName: string;
544
+ default(name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
545
+ resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null;
546
+ resolvePath(params: ResolverPathParams, context: ResolverContext): string;
547
+ resolveFile(params: ResolverFileParams, context: ResolverContext): FileNode;
548
+ resolveBanner(node: InputNode | null, context: ResolveBannerContext): string | undefined;
549
+ resolveFooter(node: InputNode | null, context: ResolveBannerContext): string | undefined;
550
+ };
578
551
  /**
579
- * Kubb code generation instance returned by {@link createKubb}.
552
+ * File-specific parameters for `Resolver.resolvePath`.
580
553
  *
581
- * Use this when orchestrating multiple builds, inspecting plugin timings, or integrating Kubb into a larger toolchain.
582
- * For a single one-off build, chain directly: `await createKubb(config).build()`.
554
+ * Pass alongside a `ResolverContext` to identify which file to resolve.
555
+ * Provide `tag` for tag-based grouping or `path` for path-based grouping.
556
+ *
557
+ * @example
558
+ * ```ts
559
+ * resolver.resolvePath(
560
+ * { baseName: 'petTypes.ts', tag: 'pets' },
561
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
562
+ * )
563
+ * // → '/src/types/petsController/petTypes.ts'
564
+ * ```
583
565
  */
584
- type Kubb$1 = {
585
- /**
586
- * Shared event emitter for lifecycle and status events. Attach listeners before calling `setup()` or `build()`.
587
- */
588
- readonly hooks: AsyncEventEmitter<KubbHooks>;
589
- /**
590
- * Generated source code keyed by absolute file path. Available after `build()` or `safeBuild()` completes.
591
- */
592
- readonly sources: Map<string, string>;
566
+ type ResolverPathParams = {
567
+ baseName: FileNode['baseName'];
568
+ pathMode?: 'single' | 'split';
593
569
  /**
594
- * Plugin driver managing all plugins. Available after `setup()` completes.
570
+ * Tag value used when `group.type === 'tag'`.
595
571
  */
596
- readonly driver: PluginDriver | undefined;
572
+ tag?: string;
597
573
  /**
598
- * Resolved configuration with defaults applied. Available after `setup()` completes.
574
+ * Path value used when `group.type === 'path'`.
599
575
  */
600
- readonly config: Config | undefined;
576
+ path?: string;
577
+ };
578
+ /**
579
+ * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
580
+ *
581
+ * Describes where on disk output is rooted, which output config is active, and the optional
582
+ * grouping strategy that controls subdirectory layout.
583
+ *
584
+ * @example
585
+ * ```ts
586
+ * const context: ResolverContext = {
587
+ * root: config.root,
588
+ * output,
589
+ * group,
590
+ * }
591
+ * ```
592
+ */
593
+ type ResolverContext = {
594
+ root: string;
595
+ output: Output;
596
+ group?: Group;
601
597
  /**
602
- * Resolves config and initializes the driver. `build()` calls this automatically.
598
+ * Plugin name used to populate `meta.pluginName` on the resolved file.
603
599
  */
604
- setup(): Promise<void>;
600
+ pluginName?: string;
601
+ };
602
+ /**
603
+ * File-specific parameters for `Resolver.resolveFile`.
604
+ *
605
+ * Pass alongside a `ResolverContext` to fully describe the file to resolve.
606
+ * `tag` and `path` are used only when a matching `group` is present in the context.
607
+ *
608
+ * @example
609
+ * ```ts
610
+ * resolver.resolveFile(
611
+ * { name: 'listPets', extname: '.ts', tag: 'pets' },
612
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
613
+ * )
614
+ * // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
615
+ * ```
616
+ */
617
+ type ResolverFileParams = {
618
+ name: string;
619
+ extname: FileNode['extname'];
605
620
  /**
606
- * Runs the full pipeline and throws on any plugin error. Automatically calls `setup()` if needed.
621
+ * Tag value used when `group.type === 'tag'`.
607
622
  */
608
- build(): Promise<BuildOutput>;
623
+ tag?: string;
609
624
  /**
610
- * Runs the full pipeline and captures errors in `BuildOutput` instead of throwing. Automatically calls `setup()` if needed.
625
+ * Path value used when `group.type === 'path'`.
611
626
  */
612
- safeBuild(): Promise<BuildOutput>;
627
+ path?: string;
613
628
  };
614
629
  /**
615
- * Lifecycle events emitted during Kubb code generation.
616
- * Use these for logging, progress tracking, and custom integrations.
630
+ * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
631
+ *
632
+ * `output` is optional — not every plugin configures a banner/footer.
633
+ * `config` carries the global Kubb config, used to derive the default Kubb banner.
617
634
  *
618
635
  * @example
619
- * ```typescript
620
- * import type { AsyncEventEmitter } from '@internals/utils'
621
- * import type { KubbHooks } from '@kubb/core'
636
+ * ```ts
637
+ * resolver.resolveBanner(inputNode, { output: { banner: '// generated' }, config })
638
+ * // '// generated'
639
+ * ```
640
+ */
641
+ type ResolveBannerContext = {
642
+ output?: Pick<Output, 'banner' | 'footer'>;
643
+ config: Config;
644
+ };
645
+ /**
646
+ * Builder type for the plugin-specific resolver fields.
622
647
  *
623
- * const hooks: AsyncEventEmitter<KubbHooks> = new AsyncEventEmitter()
648
+ * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
649
+ * are optional — built-in fallbacks are injected when omitted.
624
650
  *
625
- * hooks.on('kubb:lifecycle:start', () => {
626
- * console.log('Starting Kubb generation')
651
+ * Methods in the returned object can call sibling resolver methods via `this`.
652
+ */
653
+ type ResolverBuilder<T extends PluginFactoryOptions> = () => Omit<T['resolver'], 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter' | 'name' | 'pluginName'> & Partial<Pick<T['resolver'], 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter'>> & {
654
+ name: string;
655
+ pluginName: T['name'];
656
+ };
657
+ /**
658
+ * Default option resolver — applies include/exclude filters and merges matching override options.
659
+ *
660
+ * Returns `null` when the node is filtered out by an `exclude` rule or not matched by any `include` rule.
661
+ *
662
+ * @example Include/exclude filtering
663
+ * ```ts
664
+ * const options = defaultResolveOptions(operationNode, {
665
+ * options: { output: 'types' },
666
+ * exclude: [{ type: 'tag', pattern: 'internal' }],
627
667
  * })
668
+ * // → null when node has tag 'internal'
669
+ * ```
628
670
  *
629
- * hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
630
- * console.log(`Plugin ${plugin.name} completed in ${duration}ms`)
671
+ * @example Override merging
672
+ * ```ts
673
+ * const options = defaultResolveOptions(operationNode, {
674
+ * options: { enumType: 'asConst' },
675
+ * override: [{ type: 'operationId', pattern: 'listPets', options: { enumType: 'enum' } }],
631
676
  * })
677
+ * // → { enumType: 'enum' } when operationId matches
632
678
  * ```
633
679
  */
634
- interface KubbHooks {
635
- /**
636
- * Fires at the start of the Kubb lifecycle, before code generation begins.
637
- */
638
- 'kubb:lifecycle:start': [ctx: KubbLifecycleStartContext];
639
- /**
640
- * Fires at the end of the Kubb lifecycle, after all code generation completes.
641
- */
642
- 'kubb:lifecycle:end': [];
643
- /**
644
- * Fires when configuration loading starts.
645
- */
646
- 'kubb:config:start': [];
647
- /**
648
- * Fires when configuration loading completes.
649
- */
650
- 'kubb:config:end': [ctx: KubbConfigEndContext];
651
- /**
652
- * Fires when code generation starts.
653
- */
654
- 'kubb:generation:start': [ctx: KubbGenerationStartContext];
655
- /**
656
- * Fires when code generation completes.
657
- */
658
- 'kubb:generation:end': [ctx: KubbGenerationEndContext];
659
- /**
660
- * Fires with a generation summary including summary lines, title, and success status.
661
- */
662
- 'kubb:generation:summary': [ctx: KubbGenerationSummaryContext];
663
- /**
664
- * Fires when code formatting starts (e.g., Biome or Prettier).
665
- */
666
- 'kubb:format:start': [];
667
- /**
668
- * Fires when code formatting completes.
669
- */
670
- 'kubb:format:end': [];
680
+ /**
681
+ * Defines a resolver for a plugin, injecting built-in defaults for name casing,
682
+ * include/exclude/override filtering, path resolution, and file construction.
683
+ *
684
+ * All four defaults can be overridden by providing them in the builder function:
685
+ * - `default` — name casing strategy (camelCase / PascalCase)
686
+ * - `resolveOptions` include/exclude/override filtering
687
+ * - `resolvePath` — output path computation
688
+ * - `resolveFile` — full `FileNode` construction
689
+ *
690
+ * Methods in the returned object can call sibling resolver methods via `this`.
691
+ *
692
+ * @example Basic resolver with naming helpers
693
+ * ```ts
694
+ * export const resolver = defineResolver<PluginTs>(() => ({
695
+ * name: 'default',
696
+ * resolveName(node) {
697
+ * return this.default(node.name, 'function')
698
+ * },
699
+ * resolveTypedName(node) {
700
+ * return this.default(node.name, 'type')
701
+ * },
702
+ * }))
703
+ * ```
704
+ *
705
+ * @example Override resolvePath for a custom output structure
706
+ * ```ts
707
+ * export const resolver = defineResolver<PluginTs>(() => ({
708
+ * name: 'custom',
709
+ * resolvePath({ baseName }, { root, output }) {
710
+ * return path.resolve(root, output.path, 'generated', baseName)
711
+ * },
712
+ * }))
713
+ * ```
714
+ *
715
+ * @example Use this.default inside a helper
716
+ * ```ts
717
+ * export const resolver = defineResolver<PluginTs>(() => ({
718
+ * name: 'default',
719
+ * resolveParamName(node, param) {
720
+ * return this.default(`${node.operationId} ${param.in} ${param.name}`, 'type')
721
+ * },
722
+ * }))
723
+ * ```
724
+ */
725
+ declare function defineResolver<T extends PluginFactoryOptions>(build: ResolverBuilder<T>): T['resolver'];
726
+ //#endregion
727
+ //#region src/definePlugin.d.ts
728
+ /**
729
+ * Safely extracts a type from a registry, returning `{}` if the key doesn't exist.
730
+ * Enables optional interface augmentation for `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
731
+ * without requiring changes to core.
732
+ *
733
+ * @internal
734
+ */
735
+ type ExtractRegistryKey$1<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
736
+ /**
737
+ * Output configuration for generated files.
738
+ */
739
+ type Output<_TOptions = unknown> = {
671
740
  /**
672
- * Fires when linting starts.
741
+ * Output folder or file path for generated code.
673
742
  */
674
- 'kubb:lint:start': [];
743
+ path: string;
675
744
  /**
676
- * Fires when linting completes.
745
+ * Text or function prepended to every generated file.
746
+ * When a function, receives the current `InputNode` and returns a string.
677
747
  */
678
- 'kubb:lint:end': [];
748
+ banner?: string | ((node?: InputNode) => string);
679
749
  /**
680
- * Fires when plugin hooks execution starts.
750
+ * Text or function appended to every generated file.
751
+ * When a function, receives the current `InputNode` and returns a string.
681
752
  */
682
- 'kubb:hooks:start': [];
753
+ footer?: string | ((node?: InputNode) => string);
683
754
  /**
684
- * Fires when plugin hooks execution completes.
755
+ * Whether to override existing external files if they already exist.
756
+ * @default false
685
757
  */
686
- 'kubb:hooks:end': [];
758
+ override?: boolean;
759
+ } & ExtractRegistryKey$1<Kubb.PluginOptionsRegistry, 'output'>;
760
+ type Group = {
687
761
  /**
688
- * Fires when a single hook executes (e.g., format or lint). The callback is invoked when the command finishes.
762
+ * How to group files into subdirectories.
763
+ * - `'tag'` — group by OpenAPI tags
764
+ * - `'path'` — group by OpenAPI paths
689
765
  */
690
- 'kubb:hook:start': [ctx: KubbHookStartContext];
766
+ type: 'tag' | 'path';
691
767
  /**
692
- * Fires when a single hook execution completes.
768
+ * Function that returns the subdirectory name for a group value.
769
+ * Defaults to `${camelCase(group)}Controller` for tags, first path segment for paths.
693
770
  */
694
- 'kubb:hook:end': [ctx: KubbHookEndContext];
771
+ name?: (context: {
772
+ group: string;
773
+ }) => string;
774
+ };
775
+ type ByTag = {
695
776
  /**
696
- * Fires when a new Kubb version is available.
777
+ * Filter by OpenAPI `tags` field. Matches one or more tags assigned to operations.
697
778
  */
698
- 'kubb:version:new': [ctx: KubbVersionNewContext];
779
+ type: 'tag';
699
780
  /**
700
- * Informational message event.
781
+ * Tag name to match (case-sensitive). Can be a literal string or regex pattern.
701
782
  */
702
- 'kubb:info': [ctx: KubbInfoContext];
783
+ pattern: string | RegExp;
784
+ };
785
+ type ByOperationId = {
703
786
  /**
704
- * Error event, fired when an error occurs during generation.
787
+ * Filter by OpenAPI `operationId` field. Each operation (GET, POST, etc.) has a unique identifier.
705
788
  */
706
- 'kubb:error': [ctx: KubbErrorContext];
789
+ type: 'operationId';
707
790
  /**
708
- * Success message event.
791
+ * Operation ID to match (case-sensitive). Can be a literal string or regex pattern.
709
792
  */
710
- 'kubb:success': [ctx: KubbSuccessContext];
793
+ pattern: string | RegExp;
794
+ };
795
+ type ByPath = {
711
796
  /**
712
- * Warning message event.
797
+ * Filter by OpenAPI `path` (URL endpoint). Useful to group or filter by service segments like `/pets`, `/users`, etc.
713
798
  */
714
- 'kubb:warn': [ctx: KubbWarnContext];
799
+ type: 'path';
715
800
  /**
716
- * Debug event for detailed logging with timestamp and optional filename.
801
+ * URL path to match (case-sensitive). Can be a literal string or regex pattern. Matches against the full path.
717
802
  */
718
- 'kubb:debug': [ctx: KubbDebugContext];
803
+ pattern: string | RegExp;
804
+ };
805
+ type ByMethod = {
719
806
  /**
720
- * Fires when file processing starts with the list of files to process.
807
+ * Filter by HTTP method: `'get'`, `'post'`, `'put'`, `'delete'`, `'patch'`, `'head'`, `'options'`.
721
808
  */
722
- 'kubb:files:processing:start': [ctx: KubbFilesProcessingStartContext];
809
+ type: 'method';
723
810
  /**
724
- * Fires for each file with progress updates: processed count, total, percentage, and file details.
811
+ * HTTP method to match (case-insensitive when using string, or regex for dynamic matching).
725
812
  */
726
- 'kubb:file:processing:update': [ctx: KubbFileProcessingUpdateContext];
813
+ pattern: HttpMethod | RegExp;
814
+ };
815
+ type BySchemaName = {
727
816
  /**
728
- * Fires when file processing completes with the list of processed files.
817
+ * Filter by schema component name (TypeScript or JSON schema). Matches schemas in `#/components/schemas`.
729
818
  */
730
- 'kubb:files:processing:end': [ctx: KubbFilesProcessingEndContext];
819
+ type: 'schemaName';
731
820
  /**
732
- * Fires when a plugin starts execution.
821
+ * Schema name to match (case-sensitive). Can be a literal string or regex pattern.
733
822
  */
734
- 'kubb:plugin:start': [ctx: KubbPluginStartContext];
823
+ pattern: string | RegExp;
824
+ };
825
+ type ByContentType = {
735
826
  /**
736
- * Fires when a plugin completes execution. Duration measured in milliseconds.
827
+ * Filter by response or request content type: `'application/json'`, `'application/xml'`, etc.
737
828
  */
738
- 'kubb:plugin:end': [ctx: KubbPluginEndContext];
829
+ type: 'contentType';
739
830
  /**
740
- * Fires once before plugins execute allowing plugins to register generators, configure resolvers/transformers/renderers, or inject files.
831
+ * Content type to match (case-sensitive). Can be a literal string or regex pattern.
741
832
  */
742
- 'kubb:plugin:setup': [ctx: KubbPluginSetupContext];
833
+ pattern: string | RegExp;
834
+ };
835
+ /**
836
+ * A pattern filter that prevents matching nodes from being generated.
837
+ *
838
+ * Use to skip code generation for specific operations or schemas. For example, exclude deprecated endpoints
839
+ * or internal-only schemas. Can filter by tag, operationId, path, HTTP method, content type, or schema name.
840
+ *
841
+ * @example
842
+ * ```ts
843
+ * exclude: [
844
+ * { type: 'tag', pattern: 'internal' }, // skip "internal" tag
845
+ * { type: 'path', pattern: /^\/admin/ }, // skip all /admin endpoints
846
+ * { type: 'operationId', pattern: 'deprecated_*' } // skip operationIds matching pattern
847
+ * ]
848
+ * ```
849
+ */
850
+ type Exclude = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
851
+ /**
852
+ * A pattern filter that restricts generation to only matching nodes.
853
+ *
854
+ * Use to generate code for a subset of operations or schemas. For example, only generate for a specific service
855
+ * tag or only for "production" endpoints. Can filter by tag, operationId, path, HTTP method, content type, or schema name.
856
+ *
857
+ * @example
858
+ * ```ts
859
+ * include: [
860
+ * { type: 'tag', pattern: 'public' }, // generate only "public" tag
861
+ * { type: 'path', pattern: /^\/api\/v1/ }, // generate only v1 endpoints
862
+ * ]
863
+ * ```
864
+ */
865
+ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
866
+ /**
867
+ * A pattern filter paired with partial option overrides applied when the pattern matches.
868
+ *
869
+ * Use to customize generation for specific operations or schemas. For example, apply different output paths
870
+ * for different tags, or use custom resolver functions per operation. Can filter by tag, operationId, path,
871
+ * HTTP method, schema name, or content type.
872
+ *
873
+ * @example
874
+ * ```ts
875
+ * override: [
876
+ * {
877
+ * type: 'tag',
878
+ * pattern: 'admin',
879
+ * options: { output: { path: './src/gen/admin' } } // admin APIs go to separate folder
880
+ * },
881
+ * {
882
+ * type: 'operationId',
883
+ * pattern: 'listPets',
884
+ * options: { exclude: true } // skip this specific operation
885
+ * }
886
+ * ]
887
+ * ```
888
+ */
889
+ type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
890
+ options: Partial<TOptions>;
891
+ };
892
+ type PluginFactoryOptions<
893
+ /**
894
+ * Unique plugin name.
895
+ */
896
+ TName extends string = string,
897
+ /**
898
+ * User-facing plugin options.
899
+ */
900
+ TOptions extends object = object,
901
+ /**
902
+ * Plugin options after defaults are applied.
903
+ */
904
+ TResolvedOptions extends object = TOptions,
905
+ /**
906
+ * Resolver that encapsulates naming and path-resolution helpers.
907
+ * Define with `defineResolver` and export alongside the plugin.
908
+ */
909
+ TResolver extends Resolver = Resolver> = {
910
+ name: TName;
911
+ options: TOptions;
912
+ resolvedOptions: TResolvedOptions;
913
+ resolver: TResolver;
914
+ };
915
+ /**
916
+ * Context for hook-style plugin `kubb:plugin:setup` handler.
917
+ * Provides methods to register generators, configure resolvers, transformers, and renderers.
918
+ */
919
+ type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
743
920
  /**
744
- * Fires before the plugin execution loop begins. The adapter has already parsed the source and `inputNode` is available.
921
+ * Register a generator dynamically. Generators fire during the AST walk (schema/operation/operations)
922
+ * just like generators declared statically on `createPlugin`.
745
923
  */
746
- 'kubb:build:start': [ctx: KubbBuildStartContext];
924
+ addGenerator<TElement = unknown>(generator: Generator<TFactory, TElement>): void;
747
925
  /**
748
- * Fires after all plugins run and per-plugin barrels generate, but before files write to disk.
749
- * Use this to inject final files that must persist in the same write pass as plugin output.
926
+ * Set or override the resolver for this plugin.
927
+ * The resolver controls file naming and path resolution.
750
928
  */
751
- 'kubb:plugins:end': [ctx: KubbPluginsEndContext];
929
+ setResolver(resolver: Partial<TFactory['resolver']>): void;
752
930
  /**
753
- * Fires after all files write to disk.
931
+ * Set the AST transformer to pre-process nodes before they reach generators.
754
932
  */
755
- 'kubb:build:end': [ctx: KubbBuildEndContext];
933
+ setTransformer(visitor: Visitor): void;
756
934
  /**
757
- * Fires for each schema node during AST traversal. Generator listeners respond to this.
935
+ * Set the renderer factory to process JSX elements from generators.
758
936
  */
759
- 'kubb:generate:schema': [node: SchemaNode, ctx: GeneratorContext];
937
+ setRenderer(renderer: RendererFactory): void;
760
938
  /**
761
- * Fires for each operation node during AST traversal. Generator listeners respond to this.
939
+ * Set resolved options merged into the normalized plugin's `options`.
940
+ * Call this in `kubb:plugin:setup` to provide options generators need.
762
941
  */
763
- 'kubb:generate:operation': [node: OperationNode, ctx: GeneratorContext];
942
+ setOptions(options: TFactory['resolvedOptions']): void;
764
943
  /**
765
- * Fires once after all operations traverse with the full collected array. Batch generator listeners respond to this.
766
- */
767
- 'kubb:generate:operations': [nodes: Array<OperationNode>, ctx: GeneratorContext];
768
- }
769
- declare global {
770
- namespace Kubb {
771
- /**
772
- * Registry that maps plugin names to their `PluginFactoryOptions`.
773
- * Augment this interface in each plugin's `types.ts` to enable automatic
774
- * typing for `getPlugin` and `requirePlugin`.
775
- *
776
- * @example
777
- * ```ts
778
- * // packages/plugin-ts/src/types.ts
779
- * declare global {
780
- * namespace Kubb {
781
- * interface PluginRegistry {
782
- * 'plugin-ts': PluginTs
783
- * }
784
- * }
785
- * }
786
- * ```
787
- */
788
- interface PluginRegistry {}
789
- /**
790
- * Extension point for root `Config['output']` options.
791
- * Augment the `output` key in middleware or plugin packages to add extra fields
792
- * to the global output configuration without touching core types.
793
- *
794
- * @example
795
- * ```ts
796
- * // packages/middleware-barrel/src/types.ts
797
- * declare global {
798
- * namespace Kubb {
799
- * interface ConfigOptionsRegistry {
800
- * output: {
801
- * barrel?: import('./types.ts').BarrelConfig | false
802
- * }
803
- * }
804
- * }
805
- * }
806
- * ```
807
- */
808
- interface ConfigOptionsRegistry {}
809
- /**
810
- * Extension point for per-plugin `Output` options.
811
- * Augment the `output` key in middleware or plugin packages to add extra fields
812
- * to the per-plugin output configuration without touching core types.
813
- *
814
- * @example
815
- * ```ts
816
- * // packages/middleware-barrel/src/types.ts
817
- * declare global {
818
- * namespace Kubb {
819
- * interface PluginOptionsRegistry {
820
- * output: {
821
- * barrel?: import('./types.ts').PluginBarrelConfig | false
822
- * }
823
- * }
824
- * }
825
- * }
826
- * ```
827
- */
828
- interface PluginOptionsRegistry {}
829
- }
830
- }
831
- //#endregion
832
- //#region src/defineMiddleware.d.ts
944
+ * Inject a raw file into the build output, bypassing the generation pipeline.
945
+ */
946
+ injectFile(userFileNode: UserFileNode): void;
947
+ /**
948
+ * Merge a partial config update into the current build configuration.
949
+ */
950
+ updateConfig(config: Partial<Config>): void;
951
+ /**
952
+ * The resolved build configuration at setup time.
953
+ */
954
+ config: Config;
955
+ /**
956
+ * The plugin's user-provided options.
957
+ */
958
+ options: TFactory['options'];
959
+ };
833
960
  /**
834
- * A middleware instance produced by calling a factory created with `defineMiddleware`.
835
- * It declares event handlers under a `hooks` object which are registered on the
836
- * shared emitter after all plugin hooks, so middleware handlers for any event
837
- * always fire last.
961
+ * A plugin object produced by `definePlugin`.
962
+ * Instead of flat lifecycle methods, it groups all handlers under a `hooks:` property
963
+ * (matching Astro's integration naming convention).
964
+ *
965
+ * @template TFactory - The plugin's `PluginFactoryOptions` type.
838
966
  */
839
- type Middleware = {
967
+ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
840
968
  /**
841
- * Unique identifier for this middleware.
969
+ * Unique name for the plugin, following the same naming convention as `createPlugin`.
842
970
  */
843
971
  name: string;
844
972
  /**
845
- * Lifecycle event handlers for this middleware.
973
+ * Plugins that must be registered before this plugin executes.
974
+ * An error is thrown at startup when any listed dependency is missing.
975
+ */
976
+ dependencies?: Array<string>;
977
+ /**
978
+ * Controls the execution order of this plugin relative to others.
979
+ *
980
+ * - `'pre'` — runs before all normal plugins.
981
+ * - `'post'` — runs after all normal plugins.
982
+ * - `undefined` (default) — runs in declaration order among normal plugins.
983
+ *
984
+ * Dependency constraints always take precedence over `enforce`.
985
+ */
986
+ enforce?: 'pre' | 'post';
987
+ /**
988
+ * The options passed by the user when calling the plugin factory.
989
+ */
990
+ options?: TFactory['options'];
991
+ /**
992
+ * Lifecycle event handlers for this plugin.
846
993
  * Any event from the global `KubbHooks` map can be subscribed to here.
847
- * Handlers are registered after all plugin handlers, so they always fire last.
848
994
  */
849
- hooks: { [K in keyof KubbHooks]?: (...args: KubbHooks[K]) => void | Promise<void> };
995
+ hooks: { [K in keyof KubbHooks as K extends 'kubb:plugin:setup' ? never : K]?: (...args: KubbHooks[K]) => void | Promise<void> } & {
996
+ 'kubb:plugin:setup'?(ctx: KubbPluginSetupContext<TFactory>): void | Promise<void>;
997
+ };
850
998
  };
851
999
  /**
852
- * Creates a middleware factory using the hook-style `hooks` API.
1000
+ * Normalized plugin after setup, with runtime fields populated.
1001
+ * For internal use only — plugins use the public `Plugin` type externally.
853
1002
  *
854
- * Middleware handlers fire after all plugin handlers for any given event, making them ideal for post-processing, logging, and auditing.
855
- * Per-build state (such as accumulators) belongs inside the factory closure so each `createKubb` invocation gets its own isolated instance.
1003
+ * @internal
1004
+ */
1005
+ type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & {
1006
+ options: TOptions['resolvedOptions'] & {
1007
+ output: Output;
1008
+ include?: Array<Include>;
1009
+ exclude: Array<Exclude>;
1010
+ override: Array<Override<TOptions['resolvedOptions']>>;
1011
+ };
1012
+ resolver: TOptions['resolver'];
1013
+ transformer?: Visitor;
1014
+ renderer?: RendererFactory;
1015
+ generators?: Array<Generator>;
1016
+ apply?: (config: Config) => boolean;
1017
+ version?: string;
1018
+ };
1019
+ type KubbPluginStartContext = {
1020
+ plugin: NormalizedPlugin;
1021
+ };
1022
+ type KubbPluginEndContext = {
1023
+ plugin: NormalizedPlugin;
1024
+ duration: number;
1025
+ success: boolean;
1026
+ error?: Error;
1027
+ config: Config;
1028
+ /**
1029
+ * Returns all files currently in the file manager (lazy snapshot).
1030
+ * Includes files added by plugins that have already run.
1031
+ */
1032
+ readonly files: ReadonlyArray<FileNode>;
1033
+ /**
1034
+ * Upsert one or more files into the file manager.
1035
+ */
1036
+ upsertFile: (...files: Array<FileNode>) => void;
1037
+ };
1038
+ /**
1039
+ * Wraps a factory function and returns a typed `Plugin` with lifecycle handlers grouped under `hooks`.
856
1040
  *
857
- * @note The factory can accept typed options. See examples for using options and per-build state patterns.
1041
+ * Handlers live in a single `hooks` object (inspired by Astro integrations).
1042
+ * All lifecycle events from `KubbHooks` are available for subscription.
1043
+ *
1044
+ * @note For real plugins, use a `PluginFactoryOptions` type parameter to get type-safe context in `kubb:plugin:setup`.
1045
+ * Plugin names should follow the convention `plugin-<feature>` (e.g., `plugin-react-query`, `plugin-zod`).
858
1046
  *
859
1047
  * @example
860
1048
  * ```ts
861
- * import { defineMiddleware } from '@kubb/core'
1049
+ * import { definePlugin } from '@kubb/core'
862
1050
  *
863
- * // Stateless middleware
864
- * export const logMiddleware = defineMiddleware(() => ({
865
- * name: 'log-middleware',
1051
+ * export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
1052
+ * name: 'plugin-ts',
866
1053
  * hooks: {
867
- * 'kubb:build:end'({ files }) {
868
- * console.log(`Build complete with ${files.length} files`)
1054
+ * 'kubb:plugin:setup'(ctx) {
1055
+ * ctx.setResolver(resolverTs)
869
1056
  * },
870
1057
  * },
871
1058
  * }))
1059
+ * ```
1060
+ */
1061
+ declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
1062
+ //#endregion
1063
+ //#region src/FileManager.d.ts
1064
+ /**
1065
+ * In-memory file store for generated files.
872
1066
  *
873
- * // Middleware with options and per-build state
874
- * export const prefixMiddleware = defineMiddleware((options: { prefix: string } = { prefix: '' }) => {
875
- * const seen = new Set<string>()
876
- * return {
877
- * name: 'prefix-middleware',
878
- * hooks: {
879
- * 'kubb:plugin:end'({ plugin }) {
880
- * seen.add(`${options.prefix}${plugin.name}`)
881
- * },
882
- * },
883
- * }
884
- * })
1067
+ * Files with the same `path` are merged — sources, imports, and exports are concatenated.
1068
+ * The `files` getter returns all stored files sorted by path length (shortest first).
1069
+ *
1070
+ * @example
1071
+ * ```ts
1072
+ * import { FileManager } from '@kubb/core'
1073
+ *
1074
+ * const manager = new FileManager()
1075
+ * manager.upsert(myFile)
1076
+ * console.log(manager.files) // all stored files
885
1077
  * ```
886
1078
  */
887
- declare function defineMiddleware<TOptions extends object = object>(factory: (options: TOptions) => Middleware): (options?: TOptions) => Middleware;
1079
+ declare class FileManager {
1080
+ #private;
1081
+ /**
1082
+ * Adds one or more files. Incoming files with the same path are merged
1083
+ * (sources/imports/exports concatenated), but existing cache entries are
1084
+ * replaced — use {@link upsert} when you want to merge into the cache too.
1085
+ */
1086
+ add(...files: Array<FileNode>): Array<FileNode>;
1087
+ /**
1088
+ * Adds or merges one or more files.
1089
+ * If a file with the same path already exists in the cache, its
1090
+ * sources/imports/exports are merged into the incoming file.
1091
+ */
1092
+ upsert(...files: Array<FileNode>): Array<FileNode>;
1093
+ getByPath(path: string): FileNode | null;
1094
+ deleteByPath(path: string): void;
1095
+ clear(): void;
1096
+ /**
1097
+ * All stored files, sorted by path length (shorter paths first).
1098
+ */
1099
+ get files(): Array<FileNode>;
1100
+ }
888
1101
  //#endregion
889
- //#region src/defineParser.d.ts
890
- type PrintOptions = {
891
- extname?: FileNode['extname'];
1102
+ //#region src/PluginDriver.d.ts
1103
+ type Options = {
1104
+ hooks: AsyncEventEmitter<KubbHooks>;
892
1105
  };
893
- type Parser<TMeta extends object = any> = {
894
- name: string;
1106
+ declare class PluginDriver {
1107
+ #private;
1108
+ readonly config: Config;
1109
+ readonly options: Options;
1110
+ /**
1111
+ * Returns `'single'` when `fileOrFolder` has a file extension, `'split'` otherwise.
1112
+ *
1113
+ * @example
1114
+ * ```ts
1115
+ * PluginDriver.getMode('src/gen/types.ts') // 'single'
1116
+ * PluginDriver.getMode('src/gen/types') // 'split'
1117
+ * ```
1118
+ */
1119
+ static getMode(fileOrFolder: string | undefined | null): 'single' | 'split';
1120
+ /**
1121
+ * The universal `@kubb/ast` `InputNode` produced by the adapter, set by
1122
+ * the build pipeline after the adapter's `parse()` resolves.
1123
+ */
1124
+ inputNode: InputNode | undefined;
1125
+ adapter: Adapter | undefined;
1126
+ /**
1127
+ * Central file store for all generated files.
1128
+ * Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
1129
+ * add files; this property gives direct read/write access when needed.
1130
+ */
1131
+ readonly fileManager: FileManager;
1132
+ readonly plugins: Map<string, NormalizedPlugin>;
1133
+ constructor(config: Config, options: Options);
1134
+ get hooks(): AsyncEventEmitter<KubbHooks>;
1135
+ /**
1136
+ * Registers a hook-style plugin's lifecycle handlers on the shared `AsyncEventEmitter`.
1137
+ *
1138
+ * For `kubb:plugin:setup`, the registered listener wraps the globally emitted context with a
1139
+ * plugin-specific one so that `addGenerator`, `setResolver`, `setTransformer`, and
1140
+ * `setRenderer` all target the correct `normalizedPlugin` entry in the plugins map.
1141
+ *
1142
+ * All other hooks are iterated and registered directly as pass-through listeners.
1143
+ * Any event key present in the global `KubbHooks` interface can be subscribed to.
1144
+ *
1145
+ * External tooling can subscribe to any of these events via `hooks.on(...)` to observe
1146
+ * the plugin lifecycle without modifying plugin behavior.
1147
+ *
1148
+ * @internal
1149
+ */
1150
+ registerPluginHooks(hookPlugin: Plugin, normalizedPlugin: NormalizedPlugin): void;
1151
+ /**
1152
+ * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
1153
+ * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
1154
+ *
1155
+ * Call this once from `safeBuild` before the plugin execution loop begins.
1156
+ */
1157
+ emitSetupHooks(): Promise<void>;
1158
+ /**
1159
+ * Registers a generator for the given plugin on the shared event emitter.
1160
+ *
1161
+ * The generator's `schema`, `operation`, and `operations` methods are registered as
1162
+ * listeners on `kubb:generate:schema`, `kubb:generate:operation`, and `kubb:generate:operations`
1163
+ * respectively. Each listener is scoped to the owning plugin via a `ctx.plugin.name` check
1164
+ * so that generators from different plugins do not cross-fire.
1165
+ *
1166
+ * The renderer resolution chain is: `generator.renderer → plugin.renderer → config.renderer`.
1167
+ * Set `generator.renderer = null` to explicitly opt out of rendering even when the plugin
1168
+ * declares a renderer.
1169
+ *
1170
+ * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
1171
+ */
1172
+ registerGenerator(pluginName: string, gen: Generator): void;
1173
+ /**
1174
+ * Returns `true` when at least one generator was registered for the given plugin
1175
+ * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
1176
+ *
1177
+ * Used by the build loop to decide whether to walk the AST and emit generator events
1178
+ * for a plugin that has no static `plugin.generators`.
1179
+ */
1180
+ hasRegisteredGenerators(pluginName: string): boolean;
1181
+ /**
1182
+ * Unregisters all plugin lifecycle listeners from the shared event emitter.
1183
+ * Called at the end of a build to prevent listener leaks across repeated builds.
1184
+ *
1185
+ * @internal
1186
+ */
1187
+ dispose(): void;
1188
+ /**
1189
+ * Merges `partial` with the plugin's default resolver and stores the result.
1190
+ * Also mirrors it onto `plugin.resolver` so callers using `getPlugin(name).resolver`
1191
+ * get the up-to-date resolver without going through `getResolver()`.
1192
+ */
1193
+ setPluginResolver(pluginName: string, partial: Partial<Resolver>): void;
895
1194
  /**
896
- * File extensions this parser handles.
897
- * Use `undefined` to create a catch-all fallback parser.
1195
+ * Returns the resolver for the given plugin.
898
1196
  *
899
- * @example Handled extensions
900
- * `['.ts', '.js']`
1197
+ * Resolution order: dynamic resolver set via `setPluginResolver` → static resolver on the
1198
+ * plugin → lazily created default resolver (identity name, no path transforms).
901
1199
  */
902
- extNames: Array<FileNode['extname']> | undefined;
1200
+ getResolver<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Kubb.PluginRegistry[TName]['resolver'];
1201
+ getResolver<TResolver extends Resolver = Resolver>(pluginName: string): TResolver;
1202
+ getContext<TOptions extends PluginFactoryOptions>(plugin: NormalizedPlugin<TOptions>): GeneratorContext<TOptions> & Record<string, unknown>;
1203
+ getPlugin<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
1204
+ getPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(pluginName: string): Plugin<TOptions> | undefined;
903
1205
  /**
904
- * Convert a resolved file to a string.
1206
+ * Like `getPlugin` but throws a descriptive error when the plugin is not found.
905
1207
  */
906
- parse(file: FileNode<TMeta>, options?: PrintOptions): Promise<string> | string;
907
- };
908
- /**
909
- * Defines a parser with type safety. Creates parsers that transform generated files to strings based on their extension.
910
- *
911
- * @note Call the returned factory with optional options to instantiate the parser.
912
- *
913
- * @example
914
- * ```ts
915
- * import { defineParser } from '@kubb/core'
916
- *
917
- * export const jsonParser = defineParser({
918
- * name: 'json',
919
- * extNames: ['.json'],
920
- * parse(file) {
921
- * const { extractStringsFromNodes } = await import('@kubb/ast')
922
- * return file.sources.map((s) => extractStringsFromNodes(s.nodes ?? [])).join('\n')
923
- * },
924
- * })
925
- * ```
926
- */
927
- declare function defineParser<TMeta extends object = any>(parser: Parser<TMeta>): Parser<TMeta>;
1208
+ requirePlugin<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Plugin<Kubb.PluginRegistry[TName]>;
1209
+ requirePlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(pluginName: string): Plugin<TOptions>;
1210
+ }
928
1211
  //#endregion
929
- //#region src/types.d.ts
930
- /**
931
- * Safely extracts a type from a registry, returning `{}` if the key doesn't exist.
932
- * Enables optional interface augmentation for `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
933
- * without requiring changes to core.
934
- *
935
- * @internal
936
- */
937
- type ExtractRegistryKey<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
1212
+ //#region src/defineGenerator.d.ts
938
1213
  /**
939
- * Reference to an input file to generate code from.
1214
+ * Context object passed to generator `schema`, `operation`, and `operations` methods.
940
1215
  *
941
- * Specify an absolute path or a path relative to the config file location.
942
- * The adapter will parse this file (e.g., OpenAPI YAML or JSON) into the universal AST.
1216
+ * The adapter is always defined (guaranteed by `runPluginAstHooks`) so no runtime checks
1217
+ * are needed. `ctx.options` carries resolved per-node options after exclude/include/override
1218
+ * filtering for individual schema/operation calls, or plugin-level options for operations.
943
1219
  */
944
- type InputPath = {
1220
+ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
1221
+ config: Config;
945
1222
  /**
946
- * Path to your Swagger/OpenAPI file, absolute or relative to the config file location.
947
- *
948
- * @example
949
- * ```ts
950
- * { path: './petstore.yaml' }
951
- * { path: '/absolute/path/to/openapi.json' }
952
- * ```
1223
+ * Absolute path to the current plugin's output directory.
953
1224
  */
954
- path: string;
955
- };
956
- /**
957
- * Inline input data to generate code from.
958
- *
959
- * Useful when you want to pass the specification directly instead of from a file.
960
- * Can be a string (YAML/JSON) or a parsed object.
961
- */
962
- type InputData = {
1225
+ root: string;
963
1226
  /**
964
- * Swagger/OpenAPI data as a string (YAML/JSON) or a parsed object.
965
- *
966
- * @example
967
- * ```ts
968
- * { data: fs.readFileSync('./openapi.yaml', 'utf8') }
969
- * { data: { openapi: '3.1.0', info: { ... } } }
970
- * ```
1227
+ * Determine output mode based on the output config.
1228
+ * Returns `'single'` when `output.path` is a file, `'split'` for a directory.
971
1229
  */
972
- data: string | unknown;
973
- };
974
- type Input = InputPath | InputData;
975
- /**
976
- * Source data passed to an adapter's `parse` function.
977
- * Mirrors the config input shape with paths resolved to absolute.
978
- */
979
- type AdapterSource = {
980
- type: 'path';
981
- path: string;
982
- } | {
983
- type: 'data';
984
- data: string | unknown;
985
- } | {
986
- type: 'paths';
987
- paths: Array<string>;
988
- };
989
- /**
990
- * Generic type parameters for an adapter definition.
991
- *
992
- * - `TName` — unique identifier (e.g. `'oas'`, `'asyncapi'`)
993
- * - `TOptions` — user-facing options passed to the adapter factory
994
- * - `TResolvedOptions` — options after defaults applied
995
- * - `TDocument` — type of the parsed source document
996
- */
997
- type AdapterFactoryOptions<TName extends string = string, TOptions extends object = object, TResolvedOptions extends object = TOptions, TDocument = unknown> = {
998
- name: TName;
999
- options: TOptions;
1000
- resolvedOptions: TResolvedOptions;
1001
- document: TDocument;
1002
- };
1003
- /**
1004
- * Adapter that converts input files or data into an `InputNode`.
1005
- *
1006
- * Adapters parse different schema formats (OpenAPI, AsyncAPI, Drizzle, etc.) into Kubb's
1007
- * universal intermediate representation that all plugins consume.
1008
- *
1009
- * @example
1010
- * ```ts
1011
- * import { adapterOas } from '@kubb/adapter-oas'
1012
- *
1013
- * export default defineConfig({
1014
- * adapter: adapterOas(),
1015
- * input: { path: './openapi.yaml' },
1016
- * plugins: [pluginTs(), pluginZod()],
1017
- * })
1018
- * ```
1019
- */
1020
- type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
1230
+ getMode: (output: {
1231
+ path: string;
1232
+ }) => 'single' | 'split';
1233
+ driver: PluginDriver;
1021
1234
  /**
1022
- * Human-readable adapter identifier (e.g. `'oas'`, `'asyncapi'`).
1235
+ * Get a plugin by name, typed via `Kubb.PluginRegistry` when registered.
1023
1236
  */
1024
- name: TOptions['name'];
1237
+ getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
1238
+ getPlugin(name: string): Plugin | undefined;
1025
1239
  /**
1026
- * Resolved adapter options after defaults have been applied.
1240
+ * Get a plugin by name, throws an error if not found.
1027
1241
  */
1028
- options: TOptions['resolvedOptions'];
1242
+ requirePlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]>;
1243
+ requirePlugin(name: string): Plugin;
1029
1244
  /**
1030
- * Parsed source document after the first `parse()` call. `null` before parsing.
1245
+ * Get a resolver by plugin name, typed via `Kubb.PluginRegistry` when registered.
1031
1246
  */
1032
- document: TOptions['document'] | null;
1033
- inputNode: InputNode | null;
1247
+ getResolver<TName extends keyof Kubb.PluginRegistry>(name: TName): Kubb.PluginRegistry[TName]['resolver'];
1248
+ getResolver(name: string): Resolver;
1034
1249
  /**
1035
- * Parse the source into a universal `InputNode`.
1250
+ * Add files only if they don't exist.
1036
1251
  */
1037
- parse: (source: AdapterSource) => PossiblePromise<InputNode>;
1252
+ addFile: (...file: Array<FileNode>) => Promise<void>;
1038
1253
  /**
1039
- * Extract `ImportNode` entries for a schema tree.
1040
- * Returns an empty array before the first `parse()` call.
1041
- *
1042
- * The `resolve` callback receives the collision-corrected schema name and must
1043
- * return `{ name, path }` for the import, or `undefined` to skip it.
1254
+ * Merge sources into the same output file.
1044
1255
  */
1045
- getImports: (node: SchemaNode, resolve: (schemaName: string) => {
1046
- name: string;
1047
- path: string;
1048
- }) => Array<ImportNode>;
1256
+ upsertFile: (...file: Array<FileNode>) => Promise<void>;
1257
+ hooks: AsyncEventEmitter<KubbHooks>;
1049
1258
  /**
1050
- * Validate the document at the given path or URL.
1259
+ * The current plugin instance.
1051
1260
  */
1052
- validate: (input: string, options?: {
1053
- throwOnError?: boolean;
1054
- }) => Promise<void>;
1055
- };
1056
- type DevtoolsOptions = {
1261
+ plugin: Plugin<TOptions>;
1057
1262
  /**
1058
- * Open the AST inspector in Kubb Studio (`/ast`). Defaults to the main Studio page.
1059
- * @default false
1263
+ * The current plugin's resolver.
1060
1264
  */
1061
- ast?: boolean;
1265
+ resolver: TOptions['resolver'];
1266
+ /**
1267
+ * The current plugin's transformer.
1268
+ */
1269
+ transformer: Visitor | undefined;
1270
+ /**
1271
+ * Emit a warning.
1272
+ */
1273
+ warn: (message: string) => void;
1274
+ /**
1275
+ * Emit an error.
1276
+ */
1277
+ error: (error: string | Error) => void;
1278
+ /**
1279
+ * Emit an info message.
1280
+ */
1281
+ info: (message: string) => void;
1282
+ /**
1283
+ * Open the current input node in Kubb Studio.
1284
+ */
1285
+ openInStudio: (options?: DevtoolsOptions) => Promise<void>;
1286
+ /**
1287
+ * The configured adapter instance.
1288
+ */
1289
+ adapter: Adapter;
1290
+ /**
1291
+ * The universal `InputNode` produced by the adapter.
1292
+ */
1293
+ inputNode: InputNode;
1294
+ /**
1295
+ * Resolved options after exclude/include/override filtering.
1296
+ */
1297
+ options: TOptions['resolvedOptions'];
1062
1298
  };
1063
1299
  /**
1064
- * Build configuration for Kubb code generation.
1300
+ * Declares a named generator unit that walks the AST and emits files.
1065
1301
  *
1066
- * The Config is the main entry point for customizing how Kubb generates code. It specifies:
1067
- * - What to generate from (adapter + input)
1068
- * - Where to output generated code (output)
1069
- * - How to generate (plugins + middleware)
1070
- * - Runtime details (parsers, storage, renderer)
1302
+ * Each method (`schema`, `operation`, `operations`) is called for the matching node type.
1303
+ * Each method returns `TElement | Array<FileNode> | void`. JSX-based generators require a `renderer` factory.
1304
+ * Return `Array<FileNode>` directly or call `ctx.upsertFile()` manually and return `void` to bypass rendering.
1071
1305
  *
1072
- * See `UserConfig` for a relaxed version with sensible defaults.
1306
+ * @note Generators are consumed by plugins and registered via `ctx.addGenerator()` in `kubb:plugin:setup`.
1073
1307
  *
1074
- * @private
1075
- */
1076
- type Config<TInput = Input> = {
1077
- /**
1078
- * Display name for this configuration in CLI output and logs.
1079
- * Useful when running multiple builds with `defineConfig` arrays.
1080
- *
1081
- * @example
1082
- * ```ts
1083
- * name: 'api-client'
1084
- * ```
1085
- */
1086
- name?: string;
1308
+ * @example
1309
+ * ```ts
1310
+ * import { defineGenerator } from '@kubb/core'
1311
+ * import { jsxRenderer } from '@kubb/renderer-jsx'
1312
+ *
1313
+ * export const typeGenerator = defineGenerator({
1314
+ * name: 'typescript',
1315
+ * renderer: jsxRenderer,
1316
+ * schema(node, ctx) {
1317
+ * const { adapter, resolver, root, options } = ctx
1318
+ * return <File ...><Type node={node} resolver={resolver} /></File>
1319
+ * },
1320
+ * })
1321
+ * ```
1322
+ */
1323
+ type Generator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown> = {
1087
1324
  /**
1088
- * Project root directory, absolute or relative to the config file.
1089
- * @default process.cwd()
1325
+ * Used in diagnostic messages and debug output.
1090
1326
  */
1091
- root: string;
1327
+ name: string;
1092
1328
  /**
1093
- * Parsers that convert generated files to strings.
1094
- * Each parser handles specific extensions (e.g. `.ts`, `.tsx`).
1095
- * A fallback parser is appended for unhandled extensions.
1096
- * When omitted, defaults to `parserTs` from `@kubb/parser-ts`.
1329
+ * Optional renderer factory that produces a {@link Renderer} for each render cycle.
1097
1330
  *
1098
- * @default [parserTs] from `@kubb/parser-ts`
1099
- * @example
1100
- * ```ts
1101
- * import { parserTs, tsxParser } from '@kubb/parser-ts'
1102
- * export default defineConfig({
1103
- * parsers: [parserTs, tsxParser],
1104
- * })
1105
- * ```
1106
- */
1107
- parsers: Array<Parser>;
1108
- /**
1109
- * Adapter that parses input files into the universal `InputNode` representation.
1110
- * Use `@kubb/adapter-oas` for OpenAPI/Swagger or `@kubb/adapter-asyncapi` for other formats.
1331
+ * Generators that return renderer elements (e.g. JSX via `@kubb/renderer-jsx`) must set this
1332
+ * to the matching renderer factory (e.g. `jsxRenderer` from `@kubb/renderer-jsx`).
1111
1333
  *
1112
- * When omitted, Kubb runs in plugin-only mode: `kubb:plugin:setup` fires and files
1113
- * injected via `injectFile` are written, but no AST walk occurs and generator hooks
1114
- * (`kubb:generate:schema`, `kubb:generate:operation`) are never emitted.
1334
+ * Generators that only return `Array<FileNode>` or `void` do not need to set this.
1335
+ *
1336
+ * Set `renderer: null` to explicitly opt out of rendering even when the parent plugin
1337
+ * declares a `renderer` (overrides the plugin-level fallback).
1115
1338
  *
1116
1339
  * @example
1117
1340
  * ```ts
1118
- * import { adapterOas } from '@kubb/adapter-oas'
1119
- * export default defineConfig({
1120
- * adapter: adapterOas(),
1121
- * input: { path: './petstore.yaml' },
1341
+ * import { jsxRenderer } from '@kubb/renderer-jsx'
1342
+ * export const myGenerator = defineGenerator<PluginTs>({
1343
+ * renderer: jsxRenderer,
1344
+ * schema(node, ctx) { return <File ...>...</File> },
1122
1345
  * })
1123
1346
  * ```
1124
1347
  */
1125
- adapter?: Adapter;
1348
+ renderer?: RendererFactory<TElement> | null;
1126
1349
  /**
1127
- * Source file or data to generate code from.
1128
- * Use `input.path` for a file path or `input.data` for inline data.
1129
- * Required when an adapter is configured; omit when running in plugin-only mode.
1350
+ * Called for each schema node in the AST walk.
1351
+ * `ctx` carries the plugin context with `adapter` and `inputNode` guaranteed present,
1352
+ * plus `ctx.options` with the per-node resolved options (after exclude/include/override).
1130
1353
  */
1131
- input?: TInput;
1132
- output: {
1133
- /**
1134
- * Output directory for generated files, absolute or relative to `root`.
1135
- *
1136
- * All generated files will be written under this directory. Subdirectories can be created
1137
- * by plugins based on grouping strategy (by tag, path, etc.).
1138
- *
1139
- * @example
1140
- * ```ts
1141
- * output: {
1142
- * path: './src/gen', // generates ./src/gen/api.ts, ./src/gen/types.ts, etc.
1143
- * }
1144
- * ```
1145
- */
1146
- path: string;
1147
- /**
1148
- * Remove all files from the output directory before starting the build.
1149
- *
1150
- * Useful to ensure old generated files aren't mixed with new ones.
1151
- * Set to `true` for fresh builds, `false` to preserve manual edits in output dir.
1152
- *
1153
- * @default false
1154
- * @example
1155
- * ```ts
1156
- * clean: true // wipes ./src/gen/* before generating
1157
- * ```
1158
- */
1159
- clean?: boolean;
1160
- /**
1161
- * Persists generated files to the file system.
1162
- *
1163
- * @default true
1164
- * @deprecated Use `storage` option to control where files are written instead.
1165
- */
1166
- write?: boolean;
1167
- /**
1168
- * Auto-format generated files after code generation completes.
1169
- *
1170
- * Applies a code formatter to all generated files. Use `'auto'` to detect which formatter
1171
- * is available on your system. Pass `false` to skip formatting (useful for CI or specific workflows).
1172
- *
1173
- * @default false
1174
- * @example
1175
- * ```ts
1176
- * format: 'auto' // auto-detect prettier, biome, or oxfmt
1177
- * format: 'prettier' // force prettier
1178
- * format: false // skip formatting
1179
- * ```
1180
- */
1181
- format?: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false;
1182
- /**
1183
- * Auto-lint generated files after code generation completes.
1184
- *
1185
- * Analyzes all generated files for style/correctness issues. Use `'auto'` to detect which linter
1186
- * is available on your system. Pass `false` to skip linting.
1187
- *
1188
- * @default false
1189
- * @example
1190
- * ```ts
1191
- * lint: 'auto' // auto-detect oxlint, biome, or eslint
1192
- * lint: 'eslint' // force eslint
1193
- * lint: false // skip linting
1194
- * ```
1195
- */
1196
- lint?: 'auto' | 'eslint' | 'biome' | 'oxlint' | false;
1197
- /**
1198
- * Map file extensions to different output extensions.
1199
- *
1200
- * Useful when you want generated `.ts` imports to reference `.js` files or vice versa (e.g., for ESM dual packages).
1201
- * Keys are the original extension, values are the output extension. Use empty string `''` to omit extension.
1202
- *
1203
- * @default { '.ts': '.ts' }
1204
- * @example
1205
- * ```ts
1206
- * extension: { '.ts': '.js' } // generates import './api.js' instead of './api.ts'
1207
- * extension: { '.ts': '', '.tsx': '.jsx' }
1208
- * ```
1209
- */
1210
- extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
1211
- /**
1212
- * Banner text prepended to every generated file.
1213
- *
1214
- * Useful for auto-generation notices or license headers. Choose a preset or write custom text.
1215
- * Use `'simple'` for a basic Kubb banner, `'full'` for detailed metadata, or `false` to omit.
1216
- *
1217
- * @default 'simple'
1218
- * @example
1219
- * ```ts
1220
- * defaultBanner: 'simple' // "This file was autogenerated by Kubb"
1221
- * defaultBanner: 'full' // adds source, title, description, API version
1222
- * defaultBanner: false // no banner
1223
- * ```
1224
- */
1225
- defaultBanner?: 'simple' | 'full' | false;
1226
- /**
1227
- * When `true`, overwrites existing files. When `false`, skips generated files that already exist.
1228
- *
1229
- * Individual plugins can override this setting. This is useful for preventing accidental data loss
1230
- * when re-generating while you have local edits in the output folder.
1231
- *
1232
- * @default false
1233
- * @example
1234
- * ```ts
1235
- * override: true // regenerate everything, even existing files
1236
- * override: false // skip files that already exist
1237
- * ```
1238
- */
1239
- override?: boolean;
1240
- } & ExtractRegistryKey<Kubb.ConfigOptionsRegistry, 'output'>;
1354
+ schema?: (node: SchemaNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
1241
1355
  /**
1242
- * Storage backend that controls where and how generated files are persisted.
1243
- *
1244
- * Defaults to `fsStorage()` which writes to the file system. Pass `memoryStorage()` to keep files in RAM,
1245
- * or implement a custom `Storage` interface to write to cloud storage, databases, or other backends.
1356
+ * Called for each operation node in the AST walk.
1357
+ * `ctx` carries the plugin context with `adapter` and `inputNode` guaranteed present,
1358
+ * plus `ctx.options` with the per-node resolved options (after exclude/include/override).
1359
+ */
1360
+ operation?: (node: OperationNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
1361
+ /**
1362
+ * Called once after all operations have been walked.
1363
+ * `ctx` carries the plugin context with `adapter` and `inputNode` guaranteed present,
1364
+ * plus `ctx.options` with the plugin-level options for the batch call.
1365
+ */
1366
+ operations?: (nodes: Array<OperationNode>, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
1367
+ };
1368
+ /**
1369
+ * Defines a generator. Returns the object as-is with correct `this` typings.
1370
+ * `applyHookResult` handles renderer elements and `File[]` uniformly using
1371
+ * the generator's declared `renderer` factory.
1372
+ */
1373
+ declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown>(generator: Generator<TOptions, TElement>): Generator<TOptions, TElement>;
1374
+ //#endregion
1375
+ //#region src/createKubb.d.ts
1376
+ /**
1377
+ * Safely extracts a type from a registry, returning `{}` if the key doesn't exist.
1378
+ * Enables optional interface augmentation for `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
1379
+ * without requiring changes to core.
1380
+ *
1381
+ * @internal
1382
+ */
1383
+ type ExtractRegistryKey<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
1384
+ /**
1385
+ * Reference to an input file to generate code from.
1386
+ *
1387
+ * Specify an absolute path or a path relative to the config file location.
1388
+ * The adapter will parse this file (e.g., OpenAPI YAML or JSON) into the universal AST.
1389
+ */
1390
+ type InputPath = {
1391
+ /**
1392
+ * Path to your Swagger/OpenAPI file, absolute or relative to the config file location.
1246
1393
  *
1247
- * @default fsStorage()
1248
1394
  * @example
1249
1395
  * ```ts
1250
- * import { memoryStorage } from '@kubb/core'
1251
- *
1252
- * // Keep generated files in memory (useful for testing, CI pipelines)
1253
- * storage: memoryStorage()
1254
- *
1255
- * // Use custom S3 storage
1256
- * storage: myS3Storage()
1396
+ * { path: './petstore.yaml' }
1397
+ * { path: '/absolute/path/to/openapi.json' }
1257
1398
  * ```
1258
- *
1259
- * @see {@link Storage} interface for implementing custom backends.
1260
1399
  */
1261
- storage?: Storage;
1400
+ path: string;
1401
+ };
1402
+ /**
1403
+ * Inline input data to generate code from.
1404
+ *
1405
+ * Useful when you want to pass the specification directly instead of from a file.
1406
+ * Can be a string (YAML/JSON) or a parsed object.
1407
+ */
1408
+ type InputData = {
1262
1409
  /**
1263
- * Plugins that execute during the build to generate code and transform the AST.
1264
- *
1265
- * Each plugin processes the AST produced by the adapter and can emit files for different
1266
- * programming languages or formats (TypeScript, Zod schemas, Faker data, etc.).
1267
- * Dependencies are enforced — an error is thrown if a plugin requires another plugin that isn't registered.
1268
- *
1269
- * Plugins can declare their own options via `PluginFactoryOptions`. See plugin documentation for details.
1410
+ * Swagger/OpenAPI data as a string (YAML/JSON) or a parsed object.
1270
1411
  *
1271
1412
  * @example
1272
1413
  * ```ts
1273
- * import { pluginTs } from '@kubb/plugin-ts'
1274
- * import { pluginZod } from '@kubb/plugin-zod'
1275
- *
1276
- * plugins: [
1277
- * pluginTs({ output: { path: './src/gen' } }),
1278
- * pluginZod({ output: { path: './src/gen' } }),
1279
- * ]
1414
+ * { data: fs.readFileSync('./openapi.yaml', 'utf8') }
1415
+ * { data: { openapi: '3.1.0', info: { ... } } }
1280
1416
  * ```
1281
1417
  */
1282
- plugins: Array<Plugin>;
1418
+ data: string | unknown;
1419
+ };
1420
+ type Input = InputPath | InputData;
1421
+ /**
1422
+ * Build configuration for Kubb code generation.
1423
+ *
1424
+ * The Config is the main entry point for customizing how Kubb generates code. It specifies:
1425
+ * - What to generate from (adapter + input)
1426
+ * - Where to output generated code (output)
1427
+ * - How to generate (plugins + middleware)
1428
+ * - Runtime details (parsers, storage, renderer)
1429
+ *
1430
+ * See `UserConfig` for a relaxed version with sensible defaults.
1431
+ *
1432
+ * @private
1433
+ */
1434
+ type Config<TInput = Input> = {
1283
1435
  /**
1284
- * Middleware instances that observe build events and post-process generated code.
1285
- *
1286
- * Middleware fires AFTER all plugins for each event. Perfect for tasks like:
1287
- * - Auditing what was generated
1288
- * - Adding barrel/index files
1289
- * - Validating output
1290
- * - Running custom transformations
1436
+ * Display name for this configuration in CLI output and logs.
1437
+ * Useful when running multiple builds with `defineConfig` arrays.
1291
1438
  *
1292
1439
  * @example
1293
1440
  * ```ts
1294
- * import { middlewareBarrel } from '@kubb/middleware-barrel'
1295
- *
1296
- * middleware: [middlewareBarrel()]
1441
+ * name: 'api-client'
1297
1442
  * ```
1298
- *
1299
- * @see {@link defineMiddleware} to create custom middleware.
1300
1443
  */
1301
- middleware?: Array<Middleware>;
1444
+ name?: string;
1445
+ /**
1446
+ * Project root directory, absolute or relative to the config file.
1447
+ * @default process.cwd()
1448
+ */
1449
+ root: string;
1302
1450
  /**
1303
- * Default renderer factory used by all plugins and generators.
1304
- * Resolution chain: `generator.renderer` `plugin.renderer` → `config.renderer` `undefined` (raw FileNode[] mode).
1451
+ * Parsers that convert generated files to strings.
1452
+ * Each parser handles specific extensions (e.g. `.ts`, `.tsx`).
1453
+ * A fallback parser is appended for unhandled extensions.
1454
+ * When omitted, defaults to `parserTs` from `@kubb/parser-ts`.
1305
1455
  *
1456
+ * @default [parserTs] from `@kubb/parser-ts`
1306
1457
  * @example
1307
1458
  * ```ts
1308
- * import { jsxRenderer } from '@kubb/renderer-jsx'
1459
+ * import { parserTs, tsxParser } from '@kubb/parser-ts'
1309
1460
  * export default defineConfig({
1310
- * renderer: jsxRenderer,
1311
- * plugins: [pluginTs(), pluginZod()],
1461
+ * parsers: [parserTs, tsxParser],
1312
1462
  * })
1313
1463
  * ```
1314
1464
  */
1465
+ parsers: Array<Parser>;
1315
1466
  /**
1316
- * Renderer that converts generated AST nodes to code strings.
1467
+ * Adapter that parses input files into the universal `InputNode` representation.
1468
+ * Use `@kubb/adapter-oas` for OpenAPI/Swagger or `@kubb/adapter-asyncapi` for other formats.
1317
1469
  *
1318
- * By default, Kubb uses the JSX renderer (`rendererJsx`). Pass a custom renderer to support
1319
- * different output formats (template engines, code generation DSLs, etc.).
1470
+ * When omitted, Kubb runs in plugin-only mode: `kubb:plugin:setup` fires and files
1471
+ * injected via `injectFile` are written, but no AST walk occurs and generator hooks
1472
+ * (`kubb:generate:schema`, `kubb:generate:operation`) are never emitted.
1320
1473
  *
1321
- * @default rendererJsx() // from @kubb/renderer-jsx
1322
1474
  * @example
1323
1475
  * ```ts
1324
- * import { rendererJsx } from '@kubb/renderer-jsx'
1325
- * renderer: rendererJsx()
1476
+ * import { adapterOas } from '@kubb/adapter-oas'
1477
+ * export default defineConfig({
1478
+ * adapter: adapterOas(),
1479
+ * input: { path: './petstore.yaml' },
1480
+ * })
1326
1481
  * ```
1327
- *
1328
- * @see {@link Renderer} to implement a custom renderer.
1329
1482
  */
1330
- renderer?: RendererFactory;
1483
+ adapter?: Adapter;
1331
1484
  /**
1332
- * Kubb Studio cloud integration settings.
1333
- *
1334
- * Kubb Studio (https://kubb.studio) is a web-based IDE for managing API specs and generated code.
1335
- * Set to `true` to enable with default settings, or pass an object to customize the Studio URL.
1336
- *
1337
- * @default false // disabled by default
1338
- * @example
1339
- * ```ts
1340
- * devtools: true // use default Kubb Studio
1341
- * devtools: { studioUrl: 'https://my-studio.dev' } // custom Studio instance
1342
- * ```
1485
+ * Source file or data to generate code from.
1486
+ * Use `input.path` for a file path or `input.data` for inline data.
1487
+ * Required when an adapter is configured; omit when running in plugin-only mode.
1343
1488
  */
1344
- devtools?: true | {
1489
+ input?: TInput;
1490
+ output: {
1345
1491
  /**
1346
- * Override the Kubb Studio base URL.
1347
- * @default 'https://kubb.studio'
1492
+ * Output directory for generated files, absolute or relative to `root`.
1493
+ *
1494
+ * All generated files will be written under this directory. Subdirectories can be created
1495
+ * by plugins based on grouping strategy (by tag, path, etc.).
1496
+ *
1497
+ * @example
1498
+ * ```ts
1499
+ * output: {
1500
+ * path: './src/gen', // generates ./src/gen/api.ts, ./src/gen/types.ts, etc.
1501
+ * }
1502
+ * ```
1348
1503
  */
1349
- studioUrl?: typeof DEFAULT_STUDIO_URL | (string & {});
1350
- };
1351
- /**
1352
- * Lifecycle hooks that execute during or after the build process.
1353
- *
1354
- * Hooks allow you to run external tools (prettier, eslint, custom scripts) based on build events.
1355
- * Currently supports the `done` hook which fires after all plugins and middleware complete.
1356
- *
1357
- * @example
1358
- * ```ts
1359
- * hooks: {
1360
- * done: 'prettier --write "./src/gen"', // auto-format generated files
1361
- * // or multiple commands:
1362
- * done: ['prettier --write "./src/gen"', 'eslint --fix "./src/gen"']
1363
- * }
1364
- * ```
1365
- */
1366
- hooks?: {
1504
+ path: string;
1367
1505
  /**
1368
- * Command(s) to run after all plugins and middleware complete generation.
1506
+ * Remove all files from the output directory before starting the build.
1369
1507
  *
1370
- * Useful for post-processing: formatting, linting, copying files, or custom validation.
1371
- * Pass a single command string or array of command strings to run sequentially.
1372
- * Commands are executed relative to the `root` directory.
1508
+ * Useful to ensure old generated files aren't mixed with new ones.
1509
+ * Set to `true` for fresh builds, `false` to preserve manual edits in output dir.
1373
1510
  *
1511
+ * @default false
1374
1512
  * @example
1375
1513
  * ```ts
1376
- * done: 'prettier --write "./src/gen"'
1377
- * done: ['prettier --write "./src/gen"', 'eslint --fix "./src/gen"']
1514
+ * clean: true // wipes ./src/gen/* before generating
1378
1515
  * ```
1379
1516
  */
1380
- done?: string | Array<string>;
1381
- };
1382
- };
1383
- /**
1384
- * Type/string pattern filter for include/exclude/override matching.
1385
- */
1386
- type PatternFilter = {
1387
- type: string;
1388
- pattern: string | RegExp;
1389
- };
1390
- /**
1391
- * Pattern filter with partial option overrides applied when the pattern matches.
1392
- */
1393
- type PatternOverride<TOptions> = PatternFilter & {
1394
- options: Omit<Partial<TOptions>, 'override'>;
1395
- };
1396
- /**
1397
- * Context for resolving filtered options for a given operation or schema node.
1398
- *
1399
- * @internal
1400
- */
1401
- type ResolveOptionsContext<TOptions> = {
1402
- options: TOptions;
1403
- exclude?: Array<PatternFilter>;
1404
- include?: Array<PatternFilter>;
1405
- override?: Array<PatternOverride<TOptions>>;
1406
- };
1407
- /**
1408
- * Base constraint for all plugin resolver objects.
1409
- *
1410
- * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
1411
- * are injected automatically by `defineResolver` — extend this type to add custom resolution methods.
1412
- *
1413
- * @example
1414
- * ```ts
1415
- * type MyResolver = Resolver & {
1416
- * resolveName(node: SchemaNode): string
1417
- * resolveTypedName(node: SchemaNode): string
1418
- * }
1419
- * ```
1420
- */
1421
- type Resolver = {
1422
- name: string;
1423
- pluginName: Plugin['name'];
1424
- default(name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
1425
- resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null;
1426
- resolvePath(params: ResolverPathParams, context: ResolverContext): string;
1427
- resolveFile(params: ResolverFileParams, context: ResolverContext): FileNode;
1428
- resolveBanner(node: InputNode | null, context: ResolveBannerContext): string | undefined;
1429
- resolveFooter(node: InputNode | null, context: ResolveBannerContext): string | undefined;
1430
- };
1431
- type PluginFactoryOptions<
1432
- /**
1433
- * Unique plugin name.
1434
- */
1435
- TName extends string = string,
1436
- /**
1437
- * User-facing plugin options.
1438
- */
1439
- TOptions extends object = object,
1440
- /**
1441
- * Plugin options after defaults are applied.
1442
- */
1443
- TResolvedOptions extends object = TOptions,
1444
- /**
1445
- * Resolver that encapsulates naming and path-resolution helpers.
1446
- * Define with `defineResolver` and export alongside the plugin.
1447
- */
1448
- TResolver extends Resolver = Resolver> = {
1449
- name: TName;
1450
- options: TOptions;
1451
- resolvedOptions: TResolvedOptions;
1452
- resolver: TResolver;
1453
- };
1454
- /**
1455
- * Normalized plugin after setup, with runtime fields populated.
1456
- * For internal use only — plugins use the public `Plugin` type externally.
1457
- *
1458
- * @internal
1459
- */
1460
- type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & {
1461
- options: TOptions['resolvedOptions'] & {
1462
- output: Output;
1463
- include?: Array<Include>;
1464
- exclude: Array<Exclude$1>;
1465
- override: Array<Override<TOptions['resolvedOptions']>>;
1466
- };
1467
- resolver: TOptions['resolver'];
1468
- transformer?: Visitor;
1469
- renderer?: RendererFactory;
1470
- generators?: Array<Generator>;
1471
- apply?: (config: Config) => boolean;
1472
- version?: string;
1473
- };
1474
- /**
1475
- * Partial `Config` for user-facing entry points with sensible defaults.
1476
- *
1477
- * `UserConfig` is what you pass to `defineConfig()`. It has optional `root`, `plugins`, `parsers`, and `adapter`
1478
- * fields (which fall back to sensible defaults). All other Config options are available, including `output`, `input`,
1479
- * `storage`, `middleware`, `renderer`, `devtools`, and `hooks`.
1480
- *
1481
- * @example
1482
- * ```ts
1483
- * export default defineConfig({
1484
- * input: { path: './petstore.yaml' },
1485
- * output: { path: './src/gen' },
1486
- * plugins: [pluginTs(), pluginZod()],
1487
- * })
1488
- * ```
1489
- */
1490
- type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins' | 'parsers' | 'adapter'> & {
1517
+ clean?: boolean;
1518
+ /**
1519
+ * Auto-format generated files after code generation completes.
1520
+ *
1521
+ * Applies a code formatter to all generated files. Use `'auto'` to detect which formatter
1522
+ * is available on your system. Pass `false` to skip formatting (useful for CI or specific workflows).
1523
+ *
1524
+ * @default false
1525
+ * @example
1526
+ * ```ts
1527
+ * format: 'auto' // auto-detect prettier, biome, or oxfmt
1528
+ * format: 'prettier' // force prettier
1529
+ * format: false // skip formatting
1530
+ * ```
1531
+ */
1532
+ format?: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false;
1533
+ /**
1534
+ * Auto-lint generated files after code generation completes.
1535
+ *
1536
+ * Analyzes all generated files for style/correctness issues. Use `'auto'` to detect which linter
1537
+ * is available on your system. Pass `false` to skip linting.
1538
+ *
1539
+ * @default false
1540
+ * @example
1541
+ * ```ts
1542
+ * lint: 'auto' // auto-detect oxlint, biome, or eslint
1543
+ * lint: 'eslint' // force eslint
1544
+ * lint: false // skip linting
1545
+ * ```
1546
+ */
1547
+ lint?: 'auto' | 'eslint' | 'biome' | 'oxlint' | false;
1548
+ /**
1549
+ * Map file extensions to different output extensions.
1550
+ *
1551
+ * Useful when you want generated `.ts` imports to reference `.js` files or vice versa (e.g., for ESM dual packages).
1552
+ * Keys are the original extension, values are the output extension. Use empty string `''` to omit extension.
1553
+ *
1554
+ * @default { '.ts': '.ts' }
1555
+ * @example
1556
+ * ```ts
1557
+ * extension: { '.ts': '.js' } // generates import './api.js' instead of './api.ts'
1558
+ * extension: { '.ts': '', '.tsx': '.jsx' }
1559
+ * ```
1560
+ */
1561
+ extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
1562
+ /**
1563
+ * Banner text prepended to every generated file.
1564
+ *
1565
+ * Useful for auto-generation notices or license headers. Choose a preset or write custom text.
1566
+ * Use `'simple'` for a basic Kubb banner, `'full'` for detailed metadata, or `false` to omit.
1567
+ *
1568
+ * @default 'simple'
1569
+ * @example
1570
+ * ```ts
1571
+ * defaultBanner: 'simple' // "This file was autogenerated by Kubb"
1572
+ * defaultBanner: 'full' // adds source, title, description, API version
1573
+ * defaultBanner: false // no banner
1574
+ * ```
1575
+ */
1576
+ defaultBanner?: 'simple' | 'full' | false;
1577
+ /**
1578
+ * When `true`, overwrites existing files. When `false`, skips generated files that already exist.
1579
+ *
1580
+ * Individual plugins can override this setting. This is useful for preventing accidental data loss
1581
+ * when re-generating while you have local edits in the output folder.
1582
+ *
1583
+ * @default false
1584
+ * @example
1585
+ * ```ts
1586
+ * override: true // regenerate everything, even existing files
1587
+ * override: false // skip files that already exist
1588
+ * ```
1589
+ */
1590
+ override?: boolean;
1591
+ } & ExtractRegistryKey<Kubb$1.ConfigOptionsRegistry, 'output'>;
1491
1592
  /**
1492
- * Project root directory, absolute or relative to the config file location.
1593
+ * Storage backend that controls where and how generated files are persisted.
1493
1594
  *
1494
- * Used as the base path for `root`-relative paths (e.g., `output.path`, file paths in hooks).
1595
+ * Defaults to `fsStorage()` which writes to the file system. Pass `memoryStorage()` to keep files in RAM,
1596
+ * or implement a custom `Storage` interface to write to cloud storage, databases, or other backends.
1495
1597
  *
1496
- * @default process.cwd()
1598
+ * @default fsStorage()
1497
1599
  * @example
1498
1600
  * ```ts
1499
- * root: '/home/user/my-project'
1500
- * root: './my-project' // relative to config file
1601
+ * import { memoryStorage } from '@kubb/core'
1602
+ *
1603
+ * // Keep generated files in memory (useful for testing, CI pipelines)
1604
+ * storage: memoryStorage()
1605
+ *
1606
+ * // Use custom S3 storage
1607
+ * storage: myS3Storage()
1501
1608
  * ```
1609
+ *
1610
+ * @see {@link Storage} interface for implementing custom backends.
1502
1611
  */
1503
- root?: string;
1612
+ storage: Storage;
1504
1613
  /**
1505
- * Custom parsers that convert generated AST nodes to strings (TypeScript, JSON, markdown, etc.).
1614
+ * Plugins that execute during the build to generate code and transform the AST.
1506
1615
  *
1507
- * Each parser handles a specific file type. By default, Kubb uses `parserTs` from `@kubb/parser-ts` for TypeScript files.
1508
- * Pass custom parsers to support additional languages or custom formats.
1616
+ * Each plugin processes the AST produced by the adapter and can emit files for different
1617
+ * programming languages or formats (TypeScript, Zod schemas, Faker data, etc.).
1618
+ * Dependencies are enforced — an error is thrown if a plugin requires another plugin that isn't registered.
1619
+ *
1620
+ * Plugins can declare their own options via `PluginFactoryOptions`. See plugin documentation for details.
1509
1621
  *
1510
- * @default [parserTs] // from `@kubb/parser-ts`
1511
1622
  * @example
1512
1623
  * ```ts
1513
- * import { parserTs } from '@kubb/parser-ts'
1514
- * import { parserJsonSchema } from '@kubb/parser-json-schema'
1624
+ * import { pluginTs } from '@kubb/plugin-ts'
1625
+ * import { pluginZod } from '@kubb/plugin-zod'
1515
1626
  *
1516
- * parsers: [parserTs(), parserJsonSchema()]
1627
+ * plugins: [
1628
+ * pluginTs({ output: { path: './src/gen' } }),
1629
+ * pluginZod({ output: { path: './src/gen' } }),
1630
+ * ]
1517
1631
  * ```
1518
- *
1519
- * @see {@link Parser} to implement a custom parser.
1520
1632
  */
1521
- parsers?: Array<Parser>;
1633
+ plugins: Array<Plugin>;
1522
1634
  /**
1523
- * Adapter that parses your API specification (OpenAPI, GraphQL, AsyncAPI, etc.) into Kubb's universal AST.
1635
+ * Middleware instances that observe build events and post-process generated code.
1524
1636
  *
1525
- * Pass an adapter to support different spec formats. When omitted, Kubb runs in plugin-only mode —
1526
- * `kubb:plugin:setup` fires and `injectFile` works, but no AST walk occurs and generator hooks
1527
- * (`kubb:generate:schema`, `kubb:generate:operation`) are never emitted.
1637
+ * Middleware fires AFTER all plugins for each event. Perfect for tasks like:
1638
+ * - Auditing what was generated
1639
+ * - Adding barrel/index files
1640
+ * - Validating output
1641
+ * - Running custom transformations
1528
1642
  *
1529
1643
  * @example
1530
1644
  * ```ts
1531
- * import { adapterOas } from '@kubb/adapter-oas'
1645
+ * import { middlewareBarrel } from '@kubb/middleware-barrel'
1532
1646
  *
1533
- * adapter: adapterOas()
1647
+ * middleware: [middlewareBarrel()]
1534
1648
  * ```
1535
1649
  *
1536
- * @see {@link Adapter} to implement a custom adapter for GraphQL or other formats.
1650
+ * @see {@link defineMiddleware} to create custom middleware.
1537
1651
  */
1538
- adapter?: Adapter;
1652
+ middleware?: Array<Middleware>;
1539
1653
  /**
1540
- * Plugins that execute during the build to generate code and transform the AST.
1654
+ * Renderer that converts generated AST nodes to code strings.
1541
1655
  *
1542
- * Each plugin processes the AST produced by the adapter and can emit files for different
1543
- * programming languages or formats (TypeScript, Zod schemas, Faker data, etc.).
1656
+ * By default, Kubb uses the JSX renderer (`rendererJsx`). Pass a custom renderer to support
1657
+ * different output formats (template engines, code generation DSLs, etc.).
1544
1658
  *
1545
- * @default [] // no plugins (useful for setup/testing)
1659
+ * @default rendererJsx() // from @kubb/renderer-jsx
1546
1660
  * @example
1547
1661
  * ```ts
1548
- * plugins: [
1549
- * pluginTs({ output: { path: './src/gen' } }),
1550
- * pluginZod({ output: { path: './src/gen' } }),
1551
- * ]
1662
+ * import { rendererJsx } from '@kubb/renderer-jsx'
1663
+ * renderer: rendererJsx()
1552
1664
  * ```
1553
1665
  *
1554
- * @see {@link definePlugin} to create a custom plugin.
1555
- */
1556
- plugins?: Array<Plugin>;
1557
- };
1558
- type ResolveNameParams = {
1559
- name: string;
1560
- pluginName?: string;
1561
- /**
1562
- * Entity type being named.
1563
- * - `'file'` — file name (camelCase)
1564
- * - `'function'` — exported function name (camelCase)
1565
- * - `'type'` — TypeScript type name (PascalCase)
1566
- * - `'const'` — variable name (camelCase)
1567
- */
1568
- type?: 'file' | 'function' | 'type' | 'const';
1569
- };
1570
- /**
1571
- * Context object passed to generator `schema`, `operation`, and `operations` methods.
1572
- *
1573
- * The adapter is always defined (guaranteed by `runPluginAstHooks`) so no runtime checks
1574
- * are needed. `ctx.options` carries resolved per-node options after exclude/include/override
1575
- * filtering for individual schema/operation calls, or plugin-level options for operations.
1576
- */
1577
- type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
1578
- config: Config;
1579
- /**
1580
- * Absolute path to the current plugin's output directory.
1581
- */
1582
- root: string;
1583
- /**
1584
- * Determine output mode based on the output config.
1585
- * Returns `'single'` when `output.path` is a file, `'split'` for a directory.
1586
- */
1587
- getMode: (output: {
1588
- path: string;
1589
- }) => 'single' | 'split';
1590
- driver: PluginDriver;
1591
- /**
1592
- * Get a plugin by name, typed via `Kubb.PluginRegistry` when registered.
1593
- */
1594
- getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
1595
- getPlugin(name: string): Plugin | undefined;
1596
- /**
1597
- * Get a plugin by name, throws an error if not found.
1598
- */
1599
- requirePlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]>;
1600
- requirePlugin(name: string): Plugin;
1601
- /**
1602
- * Get a resolver by plugin name, typed via `Kubb.PluginRegistry` when registered.
1603
- */
1604
- getResolver<TName extends keyof Kubb.PluginRegistry>(name: TName): Kubb.PluginRegistry[TName]['resolver'];
1605
- getResolver(name: string): Resolver;
1606
- /**
1607
- * Add files only if they don't exist.
1608
- */
1609
- addFile: (...file: Array<FileNode>) => Promise<void>;
1610
- /**
1611
- * Merge sources into the same output file.
1612
- */
1613
- upsertFile: (...file: Array<FileNode>) => Promise<void>;
1614
- hooks: AsyncEventEmitter<KubbHooks>;
1615
- /**
1616
- * The current plugin instance.
1617
- */
1618
- plugin: Plugin<TOptions>;
1619
- /**
1620
- * The current plugin's resolver.
1621
- */
1622
- resolver: TOptions['resolver'];
1623
- /**
1624
- * The current plugin's transformer.
1625
- */
1626
- transformer: Visitor | undefined;
1627
- /**
1628
- * Emit a warning.
1629
- */
1630
- warn: (message: string) => void;
1631
- /**
1632
- * Emit an error.
1633
- */
1634
- error: (error: string | Error) => void;
1635
- /**
1636
- * Emit an info message.
1637
- */
1638
- info: (message: string) => void;
1639
- /**
1640
- * Open the current input node in Kubb Studio.
1641
- */
1642
- openInStudio: (options?: DevtoolsOptions) => Promise<void>;
1643
- /**
1644
- * The configured adapter instance.
1645
- */
1646
- adapter: Adapter;
1647
- /**
1648
- * The universal `InputNode` produced by the adapter.
1649
- */
1650
- inputNode: InputNode;
1651
- /**
1652
- * Resolved options after exclude/include/override filtering.
1653
- */
1654
- options: TOptions['resolvedOptions'];
1655
- };
1656
- /**
1657
- * Output configuration for generated files.
1658
- */
1659
- type Output<_TOptions = unknown> = {
1660
- /**
1661
- * Output folder or file path for generated code.
1662
- */
1663
- path: string;
1664
- /**
1665
- * Text or function prepended to every generated file.
1666
- * When a function, receives the current `InputNode` and returns a string.
1667
- */
1668
- banner?: string | ((node?: InputNode) => string);
1669
- /**
1670
- * Text or function appended to every generated file.
1671
- * When a function, receives the current `InputNode` and returns a string.
1672
- */
1673
- footer?: string | ((node?: InputNode) => string);
1674
- /**
1675
- * Whether to override existing external files if they already exist.
1676
- * @default false
1677
- */
1678
- override?: boolean;
1679
- } & ExtractRegistryKey<Kubb.PluginOptionsRegistry, 'output'>;
1680
- type Group = {
1681
- /**
1682
- * How to group files into subdirectories.
1683
- * - `'tag'` — group by OpenAPI tags
1684
- * - `'path'` — group by OpenAPI paths
1666
+ * @see {@link Renderer} to implement a custom renderer.
1685
1667
  */
1686
- type: 'tag' | 'path';
1668
+ renderer?: RendererFactory;
1687
1669
  /**
1688
- * Function that returns the subdirectory name for a group value.
1689
- * Defaults to `${camelCase(group)}Controller` for tags, first path segment for paths.
1670
+ * Kubb Studio cloud integration settings.
1671
+ *
1672
+ * Kubb Studio (https://kubb.studio) is a web-based IDE for managing API specs and generated code.
1673
+ * Set to `true` to enable with default settings, or pass an object to customize the Studio URL.
1674
+ *
1675
+ * @default false // disabled by default
1676
+ * @example
1677
+ * ```ts
1678
+ * devtools: true // use default Kubb Studio
1679
+ * devtools: { studioUrl: 'https://my-studio.dev' } // custom Studio instance
1680
+ * ```
1690
1681
  */
1691
- name?: (context: {
1692
- group: string;
1693
- }) => string;
1694
- };
1695
- type LoggerOptions = {
1682
+ devtools?: true | {
1683
+ /**
1684
+ * Override the Kubb Studio base URL.
1685
+ * @default 'https://kubb.studio'
1686
+ */
1687
+ studioUrl?: typeof DEFAULT_STUDIO_URL | (string & {});
1688
+ };
1696
1689
  /**
1697
- * Log level for output verbosity.
1698
- * @default 3
1690
+ * Lifecycle hooks that execute during or after the build process.
1691
+ *
1692
+ * Hooks allow you to run external tools (prettier, eslint, custom scripts) based on build events.
1693
+ * Currently supports the `done` hook which fires after all plugins and middleware complete.
1694
+ *
1695
+ * @example
1696
+ * ```ts
1697
+ * hooks: {
1698
+ * done: 'prettier --write "./src/gen"', // auto-format generated files
1699
+ * // or multiple commands:
1700
+ * done: ['prettier --write "./src/gen"', 'eslint --fix "./src/gen"']
1701
+ * }
1702
+ * ```
1699
1703
  */
1700
- logLevel: (typeof logLevel)[keyof typeof logLevel];
1701
- };
1702
- /**
1703
- * Shared context passed to plugins, parsers, and other internals.
1704
- */
1705
- type LoggerContext = AsyncEventEmitter<KubbHooks>;
1706
- type Logger<TOptions extends LoggerOptions = LoggerOptions, TInstallReturn = void> = {
1707
- name: string;
1708
- install: (context: LoggerContext, options?: TOptions) => TInstallReturn | Promise<TInstallReturn>;
1704
+ hooks?: {
1705
+ /**
1706
+ * Command(s) to run after all plugins and middleware complete generation.
1707
+ *
1708
+ * Useful for post-processing: formatting, linting, copying files, or custom validation.
1709
+ * Pass a single command string or array of command strings to run sequentially.
1710
+ * Commands are executed relative to the `root` directory.
1711
+ *
1712
+ * @example
1713
+ * ```ts
1714
+ * done: 'prettier --write "./src/gen"'
1715
+ * done: ['prettier --write "./src/gen"', 'eslint --fix "./src/gen"']
1716
+ * ```
1717
+ */
1718
+ done?: string | Array<string>;
1719
+ };
1709
1720
  };
1710
- type UserLogger<TOptions extends LoggerOptions = LoggerOptions, TInstallReturn = void> = Logger<TOptions, TInstallReturn>;
1711
1721
  /**
1712
- * Context for hook-style plugin `kubb:plugin:setup` handler.
1713
- * Provides methods to register generators, configure resolvers, transformers, and renderers.
1722
+ * Partial `Config` for user-facing entry points with sensible defaults.
1723
+ *
1724
+ * `UserConfig` is what you pass to `defineConfig()`. It has optional `root`, `plugins`, `parsers`, and `adapter`
1725
+ * fields (which fall back to sensible defaults). All other Config options are available, including `output`, `input`,
1726
+ * `storage`, `middleware`, `renderer`, `devtools`, and `hooks`.
1727
+ *
1728
+ * @example
1729
+ * ```ts
1730
+ * export default defineConfig({
1731
+ * input: { path: './petstore.yaml' },
1732
+ * output: { path: './src/gen' },
1733
+ * plugins: [pluginTs(), pluginZod()],
1734
+ * })
1735
+ * ```
1714
1736
  */
1715
- type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1716
- /**
1717
- * Register a generator dynamically. Generators fire during the AST walk (schema/operation/operations)
1718
- * just like generators declared statically on `createPlugin`.
1719
- */
1720
- addGenerator<TElement = unknown>(generator: Generator<TFactory, TElement>): void;
1721
- /**
1722
- * Set or override the resolver for this plugin.
1723
- * The resolver controls file naming and path resolution.
1724
- */
1725
- setResolver(resolver: Partial<TFactory['resolver']>): void;
1726
- /**
1727
- * Set the AST transformer to pre-process nodes before they reach generators.
1728
- */
1729
- setTransformer(visitor: Visitor): void;
1730
- /**
1731
- * Set the renderer factory to process JSX elements from generators.
1732
- */
1733
- setRenderer(renderer: RendererFactory): void;
1737
+ type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins' | 'parsers' | 'adapter' | 'storage'> & {
1734
1738
  /**
1735
- * Set resolved options merged into the normalized plugin's `options`.
1736
- * Call this in `kubb:plugin:setup` to provide options generators need.
1739
+ * Project root directory, absolute or relative to the config file location.
1740
+ * @default process.cwd()
1737
1741
  */
1738
- setOptions(options: TFactory['resolvedOptions']): void;
1742
+ root?: string;
1739
1743
  /**
1740
- * Inject a raw file into the build output, bypassing the generation pipeline.
1744
+ * Custom parsers that convert generated AST nodes to strings (TypeScript, JSON, markdown, etc.).
1745
+ * @default [parserTs] // from `@kubb/parser-ts`
1741
1746
  */
1742
- injectFile(userFileNode: UserFileNode): void;
1747
+ parsers?: Array<Parser>;
1743
1748
  /**
1744
- * Merge a partial config update into the current build configuration.
1749
+ * Adapter that parses your API specification into Kubb's universal AST.
1750
+ * When omitted, Kubb runs in plugin-only mode.
1745
1751
  */
1746
- updateConfig(config: Partial<Config>): void;
1752
+ adapter?: Adapter;
1747
1753
  /**
1748
- * The resolved build configuration at setup time.
1754
+ * Plugins that execute during the build to generate code and transform the AST.
1755
+ * @default []
1749
1756
  */
1750
- config: Config;
1757
+ plugins?: Array<Plugin>;
1751
1758
  /**
1752
- * The plugin's user-provided options.
1759
+ * Storage backend that controls where and how generated files are persisted.
1760
+ * @default fsStorage()
1753
1761
  */
1754
- options: TFactory['options'];
1762
+ storage?: Storage;
1755
1763
  };
1764
+ declare global {
1765
+ namespace Kubb {
1766
+ /**
1767
+ * Registry that maps plugin names to their `PluginFactoryOptions`.
1768
+ * Augment this interface in each plugin's `types.ts` to enable automatic
1769
+ * typing for `getPlugin` and `requirePlugin`.
1770
+ *
1771
+ * @example
1772
+ * ```ts
1773
+ * // packages/plugin-ts/src/types.ts
1774
+ * declare global {
1775
+ * namespace Kubb {
1776
+ * interface PluginRegistry {
1777
+ * 'plugin-ts': PluginTs
1778
+ * }
1779
+ * }
1780
+ * }
1781
+ * ```
1782
+ */
1783
+ interface PluginRegistry {}
1784
+ /**
1785
+ * Extension point for root `Config['output']` options.
1786
+ * Augment the `output` key in middleware or plugin packages to add extra fields
1787
+ * to the global output configuration without touching core types.
1788
+ *
1789
+ * @example
1790
+ * ```ts
1791
+ * // packages/middleware-barrel/src/types.ts
1792
+ * declare global {
1793
+ * namespace Kubb {
1794
+ * interface ConfigOptionsRegistry {
1795
+ * output: {
1796
+ * barrel?: import('./types.ts').BarrelConfig | false
1797
+ * }
1798
+ * }
1799
+ * }
1800
+ * }
1801
+ * ```
1802
+ */
1803
+ interface ConfigOptionsRegistry {}
1804
+ /**
1805
+ * Extension point for per-plugin `Output` options.
1806
+ * Augment the `output` key in middleware or plugin packages to add extra fields
1807
+ * to the per-plugin output configuration without touching core types.
1808
+ *
1809
+ * @example
1810
+ * ```ts
1811
+ * // packages/middleware-barrel/src/types.ts
1812
+ * declare global {
1813
+ * namespace Kubb {
1814
+ * interface PluginOptionsRegistry {
1815
+ * output: {
1816
+ * barrel?: import('./types.ts').PluginBarrelConfig | false
1817
+ * }
1818
+ * }
1819
+ * }
1820
+ * }
1821
+ * ```
1822
+ */
1823
+ interface PluginOptionsRegistry {}
1824
+ }
1825
+ }
1756
1826
  /**
1757
- * Context for hook-style plugin `kubb:build:start` handler.
1758
- * Fires immediately before the plugin execution loop begins.
1827
+ * Lifecycle events emitted during Kubb code generation.
1828
+ * Use these for logging, progress tracking, and custom integrations.
1829
+ *
1830
+ * @example
1831
+ * ```typescript
1832
+ * import type { AsyncEventEmitter } from '@internals/utils'
1833
+ * import type { KubbHooks } from '@kubb/core'
1834
+ *
1835
+ * const hooks: AsyncEventEmitter<KubbHooks> = new AsyncEventEmitter()
1836
+ *
1837
+ * hooks.on('kubb:lifecycle:start', () => {
1838
+ * console.log('Starting Kubb generation')
1839
+ * })
1840
+ *
1841
+ * hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
1842
+ * console.log(`Plugin ${plugin.name} completed in ${duration}ms`)
1843
+ * })
1844
+ * ```
1759
1845
  */
1846
+ interface KubbHooks {
1847
+ 'kubb:lifecycle:start': [ctx: KubbLifecycleStartContext];
1848
+ 'kubb:lifecycle:end': [];
1849
+ 'kubb:config:start': [];
1850
+ 'kubb:config:end': [ctx: KubbConfigEndContext];
1851
+ 'kubb:generation:start': [ctx: KubbGenerationStartContext];
1852
+ 'kubb:generation:end': [ctx: KubbGenerationEndContext];
1853
+ 'kubb:generation:summary': [ctx: KubbGenerationSummaryContext];
1854
+ 'kubb:format:start': [];
1855
+ 'kubb:format:end': [];
1856
+ 'kubb:lint:start': [];
1857
+ 'kubb:lint:end': [];
1858
+ 'kubb:hooks:start': [];
1859
+ 'kubb:hooks:end': [];
1860
+ 'kubb:hook:start': [ctx: KubbHookStartContext];
1861
+ 'kubb:hook:end': [ctx: KubbHookEndContext];
1862
+ 'kubb:version:new': [ctx: KubbVersionNewContext];
1863
+ 'kubb:info': [ctx: KubbInfoContext];
1864
+ 'kubb:error': [ctx: KubbErrorContext];
1865
+ 'kubb:success': [ctx: KubbSuccessContext];
1866
+ 'kubb:warn': [ctx: KubbWarnContext];
1867
+ 'kubb:debug': [ctx: KubbDebugContext];
1868
+ 'kubb:files:processing:start': [ctx: KubbFilesProcessingStartContext];
1869
+ 'kubb:file:processing:update': [ctx: KubbFileProcessingUpdateContext];
1870
+ 'kubb:files:processing:end': [ctx: KubbFilesProcessingEndContext];
1871
+ 'kubb:plugin:start': [ctx: KubbPluginStartContext];
1872
+ 'kubb:plugin:end': [ctx: KubbPluginEndContext];
1873
+ 'kubb:plugin:setup': [ctx: KubbPluginSetupContext];
1874
+ 'kubb:build:start': [ctx: KubbBuildStartContext];
1875
+ 'kubb:plugins:end': [ctx: KubbPluginsEndContext];
1876
+ 'kubb:build:end': [ctx: KubbBuildEndContext];
1877
+ 'kubb:generate:schema': [node: SchemaNode, ctx: GeneratorContext];
1878
+ 'kubb:generate:operation': [node: OperationNode, ctx: GeneratorContext];
1879
+ 'kubb:generate:operations': [nodes: Array<OperationNode>, ctx: GeneratorContext];
1880
+ }
1760
1881
  type KubbBuildStartContext = {
1761
1882
  config: Config;
1762
1883
  adapter: Adapter;
1763
1884
  inputNode: InputNode;
1764
- /**
1765
- * Get a plugin by name, typed via `Kubb.PluginRegistry` when registered.
1766
- */
1767
- getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
1885
+ getPlugin<TName extends keyof Kubb$1.PluginRegistry>(name: TName): Plugin<Kubb$1.PluginRegistry[TName]> | undefined;
1768
1886
  getPlugin(name: string): Plugin | undefined;
1769
- /**
1770
- * Get all files currently in the file manager.
1771
- * Call this lazily (e.g. in `kubb:plugin:end`) to see files added by prior plugins.
1772
- */
1773
1887
  readonly files: ReadonlyArray<FileNode>;
1774
- /**
1775
- * Upsert one or more files into the file manager.
1776
- * Files with the same path are merged; new files are appended.
1777
- * Safe to call at any point during the plugin lifecycle, including inside `kubb:plugin:end`.
1778
- */
1779
1888
  upsertFile: (...files: Array<FileNode>) => void;
1780
1889
  };
1781
- /**
1782
- * Context for `kubb:plugins:end` handlers.
1783
- * Fires after plugins run and per-plugin barrels are written, before final write to disk.
1784
- * Middleware that needs final files (e.g. root barrel) use this event.
1785
- */
1786
1890
  type KubbPluginsEndContext = {
1787
1891
  config: Config;
1788
- /**
1789
- * All files currently in the file manager (lazy snapshot).
1790
- */
1791
1892
  readonly files: ReadonlyArray<FileNode>;
1792
- /**
1793
- * Upsert files into the file manager.
1794
- * Files added here are included in the write pass.
1795
- */
1796
1893
  upsertFile: (...files: Array<FileNode>) => void;
1797
1894
  };
1798
- /**
1799
- * Context for hook-style plugin `kubb:build:end` handler.
1800
- * Fires after all files have been written to disk.
1801
- */
1802
1895
  type KubbBuildEndContext = {
1803
1896
  files: Array<FileNode>;
1804
1897
  config: Config;
@@ -1858,52 +1951,15 @@ type KubbFilesProcessingStartContext = {
1858
1951
  files: Array<FileNode>;
1859
1952
  };
1860
1953
  type KubbFileProcessingUpdateContext = {
1861
- /**
1862
- * Number of files processed.
1863
- */
1864
1954
  processed: number;
1865
- /**
1866
- * Total files to process.
1867
- */
1868
1955
  total: number;
1869
- /**
1870
- * Processing percentage (0–100).
1871
- */
1872
1956
  percentage: number;
1873
- /**
1874
- * Optional source identifier.
1875
- */
1876
1957
  source?: string;
1877
- /**
1878
- * The file being processed.
1879
- */
1880
1958
  file: FileNode;
1881
- /**
1882
- * The current build configuration.
1883
- */
1884
- config: Config;
1885
- };
1886
- type KubbFilesProcessingEndContext = {
1887
- files: Array<FileNode>;
1888
- };
1889
- type KubbPluginStartContext = {
1890
- plugin: NormalizedPlugin;
1891
- };
1892
- type KubbPluginEndContext = {
1893
- plugin: NormalizedPlugin;
1894
- duration: number;
1895
- success: boolean;
1896
- error?: Error;
1897
1959
  config: Config;
1898
- /**
1899
- * Returns all files currently in the file manager (lazy snapshot).
1900
- * Includes files added by plugins that have already run.
1901
- */
1902
- readonly files: ReadonlyArray<FileNode>;
1903
- /**
1904
- * Upsert one or more files into the file manager.
1905
- */
1906
- upsertFile: (...files: Array<FileNode>) => void;
1960
+ };
1961
+ type KubbFilesProcessingEndContext = {
1962
+ files: Array<FileNode>;
1907
1963
  };
1908
1964
  type KubbHookStartContext = {
1909
1965
  id?: string;
@@ -1917,243 +1973,110 @@ type KubbHookEndContext = {
1917
1973
  success: boolean;
1918
1974
  error: Error | null;
1919
1975
  };
1920
- type ByTag = {
1921
- /**
1922
- * Filter by OpenAPI `tags` field. Matches one or more tags assigned to operations.
1923
- */
1924
- type: 'tag';
1925
- /**
1926
- * Tag name to match (case-sensitive). Can be a literal string or regex pattern.
1927
- */
1928
- pattern: string | RegExp;
1976
+ /**
1977
+ * CLI options derived from command-line flags.
1978
+ */
1979
+ type CLIOptions = {
1980
+ config?: string;
1981
+ watch?: boolean; /** @default 'silent' */
1982
+ logLevel?: 'silent' | 'info' | 'debug';
1929
1983
  };
1930
- type ByOperationId = {
1984
+ /**
1985
+ * All accepted forms of a Kubb configuration.
1986
+ * Accepts `Config`/`Config[]`/promise or a factory (optionally receiving `TCliOptions`).
1987
+ */
1988
+ type PossibleConfig<TCliOptions = undefined> = PossiblePromise<Config | Config[]> | ((...args: [TCliOptions] extends [undefined] ? [] : [TCliOptions]) => PossiblePromise<Config | Config[]>);
1989
+ /**
1990
+ * Full output produced by a successful or failed build.
1991
+ */
1992
+ type BuildOutput = {
1931
1993
  /**
1932
- * Filter by OpenAPI `operationId` field. Each operation (GET, POST, etc.) has a unique identifier.
1994
+ * Plugins that threw during installation, paired with the caught error.
1933
1995
  */
1934
- type: 'operationId';
1996
+ failedPlugins: Set<{
1997
+ plugin: Plugin;
1998
+ error: Error;
1999
+ }>;
2000
+ files: Array<FileNode>;
2001
+ driver: PluginDriver;
1935
2002
  /**
1936
- * Operation ID to match (case-sensitive). Can be a literal string or regex pattern.
2003
+ * Elapsed time in milliseconds for each plugin, keyed by plugin name.
1937
2004
  */
1938
- pattern: string | RegExp;
1939
- };
1940
- type ByPath = {
2005
+ pluginTimings: Map<string, number>;
2006
+ error?: Error;
1941
2007
  /**
1942
- * Filter by OpenAPI `path` (URL endpoint). Useful to group or filter by service segments like `/pets`, `/users`, etc.
2008
+ * Raw generated source, keyed by absolute file path.
1943
2009
  */
1944
- type: 'path';
2010
+ sources: Map<string, string>;
2011
+ };
2012
+ /**
2013
+ * Kubb code generation instance returned by {@link createKubb}.
2014
+ *
2015
+ * Use this when orchestrating multiple builds, inspecting plugin timings, or integrating Kubb into a larger toolchain.
2016
+ * For a single one-off build, chain directly: `await createKubb(config).build()`.
2017
+ */
2018
+ type Kubb$1 = {
1945
2019
  /**
1946
- * URL path to match (case-sensitive). Can be a literal string or regex pattern. Matches against the full path.
2020
+ * Shared event emitter for lifecycle and status events. Attach listeners before calling `setup()` or `build()`.
1947
2021
  */
1948
- pattern: string | RegExp;
1949
- };
1950
- type ByMethod = {
2022
+ readonly hooks: AsyncEventEmitter<KubbHooks>;
1951
2023
  /**
1952
- * Filter by HTTP method: `'get'`, `'post'`, `'put'`, `'delete'`, `'patch'`, `'head'`, `'options'`.
2024
+ * Generated source code keyed by absolute file path. Available after `build()` or `safeBuild()` completes.
1953
2025
  */
1954
- type: 'method';
2026
+ readonly sources: Map<string, string>;
1955
2027
  /**
1956
- * HTTP method to match (case-insensitive when using string, or regex for dynamic matching).
2028
+ * Plugin driver managing all plugins. Available after `setup()` completes.
1957
2029
  */
1958
- pattern: HttpMethod | RegExp;
1959
- };
1960
- type BySchemaName = {
2030
+ readonly driver: PluginDriver | undefined;
1961
2031
  /**
1962
- * Filter by schema component name (TypeScript or JSON schema). Matches schemas in `#/components/schemas`.
2032
+ * Resolved configuration with defaults applied. Available after `setup()` completes.
1963
2033
  */
1964
- type: 'schemaName';
2034
+ readonly config: Config | undefined;
1965
2035
  /**
1966
- * Schema name to match (case-sensitive). Can be a literal string or regex pattern.
2036
+ * Resolves config and initializes the driver. `build()` calls this automatically.
1967
2037
  */
1968
- pattern: string | RegExp;
1969
- };
1970
- type ByContentType = {
2038
+ setup(): Promise<void>;
1971
2039
  /**
1972
- * Filter by response or request content type: `'application/json'`, `'application/xml'`, etc.
2040
+ * Runs the full pipeline and throws on any plugin error. Automatically calls `setup()` if needed.
1973
2041
  */
1974
- type: 'contentType';
2042
+ build(): Promise<BuildOutput>;
1975
2043
  /**
1976
- * Content type to match (case-sensitive). Can be a literal string or regex pattern.
2044
+ * Runs the full pipeline and captures errors in `BuildOutput` instead of throwing. Automatically calls `setup()` if needed.
1977
2045
  */
1978
- pattern: string | RegExp;
2046
+ safeBuild(): Promise<BuildOutput>;
1979
2047
  };
1980
2048
  /**
1981
- * A pattern filter that prevents matching nodes from being generated.
1982
- *
1983
- * Use to skip code generation for specific operations or schemas. For example, exclude deprecated endpoints
1984
- * or internal-only schemas. Can filter by tag, operationId, path, HTTP method, content type, or schema name.
1985
- *
1986
- * @example
1987
- * ```ts
1988
- * exclude: [
1989
- * { type: 'tag', pattern: 'internal' }, // skip "internal" tag
1990
- * { type: 'path', pattern: /^\/admin/ }, // skip all /admin endpoints
1991
- * { type: 'operationId', pattern: 'deprecated_*' } // skip operationIds matching pattern
1992
- * ]
1993
- * ```
1994
- */
1995
- type Exclude$1 = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1996
- /**
1997
- * A pattern filter that restricts generation to only matching nodes.
1998
- *
1999
- * Use to generate code for a subset of operations or schemas. For example, only generate for a specific service
2000
- * tag or only for "production" endpoints. Can filter by tag, operationId, path, HTTP method, content type, or schema name.
2001
- *
2002
- * @example
2003
- * ```ts
2004
- * include: [
2005
- * { type: 'tag', pattern: 'public' }, // generate only "public" tag
2006
- * { type: 'path', pattern: /^\/api\/v1/ }, // generate only v1 endpoints
2007
- * ]
2008
- * ```
2009
- */
2010
- type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
2011
- /**
2012
- * A pattern filter paired with partial option overrides applied when the pattern matches.
2013
- *
2014
- * Use to customize generation for specific operations or schemas. For example, apply different output paths
2015
- * for different tags, or use custom resolver functions per operation. Can filter by tag, operationId, path,
2016
- * HTTP method, schema name, or content type.
2017
- *
2018
- * @example
2019
- * ```ts
2020
- * override: [
2021
- * {
2022
- * type: 'tag',
2023
- * pattern: 'admin',
2024
- * options: { output: { path: './src/gen/admin' } } // admin APIs go to separate folder
2025
- * },
2026
- * {
2027
- * type: 'operationId',
2028
- * pattern: 'listPets',
2029
- * options: { exclude: true } // skip this specific operation
2030
- * }
2031
- * ]
2032
- * ```
2049
+ * Type guard to check if a given config has an `input.path`.
2033
2050
  */
2034
- type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
2035
- options: Partial<TOptions>;
2051
+ declare function isInputPath(config: UserConfig | undefined): config is UserConfig<InputPath> & {
2052
+ input: InputPath;
2036
2053
  };
2037
- /**
2038
- * File-specific parameters for `Resolver.resolvePath`.
2039
- *
2040
- * Pass alongside a `ResolverContext` to identify which file to resolve.
2041
- * Provide `tag` for tag-based grouping or `path` for path-based grouping.
2042
- *
2043
- * @example
2044
- * ```ts
2045
- * resolver.resolvePath(
2046
- * { baseName: 'petTypes.ts', tag: 'pets' },
2047
- * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
2048
- * )
2049
- * // → '/src/types/petsController/petTypes.ts'
2050
- * ```
2051
- */
2052
- type ResolverPathParams = {
2053
- baseName: FileNode['baseName'];
2054
- pathMode?: 'single' | 'split';
2055
- /**
2056
- * Tag value used when `group.type === 'tag'`.
2057
- */
2058
- tag?: string;
2059
- /**
2060
- * Path value used when `group.type === 'path'`.
2061
- */
2062
- path?: string;
2054
+ declare function isInputPath(config: Config | undefined): config is Config<InputPath> & {
2055
+ input: InputPath;
2063
2056
  };
2064
- /**
2065
- * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
2066
- *
2067
- * Describes where on disk output is rooted, which output config is active, and the optional
2068
- * grouping strategy that controls subdirectory layout.
2069
- *
2070
- * @example
2071
- * ```ts
2072
- * const context: ResolverContext = {
2073
- * root: config.root,
2074
- * output,
2075
- * group,
2076
- * }
2077
- * ```
2078
- */
2079
- type ResolverContext = {
2080
- root: string;
2081
- output: Output;
2082
- group?: Group;
2083
- /**
2084
- * Plugin name used to populate `meta.pluginName` on the resolved file.
2085
- */
2086
- pluginName?: string;
2057
+ type CreateKubbOptions = {
2058
+ hooks?: AsyncEventEmitter<KubbHooks>;
2087
2059
  };
2088
2060
  /**
2089
- * File-specific parameters for `Resolver.resolveFile`.
2061
+ * Creates a Kubb instance bound to a single config entry.
2090
2062
  *
2091
- * Pass alongside a `ResolverContext` to fully describe the file to resolve.
2092
- * `tag` and `path` are used only when a matching `group` is present in the context.
2063
+ * Accepts a user-facing config shape and resolves it to a full {@link Config} during
2064
+ * `setup()`. The instance then holds shared state (`hooks`, `sources`, `driver`, `config`)
2065
+ * across the `setup → build` lifecycle. Attach event listeners to `kubb.hooks` before
2066
+ * calling `setup()` or `build()`.
2093
2067
  *
2094
2068
  * @example
2095
2069
  * ```ts
2096
- * resolver.resolveFile(
2097
- * { name: 'listPets', extname: '.ts', tag: 'pets' },
2098
- * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
2099
- * )
2100
- * // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
2101
- * ```
2102
- */
2103
- type ResolverFileParams = {
2104
- name: string;
2105
- extname: FileNode['extname'];
2106
- /**
2107
- * Tag value used when `group.type === 'tag'`.
2108
- */
2109
- tag?: string;
2110
- /**
2111
- * Path value used when `group.type === 'path'`.
2112
- */
2113
- path?: string;
2114
- };
2115
- /**
2116
- * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
2070
+ * const kubb = createKubb(userConfig)
2117
2071
  *
2118
- * `output` is optional not every plugin configures a banner/footer.
2119
- * `config` carries the global Kubb config, used to derive the default Kubb banner.
2072
+ * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
2073
+ * console.log(`${plugin.name} completed in ${duration}ms`)
2074
+ * })
2120
2075
  *
2121
- * @example
2122
- * ```ts
2123
- * resolver.resolveBanner(inputNode, { output: { banner: '// generated' }, config })
2124
- * // → '// generated'
2076
+ * const { files, failedPlugins } = await kubb.safeBuild()
2125
2077
  * ```
2126
2078
  */
2127
- type ResolveBannerContext = {
2128
- output?: Pick<Output, 'banner' | 'footer'>;
2129
- config: Config;
2130
- };
2131
- /**
2132
- * CLI options derived from command-line flags.
2133
- */
2134
- type CLIOptions = {
2135
- /**
2136
- * Path to `kubb.config.js`.
2137
- */
2138
- config?: string;
2139
- /**
2140
- * Enable watch mode for input files.
2141
- */
2142
- watch?: boolean;
2143
- /**
2144
- * Logging verbosity for CLI usage.
2145
- * @default 'silent'
2146
- */
2147
- logLevel?: 'silent' | 'info' | 'debug';
2148
- };
2149
- /**
2150
- * All accepted forms of a Kubb configuration.
2151
- *
2152
- * Config is always `@kubb/core` {@link Config}.
2153
- * - `PossibleConfig` accepts `Config`/`Config[]`/promise or a no-arg config factory.
2154
- * - `PossibleConfig<TCliOptions>` accepts the same config forms or a config factory receiving `TCliOptions`.
2155
- */
2156
- type PossibleConfig<TCliOptions = undefined> = PossiblePromise<Config | Config[]> | ((...args: [TCliOptions] extends [undefined] ? [] : [TCliOptions]) => PossiblePromise<Config | Config[]>);
2079
+ declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
2157
2080
  //#endregion
2158
- export { defineParser as $, KubbPluginStartContext as A, Override as B, KubbGenerationSummaryContext as C, KubbLifecycleStartContext as D, KubbInfoContext as E, Logger as F, ResolveOptionsContext as G, PossibleConfig as H, LoggerContext as I, ResolverFileParams as J, Resolver as K, LoggerOptions as L, KubbSuccessContext as M, KubbVersionNewContext as N, KubbPluginEndContext as O, KubbWarnContext as P, Parser as Q, NormalizedPlugin as R, KubbGenerationStartContext as S, KubbHookStartContext as T, ResolveBannerContext as U, PluginFactoryOptions as V, ResolveNameParams as W, UserConfig as X, ResolverPathParams as Y, UserLogger as Z, KubbErrorContext as _, logLevel as _t, Config as a, createKubb as at, KubbFilesProcessingStartContext as b, GeneratorContext as c, Plugin as ct, InputData as d, defineGenerator as dt, Middleware as et, InputPath as f, Storage as ft, KubbDebugContext as g, createRenderer as gt, KubbConfigEndContext as h, RendererFactory as ht, CLIOptions as i, BuildOutput as it, KubbPluginsEndContext as j, KubbPluginSetupContext as k, Group as l, definePlugin as lt, KubbBuildStartContext as m, Renderer as mt, AdapterFactoryOptions as n, Kubb$1 as nt, DevtoolsOptions as o, PluginDriver as ot, KubbBuildEndContext as p, createStorage as pt, ResolverContext as q, AdapterSource as r, KubbHooks as rt, Exclude$1 as s, FileManager as st, Adapter as t, defineMiddleware as tt, Include as u, Generator as ut, KubbFileProcessingUpdateContext as v, AsyncEventEmitter as vt, KubbHookEndContext as w, KubbGenerationEndContext as x, KubbFilesProcessingEndContext as y, Output as z };
2159
- //# sourceMappingURL=types-ChyWgIgi.d.ts.map
2081
+ export { ResolverPathParams as $, isInputPath as A, KubbPluginSetupContext as B, KubbPluginsEndContext as C, PossibleConfig as D, KubbWarnContext as E, FileManager as F, Plugin as G, NormalizedPlugin as H, Exclude as I, ResolveBannerContext as J, PluginFactoryOptions as K, Group as L, GeneratorContext as M, defineGenerator as N, UserConfig as O, PluginDriver as P, ResolverFileParams as Q, Include as R, KubbLifecycleStartContext as S, KubbVersionNewContext as T, Output as U, KubbPluginStartContext as V, Override as W, Resolver as X, ResolveOptionsContext as Y, ResolverContext as Z, KubbGenerationSummaryContext as _, AdapterFactoryOptions as _t, InputPath as a, Logger as at, KubbHooks as b, logLevel as bt, KubbBuildStartContext as c, UserLogger as ct, KubbErrorContext as d, Storage as dt, defineResolver as et, KubbFileProcessingUpdateContext as f, createStorage as ft, KubbGenerationStartContext as g, Adapter as gt, KubbGenerationEndContext as h, createRenderer as ht, InputData as i, defineMiddleware as it, Generator as j, createKubb as k, KubbConfigEndContext as l, defineLogger as lt, KubbFilesProcessingStartContext as m, RendererFactory as mt, CLIOptions as n, defineParser as nt, Kubb$1 as o, LoggerContext as ot, KubbFilesProcessingEndContext as p, Renderer as pt, definePlugin as q, Config as r, Middleware as rt, KubbBuildEndContext as s, LoggerOptions as st, BuildOutput as t, Parser as tt, KubbDebugContext as u, DevtoolsOptions as ut, KubbHookEndContext as v, AdapterSource as vt, KubbSuccessContext as w, KubbInfoContext as x, AsyncEventEmitter as xt, KubbHookStartContext as y, createAdapter as yt, KubbPluginEndContext as z };
2082
+ //# sourceMappingURL=createKubb-Cagd4PIe.d.ts.map