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

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,106 @@ 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
516
+ //#region src/devtools.d.ts
517
+ type DevtoolsOptions = {
518
+ /**
519
+ * Open the AST inspector in Kubb Studio (`/ast`). Defaults to the main Studio page.
520
+ * @default false
521
+ */
522
+ ast?: boolean;
523
+ };
524
+ //#endregion
525
+ //#region src/createReporter.d.ts
331
526
  /**
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.
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`.
335
532
  */
336
- type Storage = {
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;
337
539
  /**
338
- * Identifier used in logs and diagnostics (`'fs'`, `'memory'`, `'s3'`).
540
+ * Diagnostics collected while generating this config.
339
541
  */
340
- readonly name: string;
542
+ diagnostics: Array<Diagnostic>;
341
543
  /**
342
- * Returns `true` when an entry for `key` exists.
544
+ * Number of files written for this config.
343
545
  */
344
- hasItem(key: string): Promise<boolean>;
546
+ filesCreated: number;
547
+ status: 'success' | 'failed';
345
548
  /**
346
- * Reads the stored string. Returns `null` when the key is missing.
549
+ * `process.hrtime()` snapshot taken when this config started generating.
347
550
  */
348
- getItem(key: string): Promise<string | null>;
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 = {
349
558
  /**
350
- * Stores `value` under `key`, creating any required structure (directories,
351
- * buckets, ...).
559
+ * Output verbosity. Use the `logLevel` constants exported from `@kubb/core`
560
+ * (`silent`, `error`, `warn`, `info`, `verbose`, `debug`).
352
561
  */
353
- setItem(key: string, value: string): Promise<void>;
562
+ logLevel: (typeof logLevel)[keyof typeof logLevel];
563
+ };
564
+ /**
565
+ * Host-facing reporter, as installed onto a run. Unlike a Logger (the live TUI view), a reporter
566
+ * never sees the event emitter. `report` runs once per config; `flush`, when present, runs once
567
+ * after the last config.
568
+ */
569
+ type Reporter = {
354
570
  /**
355
- * Deletes the entry for `key`. No-op when the key does not exist.
571
+ * Display name, matching a {@link ReporterName} for the built-ins.
356
572
  */
357
- removeItem(key: string): Promise<void>;
573
+ name: string;
358
574
  /**
359
- * Returns every key. Pass `base` to filter to keys starting with that prefix.
575
+ * Called once per config with that config's result and the render context.
360
576
  */
361
- getKeys(base?: string): Promise<Array<string>>;
577
+ report: (result: GenerationResult, context: ReporterContext) => void | Promise<void>;
362
578
  /**
363
- * Removes every entry. Pass `base` to scope the wipe to a key prefix.
579
+ * Optional finalizer called once after the run's last config. The host wires it to
580
+ * `kubb:lifecycle:end`. {@link createReporter} closes it over the reports `report` returned.
364
581
  */
365
- clear(base?: string): Promise<void>;
366
- /**
367
- * Optional teardown hook called after the build completes. Use to flush
368
- * buffers, close connections, or release file locks.
369
- */
370
- dispose?(): Promise<void>;
582
+ flush?: (context: ReporterContext) => void | Promise<void>;
371
583
  };
372
584
  /**
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).
585
+ * Reporter definition passed to {@link createReporter}. `report` returns the value to collect for
586
+ * this config (e.g. a built report), and the optional `flush` receives the collected reports to
587
+ * emit as one document. `T` is inferred from `report`'s return type.
588
+ */
589
+ type UserReporter<T = void> = {
590
+ name: string;
591
+ report: (result: GenerationResult, context: ReporterContext) => T | Promise<T>;
592
+ flush?: (context: ReporterContext, reports: Array<T>) => void | Promise<void>;
593
+ };
594
+ /**
595
+ * Defines a reporter. When the definition has a `flush`, the returned reporter buffers each value
596
+ * `report` returns and hands the array to `flush` once, then clears it. Without a `flush`, nothing
597
+ * is buffered. Wiring the reporter onto the run's events is the host's job, so the reporter only
598
+ * ever deals with a {@link GenerationResult}.
377
599
  *
378
- * @example In-memory storage (the built-in implementation)
600
+ * @example
379
601
  * ```ts
380
- * import { createStorage } from '@kubb/core'
381
- *
382
- * export const memoryStorage = createStorage(() => {
383
- * const store = new Map<string, string>()
602
+ * import { createReporter, Diagnostics } from '@kubb/core'
384
603
  *
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
- * }
604
+ * export const jsonReporter = createReporter({
605
+ * name: 'json',
606
+ * report(result) {
607
+ * return { status: Diagnostics.hasError(result.diagnostics) ? 'failed' : 'success', diagnostics: result.diagnostics }
608
+ * },
609
+ * flush(context, reports) {
610
+ * process.stdout.write(`${JSON.stringify(reports, null, 2)}\n`)
611
+ * },
407
612
  * })
408
613
  * ```
409
614
  */
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
- };
615
+ declare function createReporter<T = void>(reporter: UserReporter<T>): Reporter;
420
616
  //#endregion
421
617
  //#region src/defineParser.d.ts
422
618
  type PrintOptions = {
@@ -424,7 +620,7 @@ type PrintOptions = {
424
620
  };
425
621
  /**
426
622
  * 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
623
+ * written to disk. Kubb ships with TypeScript and TSX parsers. Add your own
428
624
  * for new file types (JSON, Markdown, ...).
429
625
  */
430
626
  type Parser<TMeta extends object = object, TNode = unknown> = {
@@ -476,11 +672,16 @@ type Parser<TMeta extends object = object, TNode = unknown> = {
476
672
  declare function defineParser<T extends Parser>(parser: T): T;
477
673
  //#endregion
478
674
  //#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 = {
675
+ /**
676
+ * Hooks fired by a `FileProcessor`.
677
+ *
678
+ * - `start` opens a batch, from `run` or a queue flush.
679
+ * - `update` fires once per file as it is converted.
680
+ * - `end` closes a batch.
681
+ * - `enqueue` fires for every `enqueue` call.
682
+ * - `drain` fires when `drain()` empties the queue with no in-flight batch left.
683
+ */
684
+ type FileProcessorHooks = {
484
685
  start: [files: Array<FileNode>];
485
686
  update: [params: {
486
687
  file: FileNode;
@@ -490,7 +691,12 @@ type FileProcessorEvents = {
490
691
  percentage: number;
491
692
  }];
492
693
  end: [files: Array<FileNode>];
694
+ enqueue: [file: FileNode];
695
+ drain: [];
493
696
  };
697
+ /**
698
+ * Per-file progress record yielded by `stream` and surfaced through the `update` event.
699
+ */
494
700
  type ParsedFile = {
495
701
  file: FileNode;
496
702
  source: string;
@@ -498,22 +704,63 @@ type ParsedFile = {
498
704
  total: number;
499
705
  percentage: number;
500
706
  };
707
+ type FileProcessorOptions = {
708
+ /**
709
+ * Storage destination for queued writes.
710
+ */
711
+ storage: Storage;
712
+ /**
713
+ * Parsers indexed by file extension.
714
+ */
715
+ parsers?: Map<FileNode['extname'], Parser>;
716
+ /**
717
+ * Output extname per source extname, applied during conversion.
718
+ */
719
+ extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
720
+ };
501
721
  /**
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.
722
+ * Turns `FileNode`s into source strings and writes them to storage.
504
723
  *
505
- * @internal
724
+ * Two modes share the same instance. Stateless mode (`parse`, `stream`, `run`) just runs the
725
+ * conversion. Queue mode (`enqueue`, `flush`, `drain`) buffers files deduped by path and
726
+ * writes each batch through storage with up to `STREAM_FLUSH_EVERY` requests in flight.
727
+ *
728
+ * `flush` does not wait for its batch to finish, so dispatch can overlap with IO. The next
729
+ * `flush` or `drain` picks the in-flight batch up. `drain` blocks until everything has been
730
+ * written and is meant for the end of a build.
731
+ *
732
+ * To surface build-level hook signals (`kubb:files:processing:*` and friends) subscribe to
733
+ * `hooks` and re-emit on the kubb bus.
506
734
  */
507
735
  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>>;
736
+ #private;
737
+ readonly hooks: AsyncEventEmitter<FileProcessorHooks>;
738
+ constructor(options: FileProcessorOptions);
515
739
  /**
516
- * Clears all registered event listeners.
740
+ * Files waiting in the queue.
741
+ */
742
+ get size(): number;
743
+ parse(file: FileNode): string;
744
+ stream(files: ReadonlyArray<FileNode>): Generator<ParsedFile>;
745
+ run(files: Array<FileNode>): Promise<Array<FileNode>>;
746
+ /**
747
+ * Adds a file to the next flush. A later `enqueue` for the same path replaces the previous
748
+ * entry, matching `FileManager.upsert`. Fires the `enqueue` event.
749
+ */
750
+ enqueue(file: FileNode): void;
751
+ /**
752
+ * Starts processing the queued files. Waits for any previous flush to finish (so two
753
+ * batches never run together) and then returns without waiting for the new one. The next
754
+ * `flush` or `drain` picks up the in-flight task.
755
+ */
756
+ flush(): Promise<void>;
757
+ /**
758
+ * Waits for the in-flight flush and writes any files still queued. Fires the `drain` event
759
+ * when both are done.
760
+ */
761
+ drain(): Promise<void>;
762
+ /**
763
+ * Clears every listener and the pending queue.
517
764
  */
518
765
  dispose(): void;
519
766
  [Symbol.dispose](): void;
@@ -675,7 +922,7 @@ type ResolveOptionsContext<TOptions> = {
675
922
  * Base constraint for all plugin resolver objects.
676
923
  *
677
924
  * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
678
- * are injected automatically by `defineResolver` extend this type to add custom resolution methods.
925
+ * are injected automatically by `defineResolver`. Extend this type to add custom resolution methods.
679
926
  *
680
927
  * @example
681
928
  * ```ts
@@ -777,7 +1024,7 @@ type ResolverFileParams = {
777
1024
  * Per-file context describing the file a banner/footer is being resolved for.
778
1025
  *
779
1026
  * 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
1027
+ * into `BannerMeta` so a `banner`/`footer` function can branch on the file kind,
781
1028
  * e.g. omit a `'use server'` directive on re-export files.
782
1029
  */
783
1030
  type ResolveBannerFile = {
@@ -828,7 +1075,7 @@ type BannerMeta = InputMeta & {
828
1075
  /**
829
1076
  * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
830
1077
  *
831
- * `output` is optional not every plugin configures a banner/footer.
1078
+ * `output` is optional, since not every plugin configures a banner/footer.
832
1079
  * `config` carries the global Kubb config, used to derive the default Kubb banner.
833
1080
  * `file` carries per-file context forwarded to a `banner`/`footer` function.
834
1081
  *
@@ -847,7 +1094,7 @@ type ResolveBannerContext = {
847
1094
  * Builder type for the plugin-specific resolver fields.
848
1095
  *
849
1096
  * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
850
- * are optional built-in fallbacks are injected when omitted.
1097
+ * are optional, with built-in fallbacks injected when omitted.
851
1098
  *
852
1099
  * Methods in the returned object can call sibling resolver methods via `this`.
853
1100
  */
@@ -861,11 +1108,11 @@ type ResolverBuilder<T extends PluginFactoryOptions> = () => Omit<T['resolver'],
861
1108
  * name casing, include/exclude/override filtering, output path computation,
862
1109
  * and file construction. Supply your own to override any of them:
863
1110
  *
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.
1111
+ * - `default` sets the name casing strategy (camelCase or PascalCase).
1112
+ * - `resolveOptions` does include/exclude/override filtering.
1113
+ * - `resolvePath` computes the output path.
1114
+ * - `resolveFile` builds the full `FileNode`.
1115
+ * - `resolveBanner` and `resolveFooter` produce the top and bottom of file text.
869
1116
  *
870
1117
  * Methods in the returned object can call sibling resolver methods via `this`,
871
1118
  * which keeps custom rules small (`this.default(name, 'type')` to delegate).
@@ -921,8 +1168,8 @@ type Output<_TOptions = unknown> = {
921
1168
  * lint disables, or `@ts-nocheck` directives.
922
1169
  *
923
1170
  * 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
1171
+ * Pass a function to compute the banner from the file's `BannerMeta` document metadata
1172
+ * plus per-file context (`isBarrel`, `isAggregation`, `filePath`, `baseName`), so you can
926
1173
  * skip the banner on specific files.
927
1174
  *
928
1175
  * @example Add a directive to source files but not re-export files
@@ -949,8 +1196,8 @@ type Output<_TOptions = unknown> = {
949
1196
  type Group = {
950
1197
  /**
951
1198
  * 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.
1199
+ * - `'tag'` uses the first tag (`operation.getTags().at(0)?.name`).
1200
+ * - `'path'` uses the first segment of the operation's URL.
954
1201
  */
955
1202
  type: 'tag' | 'path';
956
1203
  /**
@@ -1035,7 +1282,7 @@ type ByContentType = {
1035
1282
  * ]
1036
1283
  * ```
1037
1284
  */
1038
- type Exclude = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1285
+ type Exclude$1 = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1039
1286
  /**
1040
1287
  * Filter that restricts generation to operations or schemas matching at least
1041
1288
  * one entry. Useful for partial builds (one tag, one API version).
@@ -1054,7 +1301,7 @@ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySch
1054
1301
  * options are merged on top of the plugin defaults for that operation only.
1055
1302
  * Useful for "this one tag goes to a different folder" rules.
1056
1303
  *
1057
- * Entries are evaluated top to bottom; the first matching entry wins.
1304
+ * Entries are evaluated top to bottom. The first matching entry wins.
1058
1305
  *
1059
1306
  * @example
1060
1307
  * ```ts
@@ -1073,7 +1320,7 @@ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySch
1073
1320
  * ```
1074
1321
  */
1075
1322
  type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
1076
- options: Partial<TOptions>;
1323
+ options: Omit<Partial<TOptions>, 'override'>;
1077
1324
  };
1078
1325
  type PluginFactoryOptions<
1079
1326
  /**
@@ -1117,10 +1364,6 @@ type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactor
1117
1364
  * Set the AST transformer to pre-process nodes before they reach generators.
1118
1365
  */
1119
1366
  setTransformer(visitor: Visitor): void;
1120
- /**
1121
- * Set the renderer factory to process JSX elements from generators.
1122
- */
1123
- setRenderer(renderer: RendererFactory): void;
1124
1367
  /**
1125
1368
  * Set resolved options merged into the normalized plugin's `options`.
1126
1369
  * Call this in `kubb:plugin:setup` to provide options generators need.
@@ -1163,9 +1406,9 @@ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1163
1406
  /**
1164
1407
  * Controls the execution order of this plugin relative to others.
1165
1408
  *
1166
- * - `'pre'` runs before all normal plugins.
1167
- * - `'post'` runs after all normal plugins.
1168
- * - `undefined` (default) runs in declaration order among normal plugins.
1409
+ * - `'pre'` runs before all normal plugins.
1410
+ * - `'post'` runs after all normal plugins.
1411
+ * - `undefined` (default), runs in declaration order among normal plugins.
1169
1412
  *
1170
1413
  * Dependency constraints always take precedence over `enforce`.
1171
1414
  */
@@ -1184,7 +1427,7 @@ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1184
1427
  };
1185
1428
  /**
1186
1429
  * Normalized plugin after setup, with runtime fields populated.
1187
- * For internal use only plugins use the public `Plugin` type externally.
1430
+ * For internal use only, plugins use the public `Plugin` type externally.
1188
1431
  *
1189
1432
  * @internal
1190
1433
  */
@@ -1192,12 +1435,11 @@ type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1192
1435
  options: TOptions['resolvedOptions'] & {
1193
1436
  output: Output;
1194
1437
  include?: Array<Include>;
1195
- exclude: Array<Exclude>;
1438
+ exclude: Array<Exclude$1>;
1196
1439
  override: Array<Override<TOptions['resolvedOptions']>>;
1197
1440
  };
1198
1441
  resolver: TOptions['resolver'];
1199
1442
  transformer?: Visitor;
1200
- renderer?: RendererFactory;
1201
1443
  generators?: Array<Generator$1>;
1202
1444
  apply?: (config: Config) => boolean;
1203
1445
  version?: string;
@@ -1247,6 +1489,14 @@ type KubbPluginEndContext = {
1247
1489
  declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
1248
1490
  //#endregion
1249
1491
  //#region src/FileManager.d.ts
1492
+ /**
1493
+ * Hooks fired by a `FileManager`.
1494
+ *
1495
+ * - `upsert` fires once per resolved file added through `add` or `upsert`.
1496
+ */
1497
+ type FileManagerHooks = {
1498
+ upsert: [file: FileNode];
1499
+ };
1250
1500
  /**
1251
1501
  * In-memory file store for generated files. Files sharing a `path` are merged
1252
1502
  * (sources/imports/exports concatenated). The `files` getter is sorted by
@@ -1262,25 +1512,24 @@ declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFact
1262
1512
  declare class FileManager {
1263
1513
  #private;
1264
1514
  /**
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.
1515
+ * Subscribe to file-store changes. Listeners on `upsert` see each resolved file as it lands
1516
+ * through `add` or `upsert`.
1269
1517
  */
1270
- setOnUpsert(callback: ((file: FileNode) => void) | null): void;
1518
+ readonly hooks: AsyncEventEmitter<FileManagerHooks>;
1271
1519
  add(...files: Array<FileNode>): Array<FileNode>;
1272
1520
  upsert(...files: Array<FileNode>): Array<FileNode>;
1273
1521
  getByPath(path: string): FileNode | null;
1274
1522
  deleteByPath(path: string): void;
1275
1523
  clear(): void;
1276
1524
  /**
1277
- * Releases all stored files. Called by the core after `kubb:build:end`.
1525
+ * Releases all stored files and clears every `hooks` listener. Called by the core after
1526
+ * `kubb:build:end`.
1278
1527
  */
1279
1528
  dispose(): void;
1280
1529
  [Symbol.dispose](): void;
1281
1530
  /**
1282
1531
  * 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.
1532
+ * last within a length bucket). Returns a cached view, do not mutate.
1284
1533
  */
1285
1534
  get files(): Array<FileNode>;
1286
1535
  }
@@ -1305,14 +1554,14 @@ declare class KubbDriver {
1305
1554
  static getMode(fileOrFolder: string | undefined | null): 'single' | 'split';
1306
1555
  /**
1307
1556
  * The streaming `InputStreamNode` produced by the adapter.
1308
- * Always set after adapter setup parse-only adapters are wrapped automatically.
1557
+ * Always set after adapter setup, parse-only adapters are wrapped automatically.
1309
1558
  */
1310
1559
  inputNode: InputStreamNode | null;
1311
1560
  adapter: Adapter | null;
1312
1561
  /**
1313
1562
  * Central file store for all generated files.
1314
1563
  * Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
1315
- * add files; this property gives direct read/write access when needed.
1564
+ * add files. This property gives direct read/write access when needed.
1316
1565
  */
1317
1566
  readonly fileManager: FileManager;
1318
1567
  readonly plugins: Map<string, NormalizedPlugin>;
@@ -1334,13 +1583,12 @@ declare class KubbDriver {
1334
1583
  * respectively. Each listener is scoped to the owning plugin via a `ctx.plugin.name` check
1335
1584
  * so that generators from different plugins do not cross-fire.
1336
1585
  *
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.
1586
+ * The renderer comes from `generator.renderer`. Set `generator.renderer = null` (or leave it
1587
+ * unset) to opt out of rendering.
1340
1588
  *
1341
1589
  * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
1342
1590
  */
1343
- registerGenerator(pluginName: string, gen: Generator$1): void;
1591
+ registerGenerator(pluginName: string, generator: Generator$1): void;
1344
1592
  /**
1345
1593
  * Returns `true` when at least one generator was registered for the given plugin
1346
1594
  * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
@@ -1350,25 +1598,40 @@ declare class KubbDriver {
1350
1598
  */
1351
1599
  hasEventGenerators(pluginName: string): boolean;
1352
1600
  /**
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.
1601
+ * Runs the full plugin pipeline. Returns the diagnostics collected so far even
1602
+ * when an outer hook throws, since the orchestrator preserves partial state by capturing
1603
+ * the failure as a {@link Diagnostic} instead of propagating. Each plugin also
1604
+ * contributes a `timing` diagnostic for the run summary.
1356
1605
  */
1357
1606
  run({
1358
1607
  storage
1359
1608
  }: {
1360
1609
  storage: Storage;
1361
1610
  }): Promise<{
1362
- failedPlugins: Set<{
1363
- plugin: Plugin;
1364
- error: Error;
1365
- }>;
1366
- pluginTimings: Map<string, number>;
1367
- error?: Error;
1611
+ diagnostics: Array<Diagnostic>;
1368
1612
  }>;
1369
1613
  /**
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.
1614
+ * Stores whatever a generator method or `kubb:generate:*` hook returned.
1615
+ *
1616
+ * - An `Array<FileNode>` goes straight into `fileManager` via `upsert`.
1617
+ * - A renderer element runs through `renderer` (the renderer factory, e.g. JSX) and the
1618
+ * produced files go to `fileManager.upsert`.
1619
+ * - A falsy result is treated as a no-op. The generator wrote files itself via
1620
+ * `ctx.upsertFile`.
1621
+ *
1622
+ * Pass `renderer` when the result may be a renderer element. Generators that only return
1623
+ * `Array<FileNode>` do not need one.
1624
+ */
1625
+ dispatch<TElement = unknown>({
1626
+ result,
1627
+ renderer
1628
+ }: {
1629
+ result: TElement | Array<FileNode> | undefined | null;
1630
+ renderer?: RendererFactory<TElement> | null;
1631
+ }): Promise<void>;
1632
+ /**
1633
+ * Removes every listener the driver added. Listeners attached directly to `hooks` from outside
1634
+ * the driver survive. Called at the end of a build to prevent leaks across repeated builds.
1372
1635
  *
1373
1636
  * @internal
1374
1637
  */
@@ -1457,15 +1720,20 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1457
1720
  */
1458
1721
  transformer: Visitor | undefined;
1459
1722
  /**
1460
- * Emit a warning.
1723
+ * Report a warning. Collected as a `warning` diagnostic attributed to the current
1724
+ * plugin. It surfaces in the run summary but does not fail the build. For a structured
1725
+ * diagnostic with a code and source location, use `Diagnostics.report` or throw a
1726
+ * `DiagnosticError` directly.
1461
1727
  */
1462
1728
  warn: (message: string) => void;
1463
1729
  /**
1464
- * Emit an error.
1730
+ * Report an error. Collected as an `error` diagnostic attributed to the current
1731
+ * plugin, which fails the build.
1465
1732
  */
1466
1733
  error: (error: string | Error) => void;
1467
1734
  /**
1468
- * Emit an info message.
1735
+ * Report an informational message. Collected as an `info` diagnostic attributed to
1736
+ * the current plugin.
1469
1737
  */
1470
1738
  info: (message: string) => void;
1471
1739
  /**
@@ -1477,7 +1745,7 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1477
1745
  */
1478
1746
  adapter: Adapter;
1479
1747
  /**
1480
- * Document metadata from the adapter title, version, base URL, and pre-computed
1748
+ * Document metadata from the adapter: title, version, base URL, and pre-computed
1481
1749
  * schema index fields (`circularNames`, `enumNames`).
1482
1750
  */
1483
1751
  meta: InputMeta;
@@ -1523,8 +1791,7 @@ type Generator$1<TOptions extends PluginFactoryOptions = PluginFactoryOptions, T
1523
1791
  *
1524
1792
  * Generators that only return `Array<FileNode>` or `void` do not need to set this.
1525
1793
  *
1526
- * Set `renderer: null` to explicitly opt out of rendering even when the parent plugin
1527
- * declares a `renderer` (overrides the plugin-level fallback).
1794
+ * Leave it unset or set `renderer: null` to opt out of rendering.
1528
1795
  *
1529
1796
  * @example
1530
1797
  * ```ts
@@ -1563,7 +1830,7 @@ type Generator$1<TOptions extends PluginFactoryOptions = PluginFactoryOptions, T
1563
1830
  * The returned object is the input as-is, but with `this` types preserved so
1564
1831
  * `schema`/`operation`/`operations` methods are correctly typed against the
1565
1832
  * plugin's `PluginFactoryOptions`. Renderer elements and `FileNode[]` returns
1566
- * are both handled by the runtime pick whichever style fits.
1833
+ * are both handled by the runtime, so pick whichever style fits.
1567
1834
  *
1568
1835
  * @example JSX-based schema generator
1569
1836
  * ```tsx
@@ -1595,10 +1862,8 @@ declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginF
1595
1862
  */
1596
1863
  type ExtractRegistryKey<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
1597
1864
  /**
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.
1865
+ * Path to an input file to generate from, absolute or relative to the config file. The adapter
1866
+ * parses it (e.g. an OpenAPI YAML or JSON spec) into the universal AST.
1602
1867
  */
1603
1868
  type InputPath = {
1604
1869
  /**
@@ -1613,10 +1878,8 @@ type InputPath = {
1613
1878
  path: string;
1614
1879
  };
1615
1880
  /**
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.
1881
+ * Inline spec to generate from, passed directly instead of read from a file. A string
1882
+ * (YAML/JSON) or a parsed object.
1620
1883
  */
1621
1884
  type InputData = {
1622
1885
  /**
@@ -1632,15 +1895,9 @@ type InputData = {
1632
1895
  };
1633
1896
  type Input = InputPath | InputData;
1634
1897
  /**
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.
1898
+ * Resolved build configuration for a Kubb run: what to generate from (adapter, input), where to
1899
+ * write it (output), how (plugins, middleware), and the runtime pieces (parsers, storage). See
1900
+ * `UserConfig` for the relaxed form with defaults applied.
1644
1901
  *
1645
1902
  * @private
1646
1903
  */
@@ -1657,16 +1914,16 @@ type Config<TInput = Input> = {
1657
1914
  name?: string;
1658
1915
  /**
1659
1916
  * 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()`.
1917
+ * resolved on the `Config` instance (see `UserConfig` for the optional
1918
+ * form that defaults to `process.cwd()`).
1662
1919
  */
1663
1920
  root: string;
1664
1921
  /**
1665
1922
  * Parsers that convert generated files into strings. Each parser handles a
1666
- * set of file extensions; a fallback parser handles anything else.
1923
+ * set of file extensions, and a fallback parser handles anything else.
1667
1924
  *
1668
- * Already resolved on the `Config` instance see `UserConfig` for the
1669
- * optional form that defaults to `[parserTs, parserTsx, parserMd]`.
1925
+ * Already resolved on the `Config` instance (see `UserConfig` for the
1926
+ * optional form that defaults to `[parserTs, parserTsx, parserMd]`).
1670
1927
  *
1671
1928
  * @example
1672
1929
  * ```ts
@@ -1700,15 +1957,13 @@ type Config<TInput = Input> = {
1700
1957
  /**
1701
1958
  * Source file or data to generate code from.
1702
1959
  * 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.
1960
+ * Required when an adapter is configured. Omit it when running in plugin-only mode.
1704
1961
  */
1705
1962
  input?: TInput;
1706
1963
  output: {
1707
1964
  /**
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.).
1965
+ * Output directory for generated files, absolute or relative to `root`. Plugins can nest
1966
+ * subdirectories under it by grouping strategy (tag, path).
1712
1967
  *
1713
1968
  * @example
1714
1969
  * ```ts
@@ -1719,10 +1974,8 @@ type Config<TInput = Input> = {
1719
1974
  */
1720
1975
  path: string;
1721
1976
  /**
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.
1977
+ * Remove every file in the output directory before the build, so stale output isn't mixed
1978
+ * with new files. Leave `false` to preserve manual edits in the output directory.
1726
1979
  *
1727
1980
  * @default false
1728
1981
  * @example
@@ -1732,10 +1985,8 @@ type Config<TInput = Input> = {
1732
1985
  */
1733
1986
  clean?: boolean;
1734
1987
  /**
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).
1988
+ * Format the generated files after generation. `'auto'` runs the first formatter it finds
1989
+ * (oxfmt, biome, or prettier), a named tool forces that one, and `false` skips formatting.
1739
1990
  *
1740
1991
  * @default false
1741
1992
  * @example
@@ -1747,10 +1998,8 @@ type Config<TInput = Input> = {
1747
1998
  */
1748
1999
  format?: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false;
1749
2000
  /**
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.
2001
+ * Lint the generated files after generation. `'auto'` runs the first linter it finds
2002
+ * (oxlint, biome, or eslint), a named tool forces that one, and `false` skips linting.
1754
2003
  *
1755
2004
  * @default false
1756
2005
  * @example
@@ -1762,10 +2011,8 @@ type Config<TInput = Input> = {
1762
2011
  */
1763
2012
  lint?: 'auto' | 'eslint' | 'biome' | 'oxlint' | false;
1764
2013
  /**
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.
2014
+ * Rewrite import extensions in generated files, e.g. emit `.js` imports from `.ts` sources for
2015
+ * ESM dual packages. Keys are the source extension, values the output, and `''` drops it.
1769
2016
  *
1770
2017
  * @default { '.ts': '.ts' }
1771
2018
  * @example
@@ -1776,10 +2023,8 @@ type Config<TInput = Input> = {
1776
2023
  */
1777
2024
  extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
1778
2025
  /**
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.
2026
+ * Banner prepended to every generated file. `'simple'` is the basic Kubb notice, `'full'` adds
2027
+ * source, title, description, and API version, and `false` omits it.
1783
2028
  *
1784
2029
  * @default 'simple'
1785
2030
  * @example
@@ -1791,10 +2036,8 @@ type Config<TInput = Input> = {
1791
2036
  */
1792
2037
  defaultBanner?: 'simple' | 'full' | false;
1793
2038
  /**
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.
2039
+ * Overwrite existing files when `true`, skip files that already exist when `false`. Individual
2040
+ * plugins can override it. Keep `false` to avoid clobbering local edits in the output folder.
1798
2041
  *
1799
2042
  * @default false
1800
2043
  * @example
@@ -1806,10 +2049,8 @@ type Config<TInput = Input> = {
1806
2049
  override?: boolean;
1807
2050
  } & ExtractRegistryKey<Kubb$1.ConfigOptionsRegistry, 'output'>;
1808
2051
  /**
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.
2052
+ * Where generated files are persisted. Defaults to `fsStorage()` (disk). Pass `memoryStorage()`
2053
+ * to keep files in RAM, or implement `Storage` for a custom backend such as cloud or a database.
1813
2054
  *
1814
2055
  * @default fsStorage()
1815
2056
  * @example
@@ -1827,13 +2068,9 @@ type Config<TInput = Input> = {
1827
2068
  */
1828
2069
  storage: Storage;
1829
2070
  /**
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.
2071
+ * Plugins that run during the build to generate code and transform the AST. Each one processes
2072
+ * the adapter's AST and can emit files for a different target (TypeScript, Zod, Faker). A plugin
2073
+ * that depends on another throws when that plugin isn't registered.
1837
2074
  *
1838
2075
  * @example
1839
2076
  * ```ts
@@ -1866,22 +2103,6 @@ type Config<TInput = Input> = {
1866
2103
  * @see {@link defineMiddleware} to create custom middleware.
1867
2104
  */
1868
2105
  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
2106
  /**
1886
2107
  * Kubb Studio cloud integration settings.
1887
2108
  *
@@ -1933,13 +2154,29 @@ type Config<TInput = Input> = {
1933
2154
  */
1934
2155
  done?: string | Array<string>;
1935
2156
  };
2157
+ /**
2158
+ * Reporters that render the run's output, like Vitest. List one or more by name;
2159
+ * the CLI `--reporter` flag overrides this when set.
2160
+ *
2161
+ * - `cli` writes the end-of-run summary to the terminal.
2162
+ * - `json` writes a machine-readable report to stdout, for CI.
2163
+ * - `file` writes a debug log to `.kubb/<name>-<timestamp>.log`.
2164
+ *
2165
+ * @default ['cli']
2166
+ *
2167
+ * @example
2168
+ * ```ts
2169
+ * reporters: ['cli', 'file']
2170
+ * ```
2171
+ */
2172
+ reporters?: Array<ReporterName>;
1936
2173
  };
1937
2174
  /**
1938
2175
  * Partial `Config` for user-facing entry points with sensible defaults.
1939
2176
  *
1940
2177
  * `UserConfig` is what you pass to `defineConfig()`. It has optional `root`, `plugins`, `parsers`, and `adapter`
1941
2178
  * fields (which fall back to sensible defaults). All other Config options are available, including `output`, `input`,
1942
- * `storage`, `middleware`, `renderer`, `devtools`, and `hooks`.
2179
+ * `storage`, `middleware`, `devtools`, and `hooks`.
1943
2180
  *
1944
2181
  * @example
1945
2182
  * ```ts
@@ -2061,7 +2298,6 @@ interface KubbHooks {
2061
2298
  'kubb:config:end': [ctx: KubbConfigEndContext];
2062
2299
  'kubb:generation:start': [ctx: KubbGenerationStartContext];
2063
2300
  'kubb:generation:end': [ctx: KubbGenerationEndContext];
2064
- 'kubb:generation:summary': [ctx: KubbGenerationSummaryContext];
2065
2301
  'kubb:format:start': [];
2066
2302
  'kubb:format:end': [];
2067
2303
  'kubb:lint:start': [];
@@ -2070,12 +2306,11 @@ interface KubbHooks {
2070
2306
  'kubb:hooks:end': [];
2071
2307
  'kubb:hook:start': [ctx: KubbHookStartContext];
2072
2308
  'kubb:hook:end': [ctx: KubbHookEndContext];
2073
- 'kubb:version:new': [ctx: KubbVersionNewContext];
2074
2309
  'kubb:info': [ctx: KubbInfoContext];
2075
2310
  'kubb:error': [ctx: KubbErrorContext];
2076
2311
  'kubb:success': [ctx: KubbSuccessContext];
2077
2312
  'kubb:warn': [ctx: KubbWarnContext];
2078
- 'kubb:debug': [ctx: KubbDebugContext];
2313
+ 'kubb:diagnostic': [ctx: KubbDiagnosticContext];
2079
2314
  'kubb:files:processing:start': [ctx: KubbFilesProcessingStartContext];
2080
2315
  'kubb:files:processing:update': [ctx: KubbFilesProcessingUpdateContext];
2081
2316
  'kubb:files:processing:end': [ctx: KubbFilesProcessingEndContext];
@@ -2170,7 +2405,7 @@ type KubbGenerationEndContext = {
2170
2405
  config: Config;
2171
2406
  /**
2172
2407
  * Read-only view of the files written during this build.
2173
- * Reads go directly to `config.storage` nothing extra is held in memory.
2408
+ * Reads go directly to `config.storage`, nothing extra is held in memory.
2174
2409
  *
2175
2410
  * @example Read a generated file
2176
2411
  * `const code = await storage.getItem('/src/gen/pet.ts')`
@@ -2183,45 +2418,24 @@ type KubbGenerationEndContext = {
2183
2418
  * ```
2184
2419
  */
2185
2420
  storage: Storage;
2186
- };
2187
- type KubbGenerationSummaryContext = {
2188
2421
  /**
2189
- * Resolved configuration for this generation run.
2422
+ * Diagnostics collected during the build: error/warning/info problems plus a
2423
+ * `timing` diagnostic per plugin. The end-of-run summary derives its failure counts
2424
+ * and per-plugin timings from these. Set by the CLI runner, omitted by other callers.
2190
2425
  */
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
- }>;
2426
+ diagnostics?: Array<Diagnostic>;
2199
2427
  /**
2200
2428
  * `'success'` when all plugins completed without errors, `'failed'` otherwise.
2201
2429
  */
2202
- status: 'success' | 'failed';
2430
+ status?: 'success' | 'failed';
2203
2431
  /**
2204
- * High-resolution start time from `process.hrtime()`.
2432
+ * High-resolution start time from `process.hrtime()`, used to compute the elapsed time.
2205
2433
  */
2206
- hrStart: [number, number];
2434
+ hrStart?: [number, number];
2207
2435
  /**
2208
2436
  * Total number of files created during this run.
2209
2437
  */
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;
2438
+ filesCreated?: number;
2225
2439
  };
2226
2440
  type KubbInfoContext = {
2227
2441
  /**
@@ -2263,19 +2477,11 @@ type KubbWarnContext = {
2263
2477
  */
2264
2478
  info?: string;
2265
2479
  };
2266
- type KubbDebugContext = {
2267
- /**
2268
- * Timestamp when the debug entry was created.
2269
- */
2270
- date: Date;
2480
+ type KubbDiagnosticContext = {
2271
2481
  /**
2272
- * One or more log lines to emit.
2482
+ * The structured diagnostic to render: a build problem or a version-update notice.
2273
2483
  */
2274
- logs: Array<string>;
2275
- /**
2276
- * Optional source file name associated with this entry.
2277
- */
2278
- fileName?: string;
2484
+ diagnostic: ProblemDiagnostic | UpdateDiagnostic;
2279
2485
  };
2280
2486
  type KubbFilesProcessingStartContext = {
2281
2487
  /**
@@ -2293,7 +2499,7 @@ type KubbFileProcessingUpdate = {
2293
2499
  */
2294
2500
  total: number;
2295
2501
  /**
2296
- * Completion percentage (`0`–`100`).
2502
+ * Completion percentage, `0` to `100`.
2297
2503
  */
2298
2504
  percentage: number;
2299
2505
  /**
@@ -2379,7 +2585,11 @@ type CLIOptions = {
2379
2585
  *
2380
2586
  * @default 'info'
2381
2587
  */
2382
- logLevel?: 'silent' | 'info' | 'verbose' | 'debug';
2588
+ logLevel?: 'silent' | 'info' | 'verbose';
2589
+ /**
2590
+ * Reporters selected on the CLI via `--reporter`, overriding `config.reporters`.
2591
+ */
2592
+ reporters?: Array<ReporterName>;
2383
2593
  };
2384
2594
  /**
2385
2595
  * All accepted forms of a Kubb configuration.
@@ -2391,12 +2601,12 @@ type PossibleConfig<TCliOptions = undefined> = PossiblePromise<Config | Array<Co
2391
2601
  */
2392
2602
  type BuildOutput = {
2393
2603
  /**
2394
- * Plugins that threw during generation, paired with their errors.
2604
+ * Structured diagnostics collected during the build: error/warning/info problems
2605
+ * (each with a code, severity, and where known a JSON-pointer location) plus a
2606
+ * `timing` diagnostic per plugin. Includes a top-level diagnostic when the build
2607
+ * threw before completing. Use {@link Diagnostics.hasError} to test for failure.
2395
2608
  */
2396
- failedPlugins: Set<{
2397
- plugin: Plugin;
2398
- error: Error;
2399
- }>;
2609
+ diagnostics: Array<Diagnostic>;
2400
2610
  /**
2401
2611
  * All files generated during this build.
2402
2612
  */
@@ -2405,17 +2615,9 @@ type BuildOutput = {
2405
2615
  * The plugin driver that orchestrated this build.
2406
2616
  */
2407
2617
  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
2618
  /**
2417
2619
  * Read-only view of every file written during this build.
2418
- * Reads go straight to `config.storage` nothing extra is held in memory.
2620
+ * Reads go straight to `config.storage`, nothing extra is held in memory.
2419
2621
  *
2420
2622
  * @example Read a generated file
2421
2623
  * `const code = await buildOutput.storage.getItem('/src/gen/pet.ts')`
@@ -2448,7 +2650,7 @@ type CreateKubbOptions = {
2448
2650
  * ```ts
2449
2651
  * const kubb = createKubb(userConfig)
2450
2652
  * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
2451
- * const { files, failedPlugins } = await kubb.safeBuild()
2653
+ * const { files, diagnostics } = await kubb.safeBuild()
2452
2654
  * ```
2453
2655
  */
2454
2656
  declare class Kubb$1 {
@@ -2497,5 +2699,323 @@ declare class Kubb$1 {
2497
2699
  */
2498
2700
  declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
2499
2701
  //#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
2702
+ //#region src/diagnostics.d.ts
2703
+ /**
2704
+ * How serious a diagnostic is. `error` fails the build, `warning` and `info`
2705
+ * are reported but do not.
2706
+ */
2707
+ type DiagnosticSeverity = 'error' | 'warning' | 'info';
2708
+ /**
2709
+ * A human-readable explanation of a diagnostic code: a short title, what triggers it, and how
2710
+ * to resolve it. This is the single source of truth the kubb.dev `/diagnostics/<slug>` pages
2711
+ * mirror, so every code stays documented in one place. Typed as a total record over
2712
+ * {@link DiagnosticCode}, so adding a code without documenting it fails the build.
2713
+ */
2714
+ type DiagnosticDoc = {
2715
+ /**
2716
+ * Short title shown as the docs heading.
2717
+ */
2718
+ title: string;
2719
+ /**
2720
+ * What triggers the diagnostic.
2721
+ */
2722
+ cause: string;
2723
+ /**
2724
+ * The action that resolves it.
2725
+ */
2726
+ fix: string;
2727
+ };
2728
+ /**
2729
+ * Points a diagnostic back into the source document. Inputs are parsed into an
2730
+ * object model with no line/column, so locations carry a JSON pointer the adapter
2731
+ * builds (the OAS adapter emits `#/components/schemas/Pet`). A `config` diagnostic
2732
+ * points at the Kubb config itself and so has no pointer.
2733
+ */
2734
+ type DiagnosticLocation = {
2735
+ kind: 'schema';
2736
+ /**
2737
+ * RFC 6901 JSON pointer into the source document.
2738
+ */
2739
+ pointer: string;
2740
+ /**
2741
+ * The original reference when the diagnostic stems from an unresolved one.
2742
+ */
2743
+ ref?: string;
2744
+ } | {
2745
+ kind: 'operation' | 'document';
2746
+ /**
2747
+ * RFC 6901 JSON pointer into the source document.
2748
+ */
2749
+ pointer: string;
2750
+ } | {
2751
+ kind: 'config';
2752
+ };
2753
+ /**
2754
+ * What a diagnostic carries.
2755
+ * - `problem` is a build issue shown to the user, and the only kind rendered as a problem.
2756
+ * - `performance` records a plugin's elapsed time.
2757
+ * - `update` is a version notice.
2758
+ */
2759
+ type DiagnosticKind = 'problem' | 'performance' | 'update';
2760
+ /**
2761
+ * Codes that describe a build problem: every {@link DiagnosticCode} except the
2762
+ * `performance` and `updateAvailable` codes, which ride on their own variants.
2763
+ */
2764
+ type ProblemCode = Exclude<DiagnosticCode, typeof diagnosticCode.performance | typeof diagnosticCode.updateAvailable>;
2765
+ /**
2766
+ * A build problem collected during a run, gathered into the result instead of
2767
+ * aborting on the first failure. It carries a stable {@link ProblemCode}, a
2768
+ * `severity`, a `message`, and optionally a `location` into the source document,
2769
+ * a `help`, the `plugin` that produced it, and the `cause` it wraps.
2770
+ */
2771
+ type ProblemDiagnostic = {
2772
+ /**
2773
+ * @default 'problem'
2774
+ */
2775
+ kind?: 'problem';
2776
+ /**
2777
+ * Stable identifier for the problem, from the {@link diagnosticCode} catalog.
2778
+ */
2779
+ code: ProblemCode;
2780
+ severity: DiagnosticSeverity;
2781
+ message: string;
2782
+ location?: DiagnosticLocation;
2783
+ /**
2784
+ * A suggested fix, phrased as an action the user can take.
2785
+ */
2786
+ help?: string;
2787
+ /**
2788
+ * Name of the plugin or subsystem that produced the diagnostic.
2789
+ */
2790
+ plugin?: string;
2791
+ /**
2792
+ * The underlying error, when the diagnostic wraps a thrown one.
2793
+ */
2794
+ cause?: Error;
2795
+ };
2796
+ /**
2797
+ * A per-plugin performance record, built with {@link Diagnostics.performance}. It carries the
2798
+ * `plugin` and its elapsed `duration`, and the `performance` kind keeps it out of the problem
2799
+ * list. It feeds the per-plugin timing bars, and reporters sum these into the run total.
2800
+ */
2801
+ type PerformanceDiagnostic = {
2802
+ kind: 'performance';
2803
+ code: typeof diagnosticCode.performance;
2804
+ severity: 'info';
2805
+ message: string;
2806
+ /**
2807
+ * The plugin this measurement belongs to.
2808
+ */
2809
+ plugin: string;
2810
+ /**
2811
+ * Elapsed milliseconds.
2812
+ */
2813
+ duration: number;
2814
+ };
2815
+ /**
2816
+ * A notice that a newer Kubb version is available on npm, built with {@link Diagnostics.update}.
2817
+ * It carries the running and latest versions and renders like any info diagnostic.
2818
+ */
2819
+ type UpdateDiagnostic = {
2820
+ kind: 'update';
2821
+ code: typeof diagnosticCode.updateAvailable;
2822
+ severity: 'info';
2823
+ message: string;
2824
+ /**
2825
+ * The running Kubb version.
2826
+ */
2827
+ currentVersion: string;
2828
+ /**
2829
+ * The newest version published on npm.
2830
+ */
2831
+ latestVersion: string;
2832
+ };
2833
+ /**
2834
+ * A structured record collected during a build, discriminated on `kind`: a
2835
+ * {@link ProblemDiagnostic} for an issue, a {@link PerformanceDiagnostic} for a per-plugin
2836
+ * timing, or an {@link UpdateDiagnostic} for a version notice.
2837
+ */
2838
+ type Diagnostic = ProblemDiagnostic | PerformanceDiagnostic | UpdateDiagnostic;
2839
+ /**
2840
+ * Maps each {@link DiagnosticCode} to the variant it selects, for {@link narrowDiagnostic}.
2841
+ * Every {@link ProblemCode} selects a {@link ProblemDiagnostic}, and the two bookkeeping codes
2842
+ * select their own variant.
2843
+ */
2844
+ type DiagnosticByCode = Record<ProblemCode, ProblemDiagnostic> & Record<typeof diagnosticCode.performance, PerformanceDiagnostic> & Record<typeof diagnosticCode.updateAvailable, UpdateDiagnostic>;
2845
+ /**
2846
+ * Narrows a {@link Diagnostic} to the variant for `code`, or `null` when it does not match.
2847
+ *
2848
+ * @example
2849
+ * ```ts
2850
+ * const update = narrowDiagnostic(diagnostic, diagnosticCode.updateAvailable)
2851
+ * if (update) {
2852
+ * console.log(update.latestVersion)
2853
+ * }
2854
+ * ```
2855
+ */
2856
+ declare function narrowDiagnostic<C extends DiagnosticCode>(diagnostic: Diagnostic, code: C): DiagnosticByCode[C] | null;
2857
+ /**
2858
+ * Returns `true` when the diagnostic is a build {@link ProblemDiagnostic}.
2859
+ *
2860
+ * @example
2861
+ * ```ts
2862
+ * if (isProblemDiagnostic(diagnostic)) {
2863
+ * console.log(diagnostic.location)
2864
+ * }
2865
+ * ```
2866
+ */
2867
+ declare const isProblemDiagnostic: (diagnostic: Diagnostic) => diagnostic is ProblemDiagnostic;
2868
+ /**
2869
+ * Returns `true` when the diagnostic is a per-plugin {@link PerformanceDiagnostic}.
2870
+ *
2871
+ * @example
2872
+ * ```ts
2873
+ * const timings = diagnostics.filter(isPerformanceDiagnostic)
2874
+ * ```
2875
+ */
2876
+ declare const isPerformanceDiagnostic: (diagnostic: Diagnostic) => diagnostic is PerformanceDiagnostic;
2877
+ /**
2878
+ * Returns `true` when the diagnostic is a version-update {@link UpdateDiagnostic}.
2879
+ *
2880
+ * @example
2881
+ * ```ts
2882
+ * if (isUpdateDiagnostic(diagnostic)) {
2883
+ * console.log(diagnostic.latestVersion)
2884
+ * }
2885
+ * ```
2886
+ */
2887
+ declare const isUpdateDiagnostic: (diagnostic: Diagnostic) => diagnostic is UpdateDiagnostic;
2888
+ /**
2889
+ * A {@link Diagnostic} reduced to its JSON-safe fields plus a `docsUrl`, for
2890
+ * machine-readable output (the `--reporter json` report, the MCP tools). Drops the
2891
+ * non-serializable `cause` and the `timing`/`duration` bookkeeping.
2892
+ */
2893
+ type SerializedDiagnostic = {
2894
+ code: DiagnosticCode;
2895
+ severity: DiagnosticSeverity;
2896
+ message: string;
2897
+ location?: DiagnosticLocation;
2898
+ help?: string;
2899
+ plugin?: string;
2900
+ /**
2901
+ * The kubb.dev docs link for the code, omitted for the unknown fallback.
2902
+ */
2903
+ docsUrl?: string;
2904
+ };
2905
+ /**
2906
+ * An `Error` that carries a {@link Diagnostic}, so structured problems can flow
2907
+ * through the existing throw/catch paths while keeping their code and location.
2908
+ *
2909
+ * @example
2910
+ * ```ts
2911
+ * throw new DiagnosticError({ code: diagnosticCode.refNotFound, severity: 'error', message: `Could not find ${ref}`, location: { kind: 'schema', pointer: ref, ref } })
2912
+ * ```
2913
+ */
2914
+ declare class DiagnosticError extends Error {
2915
+ diagnostic: ProblemDiagnostic;
2916
+ constructor(diagnostic: ProblemDiagnostic);
2917
+ }
2918
+ /**
2919
+ * Explanation for every {@link diagnosticCode}. Use {@link Diagnostics.explain} to look one up
2920
+ * and `Diagnostics.docsUrl` for the matching kubb.dev page.
2921
+ */
2922
+ declare const diagnosticCatalog: Record<DiagnosticCode, DiagnosticDoc>;
2923
+ /**
2924
+ * Static helpers for working with {@link Diagnostic}s, plus the run-scoped sink
2925
+ * that lets deep code report a diagnostic without threading a callback.
2926
+ *
2927
+ * The sink lives in a single `AsyncLocalStorage` in the `@kubb/core` bundle.
2928
+ * `Diagnostics.scope` activates it for a run, so anything inside that run (the
2929
+ * adapter parse, a lazily consumed stream, a generator) reports through
2930
+ * `Diagnostics.report` and lands in the same run.
2931
+ */
2932
+ declare class Diagnostics {
2933
+ #private;
2934
+ /**
2935
+ * Runs `fn` with `sink` as the active diagnostic sink for the whole async
2936
+ * subtree, so {@link Diagnostics.report} reaches it from anywhere inside.
2937
+ */
2938
+ static scope<T>(sink: (diagnostic: Diagnostic) => void, fn: () => T): T;
2939
+ /**
2940
+ * Collects a diagnostic into the active build via the run-scoped sink, without throwing.
2941
+ * Returns `true` when a run consumed it, `false` when called outside a {@link Diagnostics.scope}
2942
+ * (so callers can fall back to throwing). Use a `warning`/`info` severity for non-fatal issues.
2943
+ * For rendering a diagnostic live on the hook bus, use {@link Diagnostics.emit} instead.
2944
+ */
2945
+ static report(diagnostic: Diagnostic): boolean;
2946
+ /**
2947
+ * Emits a diagnostic on the run's `kubb:diagnostic` event so the loggers render it live.
2948
+ * Use it instead of calling `hooks.emit('kubb:diagnostic', ...)` directly. To collect a
2949
+ * diagnostic into the build result from deep in a run, use {@link Diagnostics.report} instead.
2950
+ */
2951
+ static emit(hooks: AsyncEventEmitter<KubbHooks>, diagnostic: ProblemDiagnostic | UpdateDiagnostic): Promise<void>;
2952
+ /**
2953
+ * Coerces any thrown value into a {@link ProblemDiagnostic}. A {@link DiagnosticError}
2954
+ * keeps its structured data, and anything else becomes a `KUBB_UNKNOWN` error.
2955
+ */
2956
+ static from(error: unknown): ProblemDiagnostic;
2957
+ /**
2958
+ * Builds a per-plugin performance record. Reporters sum these into the run total.
2959
+ */
2960
+ static performance({
2961
+ plugin,
2962
+ duration
2963
+ }: {
2964
+ plugin: string;
2965
+ duration: number;
2966
+ }): PerformanceDiagnostic;
2967
+ /**
2968
+ * Builds the version-update notice shown when a newer Kubb is published on npm.
2969
+ */
2970
+ static update({
2971
+ currentVersion,
2972
+ latestVersion
2973
+ }: {
2974
+ currentVersion: string;
2975
+ latestVersion: string;
2976
+ }): UpdateDiagnostic;
2977
+ /**
2978
+ * True when any diagnostic is an error, the severity that fails a build. Non-error
2979
+ * diagnostics are ignored.
2980
+ */
2981
+ static hasError(diagnostics: ReadonlyArray<Diagnostic>): boolean;
2982
+ /**
2983
+ * Names of the plugins that failed, deduped, derived from the error diagnostics
2984
+ * that carry a `plugin`.
2985
+ */
2986
+ static failedPlugins(diagnostics: ReadonlyArray<Diagnostic>): Array<string>;
2987
+ /**
2988
+ * Counts `problem` diagnostics by severity for the run summary. `timing`
2989
+ * diagnostics are ignored.
2990
+ */
2991
+ static count(diagnostics: ReadonlyArray<Diagnostic>): {
2992
+ errors: number;
2993
+ warnings: number;
2994
+ infos: number;
2995
+ };
2996
+ /**
2997
+ * Drops duplicate `problem` diagnostics that share a code, location pointer, and
2998
+ * plugin, so the same issue reported across several passes is shown once. Non-problem
2999
+ * diagnostics are always kept.
3000
+ */
3001
+ static dedupe(diagnostics: ReadonlyArray<Diagnostic>): Array<Diagnostic>;
3002
+ /**
3003
+ * Builds the kubb.dev docs URL for a diagnostic code, e.g.
3004
+ * `KUBB_REF_NOT_FOUND` → `https://kubb.dev/docs/5.x/reference/diagnostics/kubb-ref-not-found`.
3005
+ */
3006
+ static docsUrl(code: string): string;
3007
+ /**
3008
+ * The catalog entry for a code: its title, cause, and fix. Mirrors the kubb.dev
3009
+ * `/diagnostics/<slug>` page.
3010
+ */
3011
+ static explain(code: DiagnosticCode): DiagnosticDoc;
3012
+ /**
3013
+ * Reduces a diagnostic to its JSON-safe fields plus a `docsUrl`, for machine-readable
3014
+ * consumers. The `cause`, `kind`, and `duration` are dropped, and absent optional
3015
+ * fields are omitted rather than set to `undefined`.
3016
+ */
3017
+ static serialize(diagnostic: Diagnostic): SerializedDiagnostic;
3018
+ }
3019
+ //#endregion
3020
+ 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 };
3021
+ //# sourceMappingURL=diagnostics-CYfKPtbU.d.ts.map