@kubb/core 5.0.0-beta.3 → 5.0.0-beta.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +8 -38
  2. package/dist/KubbDriver-CFx2DdhF.js +2131 -0
  3. package/dist/KubbDriver-CFx2DdhF.js.map +1 -0
  4. package/dist/KubbDriver-vyD7F0Ip.cjs +2252 -0
  5. package/dist/KubbDriver-vyD7F0Ip.cjs.map +1 -0
  6. package/dist/{types-CC09VtBt.d.ts → createKubb-6zii1jo-.d.ts} +1610 -1257
  7. package/dist/index.cjs +351 -1125
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +3 -186
  10. package/dist/index.js +341 -1119
  11. package/dist/index.js.map +1 -1
  12. package/dist/mocks.cjs +30 -21
  13. package/dist/mocks.cjs.map +1 -1
  14. package/dist/mocks.d.ts +5 -5
  15. package/dist/mocks.js +29 -20
  16. package/dist/mocks.js.map +1 -1
  17. package/package.json +6 -18
  18. package/src/FileManager.ts +78 -61
  19. package/src/FileProcessor.ts +48 -38
  20. package/src/KubbDriver.ts +930 -0
  21. package/src/constants.ts +11 -6
  22. package/src/createAdapter.ts +113 -17
  23. package/src/createKubb.ts +1039 -478
  24. package/src/createRenderer.ts +58 -27
  25. package/src/createStorage.ts +36 -23
  26. package/src/defineGenerator.ts +127 -15
  27. package/src/defineLogger.ts +66 -7
  28. package/src/defineMiddleware.ts +19 -17
  29. package/src/defineParser.ts +30 -13
  30. package/src/definePlugin.ts +329 -14
  31. package/src/defineResolver.ts +365 -167
  32. package/src/devtools.ts +8 -1
  33. package/src/index.ts +2 -2
  34. package/src/mocks.ts +11 -14
  35. package/src/storages/fsStorage.ts +13 -37
  36. package/src/types.ts +48 -1292
  37. package/dist/PluginDriver-BXibeQk-.cjs +0 -1036
  38. package/dist/PluginDriver-BXibeQk-.cjs.map +0 -1
  39. package/dist/PluginDriver-DV3p2Hky.js +0 -945
  40. package/dist/PluginDriver-DV3p2Hky.js.map +0 -1
  41. package/src/Kubb.ts +0 -300
  42. package/src/PluginDriver.ts +0 -424
  43. package/src/renderNode.ts +0 -35
  44. package/src/utils/diagnostics.ts +0 -18
  45. package/src/utils/isInputPath.ts +0 -10
  46. package/src/utils/packageJSON.ts +0 -99
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { FileNode, HttpMethod, ImportNode, InputNode, Node, OperationNode, SchemaNode, UserFileNode, Visitor } from "@kubb/ast";
2
+ import { FileNode, HttpMethod, ImportNode, InputMeta, InputNode, InputStreamNode, Node, OperationNode, SchemaNode, UserFileNode, Visitor } from "@kubb/ast";
3
3
 
4
4
  //#region ../../internals/utils/src/asyncEventEmitter.d.ts
5
5
  /**
@@ -33,7 +33,7 @@ declare class AsyncEventEmitter<TEvents extends { [K in keyof TEvents]: unknown[
33
33
  * await emitter.emit('build', 'petstore')
34
34
  * ```
35
35
  */
36
- emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void>;
36
+ emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> | void;
37
37
  /**
38
38
  * Registers a persistent listener for `eventName`.
39
39
  *
@@ -98,7 +98,7 @@ type PossiblePromise<T> = Promise<T> | T;
98
98
  /**
99
99
  * Base URL for the Kubb Studio web app.
100
100
  */
101
- declare const DEFAULT_STUDIO_URL: "https://studio.kubb.dev";
101
+ declare const DEFAULT_STUDIO_URL: "https://kubb.studio";
102
102
  /**
103
103
  * Numeric log-level thresholds used internally to compare verbosity.
104
104
  *
@@ -113,314 +113,1183 @@ declare const logLevel: {
113
113
  readonly debug: 5;
114
114
  };
115
115
  //#endregion
116
+ //#region src/createAdapter.d.ts
117
+ /**
118
+ * Source data handed to an adapter's `parse` function. Mirrors the config
119
+ * input shape with paths resolved to absolute.
120
+ *
121
+ * - `{ type: 'path' }`: single file on disk.
122
+ * - `{ type: 'paths' }`: multiple files (e.g. split spec).
123
+ * - `{ type: 'data' }`: raw string or parsed object provided inline.
124
+ */
125
+ type AdapterSource = {
126
+ type: 'path';
127
+ path: string;
128
+ } | {
129
+ type: 'data';
130
+ data: string | unknown;
131
+ } | {
132
+ type: 'paths';
133
+ paths: Array<string>;
134
+ };
135
+ /**
136
+ * Generic parameters used by `createAdapter` and the resulting `Adapter` type.
137
+ *
138
+ * - `TName`: unique adapter identifier (`'oas'`, `'asyncapi'`, ...).
139
+ * - `TOptions`: user-facing options accepted by the adapter factory.
140
+ * - `TResolvedOptions`: options after defaults are applied.
141
+ * - `TDocument`: type of the parsed source document.
142
+ */
143
+ type AdapterFactoryOptions<TName extends string = string, TOptions extends object = object, TResolvedOptions extends object = TOptions, TDocument = unknown> = {
144
+ name: TName;
145
+ options: TOptions;
146
+ resolvedOptions: TResolvedOptions;
147
+ document: TDocument;
148
+ };
149
+ /**
150
+ * Converts input files or inline data into Kubb's universal AST `InputNode`.
151
+ *
152
+ * Adapters live between the spec format and the plugins. The built-in
153
+ * `@kubb/adapter-oas` handles OpenAPI 2.0, 3.0, and 3.1; custom adapters can
154
+ * support GraphQL, gRPC, AsyncAPI, or any domain-specific schema language.
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * import { defineConfig } from 'kubb'
159
+ * import { adapterOas } from '@kubb/adapter-oas'
160
+ * import { pluginTs } from '@kubb/plugin-ts'
161
+ *
162
+ * export default defineConfig({
163
+ * input: { path: './petStore.yaml' },
164
+ * output: { path: './src/gen' },
165
+ * adapter: adapterOas(),
166
+ * plugins: [pluginTs()],
167
+ * })
168
+ * ```
169
+ */
170
+ type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
171
+ /**
172
+ * Human-readable adapter identifier (e.g. `'oas'`, `'asyncapi'`).
173
+ */
174
+ name: TOptions['name'];
175
+ /**
176
+ * Resolved adapter options after defaults have been applied.
177
+ */
178
+ options: TOptions['resolvedOptions'];
179
+ /**
180
+ * Parsed source document after the first `parse()` call. `null` before parsing.
181
+ */
182
+ document: TOptions['document'] | null;
183
+ /**
184
+ * Parse the source into a universal `InputNode`.
185
+ */
186
+ parse: (source: AdapterSource) => PossiblePromise<InputNode>;
187
+ /**
188
+ * Extract `ImportNode` entries for a schema tree.
189
+ * Returns an empty array before the first `parse()` call.
190
+ *
191
+ * The `resolve` callback receives the collision-corrected schema name and must
192
+ * return `{ name, path }` for the import, or `undefined` to skip it.
193
+ */
194
+ getImports: (node: SchemaNode, resolve: (schemaName: string) => {
195
+ name: string;
196
+ path: string;
197
+ }) => Array<ImportNode>;
198
+ /**
199
+ * Validate the document at the given path or URL.
200
+ */
201
+ validate: (input: string, options?: {
202
+ throwOnError?: boolean;
203
+ }) => Promise<void>;
204
+ /**
205
+ * Memory-efficient streaming variant of `parse()`.
206
+ *
207
+ * Returns an `InputStreamNode` whose `schemas` and `operations` are `AsyncIterable`.
208
+ * Each `for await` loop creates a fresh parse pass over the cached in-memory document.
209
+ * No pre-built arrays are held in memory.
210
+ */
211
+ stream?: (source: AdapterSource) => Promise<InputStreamNode>;
212
+ };
213
+ type AdapterBuilder<T extends AdapterFactoryOptions> = (options: T['options']) => Adapter<T>;
214
+ /**
215
+ * Defines a custom adapter that translates a spec format into Kubb's universal
216
+ * AST. Use this when you need to consume GraphQL, gRPC, AsyncAPI, or another
217
+ * domain-specific schema. Built-in adapters: `@kubb/adapter-oas` for
218
+ * OpenAPI/Swagger documents.
219
+ *
220
+ * Adapters must return an `InputNode` from `parse`. That node is what every
221
+ * plugin in the build consumes.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * import { createAdapter, ast, type AdapterFactoryOptions } from '@kubb/core'
226
+ *
227
+ * type MyAdapter = AdapterFactoryOptions<'my-adapter', { validate?: boolean }>
228
+ *
229
+ * export const myAdapter = createAdapter<MyAdapter>((options) => ({
230
+ * name: 'my-adapter',
231
+ * options,
232
+ * document: null,
233
+ * async parse(_source) {
234
+ * // Convert `source` (path or inline data) into an InputNode.
235
+ * return ast.createInput()
236
+ * },
237
+ * getImports: () => [],
238
+ * async validate() {
239
+ * // Throw or call ctx.error here when the spec is invalid.
240
+ * },
241
+ * }))
242
+ * ```
243
+ */
244
+ declare function createAdapter<T extends AdapterFactoryOptions = AdapterFactoryOptions>(build: AdapterBuilder<T>): (options?: T['options']) => Adapter<T>;
245
+ //#endregion
116
246
  //#region src/createRenderer.d.ts
117
247
  /**
118
248
  * Minimal interface any Kubb renderer must satisfy.
119
249
  *
120
- * The generic `TElement` is the type of the element the renderer accepts
121
- * e.g. `KubbReactElement` for `@kubb/renderer-jsx`, or a custom type for
122
- * your own renderer. Defaults to `unknown` so that generators which do not
123
- * care about the element type continue to work without specifying it.
124
- *
125
- * This allows core to drive rendering without a hard dependency on
126
- * `@kubb/renderer-jsx` or any specific renderer implementation.
250
+ * `TElement` is the type the renderer accepts, for example `KubbReactElement`
251
+ * for `@kubb/renderer-jsx` or a custom type for your own renderer. Defaults to
252
+ * `unknown` so generators that don't care about the element type work without
253
+ * specifying it.
127
254
  */
128
255
  type Renderer<TElement = unknown> = {
256
+ /**
257
+ * Renders `element` and populates {@link files} with the resulting {@link FileNode} objects.
258
+ * Called once per render cycle; must resolve before {@link files} is read.
259
+ */
129
260
  render(element: TElement): Promise<void>;
261
+ /**
262
+ * Tears down the renderer and releases any held resources.
263
+ * Pass an `Error` to signal a failure, a number for an exit code, or omit for a clean shutdown.
264
+ */
130
265
  unmount(error?: Error | number | null): void;
266
+ /**
267
+ * Releases any held resources. `[Symbol.dispose]` delegates here.
268
+ */
269
+ dispose(): void;
270
+ /**
271
+ * Accumulated {@link FileNode} results produced by the last {@link render} call.
272
+ * Not populated when {@link stream} is implemented.
273
+ */
131
274
  readonly files: Array<FileNode>;
275
+ /**
276
+ * When present, core calls this instead of {@link render} and {@link files},
277
+ * forwarding each file to `FileManager` as soon as it is ready.
278
+ */
279
+ stream?(element: TElement): Iterable<FileNode>;
280
+ /**
281
+ * Disposer hook so renderers participate in `using` blocks: `using r = rendererFactory()`
282
+ * guarantees {@link dispose} runs on every exit path, including thrown errors.
283
+ */
284
+ [Symbol.dispose](): void;
132
285
  };
133
286
  /**
134
- * A factory function that produces a fresh {@link Renderer} per render.
287
+ * A factory function that produces a fresh {@link Renderer} per render cycle.
135
288
  *
136
289
  * Generators use this to declare which renderer handles their output.
137
290
  */
138
291
  type RendererFactory<TElement = unknown> = () => Renderer<TElement>;
139
292
  /**
140
- * Creates a renderer factory for use in generator definitions.
293
+ * Defines a renderer factory. Renderers turn the generator's return value
294
+ * (JSX, a template string, a tree of any shape) into `FileNode`s that get
295
+ * written to disk.
141
296
  *
142
- * Wrap your renderer factory function with this helper to register it as the
143
- * renderer for a generator. Core will call this factory once per render cycle
144
- * to obtain a fresh renderer instance.
297
+ * Use this to support output formats beyond JSX for instance, a Handlebars
298
+ * renderer, a string-template renderer, or a renderer that writes binary
299
+ * files. Plugins and generators pick the renderer to use via the `renderer`
300
+ * field on `defineGenerator`.
145
301
  *
146
- * @example
302
+ * @example A minimal renderer that wraps a custom runtime
147
303
  * ```ts
148
- * // packages/renderer-jsx/src/index.ts
149
- * export const jsxRenderer = createRenderer(() => {
150
- * const runtime = new Runtime()
304
+ * import { createRenderer } from '@kubb/core'
305
+ *
306
+ * export const myRenderer = createRenderer(() => {
307
+ * const runtime = new MyRuntime()
151
308
  * return {
152
- * async render(element) { await runtime.render(element) },
153
- * get files() { return runtime.nodes },
154
- * unmount(error) { runtime.unmount(error) },
309
+ * async render(element) {
310
+ * await runtime.render(element)
311
+ * },
312
+ * get files() {
313
+ * return runtime.files
314
+ * },
315
+ * dispose() {
316
+ * runtime.dispose()
317
+ * },
318
+ * unmount(error) {
319
+ * runtime.dispose(error)
320
+ * },
321
+ * [Symbol.dispose]() {
322
+ * this.dispose()
323
+ * },
155
324
  * }
156
325
  * })
157
- *
158
- * // packages/plugin-zod/src/generators/zodGenerator.tsx
159
- * import { jsxRenderer } from '@kubb/renderer-jsx'
160
- * export const zodGenerator = defineGenerator<PluginZod>({
161
- * name: 'zod',
162
- * renderer: jsxRenderer,
163
- * schema(node, options) { return <File ...>...</File> },
164
- * })
165
326
  * ```
166
327
  */
167
328
  declare function createRenderer<TElement = unknown>(factory: RendererFactory<TElement>): RendererFactory<TElement>;
168
329
  //#endregion
169
330
  //#region src/createStorage.d.ts
331
+ /**
332
+ * Backend that persists generated files. Kubb ships with `fsStorage` (writes
333
+ * to disk) and `memoryStorage` (keeps everything in RAM). Implement this
334
+ * interface to write to S3, a database, or any other target.
335
+ */
170
336
  type Storage = {
171
337
  /**
172
- * Identifier used for logging and debugging (e.g. `'fs'`, `'s3'`).
338
+ * Identifier used in logs and diagnostics (`'fs'`, `'memory'`, `'s3'`).
173
339
  */
174
340
  readonly name: string;
175
341
  /**
176
- * Returns `true` when an entry for `key` exists in storage.
342
+ * Returns `true` when an entry for `key` exists.
177
343
  */
178
344
  hasItem(key: string): Promise<boolean>;
179
345
  /**
180
- * Returns the stored string value, or `null` when `key` does not exist.
346
+ * Reads the stored string. Returns `null` when the key is missing.
181
347
  */
182
348
  getItem(key: string): Promise<string | null>;
183
349
  /**
184
- * Persists `value` under `key`, creating any required structure.
350
+ * Stores `value` under `key`, creating any required structure (directories,
351
+ * buckets, ...).
185
352
  */
186
353
  setItem(key: string, value: string): Promise<void>;
187
354
  /**
188
- * Removes the entry for `key`. No-ops when the key does not exist.
355
+ * Deletes the entry for `key`. No-op when the key does not exist.
189
356
  */
190
357
  removeItem(key: string): Promise<void>;
191
358
  /**
192
- * Returns all keys, optionally filtered to those starting with `base`.
359
+ * Returns every key. Pass `base` to filter to keys starting with that prefix.
193
360
  */
194
361
  getKeys(base?: string): Promise<Array<string>>;
195
362
  /**
196
- * Removes all entries, optionally scoped to those starting with `base`.
363
+ * Removes every entry. Pass `base` to scope the wipe to a key prefix.
197
364
  */
198
365
  clear(base?: string): Promise<void>;
199
366
  /**
200
- * Optional teardown hook called after the build completes.
367
+ * Optional teardown hook called after the build completes. Use to flush
368
+ * buffers, close connections, or release file locks.
201
369
  */
202
370
  dispose?(): Promise<void>;
203
371
  };
204
372
  /**
205
- * Factory for implementing custom storage backends that control where generated files are written.
206
- *
207
- * Takes a builder function `(options: TOptions) => Storage` and returns a factory `(options?: TOptions) => Storage`.
208
- * Kubb provides filesystem and in-memory implementations out of the box.
373
+ * Defines a custom storage backend. The builder receives user options and
374
+ * returns a `Storage` implementation. Kubb ships with filesystem and
375
+ * in-memory storages reach for this when you need to write generated files
376
+ * elsewhere (cloud storage, a database, a remote API).
209
377
  *
210
- * @note Call the returned factory with optional options to instantiate the storage adapter.
211
- *
212
- * @example
378
+ * @example In-memory storage (the built-in implementation)
213
379
  * ```ts
214
380
  * import { createStorage } from '@kubb/core'
215
381
  *
216
382
  * export const memoryStorage = createStorage(() => {
217
383
  * const store = new Map<string, string>()
384
+ *
218
385
  * return {
219
386
  * name: 'memory',
220
- * async hasItem(key) { return store.has(key) },
221
- * async getItem(key) { return store.get(key) ?? null },
222
- * async setItem(key, value) { store.set(key, value) },
223
- * async removeItem(key) { store.delete(key) },
387
+ * async hasItem(key) {
388
+ * return store.has(key)
389
+ * },
390
+ * async getItem(key) {
391
+ * return store.get(key) ?? null
392
+ * },
393
+ * async setItem(key, value) {
394
+ * store.set(key, value)
395
+ * },
396
+ * async removeItem(key) {
397
+ * store.delete(key)
398
+ * },
224
399
  * async getKeys(base) {
225
400
  * const keys = [...store.keys()]
226
401
  * return base ? keys.filter((k) => k.startsWith(base)) : keys
227
402
  * },
228
- * async clear(base) { if (!base) store.clear() },
403
+ * async clear(base) {
404
+ * if (!base) store.clear()
405
+ * },
229
406
  * }
230
407
  * })
231
- *
232
- * // Instantiate:
233
- * const storage = memoryStorage()
234
408
  * ```
235
409
  */
236
410
  declare function createStorage<TOptions = Record<string, never>>(build: (options: TOptions) => Storage): (options?: TOptions) => Storage;
237
411
  //#endregion
238
- //#region src/defineGenerator.d.ts
412
+ //#region src/devtools.d.ts
413
+ type DevtoolsOptions = {
414
+ /**
415
+ * Open the AST inspector in Kubb Studio (`/ast`). Defaults to the main Studio page.
416
+ * @default false
417
+ */
418
+ ast?: boolean;
419
+ };
420
+ //#endregion
421
+ //#region src/defineParser.d.ts
422
+ type PrintOptions = {
423
+ extname?: FileNode['extname'];
424
+ };
239
425
  /**
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.
245
- *
246
- * @note Generators are consumed by plugins and registered via `ctx.addGenerator()` in `kubb:plugin:setup`.
247
- *
248
- * @example
249
- * ```ts
250
- * import { defineGenerator } from '@kubb/core'
251
- * import { jsxRenderer } from '@kubb/renderer-jsx'
252
- *
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>
259
- * },
260
- * })
261
- * ```
426
+ * Converts a resolved {@link FileNode} into the final source string that gets
427
+ * written to disk. Kubb ships with TypeScript and TSX parsers; add your own
428
+ * for new file types (JSON, Markdown, ...).
262
429
  */
263
- type Generator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown> = {
430
+ type Parser<TMeta extends object = any, TNode = unknown> = {
264
431
  /**
265
- * Used in diagnostic messages and debug output.
432
+ * Display name used in diagnostics and the parser registry.
266
433
  */
267
434
  name: string;
268
435
  /**
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).
436
+ * File extensions this parser handles. Set to `undefined` to define a
437
+ * catch-all fallback used when no other parser claims the extension.
278
438
  *
279
439
  * @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).
440
+ * `['.ts', '.js']`
293
441
  */
294
- schema?: (node: SchemaNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
442
+ extNames: Array<FileNode['extname']> | undefined;
295
443
  /**
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).
444
+ * Serialise the file's AST into source code.
299
445
  */
300
- operation?: (node: OperationNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
446
+ parse(file: FileNode<TMeta>, options?: PrintOptions): string;
301
447
  /**
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.
448
+ * Render compiler AST nodes for this parser's language into source text.
449
+ * Plugins call this to format the nodes they assemble before handing them
450
+ * back to the parser as `FileNode.sources`.
305
451
  */
306
- operations?: (nodes: Array<OperationNode>, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | void>;
452
+ print(...nodes: Array<TNode>): string;
307
453
  };
308
454
  /**
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.
455
+ * Defines a parser with type-safe `this`. Used to register handlers for new
456
+ * file extensions or to plug a non-TypeScript output into the build.
457
+ *
458
+ * @example
459
+ * ```ts
460
+ * import { defineParser, ast } from '@kubb/core'
461
+ *
462
+ * export const jsonParser = defineParser({
463
+ * name: 'json',
464
+ * extNames: ['.json'],
465
+ * parse(file) {
466
+ * return file.sources
467
+ * .map((source) => ast.extractStringsFromNodes(source.nodes ?? []))
468
+ * .join('\n')
469
+ * },
470
+ * print(...nodes) {
471
+ * return nodes.map(String).join('\n')
472
+ * },
473
+ * })
474
+ * ```
312
475
  */
313
- declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown>(generator: Generator<TOptions, TElement>): Generator<TOptions, TElement>;
476
+ declare function defineParser<T extends Parser>(parser: T): T;
314
477
  //#endregion
315
- //#region src/definePlugin.d.ts
478
+ //#region src/FileProcessor.d.ts
479
+ type ParseOptions = {
480
+ parsers?: Map<FileNode['extname'], Parser>;
481
+ extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
482
+ };
483
+ type FileProcessorEvents = {
484
+ start: [files: Array<FileNode>];
485
+ update: [params: {
486
+ file: FileNode;
487
+ source?: string;
488
+ processed: number;
489
+ total: number;
490
+ percentage: number;
491
+ }];
492
+ end: [files: Array<FileNode>];
493
+ };
494
+ type ParsedFile = {
495
+ file: FileNode;
496
+ source: string;
497
+ processed: number;
498
+ total: number;
499
+ percentage: number;
500
+ };
316
501
  /**
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).
502
+ * Converts a single file to a string using the registered parsers.
503
+ * Falls back to joining source values when no matching parser is found.
320
504
  *
321
- * @template TFactory - The plugin's `PluginFactoryOptions` type.
505
+ * @internal
322
506
  */
323
- type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
324
- /**
325
- * Unique name for the plugin, following the same naming convention as `createPlugin`.
326
- */
327
- name: string;
507
+ declare class FileProcessor {
508
+ readonly events: AsyncEventEmitter<FileProcessorEvents>;
509
+ parse(file: FileNode, {
510
+ parsers,
511
+ extension
512
+ }?: ParseOptions): string;
513
+ stream(files: ReadonlyArray<FileNode>, options?: ParseOptions): Generator<ParsedFile>;
514
+ run(files: Array<FileNode>, options?: ParseOptions): Promise<Array<FileNode>>;
328
515
  /**
329
- * Plugins that must be registered before this plugin executes.
330
- * An error is thrown at startup when any listed dependency is missing.
516
+ * Clears all registered event listeners.
331
517
  */
332
- dependencies?: Array<string>;
518
+ dispose(): void;
519
+ [Symbol.dispose](): void;
520
+ }
521
+ //#endregion
522
+ //#region src/defineLogger.d.ts
523
+ /**
524
+ * Options accepted by a logger's `install` callback.
525
+ */
526
+ type LoggerOptions = {
333
527
  /**
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`.
528
+ * Output verbosity. Use the `logLevel` constants exported from `@kubb/core`
529
+ * (`silent`, `error`, `warn`, `info`, `verbose`, `debug`).
341
530
  */
342
- enforce?: 'pre' | 'post';
531
+ logLevel: (typeof logLevel)[keyof typeof logLevel];
532
+ };
533
+ /**
534
+ * Event emitter handed to `Logger.install`. Use `.on('kubb:info', ...)` and
535
+ * friends to subscribe to build events.
536
+ */
537
+ type LoggerContext = AsyncEventEmitter<KubbHooks>;
538
+ /**
539
+ * Logger contract. A logger receives the build's event emitter and subscribes
540
+ * to whichever lifecycle events it wants to forward to its destination
541
+ * (console, file, remote sink).
542
+ */
543
+ type Logger<TOptions extends LoggerOptions = LoggerOptions, TInstallReturn = void> = {
343
544
  /**
344
- * The options passed by the user when calling the plugin factory.
545
+ * Display name used in diagnostics.
345
546
  */
346
- options?: TFactory['options'];
547
+ name: string;
347
548
  /**
348
- * Lifecycle event handlers for this plugin.
349
- * Any event from the global `KubbHooks` map can be subscribed to here.
549
+ * Called once per build with the shared event emitter. Subscribe to events
550
+ * here. The return value (if any) is forwarded to whoever installed the
551
+ * logger, which is handy for sink factories.
350
552
  */
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
- };
553
+ install: (context: LoggerContext, options?: TOptions) => TInstallReturn | Promise<TInstallReturn>;
354
554
  };
555
+ type UserLogger<TOptions extends LoggerOptions = LoggerOptions, TInstallReturn = void> = Logger<TOptions, TInstallReturn>;
355
556
  /**
356
- * Wraps a factory function and returns a typed `Plugin` with lifecycle handlers grouped under `hooks`.
557
+ * Defines a typed logger. Use the second type parameter to declare a return
558
+ * value from `install`, which is handy when the logger exposes a sink factory
559
+ * or cleanup callback to the caller.
357
560
  *
358
- * Handlers live in a single `hooks` object (inspired by Astro integrations).
359
- * All lifecycle events from `KubbHooks` are available for subscription.
561
+ * @example Basic logger
562
+ * ```ts
563
+ * import { defineLogger } from '@kubb/core'
360
564
  *
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`).
565
+ * export const myLogger = defineLogger({
566
+ * name: 'my-logger',
567
+ * install(context) {
568
+ * context.on('kubb:info', ({ message }) => console.log('ℹ', message))
569
+ * context.on('kubb:error', ({ error }) => console.error('✗', error.message))
570
+ * },
571
+ * })
572
+ * ```
363
573
  *
364
- * @example
574
+ * @example Logger that returns a hook sink factory
365
575
  * ```ts
366
- * import { definePlugin } from '@kubb/core'
367
- *
368
- * export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
369
- * name: 'plugin-ts',
370
- * hooks: {
371
- * 'kubb:plugin:setup'(ctx) {
372
- * ctx.setResolver(resolverTs)
373
- * },
576
+ * import { defineLogger, type LoggerOptions } from '@kubb/core'
577
+ * import type { HookSinkFactory } from './sinks'
578
+ *
579
+ * export const myLogger = defineLogger<LoggerOptions, HookSinkFactory>({
580
+ * name: 'my-logger',
581
+ * install(context) {
582
+ * // … register event handlers …
583
+ * return () => ({ onStdout: console.log })
374
584
  * },
375
- * }))
585
+ * })
376
586
  * ```
377
587
  */
378
- declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
588
+ declare function defineLogger<Options extends LoggerOptions = LoggerOptions, TInstallReturn = void>(logger: UserLogger<Options, TInstallReturn>): Logger<Options, TInstallReturn>;
379
589
  //#endregion
380
- //#region src/FileManager.d.ts
590
+ //#region src/defineMiddleware.d.ts
591
+ /**
592
+ * A middleware instance. Subscribes to lifecycle events via `hooks`. Middleware
593
+ * handlers always fire after every plugin handler for the same event, so they
594
+ * see the full set of generated files.
595
+ */
596
+ type Middleware = {
597
+ /**
598
+ * Unique name. Use a `middleware-<feature>` convention (e.g.
599
+ * `middleware-barrel`).
600
+ */
601
+ name: string;
602
+ /**
603
+ * Lifecycle event handlers. Any event from the global `KubbHooks` map can be
604
+ * subscribed to here. Handlers run after all plugin handlers for that event.
605
+ */
606
+ hooks: { [K in keyof KubbHooks]?: (...args: KubbHooks[K]) => void | Promise<void> };
607
+ };
608
+ /**
609
+ * Creates a middleware factory. Middleware fires after every plugin handler
610
+ * for the same event, which makes it the natural place for post-processing
611
+ * (barrel files, lint runs, audit logs).
612
+ *
613
+ * Per-build state belongs inside the factory closure so each `createKubb`
614
+ * invocation gets its own isolated instance.
615
+ *
616
+ * @example Stateless middleware
617
+ * ```ts
618
+ * import { defineMiddleware } from '@kubb/core'
619
+ *
620
+ * export const logMiddleware = defineMiddleware(() => ({
621
+ * name: 'log-middleware',
622
+ * hooks: {
623
+ * 'kubb:build:end'({ files }) {
624
+ * console.log(`Build complete with ${files.length} files`)
625
+ * },
626
+ * },
627
+ * }))
628
+ * ```
629
+ *
630
+ * @example Middleware with options and per-build state
631
+ * ```ts
632
+ * import { defineMiddleware } from '@kubb/core'
633
+ *
634
+ * export const prefixMiddleware = defineMiddleware((options: { prefix: string } = { prefix: '' }) => {
635
+ * const seen = new Set<string>()
636
+ * return {
637
+ * name: 'prefix-middleware',
638
+ * hooks: {
639
+ * 'kubb:plugin:end'({ plugin }) {
640
+ * seen.add(`${options.prefix}${plugin.name}`)
641
+ * },
642
+ * },
643
+ * }
644
+ * })
645
+ * ```
646
+ */
647
+ declare function defineMiddleware<TOptions extends object = object>(factory: (options: TOptions) => Middleware): (options?: TOptions) => Middleware;
648
+ //#endregion
649
+ //#region src/defineResolver.d.ts
650
+ /**
651
+ * Type/string pattern filter for include/exclude/override matching.
652
+ */
653
+ type PatternFilter = {
654
+ type: string;
655
+ pattern: string | RegExp;
656
+ };
657
+ /**
658
+ * Pattern filter with partial option overrides applied when the pattern matches.
659
+ */
660
+ type PatternOverride<TOptions> = PatternFilter & {
661
+ options: Omit<Partial<TOptions>, 'override'>;
662
+ };
663
+ /**
664
+ * Context for resolving filtered options for a given operation or schema node.
665
+ *
666
+ * @internal
667
+ */
668
+ type ResolveOptionsContext<TOptions> = {
669
+ options: TOptions;
670
+ exclude?: Array<PatternFilter>;
671
+ include?: Array<PatternFilter>;
672
+ override?: Array<PatternOverride<TOptions>>;
673
+ };
674
+ /**
675
+ * Base constraint for all plugin resolver objects.
676
+ *
677
+ * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
678
+ * are injected automatically by `defineResolver` — extend this type to add custom resolution methods.
679
+ *
680
+ * @example
681
+ * ```ts
682
+ * type MyResolver = Resolver & {
683
+ * resolveName(node: SchemaNode): string
684
+ * resolveTypedName(node: SchemaNode): string
685
+ * }
686
+ * ```
687
+ */
688
+ type Resolver = {
689
+ name: string;
690
+ pluginName: string;
691
+ default(name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
692
+ resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null;
693
+ resolvePath(params: ResolverPathParams, context: ResolverContext): string;
694
+ resolveFile(params: ResolverFileParams, context: ResolverContext): FileNode;
695
+ resolveBanner(meta: InputMeta | undefined, context: ResolveBannerContext): string | null;
696
+ resolveFooter(meta: InputMeta | undefined, context: ResolveBannerContext): string | null;
697
+ };
698
+ /**
699
+ * File-specific parameters for `Resolver.resolvePath`.
700
+ *
701
+ * Pass alongside a `ResolverContext` to identify which file to resolve.
702
+ * Provide `tag` for tag-based grouping or `path` for path-based grouping.
703
+ *
704
+ * @example
705
+ * ```ts
706
+ * resolver.resolvePath(
707
+ * { baseName: 'petTypes.ts', tag: 'pets' },
708
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
709
+ * )
710
+ * // → '/src/types/petsController/petTypes.ts'
711
+ * ```
712
+ */
713
+ type ResolverPathParams = {
714
+ baseName: FileNode['baseName'];
715
+ pathMode?: 'single' | 'split';
716
+ /**
717
+ * Tag value used when `group.type === 'tag'`.
718
+ */
719
+ tag?: string;
720
+ /**
721
+ * Path value used when `group.type === 'path'`.
722
+ */
723
+ path?: string;
724
+ };
725
+ /**
726
+ * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
727
+ *
728
+ * Describes where on disk output is rooted, which output config is active, and the optional
729
+ * grouping strategy that controls subdirectory layout.
730
+ *
731
+ * @example
732
+ * ```ts
733
+ * const context: ResolverContext = {
734
+ * root: config.root,
735
+ * output,
736
+ * group,
737
+ * }
738
+ * ```
739
+ */
740
+ type ResolverContext = {
741
+ root: string;
742
+ output: Output;
743
+ group?: Group;
744
+ /**
745
+ * Plugin name used to populate `meta.pluginName` on the resolved file.
746
+ */
747
+ pluginName?: string;
748
+ };
749
+ /**
750
+ * File-specific parameters for `Resolver.resolveFile`.
751
+ *
752
+ * Pass alongside a `ResolverContext` to fully describe the file to resolve.
753
+ * `tag` and `path` are used only when a matching `group` is present in the context.
754
+ *
755
+ * @example
756
+ * ```ts
757
+ * resolver.resolveFile(
758
+ * { name: 'listPets', extname: '.ts', tag: 'pets' },
759
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
760
+ * )
761
+ * // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
762
+ * ```
763
+ */
764
+ type ResolverFileParams = {
765
+ name: string;
766
+ extname: FileNode['extname'];
767
+ /**
768
+ * Tag value used when `group.type === 'tag'`.
769
+ */
770
+ tag?: string;
771
+ /**
772
+ * Path value used when `group.type === 'path'`.
773
+ */
774
+ path?: string;
775
+ };
776
+ /**
777
+ * Per-file context describing the file a banner/footer is being resolved for.
778
+ *
779
+ * Supplied by the generator (or the barrel middleware) at resolve-time and merged
780
+ * into `BannerMeta` so a `banner`/`footer` function can branch on the file kind —
781
+ * e.g. omit a `'use server'` directive on re-export files.
782
+ */
783
+ type ResolveBannerFile = {
784
+ /**
785
+ * Full output path of the file being generated.
786
+ */
787
+ path: string;
788
+ /**
789
+ * File name only, e.g. `'stocks.ts'`.
790
+ */
791
+ baseName: string;
792
+ /**
793
+ * `true` for `index.ts` re-export barrels.
794
+ */
795
+ isBarrel?: boolean;
796
+ /**
797
+ * `true` for group `[dir]/[dir].ts` aggregation files.
798
+ */
799
+ isAggregation?: boolean;
800
+ };
801
+ /**
802
+ * Document metadata extended with per-file context, passed to a `banner`/`footer` function.
803
+ *
804
+ * Carries everything in {@link InputMeta} plus the file the banner is rendered into, so a
805
+ * single function can decide per file (e.g. skip a directive on barrel/aggregation files).
806
+ *
807
+ * @example Skip a directive on re-export files
808
+ * `banner: (meta) => (meta.isBarrel || meta.isAggregation) ? '' : "'use server'"`
809
+ */
810
+ type BannerMeta = InputMeta & {
811
+ /**
812
+ * Full output path of the file being generated.
813
+ */
814
+ filePath: string;
815
+ /**
816
+ * File name only, e.g. `'stocks.ts'`.
817
+ */
818
+ baseName: string;
819
+ /**
820
+ * `true` for `index.ts` re-export barrels.
821
+ */
822
+ isBarrel: boolean;
823
+ /**
824
+ * `true` for group `[dir]/[dir].ts` aggregation files.
825
+ */
826
+ isAggregation: boolean;
827
+ };
828
+ /**
829
+ * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
830
+ *
831
+ * `output` is optional — not every plugin configures a banner/footer.
832
+ * `config` carries the global Kubb config, used to derive the default Kubb banner.
833
+ * `file` carries per-file context forwarded to a `banner`/`footer` function.
834
+ *
835
+ * @example
836
+ * ```ts
837
+ * resolver.resolveBanner(meta, { output: { banner: '// generated' }, config })
838
+ * // → '// generated'
839
+ * ```
840
+ */
841
+ type ResolveBannerContext = {
842
+ output?: Pick<Output, 'banner' | 'footer'>;
843
+ config: Config;
844
+ file?: ResolveBannerFile;
845
+ };
846
+ /**
847
+ * Builder type for the plugin-specific resolver fields.
848
+ *
849
+ * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
850
+ * are optional — built-in fallbacks are injected when omitted.
851
+ *
852
+ * Methods in the returned object can call sibling resolver methods via `this`.
853
+ */
854
+ 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'>> & {
855
+ name: string;
856
+ pluginName: T['name'];
857
+ } & ThisType<T['resolver']>;
858
+ /**
859
+ * Defines a plugin resolver. The resolver is the object that decides what
860
+ * every generated symbol and file path is called. Built-in defaults handle
861
+ * name casing, include/exclude/override filtering, output path computation,
862
+ * and file construction. Supply your own to override any of them:
863
+ *
864
+ * - `default` — name casing strategy (camelCase / PascalCase).
865
+ * - `resolveOptions` — include/exclude/override filtering.
866
+ * - `resolvePath` — output path computation.
867
+ * - `resolveFile` — full `FileNode` construction.
868
+ * - `resolveBanner` / `resolveFooter` — top/bottom-of-file text.
869
+ *
870
+ * Methods in the returned object can call sibling resolver methods via `this`,
871
+ * which keeps custom rules small (`this.default(name, 'type')` to delegate).
872
+ *
873
+ * @example Basic resolver with naming helpers
874
+ * ```ts
875
+ * export const resolverTs = defineResolver<PluginTs>(() => ({
876
+ * name: 'default',
877
+ * resolveName(name) {
878
+ * return this.default(name, 'function')
879
+ * },
880
+ * resolveTypeName(name) {
881
+ * return this.default(name, 'type')
882
+ * },
883
+ * }))
884
+ * ```
885
+ *
886
+ * @example Custom output path
887
+ * ```ts
888
+ * import path from 'node:path'
889
+ *
890
+ * export const resolverTs = defineResolver<PluginTs>(() => ({
891
+ * name: 'custom',
892
+ * resolvePath({ baseName }, { root, output }) {
893
+ * return path.resolve(root, output.path, 'generated', baseName)
894
+ * },
895
+ * }))
896
+ * ```
897
+ */
898
+ declare function defineResolver<T extends PluginFactoryOptions>(build: ResolverBuilder<T>): T['resolver'];
899
+ //#endregion
900
+ //#region src/definePlugin.d.ts
901
+ /**
902
+ * Safely extracts a type from a registry, returning `{}` if the key doesn't exist.
903
+ * Enables optional interface augmentation for `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
904
+ * without requiring changes to core.
905
+ *
906
+ * @internal
907
+ */
908
+ type ExtractRegistryKey$1<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
909
+ /**
910
+ * Output configuration shared by every plugin. Each plugin extends this with
911
+ * its own keys via the `Kubb.PluginOptionsRegistry.output` interface merge.
912
+ */
913
+ type Output<_TOptions = unknown> = {
914
+ /**
915
+ * Folder (or single file) where the plugin writes its generated code.
916
+ * Resolved against the global `output.path` set on `defineConfig`.
917
+ */
918
+ path: string;
919
+ /**
920
+ * Text prepended to every generated file. Useful for license headers,
921
+ * lint disables, or `@ts-nocheck` directives.
922
+ *
923
+ * A string is applied to every file (including barrel and aggregation re-export files).
924
+ * Pass a function to compute the banner from the file's `BannerMeta` — document metadata
925
+ * plus per-file context (`isBarrel`, `isAggregation`, `filePath`, `baseName`) — so you can
926
+ * skip the banner on specific files.
927
+ *
928
+ * @example Add a directive to source files but not re-export files
929
+ * `banner: (meta) => (meta.isBarrel || meta.isAggregation) ? '' : "'use server'"`
930
+ */
931
+ banner?: string | ((meta: BannerMeta) => string);
932
+ /**
933
+ * Text appended at the end of every generated file. Mirror of `banner`.
934
+ * Pass a function to compute the footer from the file's `BannerMeta`.
935
+ */
936
+ footer?: string | ((meta: BannerMeta) => string);
937
+ /**
938
+ * Allows the plugin to overwrite hand-written files at the same path.
939
+ * Defaults to `false` to protect manual edits.
940
+ *
941
+ * @default false
942
+ */
943
+ override?: boolean;
944
+ } & ExtractRegistryKey$1<Kubb.PluginOptionsRegistry, 'output'>;
945
+ /**
946
+ * Groups generated files into subdirectories based on an OpenAPI tag or path
947
+ * segment.
948
+ */
949
+ type Group = {
950
+ /**
951
+ * Property used to assign each operation to a group.
952
+ * - `'tag'` — uses the first tag (`operation.getTags().at(0)?.name`).
953
+ * - `'path'` — uses the first segment of the operation's URL.
954
+ */
955
+ type: 'tag' | 'path';
956
+ /**
957
+ * Returns the subdirectory name from the group key. Defaults to
958
+ * `${camelCase(group)}Controller` for tags, or the first path segment.
959
+ */
960
+ name?: (context: {
961
+ group: string;
962
+ }) => string;
963
+ };
964
+ type ByTag = {
965
+ /**
966
+ * Filter by OpenAPI `tags` field. Matches one or more tags assigned to operations.
967
+ */
968
+ type: 'tag';
969
+ /**
970
+ * Tag name to match (case-sensitive). Can be a literal string or regex pattern.
971
+ */
972
+ pattern: string | RegExp;
973
+ };
974
+ type ByOperationId = {
975
+ /**
976
+ * Filter by OpenAPI `operationId` field. Each operation (GET, POST, etc.) has a unique identifier.
977
+ */
978
+ type: 'operationId';
979
+ /**
980
+ * Operation ID to match (case-sensitive). Can be a literal string or regex pattern.
981
+ */
982
+ pattern: string | RegExp;
983
+ };
984
+ type ByPath = {
985
+ /**
986
+ * Filter by OpenAPI `path` (URL endpoint). Useful to group or filter by service segments like `/pets`, `/users`, etc.
987
+ */
988
+ type: 'path';
989
+ /**
990
+ * URL path to match (case-sensitive). Can be a literal string or regex pattern. Matches against the full path.
991
+ */
992
+ pattern: string | RegExp;
993
+ };
994
+ type ByMethod = {
995
+ /**
996
+ * Filter by HTTP method: `'get'`, `'post'`, `'put'`, `'delete'`, `'patch'`, `'head'`, `'options'`.
997
+ */
998
+ type: 'method';
999
+ /**
1000
+ * HTTP method to match (case-insensitive when using string, or regex for dynamic matching).
1001
+ */
1002
+ pattern: HttpMethod | RegExp;
1003
+ };
1004
+ type BySchemaName = {
1005
+ /**
1006
+ * Filter by schema component name (TypeScript or JSON schema). Matches schemas in `#/components/schemas`.
1007
+ */
1008
+ type: 'schemaName';
1009
+ /**
1010
+ * Schema name to match (case-sensitive). Can be a literal string or regex pattern.
1011
+ */
1012
+ pattern: string | RegExp;
1013
+ };
1014
+ type ByContentType = {
1015
+ /**
1016
+ * Filter by response or request content type: `'application/json'`, `'application/xml'`, etc.
1017
+ */
1018
+ type: 'contentType';
1019
+ /**
1020
+ * Content type to match (case-sensitive). Can be a literal string or regex pattern.
1021
+ */
1022
+ pattern: string | RegExp;
1023
+ };
1024
+ /**
1025
+ * Filter that skips matching operations or schemas during generation. Use it
1026
+ * to drop deprecated endpoints, internal-only schemas, or anything you do
1027
+ * not want code generated for.
1028
+ *
1029
+ * @example
1030
+ * ```ts
1031
+ * exclude: [
1032
+ * { type: 'tag', pattern: 'internal' },
1033
+ * { type: 'path', pattern: /^\/admin/ },
1034
+ * { type: 'operationId', pattern: /^deprecated_/ },
1035
+ * ]
1036
+ * ```
1037
+ */
1038
+ type Exclude = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1039
+ /**
1040
+ * Filter that restricts generation to operations or schemas matching at least
1041
+ * one entry. Useful for partial builds (one tag, one API version).
1042
+ *
1043
+ * @example
1044
+ * ```ts
1045
+ * include: [
1046
+ * { type: 'tag', pattern: 'public' },
1047
+ * { type: 'path', pattern: /^\/api\/v1/ },
1048
+ * ]
1049
+ * ```
1050
+ */
1051
+ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1052
+ /**
1053
+ * Filter paired with a partial options object. When the filter matches, the
1054
+ * options are merged on top of the plugin defaults for that operation only.
1055
+ * Useful for "this one tag goes to a different folder" rules.
1056
+ *
1057
+ * Entries are evaluated top to bottom; the first matching entry wins.
1058
+ *
1059
+ * @example
1060
+ * ```ts
1061
+ * override: [
1062
+ * {
1063
+ * type: 'tag',
1064
+ * pattern: 'admin',
1065
+ * options: { output: { path: './src/gen/admin' } },
1066
+ * },
1067
+ * {
1068
+ * type: 'operationId',
1069
+ * pattern: 'listPets',
1070
+ * options: { enumType: 'literal' },
1071
+ * },
1072
+ * ]
1073
+ * ```
1074
+ */
1075
+ type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
1076
+ options: Partial<TOptions>;
1077
+ };
1078
+ type PluginFactoryOptions<
1079
+ /**
1080
+ * Unique plugin name.
1081
+ */
1082
+ TName extends string = string,
1083
+ /**
1084
+ * User-facing plugin options.
1085
+ */
1086
+ TOptions extends object = object,
1087
+ /**
1088
+ * Plugin options after defaults are applied.
1089
+ */
1090
+ TResolvedOptions extends object = TOptions,
1091
+ /**
1092
+ * Resolver that encapsulates naming and path-resolution helpers.
1093
+ * Define with `defineResolver` and export alongside the plugin.
1094
+ */
1095
+ TResolver extends Resolver = Resolver> = {
1096
+ name: TName;
1097
+ options: TOptions;
1098
+ resolvedOptions: TResolvedOptions;
1099
+ resolver: TResolver;
1100
+ };
1101
+ /**
1102
+ * Context for hook-style plugin `kubb:plugin:setup` handler.
1103
+ * Provides methods to register generators, configure resolvers, transformers, and renderers.
1104
+ */
1105
+ type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1106
+ /**
1107
+ * Register a generator dynamically. Generators fire during the AST walk (schema/operation/operations)
1108
+ * just like generators declared statically on `createPlugin`.
1109
+ */
1110
+ addGenerator<TElement = unknown>(generator: Generator$1<TFactory, TElement>): void;
1111
+ /**
1112
+ * Set or override the resolver for this plugin.
1113
+ * The resolver controls file naming and path resolution.
1114
+ */
1115
+ setResolver(resolver: Partial<TFactory['resolver']>): void;
1116
+ /**
1117
+ * Set the AST transformer to pre-process nodes before they reach generators.
1118
+ */
1119
+ setTransformer(visitor: Visitor): void;
1120
+ /**
1121
+ * Set the renderer factory to process JSX elements from generators.
1122
+ */
1123
+ setRenderer(renderer: RendererFactory): void;
1124
+ /**
1125
+ * Set resolved options merged into the normalized plugin's `options`.
1126
+ * Call this in `kubb:plugin:setup` to provide options generators need.
1127
+ */
1128
+ setOptions(options: TFactory['resolvedOptions']): void;
1129
+ /**
1130
+ * Inject a raw file into the build output, bypassing the generation pipeline.
1131
+ */
1132
+ injectFile(userFileNode: UserFileNode): void;
1133
+ /**
1134
+ * Merge a partial config update into the current build configuration.
1135
+ */
1136
+ updateConfig(config: Partial<Config>): void;
1137
+ /**
1138
+ * The resolved build configuration at setup time.
1139
+ */
1140
+ config: Config;
1141
+ /**
1142
+ * The plugin's user-provided options.
1143
+ */
1144
+ options: TFactory['options'];
1145
+ };
1146
+ /**
1147
+ * A plugin object produced by `definePlugin`.
1148
+ * Instead of flat lifecycle methods, it groups all handlers under a `hooks:` property
1149
+ * (matching Astro's integration naming convention).
1150
+ *
1151
+ * @template TFactory - The plugin's `PluginFactoryOptions` type.
1152
+ */
1153
+ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1154
+ /**
1155
+ * Unique name for the plugin, following the same naming convention as `createPlugin`.
1156
+ */
1157
+ name: string;
1158
+ /**
1159
+ * Plugins that must be registered before this plugin executes.
1160
+ * An error is thrown at startup when any listed dependency is missing.
1161
+ */
1162
+ dependencies?: Array<string>;
1163
+ /**
1164
+ * Controls the execution order of this plugin relative to others.
1165
+ *
1166
+ * - `'pre'` — runs before all normal plugins.
1167
+ * - `'post'` — runs after all normal plugins.
1168
+ * - `undefined` (default) — runs in declaration order among normal plugins.
1169
+ *
1170
+ * Dependency constraints always take precedence over `enforce`.
1171
+ */
1172
+ enforce?: 'pre' | 'post';
1173
+ /**
1174
+ * The options passed by the user when calling the plugin factory.
1175
+ */
1176
+ options?: TFactory['options'];
1177
+ /**
1178
+ * Lifecycle event handlers for this plugin.
1179
+ * Any event from the global `KubbHooks` map can be subscribed to here.
1180
+ */
1181
+ hooks: { [K in keyof KubbHooks as K extends 'kubb:plugin:setup' ? never : K]?: (...args: KubbHooks[K]) => void | Promise<void> } & {
1182
+ 'kubb:plugin:setup'?(ctx: KubbPluginSetupContext<TFactory>): void | Promise<void>;
1183
+ };
1184
+ };
1185
+ /**
1186
+ * Normalized plugin after setup, with runtime fields populated.
1187
+ * For internal use only — plugins use the public `Plugin` type externally.
1188
+ *
1189
+ * @internal
1190
+ */
1191
+ type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & {
1192
+ options: TOptions['resolvedOptions'] & {
1193
+ output: Output;
1194
+ include?: Array<Include>;
1195
+ exclude: Array<Exclude>;
1196
+ override: Array<Override<TOptions['resolvedOptions']>>;
1197
+ };
1198
+ resolver: TOptions['resolver'];
1199
+ transformer?: Visitor;
1200
+ renderer?: RendererFactory;
1201
+ generators?: Array<Generator$1>;
1202
+ apply?: (config: Config) => boolean;
1203
+ version?: string;
1204
+ };
1205
+ type KubbPluginStartContext = {
1206
+ plugin: NormalizedPlugin;
1207
+ };
1208
+ type KubbPluginEndContext = {
1209
+ plugin: NormalizedPlugin;
1210
+ duration: number;
1211
+ success: boolean;
1212
+ error?: Error;
1213
+ config: Config;
1214
+ /**
1215
+ * Returns all files currently in the file manager (lazy snapshot).
1216
+ * Includes files added by plugins that have already run.
1217
+ */
1218
+ readonly files: ReadonlyArray<FileNode>;
1219
+ /**
1220
+ * Upsert one or more files into the file manager.
1221
+ */
1222
+ upsertFile: (...files: Array<FileNode>) => void;
1223
+ };
381
1224
  /**
382
- * In-memory file store for generated files.
1225
+ * Wraps a plugin factory and returns a function that accepts user options and
1226
+ * yields a fully typed `Plugin`. Lifecycle handlers go inside a single
1227
+ * `hooks` object (inspired by Astro integrations).
383
1228
  *
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).
1229
+ * Pass a `PluginFactoryOptions` type parameter to get a typed `ctx` inside
1230
+ * `kubb:plugin:setup`. Plugin names should follow the `plugin-<feature>`
1231
+ * convention (`plugin-react-query`, `plugin-zod`, ...).
386
1232
  *
387
1233
  * @example
388
1234
  * ```ts
389
- * import { FileManager } from '@kubb/core'
1235
+ * import { definePlugin } from '@kubb/core'
390
1236
  *
1237
+ * export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
1238
+ * name: 'plugin-ts',
1239
+ * hooks: {
1240
+ * 'kubb:plugin:setup'(ctx) {
1241
+ * ctx.setResolver(resolverTs)
1242
+ * },
1243
+ * },
1244
+ * }))
1245
+ * ```
1246
+ */
1247
+ declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
1248
+ //#endregion
1249
+ //#region src/FileManager.d.ts
1250
+ /**
1251
+ * In-memory file store for generated files. Files sharing a `path` are merged
1252
+ * (sources/imports/exports concatenated). The `files` getter is sorted by
1253
+ * path length (barrel `index.ts` last within a bucket).
1254
+ *
1255
+ * @example
1256
+ * ```ts
391
1257
  * const manager = new FileManager()
392
1258
  * manager.upsert(myFile)
393
- * console.log(manager.files) // all stored files
1259
+ * manager.files // sorted view
394
1260
  * ```
395
1261
  */
396
1262
  declare class FileManager {
397
1263
  #private;
398
1264
  /**
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.
1265
+ * Registers a callback invoked with the resolved {@link FileNode} on every
1266
+ * `add` / `upsert`. Used by the build loop to track newly written files
1267
+ * without keeping its own scan-based diff. Single subscriber by design
1268
+ * setting again replaces the previous callback. Pass `null` to detach.
402
1269
  */
1270
+ setOnUpsert(callback: ((file: FileNode) => void) | null): void;
403
1271
  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
1272
  upsert(...files: Array<FileNode>): Array<FileNode>;
410
1273
  getByPath(path: string): FileNode | null;
411
1274
  deleteByPath(path: string): void;
412
1275
  clear(): void;
413
1276
  /**
414
- * All stored files, sorted by path length (shorter paths first).
1277
+ * Releases all stored files. Called by the core after `kubb:build:end`.
1278
+ */
1279
+ dispose(): void;
1280
+ [Symbol.dispose](): void;
1281
+ /**
1282
+ * All stored files in stable sort order (shortest path first, barrel files
1283
+ * last within a length bucket). Returns a cached view — do not mutate.
415
1284
  */
416
1285
  get files(): Array<FileNode>;
417
1286
  }
418
1287
  //#endregion
419
- //#region src/PluginDriver.d.ts
1288
+ //#region src/KubbDriver.d.ts
420
1289
  type Options = {
421
1290
  hooks: AsyncEventEmitter<KubbHooks>;
422
1291
  };
423
- declare class PluginDriver {
1292
+ declare class KubbDriver {
424
1293
  #private;
425
1294
  readonly config: Config;
426
1295
  readonly options: Options;
@@ -429,17 +1298,17 @@ declare class PluginDriver {
429
1298
  *
430
1299
  * @example
431
1300
  * ```ts
432
- * PluginDriver.getMode('src/gen/types.ts') // 'single'
433
- * PluginDriver.getMode('src/gen/types') // 'split'
1301
+ * KubbDriver.getMode('src/gen/types.ts') // 'single'
1302
+ * KubbDriver.getMode('src/gen/types') // 'split'
434
1303
  * ```
435
1304
  */
436
1305
  static getMode(fileOrFolder: string | undefined | null): 'single' | 'split';
437
1306
  /**
438
- * The universal `@kubb/ast` `InputNode` produced by the adapter, set by
439
- * the build pipeline after the adapter's `parse()` resolves.
1307
+ * The streaming `InputStreamNode` produced by the adapter.
1308
+ * Always set after adapter setup — parse-only adapters are wrapped automatically.
440
1309
  */
441
- inputNode: InputNode | undefined;
442
- adapter: Adapter | undefined;
1310
+ inputNode: InputStreamNode | null;
1311
+ adapter: Adapter | null;
443
1312
  /**
444
1313
  * Central file store for all generated files.
445
1314
  * Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
@@ -448,23 +1317,8 @@ declare class PluginDriver {
448
1317
  readonly fileManager: FileManager;
449
1318
  readonly plugins: Map<string, NormalizedPlugin>;
450
1319
  constructor(config: Config, options: Options);
1320
+ setup(): Promise<void>;
451
1321
  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
1322
  /**
469
1323
  * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
470
1324
  * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
@@ -486,7 +1340,7 @@ declare class PluginDriver {
486
1340
  *
487
1341
  * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
488
1342
  */
489
- registerGenerator(pluginName: string, gen: Generator): void;
1343
+ registerGenerator(pluginName: string, gen: Generator$1): void;
490
1344
  /**
491
1345
  * Returns `true` when at least one generator was registered for the given plugin
492
1346
  * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
@@ -494,7 +1348,24 @@ declare class PluginDriver {
494
1348
  * Used by the build loop to decide whether to walk the AST and emit generator events
495
1349
  * for a plugin that has no static `plugin.generators`.
496
1350
  */
497
- hasRegisteredGenerators(pluginName: string): boolean;
1351
+ hasEventGenerators(pluginName: string): boolean;
1352
+ /**
1353
+ * Runs the full plugin pipeline. Returns timings/failures collected so far even
1354
+ * when an outer hook throws — the orchestrator preserves partial state by capturing
1355
+ * the error into `error` instead of propagating.
1356
+ */
1357
+ run({
1358
+ storage
1359
+ }: {
1360
+ storage: Storage;
1361
+ }): Promise<{
1362
+ failedPlugins: Set<{
1363
+ plugin: Plugin;
1364
+ error: Error;
1365
+ }>;
1366
+ pluginTimings: Map<string, number>;
1367
+ error?: Error;
1368
+ }>;
498
1369
  /**
499
1370
  * Unregisters all plugin lifecycle listeners from the shared event emitter.
500
1371
  * Called at the end of a build to prevent listener leaks across repeated builds.
@@ -502,6 +1373,7 @@ declare class PluginDriver {
502
1373
  * @internal
503
1374
  */
504
1375
  dispose(): void;
1376
+ [Symbol.dispose](): void;
505
1377
  /**
506
1378
  * Merges `partial` with the plugin's default resolver and stores the result.
507
1379
  * Also mirrors it onto `plugin.resolver` so callers using `getPlugin(name).resolver`
@@ -526,407 +1398,194 @@ declare class PluginDriver {
526
1398
  requirePlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(pluginName: string): Plugin<TOptions>;
527
1399
  }
528
1400
  //#endregion
529
- //#region src/createKubb.d.ts
530
- /**
531
- * Full output produced by a successful or failed build.
532
- */
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>;
552
- };
553
- type CreateKubbOptions = {
554
- hooks?: AsyncEventEmitter<KubbHooks>;
555
- };
556
- /**
557
- * Creates a Kubb instance bound to a single config entry.
558
- *
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()`.
563
- *
564
- * @example
565
- * ```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()
573
- * ```
574
- */
575
- declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
576
- //#endregion
577
- //#region src/Kubb.d.ts
578
- /**
579
- * Kubb code generation instance returned by {@link createKubb}.
580
- *
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()`.
583
- */
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>;
593
- /**
594
- * Plugin driver managing all plugins. Available after `setup()` completes.
595
- */
596
- readonly driver: PluginDriver | undefined;
597
- /**
598
- * Resolved configuration with defaults applied. Available after `setup()` completes.
599
- */
600
- readonly config: Config | undefined;
601
- /**
602
- * Resolves config and initializes the driver. `build()` calls this automatically.
603
- */
604
- setup(): Promise<void>;
605
- /**
606
- * Runs the full pipeline and throws on any plugin error. Automatically calls `setup()` if needed.
607
- */
608
- build(): Promise<BuildOutput>;
609
- /**
610
- * Runs the full pipeline and captures errors in `BuildOutput` instead of throwing. Automatically calls `setup()` if needed.
611
- */
612
- safeBuild(): Promise<BuildOutput>;
613
- };
1401
+ //#region src/defineGenerator.d.ts
614
1402
  /**
615
- * Lifecycle events emitted during Kubb code generation.
616
- * Use these for logging, progress tracking, and custom integrations.
617
- *
618
- * @example
619
- * ```typescript
620
- * import type { AsyncEventEmitter } from '@internals/utils'
621
- * import type { KubbHooks } from '@kubb/core'
622
- *
623
- * const hooks: AsyncEventEmitter<KubbHooks> = new AsyncEventEmitter()
624
- *
625
- * hooks.on('kubb:lifecycle:start', () => {
626
- * console.log('Starting Kubb generation')
627
- * })
1403
+ * Context object passed to generator `schema`, `operation`, and `operations` methods.
628
1404
  *
629
- * hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
630
- * console.log(`Plugin ${plugin.name} completed in ${duration}ms`)
631
- * })
632
- * ```
1405
+ * The adapter is always defined (guaranteed by `runPluginAstHooks`) so no runtime checks
1406
+ * are needed. `ctx.options` carries resolved per-node options after exclude/include/override
1407
+ * filtering for individual schema/operation calls, or plugin-level options for operations.
633
1408
  */
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': [];
671
- /**
672
- * Fires when linting starts.
673
- */
674
- 'kubb:lint:start': [];
675
- /**
676
- * Fires when linting completes.
677
- */
678
- 'kubb:lint:end': [];
679
- /**
680
- * Fires when plugin hooks execution starts.
681
- */
682
- 'kubb:hooks:start': [];
683
- /**
684
- * Fires when plugin hooks execution completes.
685
- */
686
- 'kubb:hooks:end': [];
687
- /**
688
- * Fires when a single hook executes (e.g., format or lint). The callback is invoked when the command finishes.
689
- */
690
- 'kubb:hook:start': [ctx: KubbHookStartContext];
691
- /**
692
- * Fires when a single hook execution completes.
693
- */
694
- 'kubb:hook:end': [ctx: KubbHookEndContext];
695
- /**
696
- * Fires when a new Kubb version is available.
697
- */
698
- 'kubb:version:new': [ctx: KubbVersionNewContext];
699
- /**
700
- * Informational message event.
701
- */
702
- 'kubb:info': [ctx: KubbInfoContext];
703
- /**
704
- * Error event, fired when an error occurs during generation.
705
- */
706
- 'kubb:error': [ctx: KubbErrorContext];
1409
+ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
1410
+ config: Config;
707
1411
  /**
708
- * Success message event.
1412
+ * Absolute path to the current plugin's output directory.
709
1413
  */
710
- 'kubb:success': [ctx: KubbSuccessContext];
1414
+ root: string;
711
1415
  /**
712
- * Warning message event.
1416
+ * Determine output mode based on the output config.
1417
+ * Returns `'single'` when `output.path` is a file, `'split'` for a directory.
713
1418
  */
714
- 'kubb:warn': [ctx: KubbWarnContext];
1419
+ getMode: (output: {
1420
+ path: string;
1421
+ }) => 'single' | 'split';
1422
+ driver: KubbDriver;
715
1423
  /**
716
- * Debug event for detailed logging with timestamp and optional filename.
1424
+ * Get a plugin by name, typed via `Kubb.PluginRegistry` when registered.
717
1425
  */
718
- 'kubb:debug': [ctx: KubbDebugContext];
1426
+ getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
1427
+ getPlugin(name: string): Plugin | undefined;
719
1428
  /**
720
- * Fires when file processing starts with the list of files to process.
1429
+ * Get a plugin by name, throws an error if not found.
721
1430
  */
722
- 'kubb:files:processing:start': [ctx: KubbFilesProcessingStartContext];
1431
+ requirePlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]>;
1432
+ requirePlugin(name: string): Plugin;
723
1433
  /**
724
- * Fires for each file with progress updates: processed count, total, percentage, and file details.
1434
+ * Get a resolver by plugin name, typed via `Kubb.PluginRegistry` when registered.
725
1435
  */
726
- 'kubb:file:processing:update': [ctx: KubbFileProcessingUpdateContext];
1436
+ getResolver<TName extends keyof Kubb.PluginRegistry>(name: TName): Kubb.PluginRegistry[TName]['resolver'];
1437
+ getResolver(name: string): Resolver;
727
1438
  /**
728
- * Fires when file processing completes with the list of processed files.
1439
+ * Add files only if they don't exist.
729
1440
  */
730
- 'kubb:files:processing:end': [ctx: KubbFilesProcessingEndContext];
1441
+ addFile: (...file: Array<FileNode>) => Promise<void>;
731
1442
  /**
732
- * Fires when a plugin starts execution.
1443
+ * Merge sources into the same output file.
733
1444
  */
734
- 'kubb:plugin:start': [ctx: KubbPluginStartContext];
1445
+ upsertFile: (...file: Array<FileNode>) => Promise<void>;
1446
+ hooks: AsyncEventEmitter<KubbHooks>;
735
1447
  /**
736
- * Fires when a plugin completes execution. Duration measured in milliseconds.
1448
+ * The current plugin instance.
737
1449
  */
738
- 'kubb:plugin:end': [ctx: KubbPluginEndContext];
1450
+ plugin: Plugin<TOptions>;
739
1451
  /**
740
- * Fires once before plugins execute — allowing plugins to register generators, configure resolvers/transformers/renderers, or inject files.
1452
+ * The current plugin's resolver.
741
1453
  */
742
- 'kubb:plugin:setup': [ctx: KubbPluginSetupContext];
1454
+ resolver: TOptions['resolver'];
743
1455
  /**
744
- * Fires before the plugin execution loop begins. The adapter has already parsed the source and `inputNode` is available.
1456
+ * The current plugin's transformer.
745
1457
  */
746
- 'kubb:build:start': [ctx: KubbBuildStartContext];
1458
+ transformer: Visitor | undefined;
747
1459
  /**
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.
1460
+ * Emit a warning.
750
1461
  */
751
- 'kubb:plugins:end': [ctx: KubbPluginsEndContext];
1462
+ warn: (message: string) => void;
752
1463
  /**
753
- * Fires after all files write to disk.
1464
+ * Emit an error.
754
1465
  */
755
- 'kubb:build:end': [ctx: KubbBuildEndContext];
1466
+ error: (error: string | Error) => void;
756
1467
  /**
757
- * Fires for each schema node during AST traversal. Generator listeners respond to this.
1468
+ * Emit an info message.
758
1469
  */
759
- 'kubb:generate:schema': [node: SchemaNode, ctx: GeneratorContext];
1470
+ info: (message: string) => void;
760
1471
  /**
761
- * Fires for each operation node during AST traversal. Generator listeners respond to this.
1472
+ * Open the current input node in Kubb Studio.
762
1473
  */
763
- 'kubb:generate:operation': [node: OperationNode, ctx: GeneratorContext];
1474
+ openInStudio: (options?: DevtoolsOptions) => Promise<void>;
764
1475
  /**
765
- * Fires once after all operations traverse with the full collected array. Batch generator listeners respond to this.
1476
+ * The configured adapter instance.
766
1477
  */
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
833
- /**
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.
838
- */
839
- type Middleware = {
1478
+ adapter: Adapter;
840
1479
  /**
841
- * Unique identifier for this middleware.
1480
+ * Document metadata from the adapter — title, version, base URL, and pre-computed
1481
+ * schema index fields (`circularNames`, `enumNames`).
842
1482
  */
843
- name: string;
1483
+ meta: InputMeta;
844
1484
  /**
845
- * Lifecycle event handlers for this middleware.
846
- * 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.
1485
+ * Resolved options after exclude/include/override filtering.
848
1486
  */
849
- hooks: { [K in keyof KubbHooks]?: (...args: KubbHooks[K]) => void | Promise<void> };
1487
+ options: TOptions['resolvedOptions'];
850
1488
  };
851
1489
  /**
852
- * Creates a middleware factory using the hook-style `hooks` API.
1490
+ * Declares a named generator unit that walks the AST and emits files.
853
1491
  *
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.
1492
+ * Each method (`schema`, `operation`, `operations`) is called for the matching node type.
1493
+ * Each method returns `TElement | Array<FileNode> | undefined | null`. JSX-based generators require a `renderer` factory.
1494
+ * Return `Array<FileNode>` directly or call `ctx.upsertFile()` manually and return `undefined` or `null` to bypass rendering.
856
1495
  *
857
- * @note The factory can accept typed options. See examples for using options and per-build state patterns.
1496
+ * @note Generators are consumed by plugins and registered via `ctx.addGenerator()` in `kubb:plugin:setup`.
858
1497
  *
859
1498
  * @example
860
1499
  * ```ts
861
- * import { defineMiddleware } from '@kubb/core'
1500
+ * import { defineGenerator } from '@kubb/core'
1501
+ * import { jsxRenderer } from '@kubb/renderer-jsx'
862
1502
  *
863
- * // Stateless middleware
864
- * export const logMiddleware = defineMiddleware(() => ({
865
- * name: 'log-middleware',
866
- * hooks: {
867
- * 'kubb:build:end'({ files }) {
868
- * console.log(`Build complete with ${files.length} files`)
869
- * },
1503
+ * export const typeGenerator = defineGenerator({
1504
+ * name: 'typescript',
1505
+ * renderer: jsxRenderer,
1506
+ * schema(node, ctx) {
1507
+ * const { adapter, resolver, root, options } = ctx
1508
+ * return <File ...><Type node={node} resolver={resolver} /></File>
870
1509
  * },
871
- * }))
872
- *
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
1510
  * })
885
1511
  * ```
886
1512
  */
887
- declare function defineMiddleware<TOptions extends object = object>(factory: (options: TOptions) => Middleware): (options?: TOptions) => Middleware;
888
- //#endregion
889
- //#region src/defineParser.d.ts
890
- type PrintOptions = {
891
- extname?: FileNode['extname'];
892
- };
893
- type Parser<TMeta extends object = any> = {
1513
+ type Generator$1<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown> = {
1514
+ /**
1515
+ * Used in diagnostic messages and debug output.
1516
+ */
894
1517
  name: string;
895
1518
  /**
896
- * File extensions this parser handles.
897
- * Use `undefined` to create a catch-all fallback parser.
1519
+ * Optional renderer factory that produces a {@link Renderer} for each render cycle.
898
1520
  *
899
- * @example Handled extensions
900
- * `['.ts', '.js']`
1521
+ * Generators that return renderer elements (e.g. JSX via `@kubb/renderer-jsx`) must set this
1522
+ * to the matching renderer factory (e.g. `jsxRenderer` from `@kubb/renderer-jsx`).
1523
+ *
1524
+ * Generators that only return `Array<FileNode>` or `void` do not need to set this.
1525
+ *
1526
+ * Set `renderer: null` to explicitly opt out of rendering even when the parent plugin
1527
+ * declares a `renderer` (overrides the plugin-level fallback).
1528
+ *
1529
+ * @example
1530
+ * ```ts
1531
+ * import { jsxRenderer } from '@kubb/renderer-jsx'
1532
+ * export const myGenerator = defineGenerator<PluginTs>({
1533
+ * renderer: jsxRenderer,
1534
+ * schema(node, ctx) { return <File ...>...</File> },
1535
+ * })
1536
+ * ```
901
1537
  */
902
- extNames: Array<FileNode['extname']> | undefined;
1538
+ renderer?: RendererFactory<TElement> | null;
1539
+ /**
1540
+ * Called for each schema node in the AST walk.
1541
+ * `ctx` carries the plugin context with `adapter` and `meta` (document metadata),
1542
+ * plus `ctx.options` with the per-node resolved options (after exclude/include/override).
1543
+ */
1544
+ schema?: (node: SchemaNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | undefined | null>;
1545
+ /**
1546
+ * Called for each operation node in the AST walk.
1547
+ * `ctx` carries the plugin context with `adapter` and `meta` (document metadata),
1548
+ * plus `ctx.options` with the per-node resolved options (after exclude/include/override).
1549
+ */
1550
+ operation?: (node: OperationNode, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | undefined | null>;
903
1551
  /**
904
- * Convert a resolved file to a string.
1552
+ * Called once after all operations have been walked.
1553
+ * `ctx` carries the plugin context with `adapter` and `meta` (document metadata),
1554
+ * plus `ctx.options` with the plugin-level options for the batch call.
905
1555
  */
906
- parse(file: FileNode<TMeta>, options?: PrintOptions): Promise<string> | string;
1556
+ operations?: (nodes: Array<OperationNode>, ctx: GeneratorContext<TOptions>) => PossiblePromise<TElement | Array<FileNode> | undefined | null>;
907
1557
  };
908
1558
  /**
909
- * Defines a parser with type safety. Creates parsers that transform generated files to strings based on their extension.
1559
+ * Defines a generator: a unit of work that runs during the plugin's AST walk
1560
+ * and produces files. Plugins register generators via `ctx.addGenerator()`
1561
+ * inside `kubb:plugin:setup`.
910
1562
  *
911
- * @note Call the returned factory with optional options to instantiate the parser.
1563
+ * The returned object is the input as-is, but with `this` types preserved so
1564
+ * `schema`/`operation`/`operations` methods are correctly typed against the
1565
+ * plugin's `PluginFactoryOptions`. Renderer elements and `FileNode[]` returns
1566
+ * are both handled by the runtime — pick whichever style fits.
912
1567
  *
913
- * @example
914
- * ```ts
915
- * import { defineParser } from '@kubb/core'
1568
+ * @example JSX-based schema generator
1569
+ * ```tsx
1570
+ * import { defineGenerator } from '@kubb/core'
1571
+ * import { jsxRenderer } from '@kubb/renderer-jsx'
916
1572
  *
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')
1573
+ * export const typeGenerator = defineGenerator({
1574
+ * name: 'typescript',
1575
+ * renderer: jsxRenderer,
1576
+ * schema(node, ctx) {
1577
+ * return (
1578
+ * <File path={`${ctx.root}/${node.name}.ts`}>
1579
+ * <Type node={node} resolver={ctx.resolver} />
1580
+ * </File>
1581
+ * )
923
1582
  * },
924
1583
  * })
925
1584
  * ```
926
1585
  */
927
- declare function defineParser<TMeta extends object = any>(parser: Parser<TMeta>): Parser<TMeta>;
1586
+ declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown>(generator: Generator$1<TOptions, TElement>): Generator$1<TOptions, TElement>;
928
1587
  //#endregion
929
- //#region src/types.d.ts
1588
+ //#region src/createKubb.d.ts
930
1589
  /**
931
1590
  * Safely extracts a type from a registry, returning `{}` if the key doesn't exist.
932
1591
  * Enables optional interface augmentation for `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
@@ -972,88 +1631,6 @@ type InputData = {
972
1631
  data: string | unknown;
973
1632
  };
974
1633
  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> = {
1021
- /**
1022
- * Human-readable adapter identifier (e.g. `'oas'`, `'asyncapi'`).
1023
- */
1024
- name: TOptions['name'];
1025
- /**
1026
- * Resolved adapter options after defaults have been applied.
1027
- */
1028
- options: TOptions['resolvedOptions'];
1029
- /**
1030
- * Parsed source document after the first `parse()` call. `null` before parsing.
1031
- */
1032
- document: TOptions['document'] | null;
1033
- inputNode: InputNode | null;
1034
- /**
1035
- * Parse the source into a universal `InputNode`.
1036
- */
1037
- parse: (source: AdapterSource) => PossiblePromise<InputNode>;
1038
- /**
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.
1044
- */
1045
- getImports: (node: SchemaNode, resolve: (schemaName: string) => {
1046
- name: string;
1047
- path: string;
1048
- }) => Array<ImportNode>;
1049
- };
1050
- type DevtoolsOptions = {
1051
- /**
1052
- * Open the AST inspector in Kubb Studio (`/ast`). Defaults to the main Studio page.
1053
- * @default false
1054
- */
1055
- ast?: boolean;
1056
- };
1057
1634
  /**
1058
1635
  * Build configuration for Kubb code generation.
1059
1636
  *
@@ -1079,30 +1656,37 @@ type Config<TInput = Input> = {
1079
1656
  */
1080
1657
  name?: string;
1081
1658
  /**
1082
- * Project root directory, absolute or relative to the config file.
1083
- * @default process.cwd()
1659
+ * Project root directory, absolute or relative to the config file. Already
1660
+ * resolved on the `Config` instance — see `UserConfig` for the optional
1661
+ * form that defaults to `process.cwd()`.
1084
1662
  */
1085
1663
  root: string;
1086
1664
  /**
1087
- * Parsers that convert generated files to strings.
1088
- * Each parser handles specific extensions (e.g. `.ts`, `.tsx`).
1089
- * A fallback parser is appended for unhandled extensions.
1090
- * When omitted, defaults to `parserTs` from `@kubb/parser-ts`.
1665
+ * Parsers that convert generated files into strings. Each parser handles a
1666
+ * set of file extensions; a fallback parser handles anything else.
1667
+ *
1668
+ * Already resolved on the `Config` instance — see `UserConfig` for the
1669
+ * optional form that defaults to `[parserTs, parserTsx]`.
1091
1670
  *
1092
- * @default [parserTs] from `@kubb/parser-ts`
1093
1671
  * @example
1094
1672
  * ```ts
1095
- * import { parserTs, tsxParser } from '@kubb/parser-ts'
1673
+ * import { defineConfig } from 'kubb'
1674
+ * import { parserTs, parserTsx } from '@kubb/parser-ts'
1675
+ *
1096
1676
  * export default defineConfig({
1097
- * parsers: [parserTs, tsxParser],
1677
+ * parsers: [parserTs, parserTsx],
1098
1678
  * })
1099
1679
  * ```
1100
1680
  */
1101
1681
  parsers: Array<Parser>;
1102
1682
  /**
1103
- * Adapter that parses input files into the universal `InputNode` representation.
1683
+ * Adapter that parses input files into the universal AST representation.
1104
1684
  * Use `@kubb/adapter-oas` for OpenAPI/Swagger or `@kubb/adapter-asyncapi` for other formats.
1105
1685
  *
1686
+ * When omitted, Kubb runs in plugin-only mode: `kubb:plugin:setup` fires and files
1687
+ * injected via `injectFile` are written, but no AST walk occurs and generator hooks
1688
+ * (`kubb:generate:schema`, `kubb:generate:operation`) are never emitted.
1689
+ *
1106
1690
  * @example
1107
1691
  * ```ts
1108
1692
  * import { adapterOas } from '@kubb/adapter-oas'
@@ -1112,12 +1696,13 @@ type Config<TInput = Input> = {
1112
1696
  * })
1113
1697
  * ```
1114
1698
  */
1115
- adapter: Adapter;
1699
+ adapter?: Adapter;
1116
1700
  /**
1117
1701
  * Source file or data to generate code from.
1118
1702
  * Use `input.path` for a file path or `input.data` for inline data.
1703
+ * Required when an adapter is configured; omit when running in plugin-only mode.
1119
1704
  */
1120
- input: TInput;
1705
+ input?: TInput;
1121
1706
  output: {
1122
1707
  /**
1123
1708
  * Output directory for generated files, absolute or relative to `root`.
@@ -1146,13 +1731,6 @@ type Config<TInput = Input> = {
1146
1731
  * ```
1147
1732
  */
1148
1733
  clean?: boolean;
1149
- /**
1150
- * Persists generated files to the file system.
1151
- *
1152
- * @default true
1153
- * @deprecated Use `storage` option to control where files are written instead.
1154
- */
1155
- write?: boolean;
1156
1734
  /**
1157
1735
  * Auto-format generated files after code generation completes.
1158
1736
  *
@@ -1226,7 +1804,7 @@ type Config<TInput = Input> = {
1226
1804
  * ```
1227
1805
  */
1228
1806
  override?: boolean;
1229
- } & ExtractRegistryKey<Kubb.ConfigOptionsRegistry, 'output'>;
1807
+ } & ExtractRegistryKey<Kubb$1.ConfigOptionsRegistry, 'output'>;
1230
1808
  /**
1231
1809
  * Storage backend that controls where and how generated files are persisted.
1232
1810
  *
@@ -1247,7 +1825,7 @@ type Config<TInput = Input> = {
1247
1825
  *
1248
1826
  * @see {@link Storage} interface for implementing custom backends.
1249
1827
  */
1250
- storage?: Storage;
1828
+ storage: Storage;
1251
1829
  /**
1252
1830
  * Plugins that execute during the build to generate code and transform the AST.
1253
1831
  *
@@ -1288,19 +1866,6 @@ type Config<TInput = Input> = {
1288
1866
  * @see {@link defineMiddleware} to create custom middleware.
1289
1867
  */
1290
1868
  middleware?: Array<Middleware>;
1291
- /**
1292
- * Default renderer factory used by all plugins and generators.
1293
- * Resolution chain: `generator.renderer` → `plugin.renderer` → `config.renderer` → `undefined` (raw FileNode[] mode).
1294
- *
1295
- * @example
1296
- * ```ts
1297
- * import { jsxRenderer } from '@kubb/renderer-jsx'
1298
- * export default defineConfig({
1299
- * renderer: jsxRenderer,
1300
- * plugins: [pluginTs(), pluginZod()],
1301
- * })
1302
- * ```
1303
- */
1304
1869
  /**
1305
1870
  * Renderer that converts generated AST nodes to code strings.
1306
1871
  *
@@ -1320,7 +1885,7 @@ type Config<TInput = Input> = {
1320
1885
  /**
1321
1886
  * Kubb Studio cloud integration settings.
1322
1887
  *
1323
- * Kubb Studio (https://studio.kubb.dev) is a web-based IDE for managing API specs and generated code.
1888
+ * Kubb Studio (https://kubb.studio) is a web-based IDE for managing API specs and generated code.
1324
1889
  * Set to `true` to enable with default settings, or pass an object to customize the Studio URL.
1325
1890
  *
1326
1891
  * @default false // disabled by default
@@ -1333,7 +1898,7 @@ type Config<TInput = Input> = {
1333
1898
  devtools?: true | {
1334
1899
  /**
1335
1900
  * Override the Kubb Studio base URL.
1336
- * @default 'https://studio.kubb.dev'
1901
+ * @default 'https://kubb.studio'
1337
1902
  */
1338
1903
  studioUrl?: typeof DEFAULT_STUDIO_URL | (string & {});
1339
1904
  };
@@ -1361,788 +1926,576 @@ type Config<TInput = Input> = {
1361
1926
  * Commands are executed relative to the `root` directory.
1362
1927
  *
1363
1928
  * @example
1364
- * ```ts
1365
- * done: 'prettier --write "./src/gen"'
1366
- * done: ['prettier --write "./src/gen"', 'eslint --fix "./src/gen"']
1367
- * ```
1368
- */
1369
- done?: string | Array<string>;
1370
- };
1371
- };
1372
- /**
1373
- * Type/string pattern filter for include/exclude/override matching.
1374
- */
1375
- type PatternFilter = {
1376
- type: string;
1377
- pattern: string | RegExp;
1378
- };
1379
- /**
1380
- * Pattern filter with partial option overrides applied when the pattern matches.
1381
- */
1382
- type PatternOverride<TOptions> = PatternFilter & {
1383
- options: Omit<Partial<TOptions>, 'override'>;
1384
- };
1385
- /**
1386
- * Context for resolving filtered options for a given operation or schema node.
1387
- *
1388
- * @internal
1389
- */
1390
- type ResolveOptionsContext<TOptions> = {
1391
- options: TOptions;
1392
- exclude?: Array<PatternFilter>;
1393
- include?: Array<PatternFilter>;
1394
- override?: Array<PatternOverride<TOptions>>;
1395
- };
1396
- /**
1397
- * Base constraint for all plugin resolver objects.
1398
- *
1399
- * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
1400
- * are injected automatically by `defineResolver` — extend this type to add custom resolution methods.
1401
- *
1402
- * @example
1403
- * ```ts
1404
- * type MyResolver = Resolver & {
1405
- * resolveName(node: SchemaNode): string
1406
- * resolveTypedName(node: SchemaNode): string
1407
- * }
1408
- * ```
1409
- */
1410
- type Resolver = {
1411
- name: string;
1412
- pluginName: Plugin['name'];
1413
- default(name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
1414
- resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null;
1415
- resolvePath(params: ResolverPathParams, context: ResolverContext): string;
1416
- resolveFile(params: ResolverFileParams, context: ResolverContext): FileNode;
1417
- resolveBanner(node: InputNode | null, context: ResolveBannerContext): string | undefined;
1418
- resolveFooter(node: InputNode | null, context: ResolveBannerContext): string | undefined;
1419
- };
1420
- type PluginFactoryOptions<
1421
- /**
1422
- * Unique plugin name.
1423
- */
1424
- TName extends string = string,
1425
- /**
1426
- * User-facing plugin options.
1427
- */
1428
- TOptions extends object = object,
1429
- /**
1430
- * Plugin options after defaults are applied.
1431
- */
1432
- TResolvedOptions extends object = TOptions,
1433
- /**
1434
- * Resolver that encapsulates naming and path-resolution helpers.
1435
- * Define with `defineResolver` and export alongside the plugin.
1436
- */
1437
- TResolver extends Resolver = Resolver> = {
1438
- name: TName;
1439
- options: TOptions;
1440
- resolvedOptions: TResolvedOptions;
1441
- resolver: TResolver;
1442
- };
1443
- /**
1444
- * Normalized plugin after setup, with runtime fields populated.
1445
- * For internal use only — plugins use the public `Plugin` type externally.
1446
- *
1447
- * @internal
1448
- */
1449
- type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & {
1450
- options: TOptions['resolvedOptions'] & {
1451
- output: Output;
1452
- include?: Array<Include>;
1453
- exclude: Array<Exclude$1>;
1454
- override: Array<Override<TOptions['resolvedOptions']>>;
1455
- };
1456
- resolver: TOptions['resolver'];
1457
- transformer?: Visitor;
1458
- renderer?: RendererFactory;
1459
- generators?: Array<Generator>;
1460
- apply?: (config: Config) => boolean;
1461
- version?: string;
1462
- };
1463
- /**
1464
- * Partial `Config` for user-facing entry points with sensible defaults.
1465
- *
1466
- * `UserConfig` is what you pass to `defineConfig()`. It has optional `root`, `plugins`, `parsers`, and `adapter`
1467
- * fields (which fall back to sensible defaults). All other Config options are available, including `output`, `input`,
1468
- * `storage`, `middleware`, `renderer`, `devtools`, and `hooks`.
1469
- *
1470
- * @example
1471
- * ```ts
1472
- * export default defineConfig({
1473
- * input: { path: './petstore.yaml' },
1474
- * output: { path: './src/gen' },
1475
- * plugins: [pluginTs(), pluginZod()],
1476
- * })
1477
- * ```
1478
- */
1479
- type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins' | 'parsers' | 'adapter'> & {
1480
- /**
1481
- * Project root directory, absolute or relative to the config file location.
1482
- *
1483
- * Used as the base path for `root`-relative paths (e.g., `output.path`, file paths in hooks).
1484
- *
1485
- * @default process.cwd()
1486
- * @example
1487
- * ```ts
1488
- * root: '/home/user/my-project'
1489
- * root: './my-project' // relative to config file
1490
- * ```
1491
- */
1492
- root?: string;
1493
- /**
1494
- * Custom parsers that convert generated AST nodes to strings (TypeScript, JSON, markdown, etc.).
1495
- *
1496
- * Each parser handles a specific file type. By default, Kubb uses `parserTs` from `@kubb/parser-ts` for TypeScript files.
1497
- * Pass custom parsers to support additional languages or custom formats.
1498
- *
1499
- * @default [parserTs] // from @kubb/parser-ts
1500
- * @example
1501
- * ```ts
1502
- * import { parserTs } from '@kubb/parser-ts'
1503
- * import { parserJsonSchema } from '@kubb/parser-json-schema'
1504
- *
1505
- * parsers: [parserTs(), parserJsonSchema()]
1506
- * ```
1507
- *
1508
- * @see {@link Parser} to implement a custom parser.
1509
- */
1510
- parsers?: Array<Parser>;
1511
- /**
1512
- * Adapter that parses your API specification (OpenAPI, GraphQL, AsyncAPI, etc.) into Kubb's universal AST.
1513
- *
1514
- * The adapter bridge between your input format and Kubb's internal representation. By default, uses the OAS adapter.
1515
- * Pass an alternative adapter (or multiple configs with different adapters) to support different spec formats.
1516
- *
1517
- * @default new OasAdapter() // from @kubb/adapter-oas
1518
- * @example
1519
- * ```ts
1520
- * import { Oas } from '@kubb/adapter-oas'
1521
- *
1522
- * adapter: new Oas({ apiVersion: '3.0.0' })
1523
- * ```
1524
- *
1525
- * @see {@link Adapter} to implement a custom adapter for GraphQL or other formats.
1526
- */
1527
- adapter?: Adapter;
1528
- /**
1529
- * Plugins that execute during the build to generate code and transform the AST.
1530
- *
1531
- * Each plugin processes the AST produced by the adapter and can emit files for different
1532
- * programming languages or formats (TypeScript, Zod schemas, Faker data, etc.).
1533
- *
1534
- * @default [] // no plugins (useful for setup/testing)
1535
- * @example
1536
- * ```ts
1537
- * plugins: [
1538
- * pluginTs({ output: { path: './src/gen' } }),
1539
- * pluginZod({ output: { path: './src/gen' } }),
1540
- * ]
1541
- * ```
1542
- *
1543
- * @see {@link definePlugin} to create a custom plugin.
1544
- */
1545
- plugins?: Array<Plugin>;
1546
- };
1547
- type ResolveNameParams = {
1548
- name: string;
1549
- pluginName?: string;
1550
- /**
1551
- * Entity type being named.
1552
- * - `'file'` — file name (camelCase)
1553
- * - `'function'` — exported function name (camelCase)
1554
- * - `'type'` — TypeScript type name (PascalCase)
1555
- * - `'const'` — variable name (camelCase)
1556
- */
1557
- type?: 'file' | 'function' | 'type' | 'const';
1558
- };
1559
- /**
1560
- * Context object passed to generator `schema`, `operation`, and `operations` methods.
1561
- *
1562
- * The adapter is always defined (guaranteed by `runPluginAstHooks`) so no runtime checks
1563
- * are needed. `ctx.options` carries resolved per-node options after exclude/include/override
1564
- * filtering for individual schema/operation calls, or plugin-level options for operations.
1565
- */
1566
- type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
1567
- config: Config;
1568
- /**
1569
- * Absolute path to the current plugin's output directory.
1570
- */
1571
- root: string;
1572
- /**
1573
- * Determine output mode based on the output config.
1574
- * Returns `'single'` when `output.path` is a file, `'split'` for a directory.
1575
- */
1576
- getMode: (output: {
1577
- path: string;
1578
- }) => 'single' | 'split';
1579
- driver: PluginDriver;
1580
- /**
1581
- * Get a plugin by name, typed via `Kubb.PluginRegistry` when registered.
1582
- */
1583
- getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
1584
- getPlugin(name: string): Plugin | undefined;
1585
- /**
1586
- * Get a plugin by name, throws an error if not found.
1587
- */
1588
- requirePlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]>;
1589
- requirePlugin(name: string): Plugin;
1590
- /**
1591
- * Get a resolver by plugin name, typed via `Kubb.PluginRegistry` when registered.
1592
- */
1593
- getResolver<TName extends keyof Kubb.PluginRegistry>(name: TName): Kubb.PluginRegistry[TName]['resolver'];
1594
- getResolver(name: string): Resolver;
1595
- /**
1596
- * Add files only if they don't exist.
1597
- */
1598
- addFile: (...file: Array<FileNode>) => Promise<void>;
1599
- /**
1600
- * Merge sources into the same output file.
1601
- */
1602
- upsertFile: (...file: Array<FileNode>) => Promise<void>;
1603
- hooks: AsyncEventEmitter<KubbHooks>;
1604
- /**
1605
- * The current plugin instance.
1606
- */
1607
- plugin: Plugin<TOptions>;
1608
- /**
1609
- * The current plugin's resolver.
1610
- */
1611
- resolver: TOptions['resolver'];
1612
- /**
1613
- * The current plugin's transformer.
1614
- */
1615
- transformer: Visitor | undefined;
1616
- /**
1617
- * Emit a warning.
1618
- */
1619
- warn: (message: string) => void;
1620
- /**
1621
- * Emit an error.
1622
- */
1623
- error: (error: string | Error) => void;
1624
- /**
1625
- * Emit an info message.
1626
- */
1627
- info: (message: string) => void;
1628
- /**
1629
- * Open the current input node in Kubb Studio.
1630
- */
1631
- openInStudio: (options?: DevtoolsOptions) => Promise<void>;
1632
- /**
1633
- * The configured adapter instance.
1634
- */
1635
- adapter: Adapter;
1636
- /**
1637
- * The universal `InputNode` produced by the adapter.
1638
- */
1639
- inputNode: InputNode;
1640
- /**
1641
- * Resolved options after exclude/include/override filtering.
1642
- */
1643
- options: TOptions['resolvedOptions'];
1929
+ * ```ts
1930
+ * done: 'prettier --write "./src/gen"'
1931
+ * done: ['prettier --write "./src/gen"', 'eslint --fix "./src/gen"']
1932
+ * ```
1933
+ */
1934
+ done?: string | Array<string>;
1935
+ };
1644
1936
  };
1645
1937
  /**
1646
- * Output configuration for generated files.
1938
+ * Partial `Config` for user-facing entry points with sensible defaults.
1939
+ *
1940
+ * `UserConfig` is what you pass to `defineConfig()`. It has optional `root`, `plugins`, `parsers`, and `adapter`
1941
+ * fields (which fall back to sensible defaults). All other Config options are available, including `output`, `input`,
1942
+ * `storage`, `middleware`, `renderer`, `devtools`, and `hooks`.
1943
+ *
1944
+ * @example
1945
+ * ```ts
1946
+ * export default defineConfig({
1947
+ * input: { path: './petstore.yaml' },
1948
+ * output: { path: './src/gen' },
1949
+ * plugins: [pluginTs(), pluginZod()],
1950
+ * })
1951
+ * ```
1647
1952
  */
1648
- type Output<_TOptions = unknown> = {
1649
- /**
1650
- * Output folder or file path for generated code.
1651
- */
1652
- path: string;
1653
- /**
1654
- * Text or function prepended to every generated file.
1655
- * When a function, receives the current `InputNode` and returns a string.
1656
- */
1657
- banner?: string | ((node?: InputNode) => string);
1953
+ type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins' | 'parsers' | 'adapter' | 'storage'> & {
1658
1954
  /**
1659
- * Text or function appended to every generated file.
1660
- * When a function, receives the current `InputNode` and returns a string.
1955
+ * Project root directory, absolute or relative to the config file location.
1956
+ * @default process.cwd()
1661
1957
  */
1662
- footer?: string | ((node?: InputNode) => string);
1958
+ root?: string;
1663
1959
  /**
1664
- * Whether to override existing external files if they already exist.
1665
- * @default false
1960
+ * Custom parsers that convert generated AST nodes to strings (TypeScript, JSON, markdown, etc.).
1961
+ * @default [parserTs] // from `@kubb/parser-ts`
1666
1962
  */
1667
- override?: boolean;
1668
- } & ExtractRegistryKey<Kubb.PluginOptionsRegistry, 'output'>;
1669
- type Group = {
1963
+ parsers?: Array<Parser>;
1670
1964
  /**
1671
- * How to group files into subdirectories.
1672
- * - `'tag'` group by OpenAPI tags
1673
- * - `'path'` — group by OpenAPI paths
1965
+ * Adapter that parses your API specification into Kubb's universal AST.
1966
+ * When omitted, Kubb runs in plugin-only mode.
1674
1967
  */
1675
- type: 'tag' | 'path';
1968
+ adapter?: Adapter;
1676
1969
  /**
1677
- * Function that returns the subdirectory name for a group value.
1678
- * Defaults to `${camelCase(group)}Controller` for tags, first path segment for paths.
1970
+ * Plugins that execute during the build to generate code and transform the AST.
1971
+ * @default []
1679
1972
  */
1680
- name?: (context: {
1681
- group: string;
1682
- }) => string;
1683
- };
1684
- type LoggerOptions = {
1973
+ plugins?: Array<Plugin>;
1685
1974
  /**
1686
- * Log level for output verbosity.
1687
- * @default 3
1975
+ * Storage backend that controls where and how generated files are persisted.
1976
+ * @default fsStorage()
1688
1977
  */
1689
- logLevel: (typeof logLevel)[keyof typeof logLevel];
1690
- };
1691
- /**
1692
- * Shared context passed to plugins, parsers, and other internals.
1693
- */
1694
- type LoggerContext = AsyncEventEmitter<KubbHooks>;
1695
- type Logger<TOptions extends LoggerOptions = LoggerOptions> = {
1696
- name: string;
1697
- install: (context: LoggerContext, options?: TOptions) => void | Promise<void>;
1978
+ storage?: Storage;
1698
1979
  };
1699
- type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Logger<TOptions>;
1980
+ declare global {
1981
+ namespace Kubb {
1982
+ /**
1983
+ * Registry that maps plugin names to their `PluginFactoryOptions`.
1984
+ * Augment this interface in each plugin's `types.ts` to enable automatic
1985
+ * typing for `getPlugin` and `requirePlugin`.
1986
+ *
1987
+ * @example
1988
+ * ```ts
1989
+ * // packages/plugin-ts/src/types.ts
1990
+ * declare global {
1991
+ * namespace Kubb {
1992
+ * interface PluginRegistry {
1993
+ * 'plugin-ts': PluginTs
1994
+ * }
1995
+ * }
1996
+ * }
1997
+ * ```
1998
+ */
1999
+ interface PluginRegistry {}
2000
+ /**
2001
+ * Extension point for root `Config['output']` options.
2002
+ * Augment the `output` key in middleware or plugin packages to add extra fields
2003
+ * to the global output configuration without touching core types.
2004
+ *
2005
+ * @example
2006
+ * ```ts
2007
+ * // packages/middleware-barrel/src/types.ts
2008
+ * declare global {
2009
+ * namespace Kubb {
2010
+ * interface ConfigOptionsRegistry {
2011
+ * output: {
2012
+ * barrel?: import('./types.ts').BarrelConfig | false
2013
+ * }
2014
+ * }
2015
+ * }
2016
+ * }
2017
+ * ```
2018
+ */
2019
+ interface ConfigOptionsRegistry {}
2020
+ /**
2021
+ * Extension point for per-plugin `Output` options.
2022
+ * Augment the `output` key in middleware or plugin packages to add extra fields
2023
+ * to the per-plugin output configuration without touching core types.
2024
+ *
2025
+ * @example
2026
+ * ```ts
2027
+ * // packages/middleware-barrel/src/types.ts
2028
+ * declare global {
2029
+ * namespace Kubb {
2030
+ * interface PluginOptionsRegistry {
2031
+ * output: {
2032
+ * barrel?: import('./types.ts').PluginBarrelConfig | false
2033
+ * }
2034
+ * }
2035
+ * }
2036
+ * }
2037
+ * ```
2038
+ */
2039
+ interface PluginOptionsRegistry {}
2040
+ }
2041
+ }
1700
2042
  /**
1701
- * Context for hook-style plugin `kubb:plugin:setup` handler.
1702
- * Provides methods to register generators, configure resolvers, transformers, and renderers.
2043
+ * Lifecycle events emitted during Kubb code generation.
2044
+ * Attach listeners before calling `setup()` or `build()` to observe and react to build progress.
2045
+ *
2046
+ * @example
2047
+ * ```ts
2048
+ * kubb.hooks.on('kubb:lifecycle:start', () => {
2049
+ * console.log('Starting Kubb generation')
2050
+ * })
2051
+ *
2052
+ * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
2053
+ * console.log(`${plugin.name} completed in ${duration}ms`)
2054
+ * })
2055
+ * ```
1703
2056
  */
1704
- type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1705
- /**
1706
- * Register a generator dynamically. Generators fire during the AST walk (schema/operation/operations)
1707
- * just like generators declared statically on `createPlugin`.
1708
- */
1709
- addGenerator<TElement = unknown>(generator: Generator<TFactory, TElement>): void;
1710
- /**
1711
- * Set or override the resolver for this plugin.
1712
- * The resolver controls file naming and path resolution.
1713
- */
1714
- setResolver(resolver: Partial<TFactory['resolver']>): void;
1715
- /**
1716
- * Set the AST transformer to pre-process nodes before they reach generators.
1717
- */
1718
- setTransformer(visitor: Visitor): void;
1719
- /**
1720
- * Set the renderer factory to process JSX elements from generators.
1721
- */
1722
- setRenderer(renderer: RendererFactory): void;
1723
- /**
1724
- * Set resolved options merged into the normalized plugin's `options`.
1725
- * Call this in `kubb:plugin:setup` to provide options generators need.
1726
- */
1727
- setOptions(options: TFactory['resolvedOptions']): void;
1728
- /**
1729
- * Inject a raw file into the build output, bypassing the generation pipeline.
1730
- */
1731
- injectFile(userFileNode: UserFileNode): void;
1732
- /**
1733
- * Merge a partial config update into the current build configuration.
1734
- */
1735
- updateConfig(config: Partial<Config>): void;
2057
+ interface KubbHooks {
2058
+ 'kubb:lifecycle:start': [ctx: KubbLifecycleStartContext];
2059
+ 'kubb:lifecycle:end': [];
2060
+ 'kubb:config:start': [];
2061
+ 'kubb:config:end': [ctx: KubbConfigEndContext];
2062
+ 'kubb:generation:start': [ctx: KubbGenerationStartContext];
2063
+ 'kubb:generation:end': [ctx: KubbGenerationEndContext];
2064
+ 'kubb:generation:summary': [ctx: KubbGenerationSummaryContext];
2065
+ 'kubb:format:start': [];
2066
+ 'kubb:format:end': [];
2067
+ 'kubb:lint:start': [];
2068
+ 'kubb:lint:end': [];
2069
+ 'kubb:hooks:start': [];
2070
+ 'kubb:hooks:end': [];
2071
+ 'kubb:hook:start': [ctx: KubbHookStartContext];
2072
+ 'kubb:hook:end': [ctx: KubbHookEndContext];
2073
+ 'kubb:version:new': [ctx: KubbVersionNewContext];
2074
+ 'kubb:info': [ctx: KubbInfoContext];
2075
+ 'kubb:error': [ctx: KubbErrorContext];
2076
+ 'kubb:success': [ctx: KubbSuccessContext];
2077
+ 'kubb:warn': [ctx: KubbWarnContext];
2078
+ 'kubb:debug': [ctx: KubbDebugContext];
2079
+ 'kubb:files:processing:start': [ctx: KubbFilesProcessingStartContext];
2080
+ 'kubb:files:processing:update': [ctx: KubbFilesProcessingUpdateContext];
2081
+ 'kubb:files:processing:end': [ctx: KubbFilesProcessingEndContext];
2082
+ 'kubb:plugin:start': [ctx: KubbPluginStartContext];
2083
+ 'kubb:plugin:end': [ctx: KubbPluginEndContext];
2084
+ 'kubb:plugin:setup': [ctx: KubbPluginSetupContext];
2085
+ 'kubb:build:start': [ctx: KubbBuildStartContext];
2086
+ 'kubb:plugins:end': [ctx: KubbPluginsEndContext];
2087
+ 'kubb:build:end': [ctx: KubbBuildEndContext];
2088
+ 'kubb:generate:schema': [node: SchemaNode, ctx: GeneratorContext];
2089
+ 'kubb:generate:operation': [node: OperationNode, ctx: GeneratorContext];
2090
+ 'kubb:generate:operations': [nodes: Array<OperationNode>, ctx: GeneratorContext];
2091
+ }
2092
+ type KubbBuildStartContext = {
1736
2093
  /**
1737
- * The resolved build configuration at setup time.
2094
+ * Resolved configuration for this build.
1738
2095
  */
1739
2096
  config: Config;
1740
2097
  /**
1741
- * The plugin's user-provided options.
2098
+ * Adapter that parsed the input into the universal AST.
1742
2099
  */
1743
- options: TFactory['options'];
1744
- };
1745
- /**
1746
- * Context for hook-style plugin `kubb:build:start` handler.
1747
- * Fires immediately before the plugin execution loop begins.
1748
- */
1749
- type KubbBuildStartContext = {
1750
- config: Config;
1751
2100
  adapter: Adapter;
1752
- inputNode: InputNode;
1753
2101
  /**
1754
- * Get a plugin by name, typed via `Kubb.PluginRegistry` when registered.
2102
+ * Metadata about the parsed document (title, version, base URL, circular schema names, enum names).
2103
+ * To observe individual schemas and operations use the `kubb:generate:schema` / `kubb:generate:operation` hooks.
1755
2104
  */
1756
- getPlugin<TName extends keyof Kubb.PluginRegistry>(name: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined;
2105
+ meta: InputMeta | undefined;
2106
+ /**
2107
+ * Looks up a registered plugin by name, typed by the plugin registry.
2108
+ */
2109
+ getPlugin<TName extends keyof Kubb$1.PluginRegistry>(name: TName): Plugin<Kubb$1.PluginRegistry[TName]> | undefined;
1757
2110
  getPlugin(name: string): Plugin | undefined;
1758
2111
  /**
1759
- * Get all files currently in the file manager.
1760
- * Call this lazily (e.g. in `kubb:plugin:end`) to see files added by prior plugins.
2112
+ * Snapshot of all files accumulated so far.
1761
2113
  */
1762
2114
  readonly files: ReadonlyArray<FileNode>;
1763
2115
  /**
1764
- * Upsert one or more files into the file manager.
1765
- * Files with the same path are merged; new files are appended.
1766
- * Safe to call at any point during the plugin lifecycle, including inside `kubb:plugin:end`.
2116
+ * Adds or merges one or more files into the file manager.
1767
2117
  */
1768
2118
  upsertFile: (...files: Array<FileNode>) => void;
1769
2119
  };
1770
- /**
1771
- * Context for `kubb:plugins:end` handlers.
1772
- * Fires after plugins run and per-plugin barrels are written, before final write to disk.
1773
- * Middleware that needs final files (e.g. root barrel) use this event.
1774
- */
1775
2120
  type KubbPluginsEndContext = {
2121
+ /**
2122
+ * Resolved configuration for this build.
2123
+ */
1776
2124
  config: Config;
1777
2125
  /**
1778
- * All files currently in the file manager (lazy snapshot).
2126
+ * Snapshot of all files accumulated across all plugins.
1779
2127
  */
1780
2128
  readonly files: ReadonlyArray<FileNode>;
1781
2129
  /**
1782
- * Upsert files into the file manager.
1783
- * Files added here are included in the write pass.
2130
+ * Adds or merges one or more files into the file manager.
1784
2131
  */
1785
2132
  upsertFile: (...files: Array<FileNode>) => void;
1786
2133
  };
1787
- /**
1788
- * Context for hook-style plugin `kubb:build:end` handler.
1789
- * Fires after all files have been written to disk.
1790
- */
1791
2134
  type KubbBuildEndContext = {
2135
+ /**
2136
+ * All files generated during this build.
2137
+ */
1792
2138
  files: Array<FileNode>;
2139
+ /**
2140
+ * Resolved configuration for this build.
2141
+ */
1793
2142
  config: Config;
2143
+ /**
2144
+ * Absolute path to the output directory.
2145
+ */
1794
2146
  outputDir: string;
1795
2147
  };
1796
2148
  type KubbLifecycleStartContext = {
2149
+ /**
2150
+ * Current Kubb version string.
2151
+ */
1797
2152
  version: string;
1798
2153
  };
1799
2154
  type KubbConfigEndContext = {
2155
+ /**
2156
+ * All resolved configs after defaults are applied.
2157
+ */
1800
2158
  configs: Array<Config>;
1801
2159
  };
1802
2160
  type KubbGenerationStartContext = {
2161
+ /**
2162
+ * Resolved configuration for this generation run.
2163
+ */
1803
2164
  config: Config;
1804
2165
  };
1805
2166
  type KubbGenerationEndContext = {
2167
+ /**
2168
+ * Resolved configuration for this generation run.
2169
+ */
1806
2170
  config: Config;
1807
- files: Array<FileNode>;
1808
- sources: Map<string, string>;
2171
+ /**
2172
+ * Read-only view of the files written during this build.
2173
+ * Reads go directly to `config.storage` — nothing extra is held in memory.
2174
+ *
2175
+ * @example Read a generated file
2176
+ * `const code = await storage.getItem('/src/gen/pet.ts')`
2177
+ *
2178
+ * @example Walk every generated file
2179
+ * ```ts
2180
+ * for (const path of await storage.getKeys()) {
2181
+ * const code = await storage.getItem(path)
2182
+ * }
2183
+ * ```
2184
+ */
2185
+ storage: Storage;
1809
2186
  };
1810
2187
  type KubbGenerationSummaryContext = {
2188
+ /**
2189
+ * Resolved configuration for this generation run.
2190
+ */
1811
2191
  config: Config;
2192
+ /**
2193
+ * Plugins that threw during generation, paired with their errors.
2194
+ */
1812
2195
  failedPlugins: Set<{
1813
2196
  plugin: Plugin;
1814
2197
  error: Error;
1815
2198
  }>;
2199
+ /**
2200
+ * `'success'` when all plugins completed without errors, `'failed'` otherwise.
2201
+ */
1816
2202
  status: 'success' | 'failed';
2203
+ /**
2204
+ * High-resolution start time from `process.hrtime()`.
2205
+ */
1817
2206
  hrStart: [number, number];
2207
+ /**
2208
+ * Total number of files created during this run.
2209
+ */
1818
2210
  filesCreated: number;
2211
+ /**
2212
+ * Elapsed milliseconds per plugin, keyed by plugin name.
2213
+ */
1819
2214
  pluginTimings?: Map<Plugin['name'], number>;
1820
2215
  };
1821
2216
  type KubbVersionNewContext = {
2217
+ /**
2218
+ * The installed Kubb version.
2219
+ */
1822
2220
  currentVersion: string;
2221
+ /**
2222
+ * The newest available version on npm.
2223
+ */
1823
2224
  latestVersion: string;
1824
2225
  };
1825
2226
  type KubbInfoContext = {
2227
+ /**
2228
+ * Human-readable info message.
2229
+ */
1826
2230
  message: string;
2231
+ /**
2232
+ * Optional supplementary detail.
2233
+ */
1827
2234
  info?: string;
1828
2235
  };
1829
2236
  type KubbErrorContext = {
2237
+ /**
2238
+ * The caught error.
2239
+ */
1830
2240
  error: Error;
2241
+ /**
2242
+ * Optional structured metadata for additional context.
2243
+ */
1831
2244
  meta?: Record<string, unknown>;
1832
2245
  };
1833
2246
  type KubbSuccessContext = {
2247
+ /**
2248
+ * Human-readable success message.
2249
+ */
1834
2250
  message: string;
2251
+ /**
2252
+ * Optional supplementary detail.
2253
+ */
1835
2254
  info?: string;
1836
2255
  };
1837
2256
  type KubbWarnContext = {
2257
+ /**
2258
+ * Human-readable warning message.
2259
+ */
1838
2260
  message: string;
2261
+ /**
2262
+ * Optional supplementary detail.
2263
+ */
1839
2264
  info?: string;
1840
2265
  };
1841
2266
  type KubbDebugContext = {
2267
+ /**
2268
+ * Timestamp when the debug entry was created.
2269
+ */
1842
2270
  date: Date;
2271
+ /**
2272
+ * One or more log lines to emit.
2273
+ */
1843
2274
  logs: Array<string>;
2275
+ /**
2276
+ * Optional source file name associated with this entry.
2277
+ */
1844
2278
  fileName?: string;
1845
2279
  };
1846
2280
  type KubbFilesProcessingStartContext = {
2281
+ /**
2282
+ * Files about to be serialised and written.
2283
+ */
1847
2284
  files: Array<FileNode>;
1848
2285
  };
1849
- type KubbFileProcessingUpdateContext = {
2286
+ type KubbFileProcessingUpdate = {
1850
2287
  /**
1851
- * Number of files processed.
2288
+ * Number of files processed so far in this batch.
1852
2289
  */
1853
2290
  processed: number;
1854
2291
  /**
1855
- * Total files to process.
2292
+ * Total number of files in this batch.
1856
2293
  */
1857
2294
  total: number;
1858
2295
  /**
1859
- * Processing percentage (0100).
2296
+ * Completion percentage (`0`–`100`).
1860
2297
  */
1861
2298
  percentage: number;
1862
2299
  /**
1863
- * Optional source identifier.
2300
+ * Serialised file content, or `undefined` when the file produced no output.
1864
2301
  */
1865
2302
  source?: string;
1866
2303
  /**
1867
- * The file being processed.
2304
+ * The file that was just processed.
1868
2305
  */
1869
2306
  file: FileNode;
1870
2307
  /**
1871
- * The current build configuration.
2308
+ * Resolved configuration for this build.
1872
2309
  */
1873
2310
  config: Config;
1874
2311
  };
1875
- type KubbFilesProcessingEndContext = {
1876
- files: Array<FileNode>;
1877
- };
1878
- type KubbPluginStartContext = {
1879
- plugin: NormalizedPlugin;
1880
- };
1881
- type KubbPluginEndContext = {
1882
- plugin: NormalizedPlugin;
1883
- duration: number;
1884
- success: boolean;
1885
- error?: Error;
1886
- config: Config;
2312
+ type KubbFilesProcessingUpdateContext = {
1887
2313
  /**
1888
- * Returns all files currently in the file manager (lazy snapshot).
1889
- * Includes files added by plugins that have already run.
2314
+ * All files processed in this flush chunk.
1890
2315
  */
1891
- readonly files: ReadonlyArray<FileNode>;
2316
+ files: Array<KubbFileProcessingUpdate>;
2317
+ };
2318
+ type KubbFilesProcessingEndContext = {
1892
2319
  /**
1893
- * Upsert one or more files into the file manager.
2320
+ * All files that were serialised in this batch.
1894
2321
  */
1895
- upsertFile: (...files: Array<FileNode>) => void;
2322
+ files: Array<FileNode>;
1896
2323
  };
1897
2324
  type KubbHookStartContext = {
1898
- id?: string;
1899
- command: string;
1900
- args?: readonly string[];
1901
- };
1902
- type KubbHookEndContext = {
1903
- id?: string;
1904
- command: string;
1905
- args?: readonly string[];
1906
- success: boolean;
1907
- error: Error | null;
1908
- };
1909
- type ByTag = {
1910
2325
  /**
1911
- * Filter by OpenAPI `tags` field. Matches one or more tags assigned to operations.
2326
+ * Optional identifier for correlating start/end events.
1912
2327
  */
1913
- type: 'tag';
2328
+ id?: string;
1914
2329
  /**
1915
- * Tag name to match (case-sensitive). Can be a literal string or regex pattern.
2330
+ * The shell command that is about to run.
1916
2331
  */
1917
- pattern: string | RegExp;
1918
- };
1919
- type ByOperationId = {
2332
+ command: string;
1920
2333
  /**
1921
- * Filter by OpenAPI `operationId` field. Each operation (GET, POST, etc.) has a unique identifier.
2334
+ * Parsed argument list, when available.
1922
2335
  */
1923
- type: 'operationId';
2336
+ args?: ReadonlyArray<string>;
2337
+ };
2338
+ type KubbHookEndContext = {
1924
2339
  /**
1925
- * Operation ID to match (case-sensitive). Can be a literal string or regex pattern.
2340
+ * Optional identifier matching the corresponding `kubb:hook:start` event.
1926
2341
  */
1927
- pattern: string | RegExp;
1928
- };
1929
- type ByPath = {
2342
+ id?: string;
1930
2343
  /**
1931
- * Filter by OpenAPI `path` (URL endpoint). Useful to group or filter by service segments like `/pets`, `/users`, etc.
2344
+ * The shell command that ran.
1932
2345
  */
1933
- type: 'path';
2346
+ command: string;
1934
2347
  /**
1935
- * URL path to match (case-sensitive). Can be a literal string or regex pattern. Matches against the full path.
2348
+ * Parsed argument list, when available.
1936
2349
  */
1937
- pattern: string | RegExp;
1938
- };
1939
- type ByMethod = {
2350
+ args?: ReadonlyArray<string>;
1940
2351
  /**
1941
- * Filter by HTTP method: `'get'`, `'post'`, `'put'`, `'delete'`, `'patch'`, `'head'`, `'options'`.
2352
+ * `true` when the command exited with code `0`.
1942
2353
  */
1943
- type: 'method';
2354
+ success: boolean;
1944
2355
  /**
1945
- * HTTP method to match (case-insensitive when using string, or regex for dynamic matching).
2356
+ * Error thrown by the command, or `null` on success.
1946
2357
  */
1947
- pattern: HttpMethod | RegExp;
2358
+ error: Error | null;
1948
2359
  };
1949
- type BySchemaName = {
2360
+ /**
2361
+ * CLI options derived from command-line flags.
2362
+ */
2363
+ type CLIOptions = {
1950
2364
  /**
1951
- * Filter by schema component name (TypeScript or JSON schema). Matches schemas in `#/components/schemas`.
2365
+ * Path to the Kubb config file.
1952
2366
  */
1953
- type: 'schemaName';
2367
+ config?: string;
1954
2368
  /**
1955
- * Schema name to match (case-sensitive). Can be a literal string or regex pattern.
2369
+ * OpenAPI input path passed as the positional argument to `kubb generate`.
2370
+ * Overrides `config.input.path` when set.
1956
2371
  */
1957
- pattern: string | RegExp;
1958
- };
1959
- type ByContentType = {
2372
+ input?: string;
1960
2373
  /**
1961
- * Filter by response or request content type: `'application/json'`, `'application/xml'`, etc.
2374
+ * Re-run generation whenever input files change.
1962
2375
  */
1963
- type: 'contentType';
2376
+ watch?: boolean;
1964
2377
  /**
1965
- * Content type to match (case-sensitive). Can be a literal string or regex pattern.
2378
+ * Controls how much output the CLI prints.
2379
+ *
2380
+ * @default 'info'
1966
2381
  */
1967
- pattern: string | RegExp;
2382
+ logLevel?: 'silent' | 'info' | 'verbose' | 'debug';
1968
2383
  };
1969
2384
  /**
1970
- * A pattern filter that prevents matching nodes from being generated.
1971
- *
1972
- * Use to skip code generation for specific operations or schemas. For example, exclude deprecated endpoints
1973
- * or internal-only schemas. Can filter by tag, operationId, path, HTTP method, content type, or schema name.
1974
- *
1975
- * @example
1976
- * ```ts
1977
- * exclude: [
1978
- * { type: 'tag', pattern: 'internal' }, // skip "internal" tag
1979
- * { type: 'path', pattern: /^\/admin/ }, // skip all /admin endpoints
1980
- * { type: 'operationId', pattern: 'deprecated_*' } // skip operationIds matching pattern
1981
- * ]
1982
- * ```
1983
- */
1984
- type Exclude$1 = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1985
- /**
1986
- * A pattern filter that restricts generation to only matching nodes.
1987
- *
1988
- * Use to generate code for a subset of operations or schemas. For example, only generate for a specific service
1989
- * tag or only for "production" endpoints. Can filter by tag, operationId, path, HTTP method, content type, or schema name.
1990
- *
1991
- * @example
1992
- * ```ts
1993
- * include: [
1994
- * { type: 'tag', pattern: 'public' }, // generate only "public" tag
1995
- * { type: 'path', pattern: /^\/api\/v1/ }, // generate only v1 endpoints
1996
- * ]
1997
- * ```
1998
- */
1999
- type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
2000
- /**
2001
- * A pattern filter paired with partial option overrides applied when the pattern matches.
2002
- *
2003
- * Use to customize generation for specific operations or schemas. For example, apply different output paths
2004
- * for different tags, or use custom resolver functions per operation. Can filter by tag, operationId, path,
2005
- * HTTP method, schema name, or content type.
2006
- *
2007
- * @example
2008
- * ```ts
2009
- * override: [
2010
- * {
2011
- * type: 'tag',
2012
- * pattern: 'admin',
2013
- * options: { output: { path: './src/gen/admin' } } // admin APIs go to separate folder
2014
- * },
2015
- * {
2016
- * type: 'operationId',
2017
- * pattern: 'listPets',
2018
- * options: { exclude: true } // skip this specific operation
2019
- * }
2020
- * ]
2021
- * ```
2385
+ * All accepted forms of a Kubb configuration.
2386
+ * Accepts `Config`/`Config[]`/promise or a factory (optionally receiving `TCliOptions`.
2022
2387
  */
2023
- type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
2024
- options: Partial<TOptions>;
2025
- };
2388
+ type PossibleConfig<TCliOptions = undefined> = PossiblePromise<Config | Array<Config>> | ((...args: [TCliOptions] extends [undefined] ? [] : [TCliOptions]) => PossiblePromise<Config | Array<Config>>);
2026
2389
  /**
2027
- * File-specific parameters for `Resolver.resolvePath`.
2028
- *
2029
- * Pass alongside a `ResolverContext` to identify which file to resolve.
2030
- * Provide `tag` for tag-based grouping or `path` for path-based grouping.
2031
- *
2032
- * @example
2033
- * ```ts
2034
- * resolver.resolvePath(
2035
- * { baseName: 'petTypes.ts', tag: 'pets' },
2036
- * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
2037
- * )
2038
- * // → '/src/types/petsController/petTypes.ts'
2039
- * ```
2390
+ * Full output produced by a successful or failed build.
2040
2391
  */
2041
- type ResolverPathParams = {
2042
- baseName: FileNode['baseName'];
2043
- pathMode?: 'single' | 'split';
2392
+ type BuildOutput = {
2044
2393
  /**
2045
- * Tag value used when `group.type === 'tag'`.
2394
+ * Plugins that threw during generation, paired with their errors.
2046
2395
  */
2047
- tag?: string;
2396
+ failedPlugins: Set<{
2397
+ plugin: Plugin;
2398
+ error: Error;
2399
+ }>;
2048
2400
  /**
2049
- * Path value used when `group.type === 'path'`.
2401
+ * All files generated during this build.
2050
2402
  */
2051
- path?: string;
2052
- };
2053
- /**
2054
- * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
2055
- *
2056
- * Describes where on disk output is rooted, which output config is active, and the optional
2057
- * grouping strategy that controls subdirectory layout.
2058
- *
2059
- * @example
2060
- * ```ts
2061
- * const context: ResolverContext = {
2062
- * root: config.root,
2063
- * output,
2064
- * group,
2065
- * }
2066
- * ```
2067
- */
2068
- type ResolverContext = {
2069
- root: string;
2070
- output: Output;
2071
- group?: Group;
2403
+ files: Array<FileNode>;
2072
2404
  /**
2073
- * Plugin name used to populate `meta.pluginName` on the resolved file.
2405
+ * The plugin driver that orchestrated this build.
2074
2406
  */
2075
- pluginName?: string;
2076
- };
2077
- /**
2078
- * File-specific parameters for `Resolver.resolveFile`.
2079
- *
2080
- * Pass alongside a `ResolverContext` to fully describe the file to resolve.
2081
- * `tag` and `path` are used only when a matching `group` is present in the context.
2082
- *
2083
- * @example
2084
- * ```ts
2085
- * resolver.resolveFile(
2086
- * { name: 'listPets', extname: '.ts', tag: 'pets' },
2087
- * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
2088
- * )
2089
- * // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
2090
- * ```
2091
- */
2092
- type ResolverFileParams = {
2093
- name: string;
2094
- extname: FileNode['extname'];
2407
+ driver: KubbDriver;
2095
2408
  /**
2096
- * Tag value used when `group.type === 'tag'`.
2409
+ * Elapsed milliseconds per plugin, keyed by plugin name.
2097
2410
  */
2098
- tag?: string;
2411
+ pluginTimings: Map<string, number>;
2099
2412
  /**
2100
- * Path value used when `group.type === 'path'`.
2413
+ * Top-level error when the build threw before completing, otherwise `undefined`.
2101
2414
  */
2102
- path?: string;
2415
+ error?: Error;
2416
+ /**
2417
+ * Read-only view of every file written during this build.
2418
+ * Reads go straight to `config.storage` — nothing extra is held in memory.
2419
+ *
2420
+ * @example Read a generated file
2421
+ * `const code = await buildOutput.storage.getItem('/src/gen/pet.ts')`
2422
+ *
2423
+ * @example List all generated file paths
2424
+ * `const paths = await buildOutput.storage.getKeys()`
2425
+ */
2426
+ storage: Storage;
2103
2427
  };
2104
2428
  /**
2105
- * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
2429
+ * Type guard to check if a given config has an `input.path`.
2430
+ */
2431
+ declare function isInputPath(config: UserConfig | undefined): config is UserConfig<InputPath> & {
2432
+ input: InputPath;
2433
+ };
2434
+ declare function isInputPath(config: Config | undefined): config is Config<InputPath> & {
2435
+ input: InputPath;
2436
+ };
2437
+ type CreateKubbOptions = {
2438
+ hooks?: AsyncEventEmitter<KubbHooks>;
2439
+ };
2440
+ /**
2441
+ * Kubb code-generation instance bound to a single config entry. Resolves the user
2442
+ * config during `setup()` and shares `hooks`, `storage`, `driver`, and `config` across
2443
+ * the `setup → build` lifecycle.
2106
2444
  *
2107
- * `output` is optional not every plugin configures a banner/footer.
2108
- * `config` carries the global Kubb config, used to derive the default Kubb banner.
2445
+ * Attach event listeners to `.hooks` before calling `setup()` or `build()`.
2109
2446
  *
2110
2447
  * @example
2111
2448
  * ```ts
2112
- * resolver.resolveBanner(inputNode, { output: { banner: '// generated' }, config })
2113
- * // '// generated'
2449
+ * const kubb = createKubb(userConfig)
2450
+ * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
2451
+ * const { files, failedPlugins } = await kubb.safeBuild()
2114
2452
  * ```
2115
2453
  */
2116
- type ResolveBannerContext = {
2117
- output?: Pick<Output, 'banner' | 'footer'>;
2118
- config: Config;
2119
- };
2120
- /**
2121
- * CLI options derived from command-line flags.
2122
- */
2123
- type CLIOptions = {
2454
+ declare class Kubb$1 {
2455
+ #private;
2456
+ readonly hooks: AsyncEventEmitter<KubbHooks>;
2457
+ constructor(userConfig: UserConfig, options?: CreateKubbOptions);
2458
+ get storage(): Storage;
2459
+ get driver(): KubbDriver;
2460
+ get config(): Config;
2124
2461
  /**
2125
- * Path to `kubb.config.js`.
2462
+ * Resolves config and initializes the driver. `build()` calls this automatically.
2126
2463
  */
2127
- config?: string;
2464
+ setup(): Promise<void>;
2128
2465
  /**
2129
- * Enable watch mode for input files.
2466
+ * Runs the full pipeline and throws on any plugin error.
2467
+ * Automatically calls `setup()` if needed.
2130
2468
  */
2131
- watch?: boolean;
2469
+ build(): Promise<BuildOutput>;
2132
2470
  /**
2133
- * Logging verbosity for CLI usage.
2134
- * @default 'silent'
2471
+ * Runs the full pipeline and captures errors in `BuildOutput` instead of throwing.
2472
+ * Automatically calls `setup()` if needed.
2135
2473
  */
2136
- logLevel?: 'silent' | 'info' | 'debug';
2137
- };
2474
+ safeBuild(): Promise<BuildOutput>;
2475
+ dispose(): void;
2476
+ [Symbol.dispose](): void;
2477
+ }
2138
2478
  /**
2139
- * All accepted forms of a Kubb configuration.
2479
+ * Constructs a {@link Kubb} build orchestrator from a user config. Equivalent
2480
+ * to `new Kubb(userConfig, options)` and the canonical public entry point.
2481
+ *
2482
+ * @example
2483
+ * ```ts
2484
+ * import { createKubb } from '@kubb/core'
2485
+ * import { adapterOas } from '@kubb/adapter-oas'
2486
+ * import { pluginTs } from '@kubb/plugin-ts'
2487
+ *
2488
+ * const kubb = createKubb({
2489
+ * input: { path: './petStore.yaml' },
2490
+ * output: { path: './src/gen' },
2491
+ * adapter: adapterOas(),
2492
+ * plugins: [pluginTs()],
2493
+ * })
2140
2494
  *
2141
- * Config is always `@kubb/core` {@link Config}.
2142
- * - `PossibleConfig` accepts `Config`/`Config[]`/promise or a no-arg config factory.
2143
- * - `PossibleConfig<TCliOptions>` accepts the same config forms or a config factory receiving `TCliOptions`.
2495
+ * await kubb.build()
2496
+ * ```
2144
2497
  */
2145
- type PossibleConfig<TCliOptions = undefined> = PossiblePromise<Config | Config[]> | ((...args: [TCliOptions] extends [undefined] ? [] : [TCliOptions]) => PossiblePromise<Config | Config[]>);
2498
+ declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
2146
2499
  //#endregion
2147
- 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 };
2148
- //# sourceMappingURL=types-CC09VtBt.d.ts.map
2500
+ export { Resolver as $, createKubb as A, KubbPluginEndContext as B, KubbLifecycleStartContext as C, AdapterFactoryOptions as Ct, KubbWarnContext as D, AsyncEventEmitter as Dt, KubbVersionNewContext as E, logLevel as Et, KubbDriver as F, Override as G, KubbPluginStartContext as H, FileManager as I, definePlugin as J, Plugin as K, Exclude as L, Generator$1 as M, GeneratorContext as N, PossibleConfig as O, defineGenerator as P, ResolveOptionsContext as Q, Group as R, KubbInfoContext as S, Adapter as St, KubbSuccessContext as T, createAdapter as Tt, NormalizedPlugin as U, KubbPluginSetupContext as V, Output as W, ResolveBannerContext as X, BannerMeta as Y, ResolveBannerFile as Z, KubbGenerationStartContext as _, Storage as _t, InputPath as a, defineMiddleware as at, KubbHookStartContext as b, RendererFactory as bt, KubbBuildStartContext as c, LoggerOptions as ct, KubbErrorContext as d, FileProcessor as dt, ResolverContext as et, KubbFileProcessingUpdate as f, FileProcessorEvents as ft, KubbGenerationEndContext as g, DevtoolsOptions as gt, KubbFilesProcessingUpdateContext as h, defineParser as ht, InputData as i, Middleware as it, isInputPath as j, UserConfig as k, KubbConfigEndContext as l, UserLogger as lt, KubbFilesProcessingStartContext as m, Parser as mt, CLIOptions as n, ResolverPathParams as nt, Kubb$1 as o, Logger as ot, KubbFilesProcessingEndContext as p, ParsedFile as pt, PluginFactoryOptions as q, Config as r, defineResolver as rt, KubbBuildEndContext as s, LoggerContext as st, BuildOutput as t, ResolverFileParams as tt, KubbDebugContext as u, defineLogger as ut, KubbGenerationSummaryContext as v, createStorage as vt, KubbPluginsEndContext as w, AdapterSource as wt, KubbHooks as x, createRenderer as xt, KubbHookEndContext as y, Renderer as yt, Include as z };
2501
+ //# sourceMappingURL=createKubb-6zii1jo-.d.ts.map