@kubb/core 5.0.0-beta.36 → 5.0.0-beta.37

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.
@@ -71,6 +71,20 @@ declare class AsyncEventEmitter<TEvents extends { [K in keyof TEvents]: unknown[
71
71
  * ```
72
72
  */
73
73
  listenerCount<TEventName extends keyof TEvents & string>(eventName: TEventName): number;
74
+ /**
75
+ * Raises or lowers the per-event listener ceiling before Node warns about a memory leak.
76
+ * Set this above the expected listener count when many listeners attach by design.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * emitter.setMaxListeners(40)
81
+ * ```
82
+ */
83
+ setMaxListeners(max: number): void;
84
+ /**
85
+ * Returns the current per-event listener ceiling.
86
+ */
87
+ getMaxListeners(): number;
74
88
  /**
75
89
  * Removes all listeners from every event channel.
76
90
  *
@@ -110,8 +124,98 @@ declare const logLevel: {
110
124
  readonly warn: 1;
111
125
  readonly info: 3;
112
126
  readonly verbose: 4;
113
- readonly debug: 5;
114
127
  };
128
+ /**
129
+ * Stable codes Kubb attaches to a `Diagnostic`. Each maps to a known failure mode
130
+ * and stays stable so it can be referenced in tooling and (later) docs. Reference
131
+ * these instead of inlining the string at a throw site.
132
+ */
133
+ declare const diagnosticCode: {
134
+ /**
135
+ * Fallback for an unstructured error with no specific code.
136
+ */
137
+ readonly unknown: "KUBB_UNKNOWN";
138
+ /**
139
+ * The `input.path` file or URL could not be read.
140
+ */
141
+ readonly inputNotFound: "KUBB_INPUT_NOT_FOUND";
142
+ /**
143
+ * An adapter was configured without an `input`.
144
+ */
145
+ readonly inputRequired: "KUBB_INPUT_REQUIRED";
146
+ /**
147
+ * A `$ref` (or equivalent reference) could not be resolved in the source document.
148
+ */
149
+ readonly refNotFound: "KUBB_REF_NOT_FOUND";
150
+ /**
151
+ * A server variable value is not allowed by its `enum`.
152
+ */
153
+ readonly invalidServerVariable: "KUBB_INVALID_SERVER_VARIABLE";
154
+ /**
155
+ * A required plugin is missing from the config.
156
+ */
157
+ readonly pluginNotFound: "KUBB_PLUGIN_NOT_FOUND";
158
+ /**
159
+ * A plugin threw while generating.
160
+ */
161
+ readonly pluginFailed: "KUBB_PLUGIN_FAILED";
162
+ /**
163
+ * A plugin reported a non-fatal warning through `ctx.warn`.
164
+ */
165
+ readonly pluginWarning: "KUBB_PLUGIN_WARNING";
166
+ /**
167
+ * A plugin reported an informational message through `ctx.info`.
168
+ */
169
+ readonly pluginInfo: "KUBB_PLUGIN_INFO";
170
+ /**
171
+ * A schema uses a `format` Kubb does not map to a specific type. Reserved for
172
+ * adapters to emit as a `warning`.
173
+ */
174
+ readonly unsupportedFormat: "KUBB_UNSUPPORTED_FORMAT";
175
+ /**
176
+ * A referenced schema or operation is marked `deprecated`. Reserved for adapters
177
+ * to emit as an `info`.
178
+ */
179
+ readonly deprecated: "KUBB_DEPRECATED";
180
+ /**
181
+ * An adapter is required but the config has none. The build cannot read the input
182
+ * without one.
183
+ */
184
+ readonly adapterRequired: "KUBB_ADAPTER_REQUIRED";
185
+ /**
186
+ * The `devtools` config is set to something other than an object.
187
+ */
188
+ readonly devtoolsInvalid: "KUBB_DEVTOOLS_INVALID";
189
+ /**
190
+ * A resolved output path escapes the output directory, which can stem from a path
191
+ * traversal in the spec or a misconfigured `group.name`.
192
+ */
193
+ readonly pathTraversal: "KUBB_PATH_TRAVERSAL";
194
+ /**
195
+ * A post-generate shell hook (`hooks.done`) exited with a failure.
196
+ */
197
+ readonly hookFailed: "KUBB_HOOK_FAILED";
198
+ /**
199
+ * The formatter pass over the generated files failed.
200
+ */
201
+ readonly formatFailed: "KUBB_FORMAT_FAILED";
202
+ /**
203
+ * The linter pass over the generated files failed.
204
+ */
205
+ readonly lintFailed: "KUBB_LINT_FAILED";
206
+ /**
207
+ * Not a failure. Carries a plugin's elapsed time, summed into the run total.
208
+ */
209
+ readonly performance: "KUBB_PERFORMANCE";
210
+ /**
211
+ * Not a failure. A newer Kubb version is available on npm.
212
+ */
213
+ readonly updateAvailable: "KUBB_UPDATE_AVAILABLE";
214
+ };
215
+ /**
216
+ * Union of the stable {@link diagnosticCode} values.
217
+ */
218
+ type DiagnosticCode = (typeof diagnosticCode)[keyof typeof diagnosticCode];
115
219
  //#endregion
116
220
  //#region src/createAdapter.d.ts
117
221
  /**
@@ -243,6 +347,88 @@ type AdapterBuilder<T extends AdapterFactoryOptions> = (options: T['options']) =
243
347
  */
244
348
  declare function createAdapter<T extends AdapterFactoryOptions = AdapterFactoryOptions>(build: AdapterBuilder<T>): (options?: T['options']) => Adapter<T>;
245
349
  //#endregion
350
+ //#region src/createStorage.d.ts
351
+ /**
352
+ * Backend that persists generated files. Kubb ships with `fsStorage` (writes
353
+ * to disk) and `memoryStorage` (keeps everything in RAM). Implement this
354
+ * interface to write to S3, a database, or any other target.
355
+ */
356
+ type Storage = {
357
+ /**
358
+ * Identifier used in logs and diagnostics (`'fs'`, `'memory'`, `'s3'`).
359
+ */
360
+ readonly name: string;
361
+ /**
362
+ * Returns `true` when an entry for `key` exists.
363
+ */
364
+ hasItem(key: string): Promise<boolean>;
365
+ /**
366
+ * Reads the stored string. Returns `null` when the key is missing.
367
+ */
368
+ getItem(key: string): Promise<string | null>;
369
+ /**
370
+ * Stores `value` under `key`, creating any required structure (directories,
371
+ * buckets, ...).
372
+ */
373
+ setItem(key: string, value: string): Promise<void>;
374
+ /**
375
+ * Deletes the entry for `key`. No-op when the key does not exist.
376
+ */
377
+ removeItem(key: string): Promise<void>;
378
+ /**
379
+ * Returns every key. Pass `base` to filter to keys starting with that prefix.
380
+ */
381
+ getKeys(base?: string): Promise<Array<string>>;
382
+ /**
383
+ * Removes every entry. Pass `base` to scope the wipe to a key prefix.
384
+ */
385
+ clear(base?: string): Promise<void>;
386
+ /**
387
+ * Optional teardown hook called after the build completes. Use to flush
388
+ * buffers, close connections, or release file locks.
389
+ */
390
+ dispose?(): Promise<void>;
391
+ };
392
+ /**
393
+ * Defines a custom storage backend. The builder receives user options and
394
+ * returns a `Storage` implementation. Kubb ships with filesystem and
395
+ * in-memory storages, reach for this when you need to write generated files
396
+ * elsewhere (cloud storage, a database, a remote API).
397
+ *
398
+ * @example In-memory storage (the built-in implementation)
399
+ * ```ts
400
+ * import { createStorage } from '@kubb/core'
401
+ *
402
+ * export const memoryStorage = createStorage(() => {
403
+ * const store = new Map<string, string>()
404
+ *
405
+ * return {
406
+ * name: 'memory',
407
+ * async hasItem(key) {
408
+ * return store.has(key)
409
+ * },
410
+ * async getItem(key) {
411
+ * return store.get(key) ?? null
412
+ * },
413
+ * async setItem(key, value) {
414
+ * store.set(key, value)
415
+ * },
416
+ * async removeItem(key) {
417
+ * store.delete(key)
418
+ * },
419
+ * async getKeys(base) {
420
+ * const keys = [...store.keys()]
421
+ * return base ? keys.filter((k) => k.startsWith(base)) : keys
422
+ * },
423
+ * async clear(base) {
424
+ * if (!base) store.clear()
425
+ * },
426
+ * }
427
+ * })
428
+ * ```
429
+ */
430
+ declare function createStorage<TOptions = Record<string, never>>(build: (options: TOptions) => Storage): (options?: TOptions) => Storage;
431
+ //#endregion
246
432
  //#region src/createRenderer.d.ts
247
433
  /**
248
434
  * Minimal interface any Kubb renderer must satisfy.
@@ -255,7 +441,7 @@ declare function createAdapter<T extends AdapterFactoryOptions = AdapterFactoryO
255
441
  type Renderer<TElement = unknown> = {
256
442
  /**
257
443
  * 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.
444
+ * Called once per render cycle. Must resolve before {@link files} is read.
259
445
  */
260
446
  render(element: TElement): Promise<void>;
261
447
  /**
@@ -294,7 +480,7 @@ type RendererFactory<TElement = unknown> = () => Renderer<TElement>;
294
480
  * (JSX, a template string, a tree of any shape) into `FileNode`s that get
295
481
  * written to disk.
296
482
  *
297
- * Use this to support output formats beyond JSX for instance, a Handlebars
483
+ * Use this to support output formats beyond JSX, for instance, a Handlebars
298
484
  * renderer, a string-template renderer, or a renderer that writes binary
299
485
  * files. Plugins and generators pick the renderer to use via the `renderer`
300
486
  * field on `defineGenerator`.
@@ -327,96 +513,89 @@ type RendererFactory<TElement = unknown> = () => Renderer<TElement>;
327
513
  */
328
514
  declare function createRenderer<TElement = unknown>(factory: RendererFactory<TElement>): RendererFactory<TElement>;
329
515
  //#endregion
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
- */
336
- type Storage = {
337
- /**
338
- * Identifier used in logs and diagnostics (`'fs'`, `'memory'`, `'s3'`).
339
- */
340
- readonly name: string;
516
+ //#region src/devtools.d.ts
517
+ type DevtoolsOptions = {
341
518
  /**
342
- * Returns `true` when an entry for `key` exists.
519
+ * Open the AST inspector in Kubb Studio (`/ast`). Defaults to the main Studio page.
520
+ * @default false
343
521
  */
344
- hasItem(key: string): Promise<boolean>;
522
+ ast?: boolean;
523
+ };
524
+ //#endregion
525
+ //#region src/createReporter.d.ts
526
+ /**
527
+ * A built-in reporter that renders a run's output, independent of the live logger view.
528
+ *
529
+ * - `cli` renders the per-config summary to the terminal (the default).
530
+ * - `json` writes a machine-readable report to stdout, for CI.
531
+ * - `file` writes a config's diagnostics to `.kubb/kubb-<name>-<timestamp>.log`.
532
+ */
533
+ type ReporterName = 'cli' | 'json' | 'file';
534
+ /**
535
+ * One config's outcome within a run, as handed to a {@link Reporter}.
536
+ */
537
+ type GenerationResult = {
538
+ config: Config;
345
539
  /**
346
- * Reads the stored string. Returns `null` when the key is missing.
540
+ * Diagnostics collected while generating this config.
347
541
  */
348
- getItem(key: string): Promise<string | null>;
542
+ diagnostics: Array<Diagnostic>;
349
543
  /**
350
- * Stores `value` under `key`, creating any required structure (directories,
351
- * buckets, ...).
544
+ * Number of files written for this config.
352
545
  */
353
- setItem(key: string, value: string): Promise<void>;
546
+ filesCreated: number;
547
+ status: 'success' | 'failed';
354
548
  /**
355
- * Deletes the entry for `key`. No-op when the key does not exist.
549
+ * `process.hrtime()` snapshot taken when this config started generating.
356
550
  */
357
- removeItem(key: string): Promise<void>;
551
+ hrStart: [number, number];
552
+ };
553
+ /**
554
+ * Render context passed alongside the {@link GenerationResult}, carrying knobs a reporter needs
555
+ * but that are not part of the run data (e.g. verbosity).
556
+ */
557
+ type ReporterContext = {
358
558
  /**
359
- * Returns every key. Pass `base` to filter to keys starting with that prefix.
559
+ * Output verbosity. Use the `logLevel` constants exported from `@kubb/core`
560
+ * (`silent`, `error`, `warn`, `info`, `verbose`, `debug`).
360
561
  */
361
- getKeys(base?: string): Promise<Array<string>>;
562
+ logLevel: (typeof logLevel)[keyof typeof logLevel];
563
+ };
564
+ /**
565
+ * Reporter contract. Unlike a Logger (the live TUI view), a reporter never sees the event
566
+ * emitter. `report` is called once per config with its {@link GenerationResult} and produces
567
+ * output (a terminal summary, a JSON report, a log file).
568
+ */
569
+ type Reporter = {
362
570
  /**
363
- * Removes every entry. Pass `base` to scope the wipe to a key prefix.
571
+ * Display name, matching a {@link ReporterName} for the built-ins.
364
572
  */
365
- clear(base?: string): Promise<void>;
573
+ name: string;
366
574
  /**
367
- * Optional teardown hook called after the build completes. Use to flush
368
- * buffers, close connections, or release file locks.
575
+ * Called once per config with that config's result and the render context.
369
576
  */
370
- dispose?(): Promise<void>;
577
+ report: (result: GenerationResult, context: ReporterContext) => void | Promise<void>;
371
578
  };
579
+ type UserReporter = Reporter;
372
580
  /**
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).
581
+ * Defines a reporter. Returns the reporter unchanged at runtime. It exists for type inference and
582
+ * to mark the value as a reporter, mirroring {@link defineLogger}. Wiring the reporter onto the
583
+ * run's events is the host's job, so the reporter only ever deals with a {@link GenerationResult}.
377
584
  *
378
- * @example In-memory storage (the built-in implementation)
585
+ * @example
379
586
  * ```ts
380
- * import { createStorage } from '@kubb/core'
381
- *
382
- * export const memoryStorage = createStorage(() => {
383
- * const store = new Map<string, string>()
587
+ * import { createReporter, Diagnostics } from '@kubb/core'
384
588
  *
385
- * return {
386
- * name: 'memory',
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
- * },
399
- * async getKeys(base) {
400
- * const keys = [...store.keys()]
401
- * return base ? keys.filter((k) => k.startsWith(base)) : keys
402
- * },
403
- * async clear(base) {
404
- * if (!base) store.clear()
405
- * },
406
- * }
589
+ * export const jsonReporter = createReporter({
590
+ * name: 'json',
591
+ * report(result) {
592
+ * const status = Diagnostics.hasError(result.diagnostics) ? 'failed' : 'success'
593
+ * process.stdout.write(`${JSON.stringify({ status, diagnostics: result.diagnostics }, null, 2)}\n`)
594
+ * },
407
595
  * })
408
596
  * ```
409
597
  */
410
- declare function createStorage<TOptions = Record<string, never>>(build: (options: TOptions) => Storage): (options?: TOptions) => Storage;
411
- //#endregion
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
- };
598
+ declare function createReporter(reporter: UserReporter): Reporter;
420
599
  //#endregion
421
600
  //#region src/defineParser.d.ts
422
601
  type PrintOptions = {
@@ -424,7 +603,7 @@ type PrintOptions = {
424
603
  };
425
604
  /**
426
605
  * 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
606
+ * written to disk. Kubb ships with TypeScript and TSX parsers. Add your own
428
607
  * for new file types (JSON, Markdown, ...).
429
608
  */
430
609
  type Parser<TMeta extends object = object, TNode = unknown> = {
@@ -476,11 +655,16 @@ type Parser<TMeta extends object = object, TNode = unknown> = {
476
655
  declare function defineParser<T extends Parser>(parser: T): T;
477
656
  //#endregion
478
657
  //#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 = {
658
+ /**
659
+ * Hooks fired by a `FileProcessor`.
660
+ *
661
+ * - `start` opens a batch, from `run` or a queue flush.
662
+ * - `update` fires once per file as it is converted.
663
+ * - `end` closes a batch.
664
+ * - `enqueue` fires for every `enqueue` call.
665
+ * - `drain` fires when `drain()` empties the queue with no in-flight batch left.
666
+ */
667
+ type FileProcessorHooks = {
484
668
  start: [files: Array<FileNode>];
485
669
  update: [params: {
486
670
  file: FileNode;
@@ -490,7 +674,12 @@ type FileProcessorEvents = {
490
674
  percentage: number;
491
675
  }];
492
676
  end: [files: Array<FileNode>];
677
+ enqueue: [file: FileNode];
678
+ drain: [];
493
679
  };
680
+ /**
681
+ * Per-file progress record yielded by `stream` and surfaced through the `update` event.
682
+ */
494
683
  type ParsedFile = {
495
684
  file: FileNode;
496
685
  source: string;
@@ -498,22 +687,63 @@ type ParsedFile = {
498
687
  total: number;
499
688
  percentage: number;
500
689
  };
690
+ type FileProcessorOptions = {
691
+ /**
692
+ * Storage destination for queued writes.
693
+ */
694
+ storage: Storage;
695
+ /**
696
+ * Parsers indexed by file extension.
697
+ */
698
+ parsers?: Map<FileNode['extname'], Parser>;
699
+ /**
700
+ * Output extname per source extname, applied during conversion.
701
+ */
702
+ extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
703
+ };
501
704
  /**
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.
705
+ * Turns `FileNode`s into source strings and writes them to storage.
504
706
  *
505
- * @internal
707
+ * Two modes share the same instance. Stateless mode (`parse`, `stream`, `run`) just runs the
708
+ * conversion. Queue mode (`enqueue`, `flush`, `drain`) buffers files deduped by path and
709
+ * writes each batch through storage with up to `STREAM_FLUSH_EVERY` requests in flight.
710
+ *
711
+ * `flush` does not wait for its batch to finish, so dispatch can overlap with IO. The next
712
+ * `flush` or `drain` picks the in-flight batch up. `drain` blocks until everything has been
713
+ * written and is meant for the end of a build.
714
+ *
715
+ * To surface build-level hook signals (`kubb:files:processing:*` and friends) subscribe to
716
+ * `hooks` and re-emit on the kubb bus.
506
717
  */
507
718
  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>>;
719
+ #private;
720
+ readonly hooks: AsyncEventEmitter<FileProcessorHooks>;
721
+ constructor(options: FileProcessorOptions);
722
+ /**
723
+ * Files waiting in the queue.
724
+ */
725
+ get size(): number;
726
+ parse(file: FileNode): string;
727
+ stream(files: ReadonlyArray<FileNode>): Generator<ParsedFile>;
728
+ run(files: Array<FileNode>): Promise<Array<FileNode>>;
729
+ /**
730
+ * Adds a file to the next flush. A later `enqueue` for the same path replaces the previous
731
+ * entry, matching `FileManager.upsert`. Fires the `enqueue` event.
732
+ */
733
+ enqueue(file: FileNode): void;
734
+ /**
735
+ * Starts processing the queued files. Waits for any previous flush to finish (so two
736
+ * batches never run together) and then returns without waiting for the new one. The next
737
+ * `flush` or `drain` picks up the in-flight task.
738
+ */
739
+ flush(): Promise<void>;
740
+ /**
741
+ * Waits for the in-flight flush and writes any files still queued. Fires the `drain` event
742
+ * when both are done.
743
+ */
744
+ drain(): Promise<void>;
515
745
  /**
516
- * Clears all registered event listeners.
746
+ * Clears every listener and the pending queue.
517
747
  */
518
748
  dispose(): void;
519
749
  [Symbol.dispose](): void;
@@ -675,7 +905,7 @@ type ResolveOptionsContext<TOptions> = {
675
905
  * Base constraint for all plugin resolver objects.
676
906
  *
677
907
  * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
678
- * are injected automatically by `defineResolver` extend this type to add custom resolution methods.
908
+ * are injected automatically by `defineResolver`. Extend this type to add custom resolution methods.
679
909
  *
680
910
  * @example
681
911
  * ```ts
@@ -777,7 +1007,7 @@ type ResolverFileParams = {
777
1007
  * Per-file context describing the file a banner/footer is being resolved for.
778
1008
  *
779
1009
  * 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
1010
+ * into `BannerMeta` so a `banner`/`footer` function can branch on the file kind,
781
1011
  * e.g. omit a `'use server'` directive on re-export files.
782
1012
  */
783
1013
  type ResolveBannerFile = {
@@ -828,7 +1058,7 @@ type BannerMeta = InputMeta & {
828
1058
  /**
829
1059
  * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
830
1060
  *
831
- * `output` is optional not every plugin configures a banner/footer.
1061
+ * `output` is optional, since not every plugin configures a banner/footer.
832
1062
  * `config` carries the global Kubb config, used to derive the default Kubb banner.
833
1063
  * `file` carries per-file context forwarded to a `banner`/`footer` function.
834
1064
  *
@@ -847,7 +1077,7 @@ type ResolveBannerContext = {
847
1077
  * Builder type for the plugin-specific resolver fields.
848
1078
  *
849
1079
  * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
850
- * are optional built-in fallbacks are injected when omitted.
1080
+ * are optional, with built-in fallbacks injected when omitted.
851
1081
  *
852
1082
  * Methods in the returned object can call sibling resolver methods via `this`.
853
1083
  */
@@ -861,11 +1091,11 @@ type ResolverBuilder<T extends PluginFactoryOptions> = () => Omit<T['resolver'],
861
1091
  * name casing, include/exclude/override filtering, output path computation,
862
1092
  * and file construction. Supply your own to override any of them:
863
1093
  *
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.
1094
+ * - `default` sets the name casing strategy (camelCase or PascalCase).
1095
+ * - `resolveOptions` does include/exclude/override filtering.
1096
+ * - `resolvePath` computes the output path.
1097
+ * - `resolveFile` builds the full `FileNode`.
1098
+ * - `resolveBanner` and `resolveFooter` produce the top and bottom of file text.
869
1099
  *
870
1100
  * Methods in the returned object can call sibling resolver methods via `this`,
871
1101
  * which keeps custom rules small (`this.default(name, 'type')` to delegate).
@@ -921,8 +1151,8 @@ type Output<_TOptions = unknown> = {
921
1151
  * lint disables, or `@ts-nocheck` directives.
922
1152
  *
923
1153
  * 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
1154
+ * Pass a function to compute the banner from the file's `BannerMeta` document metadata
1155
+ * plus per-file context (`isBarrel`, `isAggregation`, `filePath`, `baseName`), so you can
926
1156
  * skip the banner on specific files.
927
1157
  *
928
1158
  * @example Add a directive to source files but not re-export files
@@ -949,8 +1179,8 @@ type Output<_TOptions = unknown> = {
949
1179
  type Group = {
950
1180
  /**
951
1181
  * 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.
1182
+ * - `'tag'` uses the first tag (`operation.getTags().at(0)?.name`).
1183
+ * - `'path'` uses the first segment of the operation's URL.
954
1184
  */
955
1185
  type: 'tag' | 'path';
956
1186
  /**
@@ -1035,7 +1265,7 @@ type ByContentType = {
1035
1265
  * ]
1036
1266
  * ```
1037
1267
  */
1038
- type Exclude = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1268
+ type Exclude$1 = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1039
1269
  /**
1040
1270
  * Filter that restricts generation to operations or schemas matching at least
1041
1271
  * one entry. Useful for partial builds (one tag, one API version).
@@ -1054,7 +1284,7 @@ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySch
1054
1284
  * options are merged on top of the plugin defaults for that operation only.
1055
1285
  * Useful for "this one tag goes to a different folder" rules.
1056
1286
  *
1057
- * Entries are evaluated top to bottom; the first matching entry wins.
1287
+ * Entries are evaluated top to bottom. The first matching entry wins.
1058
1288
  *
1059
1289
  * @example
1060
1290
  * ```ts
@@ -1073,7 +1303,7 @@ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySch
1073
1303
  * ```
1074
1304
  */
1075
1305
  type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
1076
- options: Partial<TOptions>;
1306
+ options: Omit<Partial<TOptions>, 'override'>;
1077
1307
  };
1078
1308
  type PluginFactoryOptions<
1079
1309
  /**
@@ -1117,10 +1347,6 @@ type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactor
1117
1347
  * Set the AST transformer to pre-process nodes before they reach generators.
1118
1348
  */
1119
1349
  setTransformer(visitor: Visitor): void;
1120
- /**
1121
- * Set the renderer factory to process JSX elements from generators.
1122
- */
1123
- setRenderer(renderer: RendererFactory): void;
1124
1350
  /**
1125
1351
  * Set resolved options merged into the normalized plugin's `options`.
1126
1352
  * Call this in `kubb:plugin:setup` to provide options generators need.
@@ -1163,9 +1389,9 @@ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1163
1389
  /**
1164
1390
  * Controls the execution order of this plugin relative to others.
1165
1391
  *
1166
- * - `'pre'` runs before all normal plugins.
1167
- * - `'post'` runs after all normal plugins.
1168
- * - `undefined` (default) runs in declaration order among normal plugins.
1392
+ * - `'pre'` runs before all normal plugins.
1393
+ * - `'post'` runs after all normal plugins.
1394
+ * - `undefined` (default), runs in declaration order among normal plugins.
1169
1395
  *
1170
1396
  * Dependency constraints always take precedence over `enforce`.
1171
1397
  */
@@ -1184,7 +1410,7 @@ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1184
1410
  };
1185
1411
  /**
1186
1412
  * Normalized plugin after setup, with runtime fields populated.
1187
- * For internal use only plugins use the public `Plugin` type externally.
1413
+ * For internal use only, plugins use the public `Plugin` type externally.
1188
1414
  *
1189
1415
  * @internal
1190
1416
  */
@@ -1192,12 +1418,11 @@ type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1192
1418
  options: TOptions['resolvedOptions'] & {
1193
1419
  output: Output;
1194
1420
  include?: Array<Include>;
1195
- exclude: Array<Exclude>;
1421
+ exclude: Array<Exclude$1>;
1196
1422
  override: Array<Override<TOptions['resolvedOptions']>>;
1197
1423
  };
1198
1424
  resolver: TOptions['resolver'];
1199
1425
  transformer?: Visitor;
1200
- renderer?: RendererFactory;
1201
1426
  generators?: Array<Generator$1>;
1202
1427
  apply?: (config: Config) => boolean;
1203
1428
  version?: string;
@@ -1247,6 +1472,14 @@ type KubbPluginEndContext = {
1247
1472
  declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
1248
1473
  //#endregion
1249
1474
  //#region src/FileManager.d.ts
1475
+ /**
1476
+ * Hooks fired by a `FileManager`.
1477
+ *
1478
+ * - `upsert` fires once per resolved file added through `add` or `upsert`.
1479
+ */
1480
+ type FileManagerHooks = {
1481
+ upsert: [file: FileNode];
1482
+ };
1250
1483
  /**
1251
1484
  * In-memory file store for generated files. Files sharing a `path` are merged
1252
1485
  * (sources/imports/exports concatenated). The `files` getter is sorted by
@@ -1262,25 +1495,24 @@ declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFact
1262
1495
  declare class FileManager {
1263
1496
  #private;
1264
1497
  /**
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.
1498
+ * Subscribe to file-store changes. Listeners on `upsert` see each resolved file as it lands
1499
+ * through `add` or `upsert`.
1269
1500
  */
1270
- setOnUpsert(callback: ((file: FileNode) => void) | null): void;
1501
+ readonly hooks: AsyncEventEmitter<FileManagerHooks>;
1271
1502
  add(...files: Array<FileNode>): Array<FileNode>;
1272
1503
  upsert(...files: Array<FileNode>): Array<FileNode>;
1273
1504
  getByPath(path: string): FileNode | null;
1274
1505
  deleteByPath(path: string): void;
1275
1506
  clear(): void;
1276
1507
  /**
1277
- * Releases all stored files. Called by the core after `kubb:build:end`.
1508
+ * Releases all stored files and clears every `hooks` listener. Called by the core after
1509
+ * `kubb:build:end`.
1278
1510
  */
1279
1511
  dispose(): void;
1280
1512
  [Symbol.dispose](): void;
1281
1513
  /**
1282
1514
  * 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.
1515
+ * last within a length bucket). Returns a cached view, do not mutate.
1284
1516
  */
1285
1517
  get files(): Array<FileNode>;
1286
1518
  }
@@ -1305,14 +1537,14 @@ declare class KubbDriver {
1305
1537
  static getMode(fileOrFolder: string | undefined | null): 'single' | 'split';
1306
1538
  /**
1307
1539
  * The streaming `InputStreamNode` produced by the adapter.
1308
- * Always set after adapter setup parse-only adapters are wrapped automatically.
1540
+ * Always set after adapter setup, parse-only adapters are wrapped automatically.
1309
1541
  */
1310
1542
  inputNode: InputStreamNode | null;
1311
1543
  adapter: Adapter | null;
1312
1544
  /**
1313
1545
  * Central file store for all generated files.
1314
1546
  * Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
1315
- * add files; this property gives direct read/write access when needed.
1547
+ * add files. This property gives direct read/write access when needed.
1316
1548
  */
1317
1549
  readonly fileManager: FileManager;
1318
1550
  readonly plugins: Map<string, NormalizedPlugin>;
@@ -1334,13 +1566,12 @@ declare class KubbDriver {
1334
1566
  * respectively. Each listener is scoped to the owning plugin via a `ctx.plugin.name` check
1335
1567
  * so that generators from different plugins do not cross-fire.
1336
1568
  *
1337
- * The renderer resolution chain is: `generator.renderer plugin.renderer config.renderer`.
1338
- * Set `generator.renderer = null` to explicitly opt out of rendering even when the plugin
1339
- * declares a renderer.
1569
+ * The renderer comes from `generator.renderer`. Set `generator.renderer = null` (or leave it
1570
+ * unset) to opt out of rendering.
1340
1571
  *
1341
1572
  * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
1342
1573
  */
1343
- registerGenerator(pluginName: string, gen: Generator$1): void;
1574
+ registerGenerator(pluginName: string, generator: Generator$1): void;
1344
1575
  /**
1345
1576
  * Returns `true` when at least one generator was registered for the given plugin
1346
1577
  * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
@@ -1350,25 +1581,40 @@ declare class KubbDriver {
1350
1581
  */
1351
1582
  hasEventGenerators(pluginName: string): boolean;
1352
1583
  /**
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.
1584
+ * Runs the full plugin pipeline. Returns the diagnostics collected so far even
1585
+ * when an outer hook throws, since the orchestrator preserves partial state by capturing
1586
+ * the failure as a {@link Diagnostic} instead of propagating. Each plugin also
1587
+ * contributes a `timing` diagnostic for the run summary.
1356
1588
  */
1357
1589
  run({
1358
1590
  storage
1359
1591
  }: {
1360
1592
  storage: Storage;
1361
1593
  }): Promise<{
1362
- failedPlugins: Set<{
1363
- plugin: Plugin;
1364
- error: Error;
1365
- }>;
1366
- pluginTimings: Map<string, number>;
1367
- error?: Error;
1594
+ diagnostics: Array<Diagnostic>;
1368
1595
  }>;
1369
1596
  /**
1370
- * Unregisters all plugin lifecycle listeners from the shared event emitter.
1371
- * Called at the end of a build to prevent listener leaks across repeated builds.
1597
+ * Stores whatever a generator method or `kubb:generate:*` hook returned.
1598
+ *
1599
+ * - An `Array<FileNode>` goes straight into `fileManager` via `upsert`.
1600
+ * - A renderer element runs through `renderer` (the renderer factory, e.g. JSX) and the
1601
+ * produced files go to `fileManager.upsert`.
1602
+ * - A falsy result is treated as a no-op. The generator wrote files itself via
1603
+ * `ctx.upsertFile`.
1604
+ *
1605
+ * Pass `renderer` when the result may be a renderer element. Generators that only return
1606
+ * `Array<FileNode>` do not need one.
1607
+ */
1608
+ dispatch<TElement = unknown>({
1609
+ result,
1610
+ renderer
1611
+ }: {
1612
+ result: TElement | Array<FileNode> | undefined | null;
1613
+ renderer?: RendererFactory<TElement> | null;
1614
+ }): Promise<void>;
1615
+ /**
1616
+ * Removes every listener the driver added. Listeners attached directly to `hooks` from outside
1617
+ * the driver survive. Called at the end of a build to prevent leaks across repeated builds.
1372
1618
  *
1373
1619
  * @internal
1374
1620
  */
@@ -1457,15 +1703,20 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1457
1703
  */
1458
1704
  transformer: Visitor | undefined;
1459
1705
  /**
1460
- * Emit a warning.
1706
+ * Report a warning. Collected as a `warning` diagnostic attributed to the current
1707
+ * plugin. It surfaces in the run summary but does not fail the build. For a structured
1708
+ * diagnostic with a code and source location, use `Diagnostics.report` or throw a
1709
+ * `DiagnosticError` directly.
1461
1710
  */
1462
1711
  warn: (message: string) => void;
1463
1712
  /**
1464
- * Emit an error.
1713
+ * Report an error. Collected as an `error` diagnostic attributed to the current
1714
+ * plugin, which fails the build.
1465
1715
  */
1466
1716
  error: (error: string | Error) => void;
1467
1717
  /**
1468
- * Emit an info message.
1718
+ * Report an informational message. Collected as an `info` diagnostic attributed to
1719
+ * the current plugin.
1469
1720
  */
1470
1721
  info: (message: string) => void;
1471
1722
  /**
@@ -1477,7 +1728,7 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1477
1728
  */
1478
1729
  adapter: Adapter;
1479
1730
  /**
1480
- * Document metadata from the adapter title, version, base URL, and pre-computed
1731
+ * Document metadata from the adapter: title, version, base URL, and pre-computed
1481
1732
  * schema index fields (`circularNames`, `enumNames`).
1482
1733
  */
1483
1734
  meta: InputMeta;
@@ -1523,8 +1774,7 @@ type Generator$1<TOptions extends PluginFactoryOptions = PluginFactoryOptions, T
1523
1774
  *
1524
1775
  * Generators that only return `Array<FileNode>` or `void` do not need to set this.
1525
1776
  *
1526
- * Set `renderer: null` to explicitly opt out of rendering even when the parent plugin
1527
- * declares a `renderer` (overrides the plugin-level fallback).
1777
+ * Leave it unset or set `renderer: null` to opt out of rendering.
1528
1778
  *
1529
1779
  * @example
1530
1780
  * ```ts
@@ -1563,7 +1813,7 @@ type Generator$1<TOptions extends PluginFactoryOptions = PluginFactoryOptions, T
1563
1813
  * The returned object is the input as-is, but with `this` types preserved so
1564
1814
  * `schema`/`operation`/`operations` methods are correctly typed against the
1565
1815
  * plugin's `PluginFactoryOptions`. Renderer elements and `FileNode[]` returns
1566
- * are both handled by the runtime pick whichever style fits.
1816
+ * are both handled by the runtime, so pick whichever style fits.
1567
1817
  *
1568
1818
  * @example JSX-based schema generator
1569
1819
  * ```tsx
@@ -1595,10 +1845,8 @@ declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginF
1595
1845
  */
1596
1846
  type ExtractRegistryKey<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
1597
1847
  /**
1598
- * Reference to an input file to generate code from.
1599
- *
1600
- * Specify an absolute path or a path relative to the config file location.
1601
- * The adapter will parse this file (e.g., OpenAPI YAML or JSON) into the universal AST.
1848
+ * Path to an input file to generate from, absolute or relative to the config file. The adapter
1849
+ * parses it (e.g. an OpenAPI YAML or JSON spec) into the universal AST.
1602
1850
  */
1603
1851
  type InputPath = {
1604
1852
  /**
@@ -1613,10 +1861,8 @@ type InputPath = {
1613
1861
  path: string;
1614
1862
  };
1615
1863
  /**
1616
- * Inline input data to generate code from.
1617
- *
1618
- * Useful when you want to pass the specification directly instead of from a file.
1619
- * Can be a string (YAML/JSON) or a parsed object.
1864
+ * Inline spec to generate from, passed directly instead of read from a file. A string
1865
+ * (YAML/JSON) or a parsed object.
1620
1866
  */
1621
1867
  type InputData = {
1622
1868
  /**
@@ -1632,15 +1878,9 @@ type InputData = {
1632
1878
  };
1633
1879
  type Input = InputPath | InputData;
1634
1880
  /**
1635
- * Build configuration for Kubb code generation.
1636
- *
1637
- * The Config is the main entry point for customizing how Kubb generates code. It specifies:
1638
- * - What to generate from (adapter + input)
1639
- * - Where to output generated code (output)
1640
- * - How to generate (plugins + middleware)
1641
- * - Runtime details (parsers, storage, renderer)
1642
- *
1643
- * See `UserConfig` for a relaxed version with sensible defaults.
1881
+ * Resolved build configuration for a Kubb run: what to generate from (adapter, input), where to
1882
+ * write it (output), how (plugins, middleware), and the runtime pieces (parsers, storage). See
1883
+ * `UserConfig` for the relaxed form with defaults applied.
1644
1884
  *
1645
1885
  * @private
1646
1886
  */
@@ -1657,16 +1897,16 @@ type Config<TInput = Input> = {
1657
1897
  name?: string;
1658
1898
  /**
1659
1899
  * 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()`.
1900
+ * resolved on the `Config` instance (see `UserConfig` for the optional
1901
+ * form that defaults to `process.cwd()`).
1662
1902
  */
1663
1903
  root: string;
1664
1904
  /**
1665
1905
  * Parsers that convert generated files into strings. Each parser handles a
1666
- * set of file extensions; a fallback parser handles anything else.
1906
+ * set of file extensions, and a fallback parser handles anything else.
1667
1907
  *
1668
- * Already resolved on the `Config` instance see `UserConfig` for the
1669
- * optional form that defaults to `[parserTs, parserTsx, parserMd]`.
1908
+ * Already resolved on the `Config` instance (see `UserConfig` for the
1909
+ * optional form that defaults to `[parserTs, parserTsx, parserMd]`).
1670
1910
  *
1671
1911
  * @example
1672
1912
  * ```ts
@@ -1700,15 +1940,13 @@ type Config<TInput = Input> = {
1700
1940
  /**
1701
1941
  * Source file or data to generate code from.
1702
1942
  * 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.
1943
+ * Required when an adapter is configured. Omit it when running in plugin-only mode.
1704
1944
  */
1705
1945
  input?: TInput;
1706
1946
  output: {
1707
1947
  /**
1708
- * Output directory for generated files, absolute or relative to `root`.
1709
- *
1710
- * All generated files will be written under this directory. Subdirectories can be created
1711
- * by plugins based on grouping strategy (by tag, path, etc.).
1948
+ * Output directory for generated files, absolute or relative to `root`. Plugins can nest
1949
+ * subdirectories under it by grouping strategy (tag, path).
1712
1950
  *
1713
1951
  * @example
1714
1952
  * ```ts
@@ -1719,10 +1957,8 @@ type Config<TInput = Input> = {
1719
1957
  */
1720
1958
  path: string;
1721
1959
  /**
1722
- * Remove all files from the output directory before starting the build.
1723
- *
1724
- * Useful to ensure old generated files aren't mixed with new ones.
1725
- * Set to `true` for fresh builds, `false` to preserve manual edits in output dir.
1960
+ * Remove every file in the output directory before the build, so stale output isn't mixed
1961
+ * with new files. Leave `false` to preserve manual edits in the output directory.
1726
1962
  *
1727
1963
  * @default false
1728
1964
  * @example
@@ -1732,10 +1968,8 @@ type Config<TInput = Input> = {
1732
1968
  */
1733
1969
  clean?: boolean;
1734
1970
  /**
1735
- * Auto-format generated files after code generation completes.
1736
- *
1737
- * Applies a code formatter to all generated files. Use `'auto'` to detect which formatter
1738
- * is available on your system. Pass `false` to skip formatting (useful for CI or specific workflows).
1971
+ * Format the generated files after generation. `'auto'` runs the first formatter it finds
1972
+ * (oxfmt, biome, or prettier), a named tool forces that one, and `false` skips formatting.
1739
1973
  *
1740
1974
  * @default false
1741
1975
  * @example
@@ -1747,10 +1981,8 @@ type Config<TInput = Input> = {
1747
1981
  */
1748
1982
  format?: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false;
1749
1983
  /**
1750
- * Auto-lint generated files after code generation completes.
1751
- *
1752
- * Analyzes all generated files for style/correctness issues. Use `'auto'` to detect which linter
1753
- * is available on your system. Pass `false` to skip linting.
1984
+ * Lint the generated files after generation. `'auto'` runs the first linter it finds
1985
+ * (oxlint, biome, or eslint), a named tool forces that one, and `false` skips linting.
1754
1986
  *
1755
1987
  * @default false
1756
1988
  * @example
@@ -1762,10 +1994,8 @@ type Config<TInput = Input> = {
1762
1994
  */
1763
1995
  lint?: 'auto' | 'eslint' | 'biome' | 'oxlint' | false;
1764
1996
  /**
1765
- * Map file extensions to different output extensions.
1766
- *
1767
- * Useful when you want generated `.ts` imports to reference `.js` files or vice versa (e.g., for ESM dual packages).
1768
- * Keys are the original extension, values are the output extension. Use empty string `''` to omit extension.
1997
+ * Rewrite import extensions in generated files, e.g. emit `.js` imports from `.ts` sources for
1998
+ * ESM dual packages. Keys are the source extension, values the output, and `''` drops it.
1769
1999
  *
1770
2000
  * @default { '.ts': '.ts' }
1771
2001
  * @example
@@ -1776,10 +2006,8 @@ type Config<TInput = Input> = {
1776
2006
  */
1777
2007
  extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
1778
2008
  /**
1779
- * Banner text prepended to every generated file.
1780
- *
1781
- * Useful for auto-generation notices or license headers. Choose a preset or write custom text.
1782
- * Use `'simple'` for a basic Kubb banner, `'full'` for detailed metadata, or `false` to omit.
2009
+ * Banner prepended to every generated file. `'simple'` is the basic Kubb notice, `'full'` adds
2010
+ * source, title, description, and API version, and `false` omits it.
1783
2011
  *
1784
2012
  * @default 'simple'
1785
2013
  * @example
@@ -1791,10 +2019,8 @@ type Config<TInput = Input> = {
1791
2019
  */
1792
2020
  defaultBanner?: 'simple' | 'full' | false;
1793
2021
  /**
1794
- * When `true`, overwrites existing files. When `false`, skips generated files that already exist.
1795
- *
1796
- * Individual plugins can override this setting. This is useful for preventing accidental data loss
1797
- * when re-generating while you have local edits in the output folder.
2022
+ * Overwrite existing files when `true`, skip files that already exist when `false`. Individual
2023
+ * plugins can override it. Keep `false` to avoid clobbering local edits in the output folder.
1798
2024
  *
1799
2025
  * @default false
1800
2026
  * @example
@@ -1806,10 +2032,8 @@ type Config<TInput = Input> = {
1806
2032
  override?: boolean;
1807
2033
  } & ExtractRegistryKey<Kubb$1.ConfigOptionsRegistry, 'output'>;
1808
2034
  /**
1809
- * Storage backend that controls where and how generated files are persisted.
1810
- *
1811
- * Defaults to `fsStorage()` which writes to the file system. Pass `memoryStorage()` to keep files in RAM,
1812
- * or implement a custom `Storage` interface to write to cloud storage, databases, or other backends.
2035
+ * Where generated files are persisted. Defaults to `fsStorage()` (disk). Pass `memoryStorage()`
2036
+ * to keep files in RAM, or implement `Storage` for a custom backend such as cloud or a database.
1813
2037
  *
1814
2038
  * @default fsStorage()
1815
2039
  * @example
@@ -1827,13 +2051,9 @@ type Config<TInput = Input> = {
1827
2051
  */
1828
2052
  storage: Storage;
1829
2053
  /**
1830
- * Plugins that execute during the build to generate code and transform the AST.
1831
- *
1832
- * Each plugin processes the AST produced by the adapter and can emit files for different
1833
- * programming languages or formats (TypeScript, Zod schemas, Faker data, etc.).
1834
- * Dependencies are enforced — an error is thrown if a plugin requires another plugin that isn't registered.
1835
- *
1836
- * Plugins can declare their own options via `PluginFactoryOptions`. See plugin documentation for details.
2054
+ * Plugins that run during the build to generate code and transform the AST. Each one processes
2055
+ * the adapter's AST and can emit files for a different target (TypeScript, Zod, Faker). A plugin
2056
+ * that depends on another throws when that plugin isn't registered.
1837
2057
  *
1838
2058
  * @example
1839
2059
  * ```ts
@@ -1866,22 +2086,6 @@ type Config<TInput = Input> = {
1866
2086
  * @see {@link defineMiddleware} to create custom middleware.
1867
2087
  */
1868
2088
  middleware?: Array<Middleware>;
1869
- /**
1870
- * Renderer that converts generated AST nodes to code strings.
1871
- *
1872
- * By default, Kubb uses the JSX renderer (`rendererJsx`). Pass a custom renderer to support
1873
- * different output formats (template engines, code generation DSLs, etc.).
1874
- *
1875
- * @default rendererJsx() // from @kubb/renderer-jsx
1876
- * @example
1877
- * ```ts
1878
- * import { rendererJsx } from '@kubb/renderer-jsx'
1879
- * renderer: rendererJsx()
1880
- * ```
1881
- *
1882
- * @see {@link Renderer} to implement a custom renderer.
1883
- */
1884
- renderer?: RendererFactory;
1885
2089
  /**
1886
2090
  * Kubb Studio cloud integration settings.
1887
2091
  *
@@ -1933,13 +2137,29 @@ type Config<TInput = Input> = {
1933
2137
  */
1934
2138
  done?: string | Array<string>;
1935
2139
  };
2140
+ /**
2141
+ * Reporters that render the run's output, like Vitest. List one or more by name;
2142
+ * the CLI `--reporter` flag overrides this when set.
2143
+ *
2144
+ * - `cli` writes the end-of-run summary to the terminal.
2145
+ * - `json` writes a machine-readable report to stdout, for CI.
2146
+ * - `file` writes a debug log to `.kubb/<name>-<timestamp>.log`.
2147
+ *
2148
+ * @default ['cli']
2149
+ *
2150
+ * @example
2151
+ * ```ts
2152
+ * reporters: ['cli', 'file']
2153
+ * ```
2154
+ */
2155
+ reporters?: Array<ReporterName>;
1936
2156
  };
1937
2157
  /**
1938
2158
  * Partial `Config` for user-facing entry points with sensible defaults.
1939
2159
  *
1940
2160
  * `UserConfig` is what you pass to `defineConfig()`. It has optional `root`, `plugins`, `parsers`, and `adapter`
1941
2161
  * fields (which fall back to sensible defaults). All other Config options are available, including `output`, `input`,
1942
- * `storage`, `middleware`, `renderer`, `devtools`, and `hooks`.
2162
+ * `storage`, `middleware`, `devtools`, and `hooks`.
1943
2163
  *
1944
2164
  * @example
1945
2165
  * ```ts
@@ -2061,7 +2281,6 @@ interface KubbHooks {
2061
2281
  'kubb:config:end': [ctx: KubbConfigEndContext];
2062
2282
  'kubb:generation:start': [ctx: KubbGenerationStartContext];
2063
2283
  'kubb:generation:end': [ctx: KubbGenerationEndContext];
2064
- 'kubb:generation:summary': [ctx: KubbGenerationSummaryContext];
2065
2284
  'kubb:format:start': [];
2066
2285
  'kubb:format:end': [];
2067
2286
  'kubb:lint:start': [];
@@ -2070,12 +2289,11 @@ interface KubbHooks {
2070
2289
  'kubb:hooks:end': [];
2071
2290
  'kubb:hook:start': [ctx: KubbHookStartContext];
2072
2291
  'kubb:hook:end': [ctx: KubbHookEndContext];
2073
- 'kubb:version:new': [ctx: KubbVersionNewContext];
2074
2292
  'kubb:info': [ctx: KubbInfoContext];
2075
2293
  'kubb:error': [ctx: KubbErrorContext];
2076
2294
  'kubb:success': [ctx: KubbSuccessContext];
2077
2295
  'kubb:warn': [ctx: KubbWarnContext];
2078
- 'kubb:debug': [ctx: KubbDebugContext];
2296
+ 'kubb:diagnostic': [ctx: KubbDiagnosticContext];
2079
2297
  'kubb:files:processing:start': [ctx: KubbFilesProcessingStartContext];
2080
2298
  'kubb:files:processing:update': [ctx: KubbFilesProcessingUpdateContext];
2081
2299
  'kubb:files:processing:end': [ctx: KubbFilesProcessingEndContext];
@@ -2170,7 +2388,7 @@ type KubbGenerationEndContext = {
2170
2388
  config: Config;
2171
2389
  /**
2172
2390
  * Read-only view of the files written during this build.
2173
- * Reads go directly to `config.storage` nothing extra is held in memory.
2391
+ * Reads go directly to `config.storage`, nothing extra is held in memory.
2174
2392
  *
2175
2393
  * @example Read a generated file
2176
2394
  * `const code = await storage.getItem('/src/gen/pet.ts')`
@@ -2183,45 +2401,24 @@ type KubbGenerationEndContext = {
2183
2401
  * ```
2184
2402
  */
2185
2403
  storage: Storage;
2186
- };
2187
- type KubbGenerationSummaryContext = {
2188
2404
  /**
2189
- * Resolved configuration for this generation run.
2405
+ * Diagnostics collected during the build: error/warning/info problems plus a
2406
+ * `timing` diagnostic per plugin. The end-of-run summary derives its failure counts
2407
+ * and per-plugin timings from these. Set by the CLI runner, omitted by other callers.
2190
2408
  */
2191
- config: Config;
2192
- /**
2193
- * Plugins that threw during generation, paired with their errors.
2194
- */
2195
- failedPlugins: Set<{
2196
- plugin: Plugin;
2197
- error: Error;
2198
- }>;
2409
+ diagnostics?: Array<Diagnostic>;
2199
2410
  /**
2200
2411
  * `'success'` when all plugins completed without errors, `'failed'` otherwise.
2201
2412
  */
2202
- status: 'success' | 'failed';
2413
+ status?: 'success' | 'failed';
2203
2414
  /**
2204
- * High-resolution start time from `process.hrtime()`.
2415
+ * High-resolution start time from `process.hrtime()`, used to compute the elapsed time.
2205
2416
  */
2206
- hrStart: [number, number];
2417
+ hrStart?: [number, number];
2207
2418
  /**
2208
2419
  * Total number of files created during this run.
2209
2420
  */
2210
- filesCreated: number;
2211
- /**
2212
- * Elapsed milliseconds per plugin, keyed by plugin name.
2213
- */
2214
- pluginTimings?: Map<Plugin['name'], number>;
2215
- };
2216
- type KubbVersionNewContext = {
2217
- /**
2218
- * The installed Kubb version.
2219
- */
2220
- currentVersion: string;
2221
- /**
2222
- * The newest available version on npm.
2223
- */
2224
- latestVersion: string;
2421
+ filesCreated?: number;
2225
2422
  };
2226
2423
  type KubbInfoContext = {
2227
2424
  /**
@@ -2263,19 +2460,11 @@ type KubbWarnContext = {
2263
2460
  */
2264
2461
  info?: string;
2265
2462
  };
2266
- type KubbDebugContext = {
2267
- /**
2268
- * Timestamp when the debug entry was created.
2269
- */
2270
- date: Date;
2463
+ type KubbDiagnosticContext = {
2271
2464
  /**
2272
- * One or more log lines to emit.
2465
+ * The structured diagnostic to render: a build problem or a version-update notice.
2273
2466
  */
2274
- logs: Array<string>;
2275
- /**
2276
- * Optional source file name associated with this entry.
2277
- */
2278
- fileName?: string;
2467
+ diagnostic: ProblemDiagnostic | UpdateDiagnostic;
2279
2468
  };
2280
2469
  type KubbFilesProcessingStartContext = {
2281
2470
  /**
@@ -2293,7 +2482,7 @@ type KubbFileProcessingUpdate = {
2293
2482
  */
2294
2483
  total: number;
2295
2484
  /**
2296
- * Completion percentage (`0`–`100`).
2485
+ * Completion percentage, `0` to `100`.
2297
2486
  */
2298
2487
  percentage: number;
2299
2488
  /**
@@ -2379,7 +2568,11 @@ type CLIOptions = {
2379
2568
  *
2380
2569
  * @default 'info'
2381
2570
  */
2382
- logLevel?: 'silent' | 'info' | 'verbose' | 'debug';
2571
+ logLevel?: 'silent' | 'info' | 'verbose';
2572
+ /**
2573
+ * Reporters selected on the CLI via `--reporter`, overriding `config.reporters`.
2574
+ */
2575
+ reporters?: Array<ReporterName>;
2383
2576
  };
2384
2577
  /**
2385
2578
  * All accepted forms of a Kubb configuration.
@@ -2391,12 +2584,12 @@ type PossibleConfig<TCliOptions = undefined> = PossiblePromise<Config | Array<Co
2391
2584
  */
2392
2585
  type BuildOutput = {
2393
2586
  /**
2394
- * Plugins that threw during generation, paired with their errors.
2587
+ * Structured diagnostics collected during the build: error/warning/info problems
2588
+ * (each with a code, severity, and where known a JSON-pointer location) plus a
2589
+ * `timing` diagnostic per plugin. Includes a top-level diagnostic when the build
2590
+ * threw before completing. Use {@link Diagnostics.hasError} to test for failure.
2395
2591
  */
2396
- failedPlugins: Set<{
2397
- plugin: Plugin;
2398
- error: Error;
2399
- }>;
2592
+ diagnostics: Array<Diagnostic>;
2400
2593
  /**
2401
2594
  * All files generated during this build.
2402
2595
  */
@@ -2405,17 +2598,9 @@ type BuildOutput = {
2405
2598
  * The plugin driver that orchestrated this build.
2406
2599
  */
2407
2600
  driver: KubbDriver;
2408
- /**
2409
- * Elapsed milliseconds per plugin, keyed by plugin name.
2410
- */
2411
- pluginTimings: Map<string, number>;
2412
- /**
2413
- * Top-level error when the build threw before completing, otherwise `undefined`.
2414
- */
2415
- error?: Error;
2416
2601
  /**
2417
2602
  * Read-only view of every file written during this build.
2418
- * Reads go straight to `config.storage` nothing extra is held in memory.
2603
+ * Reads go straight to `config.storage`, nothing extra is held in memory.
2419
2604
  *
2420
2605
  * @example Read a generated file
2421
2606
  * `const code = await buildOutput.storage.getItem('/src/gen/pet.ts')`
@@ -2448,7 +2633,7 @@ type CreateKubbOptions = {
2448
2633
  * ```ts
2449
2634
  * const kubb = createKubb(userConfig)
2450
2635
  * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
2451
- * const { files, failedPlugins } = await kubb.safeBuild()
2636
+ * const { files, diagnostics } = await kubb.safeBuild()
2452
2637
  * ```
2453
2638
  */
2454
2639
  declare class Kubb$1 {
@@ -2497,5 +2682,323 @@ declare class Kubb$1 {
2497
2682
  */
2498
2683
  declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
2499
2684
  //#endregion
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-BKpcUB6g.d.ts.map
2685
+ //#region src/diagnostics.d.ts
2686
+ /**
2687
+ * How serious a diagnostic is. `error` fails the build, `warning` and `info`
2688
+ * are reported but do not.
2689
+ */
2690
+ type DiagnosticSeverity = 'error' | 'warning' | 'info';
2691
+ /**
2692
+ * A human-readable explanation of a diagnostic code: a short title, what triggers it, and how
2693
+ * to resolve it. This is the single source of truth the kubb.dev `/diagnostics/<slug>` pages
2694
+ * mirror, so every code stays documented in one place. Typed as a total record over
2695
+ * {@link DiagnosticCode}, so adding a code without documenting it fails the build.
2696
+ */
2697
+ type DiagnosticDoc = {
2698
+ /**
2699
+ * Short title shown as the docs heading.
2700
+ */
2701
+ title: string;
2702
+ /**
2703
+ * What triggers the diagnostic.
2704
+ */
2705
+ cause: string;
2706
+ /**
2707
+ * The action that resolves it.
2708
+ */
2709
+ fix: string;
2710
+ };
2711
+ /**
2712
+ * Points a diagnostic back into the source document. Inputs are parsed into an
2713
+ * object model with no line/column, so locations carry a JSON pointer the adapter
2714
+ * builds (the OAS adapter emits `#/components/schemas/Pet`). A `config` diagnostic
2715
+ * points at the Kubb config itself and so has no pointer.
2716
+ */
2717
+ type DiagnosticLocation = {
2718
+ kind: 'schema';
2719
+ /**
2720
+ * RFC 6901 JSON pointer into the source document.
2721
+ */
2722
+ pointer: string;
2723
+ /**
2724
+ * The original reference when the diagnostic stems from an unresolved one.
2725
+ */
2726
+ ref?: string;
2727
+ } | {
2728
+ kind: 'operation' | 'document';
2729
+ /**
2730
+ * RFC 6901 JSON pointer into the source document.
2731
+ */
2732
+ pointer: string;
2733
+ } | {
2734
+ kind: 'config';
2735
+ };
2736
+ /**
2737
+ * What a diagnostic carries.
2738
+ * - `problem` is a build issue shown to the user, and the only kind rendered as a problem.
2739
+ * - `performance` records a plugin's elapsed time.
2740
+ * - `update` is a version notice.
2741
+ */
2742
+ type DiagnosticKind = 'problem' | 'performance' | 'update';
2743
+ /**
2744
+ * Codes that describe a build problem: every {@link DiagnosticCode} except the
2745
+ * `performance` and `updateAvailable` codes, which ride on their own variants.
2746
+ */
2747
+ type ProblemCode = Exclude<DiagnosticCode, typeof diagnosticCode.performance | typeof diagnosticCode.updateAvailable>;
2748
+ /**
2749
+ * A build problem collected during a run, gathered into the result instead of
2750
+ * aborting on the first failure. It carries a stable {@link ProblemCode}, a
2751
+ * `severity`, a `message`, and optionally a `location` into the source document,
2752
+ * a `help`, the `plugin` that produced it, and the `cause` it wraps.
2753
+ */
2754
+ type ProblemDiagnostic = {
2755
+ /**
2756
+ * @default 'problem'
2757
+ */
2758
+ kind?: 'problem';
2759
+ /**
2760
+ * Stable identifier for the problem, from the {@link diagnosticCode} catalog.
2761
+ */
2762
+ code: ProblemCode;
2763
+ severity: DiagnosticSeverity;
2764
+ message: string;
2765
+ location?: DiagnosticLocation;
2766
+ /**
2767
+ * A suggested fix, phrased as an action the user can take.
2768
+ */
2769
+ help?: string;
2770
+ /**
2771
+ * Name of the plugin or subsystem that produced the diagnostic.
2772
+ */
2773
+ plugin?: string;
2774
+ /**
2775
+ * The underlying error, when the diagnostic wraps a thrown one.
2776
+ */
2777
+ cause?: Error;
2778
+ };
2779
+ /**
2780
+ * A per-plugin performance record, built with {@link Diagnostics.performance}. It carries the
2781
+ * `plugin` and its elapsed `duration`, and the `performance` kind keeps it out of the problem
2782
+ * list. It feeds the per-plugin timing bars, and reporters sum these into the run total.
2783
+ */
2784
+ type PerformanceDiagnostic = {
2785
+ kind: 'performance';
2786
+ code: typeof diagnosticCode.performance;
2787
+ severity: 'info';
2788
+ message: string;
2789
+ /**
2790
+ * The plugin this measurement belongs to.
2791
+ */
2792
+ plugin: string;
2793
+ /**
2794
+ * Elapsed milliseconds.
2795
+ */
2796
+ duration: number;
2797
+ };
2798
+ /**
2799
+ * A notice that a newer Kubb version is available on npm, built with {@link Diagnostics.update}.
2800
+ * It carries the running and latest versions and renders like any info diagnostic.
2801
+ */
2802
+ type UpdateDiagnostic = {
2803
+ kind: 'update';
2804
+ code: typeof diagnosticCode.updateAvailable;
2805
+ severity: 'info';
2806
+ message: string;
2807
+ /**
2808
+ * The running Kubb version.
2809
+ */
2810
+ currentVersion: string;
2811
+ /**
2812
+ * The newest version published on npm.
2813
+ */
2814
+ latestVersion: string;
2815
+ };
2816
+ /**
2817
+ * A structured record collected during a build, discriminated on `kind`: a
2818
+ * {@link ProblemDiagnostic} for an issue, a {@link PerformanceDiagnostic} for a per-plugin
2819
+ * timing, or an {@link UpdateDiagnostic} for a version notice.
2820
+ */
2821
+ type Diagnostic = ProblemDiagnostic | PerformanceDiagnostic | UpdateDiagnostic;
2822
+ /**
2823
+ * Maps each {@link DiagnosticCode} to the variant it selects, for {@link narrowDiagnostic}.
2824
+ * Every {@link ProblemCode} selects a {@link ProblemDiagnostic}, and the two bookkeeping codes
2825
+ * select their own variant.
2826
+ */
2827
+ type DiagnosticByCode = Record<ProblemCode, ProblemDiagnostic> & Record<typeof diagnosticCode.performance, PerformanceDiagnostic> & Record<typeof diagnosticCode.updateAvailable, UpdateDiagnostic>;
2828
+ /**
2829
+ * Narrows a {@link Diagnostic} to the variant for `code`, or `null` when it does not match.
2830
+ *
2831
+ * @example
2832
+ * ```ts
2833
+ * const update = narrowDiagnostic(diagnostic, diagnosticCode.updateAvailable)
2834
+ * if (update) {
2835
+ * console.log(update.latestVersion)
2836
+ * }
2837
+ * ```
2838
+ */
2839
+ declare function narrowDiagnostic<C extends DiagnosticCode>(diagnostic: Diagnostic, code: C): DiagnosticByCode[C] | null;
2840
+ /**
2841
+ * Returns `true` when the diagnostic is a build {@link ProblemDiagnostic}.
2842
+ *
2843
+ * @example
2844
+ * ```ts
2845
+ * if (isProblemDiagnostic(diagnostic)) {
2846
+ * console.log(diagnostic.location)
2847
+ * }
2848
+ * ```
2849
+ */
2850
+ declare const isProblemDiagnostic: (diagnostic: Diagnostic) => diagnostic is ProblemDiagnostic;
2851
+ /**
2852
+ * Returns `true` when the diagnostic is a per-plugin {@link PerformanceDiagnostic}.
2853
+ *
2854
+ * @example
2855
+ * ```ts
2856
+ * const timings = diagnostics.filter(isPerformanceDiagnostic)
2857
+ * ```
2858
+ */
2859
+ declare const isPerformanceDiagnostic: (diagnostic: Diagnostic) => diagnostic is PerformanceDiagnostic;
2860
+ /**
2861
+ * Returns `true` when the diagnostic is a version-update {@link UpdateDiagnostic}.
2862
+ *
2863
+ * @example
2864
+ * ```ts
2865
+ * if (isUpdateDiagnostic(diagnostic)) {
2866
+ * console.log(diagnostic.latestVersion)
2867
+ * }
2868
+ * ```
2869
+ */
2870
+ declare const isUpdateDiagnostic: (diagnostic: Diagnostic) => diagnostic is UpdateDiagnostic;
2871
+ /**
2872
+ * A {@link Diagnostic} reduced to its JSON-safe fields plus a `docsUrl`, for
2873
+ * machine-readable output (the `--reporter json` report, the MCP tools). Drops the
2874
+ * non-serializable `cause` and the `timing`/`duration` bookkeeping.
2875
+ */
2876
+ type SerializedDiagnostic = {
2877
+ code: DiagnosticCode;
2878
+ severity: DiagnosticSeverity;
2879
+ message: string;
2880
+ location?: DiagnosticLocation;
2881
+ help?: string;
2882
+ plugin?: string;
2883
+ /**
2884
+ * The kubb.dev docs link for the code, omitted for the unknown fallback.
2885
+ */
2886
+ docsUrl?: string;
2887
+ };
2888
+ /**
2889
+ * An `Error` that carries a {@link Diagnostic}, so structured problems can flow
2890
+ * through the existing throw/catch paths while keeping their code and location.
2891
+ *
2892
+ * @example
2893
+ * ```ts
2894
+ * throw new DiagnosticError({ code: diagnosticCode.refNotFound, severity: 'error', message: `Could not find ${ref}`, location: { kind: 'schema', pointer: ref, ref } })
2895
+ * ```
2896
+ */
2897
+ declare class DiagnosticError extends Error {
2898
+ diagnostic: ProblemDiagnostic;
2899
+ constructor(diagnostic: ProblemDiagnostic);
2900
+ }
2901
+ /**
2902
+ * Explanation for every {@link diagnosticCode}. Use {@link Diagnostics.explain} to look one up
2903
+ * and `Diagnostics.docsUrl` for the matching kubb.dev page.
2904
+ */
2905
+ declare const diagnosticCatalog: Record<DiagnosticCode, DiagnosticDoc>;
2906
+ /**
2907
+ * Static helpers for working with {@link Diagnostic}s, plus the run-scoped sink
2908
+ * that lets deep code report a diagnostic without threading a callback.
2909
+ *
2910
+ * The sink lives in a single `AsyncLocalStorage` in the `@kubb/core` bundle.
2911
+ * `Diagnostics.scope` activates it for a run, so anything inside that run (the
2912
+ * adapter parse, a lazily consumed stream, a generator) reports through
2913
+ * `Diagnostics.report` and lands in the same run.
2914
+ */
2915
+ declare class Diagnostics {
2916
+ #private;
2917
+ /**
2918
+ * Runs `fn` with `sink` as the active diagnostic sink for the whole async
2919
+ * subtree, so {@link Diagnostics.report} reaches it from anywhere inside.
2920
+ */
2921
+ static scope<T>(sink: (diagnostic: Diagnostic) => void, fn: () => T): T;
2922
+ /**
2923
+ * Collects a diagnostic into the active build via the run-scoped sink, without throwing.
2924
+ * Returns `true` when a run consumed it, `false` when called outside a {@link Diagnostics.scope}
2925
+ * (so callers can fall back to throwing). Use a `warning`/`info` severity for non-fatal issues.
2926
+ * For rendering a diagnostic live on the hook bus, use {@link Diagnostics.emit} instead.
2927
+ */
2928
+ static report(diagnostic: Diagnostic): boolean;
2929
+ /**
2930
+ * Emits a diagnostic on the run's `kubb:diagnostic` event so the loggers render it live.
2931
+ * Use it instead of calling `hooks.emit('kubb:diagnostic', ...)` directly. To collect a
2932
+ * diagnostic into the build result from deep in a run, use {@link Diagnostics.report} instead.
2933
+ */
2934
+ static emit(hooks: AsyncEventEmitter<KubbHooks>, diagnostic: ProblemDiagnostic | UpdateDiagnostic): Promise<void>;
2935
+ /**
2936
+ * Coerces any thrown value into a {@link ProblemDiagnostic}. A {@link DiagnosticError}
2937
+ * keeps its structured data, and anything else becomes a `KUBB_UNKNOWN` error.
2938
+ */
2939
+ static from(error: unknown): ProblemDiagnostic;
2940
+ /**
2941
+ * Builds a per-plugin performance record. Reporters sum these into the run total.
2942
+ */
2943
+ static performance({
2944
+ plugin,
2945
+ duration
2946
+ }: {
2947
+ plugin: string;
2948
+ duration: number;
2949
+ }): PerformanceDiagnostic;
2950
+ /**
2951
+ * Builds the version-update notice shown when a newer Kubb is published on npm.
2952
+ */
2953
+ static update({
2954
+ currentVersion,
2955
+ latestVersion
2956
+ }: {
2957
+ currentVersion: string;
2958
+ latestVersion: string;
2959
+ }): UpdateDiagnostic;
2960
+ /**
2961
+ * True when any diagnostic is an error, the severity that fails a build. Non-error
2962
+ * diagnostics are ignored.
2963
+ */
2964
+ static hasError(diagnostics: ReadonlyArray<Diagnostic>): boolean;
2965
+ /**
2966
+ * Names of the plugins that failed, deduped, derived from the error diagnostics
2967
+ * that carry a `plugin`.
2968
+ */
2969
+ static failedPlugins(diagnostics: ReadonlyArray<Diagnostic>): Array<string>;
2970
+ /**
2971
+ * Counts `problem` diagnostics by severity for the run summary. `timing`
2972
+ * diagnostics are ignored.
2973
+ */
2974
+ static count(diagnostics: ReadonlyArray<Diagnostic>): {
2975
+ errors: number;
2976
+ warnings: number;
2977
+ infos: number;
2978
+ };
2979
+ /**
2980
+ * Drops duplicate `problem` diagnostics that share a code, location pointer, and
2981
+ * plugin, so the same issue reported across several passes is shown once. Non-problem
2982
+ * diagnostics are always kept.
2983
+ */
2984
+ static dedupe(diagnostics: ReadonlyArray<Diagnostic>): Array<Diagnostic>;
2985
+ /**
2986
+ * Builds the kubb.dev docs URL for a diagnostic code, e.g.
2987
+ * `KUBB_REF_NOT_FOUND` → `https://kubb.dev/docs/5.x/reference/diagnostics/kubb-ref-not-found`.
2988
+ */
2989
+ static docsUrl(code: string): string;
2990
+ /**
2991
+ * The catalog entry for a code: its title, cause, and fix. Mirrors the kubb.dev
2992
+ * `/diagnostics/<slug>` page.
2993
+ */
2994
+ static explain(code: DiagnosticCode): DiagnosticDoc;
2995
+ /**
2996
+ * Reduces a diagnostic to its JSON-safe fields plus a `docsUrl`, for machine-readable
2997
+ * consumers. The `cause`, `kind`, and `duration` are dropped, and absent optional
2998
+ * fields are omitted rather than set to `undefined`.
2999
+ */
3000
+ static serialize(diagnostic: Diagnostic): SerializedDiagnostic;
3001
+ }
3002
+ //#endregion
3003
+ export { Exclude$1 as $, KubbFileProcessingUpdate as A, Parser as At, KubbLifecycleStartContext as B, RendererFactory as Bt, InputPath as C, LoggerContext as Ct, KubbConfigEndContext as D, FileProcessor as Dt, KubbBuildStartContext as E, defineLogger as Et, KubbGenerationStartContext as F, ReporterName as Ft, UserConfig as G, AdapterFactoryOptions as Gt, KubbSuccessContext as H, Storage as Ht, KubbHookEndContext as I, UserReporter as It, Generator$1 as J, diagnosticCode as Jt, createKubb as K, AdapterSource as Kt, KubbHookStartContext as L, createReporter as Lt, KubbFilesProcessingStartContext as M, GenerationResult as Mt, KubbFilesProcessingUpdateContext as N, Reporter as Nt, KubbDiagnosticContext as O, FileProcessorHooks as Ot, KubbGenerationEndContext as P, ReporterContext as Pt, FileManager as Q, KubbHooks as R, DevtoolsOptions as Rt, InputData as S, Logger as St, KubbBuildEndContext as T, UserLogger as Tt, KubbWarnContext as U, createStorage as Ut, KubbPluginsEndContext as V, createRenderer as Vt, PossibleConfig as W, Adapter as Wt, defineGenerator as X, AsyncEventEmitter as Xt, GeneratorContext as Y, logLevel as Yt, KubbDriver as Z, isUpdateDiagnostic as _, ResolverFileParams as _t, DiagnosticKind as a, NormalizedPlugin as at, CLIOptions as b, Middleware as bt, Diagnostics as c, Plugin as ct, ProblemDiagnostic as d, BannerMeta as dt, Group as et, SerializedDiagnostic as f, ResolveBannerContext as ft, isProblemDiagnostic as g, ResolverContext as gt, isPerformanceDiagnostic as h, Resolver as ht, DiagnosticError as i, KubbPluginStartContext as it, KubbFilesProcessingEndContext as j, defineParser as jt, KubbErrorContext as k, ParsedFile as kt, PerformanceDiagnostic as l, PluginFactoryOptions as lt, diagnosticCatalog as m, ResolveOptionsContext as mt, DiagnosticByCode as n, KubbPluginEndContext as nt, DiagnosticLocation as o, Output as ot, UpdateDiagnostic as p, ResolveBannerFile as pt, isInputPath as q, createAdapter as qt, DiagnosticDoc as r, KubbPluginSetupContext as rt, DiagnosticSeverity as s, Override as st, Diagnostic as t, Include as tt, ProblemCode as u, definePlugin as ut, narrowDiagnostic as v, ResolverPathParams as vt, Kubb$1 as w, LoggerOptions as wt, Config as x, defineMiddleware as xt, BuildOutput as y, defineResolver as yt, KubbInfoContext as z, Renderer as zt };
3004
+ //# sourceMappingURL=diagnostics-B0ONXReg.d.ts.map