@kubb/core 5.0.0-beta.84 → 5.0.0-beta.86

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.
@@ -1,88 +1,6 @@
1
1
  import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
2
2
  import { Enforce, FileNode, HttpMethod, ImportNode, InputMeta, InputNode, Macro, Node, OperationNode, SchemaNode, UserFileNode } from "@kubb/ast";
3
3
 
4
- //#region ../../internals/utils/src/asyncEventEmitter.d.ts
5
- /**
6
- * A function that can be registered as an event listener, synchronous or async.
7
- */
8
- type AsyncListener<TArgs extends Array<unknown>> = (...args: TArgs) => void | Promise<void>;
9
- /**
10
- * Typed `EventEmitter` that awaits all async listeners before resolving.
11
- * Wraps Node's `EventEmitter` with full TypeScript event-map inference.
12
- *
13
- * @example
14
- * ```ts
15
- * const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
16
- * emitter.on('build', async (name) => { console.log(name) })
17
- * await emitter.emit('build', 'petstore') // all listeners awaited
18
- * ```
19
- */
20
- declare class AsyncEventEmitter<TEvents extends { [K in keyof TEvents]: Array<unknown> }> {
21
- #private;
22
- /**
23
- * Maximum number of listeners per event before Node emits a memory-leak warning.
24
- * @default 10
25
- */
26
- constructor(maxListener?: number);
27
- /**
28
- * Emits `eventName` and awaits all registered listeners sequentially.
29
- * Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
30
- *
31
- * @example
32
- * ```ts
33
- * await emitter.emit('build', 'petstore')
34
- * ```
35
- */
36
- emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> | void;
37
- /**
38
- * Registers a persistent listener for `eventName`.
39
- *
40
- * @example
41
- * ```ts
42
- * emitter.on('build', async (name) => { console.log(name) })
43
- * ```
44
- */
45
- on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void;
46
- /**
47
- * Removes a previously registered listener.
48
- *
49
- * @example
50
- * ```ts
51
- * emitter.off('build', handler)
52
- * ```
53
- */
54
- off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void;
55
- /**
56
- * Returns the number of listeners registered for `eventName`.
57
- *
58
- * @example
59
- * ```ts
60
- * emitter.on('build', handler)
61
- * emitter.listenerCount('build') // 1
62
- * ```
63
- */
64
- listenerCount<TEventName extends keyof TEvents & string>(eventName: TEventName): number;
65
- /**
66
- * Raises or lowers the per-event listener ceiling before Node warns about a memory leak.
67
- * Set this above the expected listener count when many listeners attach by design.
68
- *
69
- * @example
70
- * ```ts
71
- * emitter.setMaxListeners(40)
72
- * ```
73
- */
74
- setMaxListeners(max: number): void;
75
- /**
76
- * Removes all listeners from every event channel.
77
- *
78
- * @example
79
- * ```ts
80
- * emitter.removeAll()
81
- * ```
82
- */
83
- removeAll(): void;
84
- }
85
- //#endregion
86
4
  //#region ../../internals/utils/src/promise.d.ts
87
5
  /** A value that may already be resolved or still pending.
88
6
  *
@@ -179,14 +97,6 @@ type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
179
97
  validate: (input: string, options?: {
180
98
  throwOnError?: boolean;
181
99
  }) => Promise<void>;
182
- /**
183
- * Memory-efficient streaming variant of `parse()`.
184
- *
185
- * Returns an `InputNode<true>` whose `schemas` and `operations` are `AsyncIterable`.
186
- * Each `for await` loop creates a fresh parse pass over the cached in-memory document.
187
- * No pre-built arrays are held in memory.
188
- */
189
- stream?: (source: AdapterSource) => Promise<InputNode<true>>;
190
100
  };
191
101
  type AdapterBuilder<T extends AdapterFactoryOptions> = (options: T['options']) => Adapter<T>;
192
102
  /**
@@ -367,7 +277,7 @@ type ReporterContext = {
367
277
  };
368
278
  /**
369
279
  * Host-facing reporter, as installed onto a run. Unlike a Logger (the live TUI view), a reporter
370
- * never sees the event emitter. `report` runs once per config. `drain`, when present, runs once
280
+ * never sees the hook emitter. `report` runs once per config. `drain`, when present, runs once
371
281
  * after the last config.
372
282
  */
373
283
  type Reporter = {
@@ -383,7 +293,8 @@ type Reporter = {
383
293
  * Optional finalizer called once after the run's last config. The host wires it to
384
294
  * `kubb:lifecycle:end`. {@link createReporter} closes it over the values that `report` returned.
385
295
  */
386
- drain?: (context: ReporterContext) => void | Promise<void>;
296
+ drain: (context: ReporterContext) => void | Promise<void>;
297
+ [Symbol.dispose](): void;
387
298
  };
388
299
  /**
389
300
  * Reporter definition passed to {@link createReporter}. `report` returns the value to collect for
@@ -398,7 +309,7 @@ type UserReporter<T = void> = {
398
309
  /**
399
310
  * Defines a reporter. When the definition has a `drain`, the returned reporter buffers each value
400
311
  * `report` returns and hands the array to `drain` once, then clears it. Without a `drain`, nothing
401
- * is buffered. Wiring the reporter onto the run's events is the host's job, so the reporter only
312
+ * is buffered. Wiring the reporter onto the run's hooks is the host's job, so the reporter only
402
313
  * ever deals with a {@link GenerationResult}.
403
314
  *
404
315
  * @example
@@ -517,14 +428,8 @@ type Renderer<TElement = unknown> = {
517
428
  render(element: TElement): Promise<void>;
518
429
  /**
519
430
  * Accumulated {@link FileNode} results produced by the last {@link render} call.
520
- * Not populated when {@link stream} is implemented.
521
431
  */
522
432
  readonly files: Array<FileNode>;
523
- /**
524
- * When present, core calls this instead of {@link render} and {@link files},
525
- * forwarding each file to `FileManager` as soon as it is ready.
526
- */
527
- stream?(element: TElement): Iterable<FileNode>;
528
433
  /**
529
434
  * Disposer hook so renderers participate in `using` blocks: `using r = rendererFactory()`
530
435
  * runs cleanup on every exit path, including thrown errors.
@@ -568,20 +473,7 @@ type RendererFactory<TElement = unknown> = () => Renderer<TElement>;
568
473
  */
569
474
  declare function createRenderer<TElement = unknown>(factory: RendererFactory<TElement>): RendererFactory<TElement>;
570
475
  //#endregion
571
- //#region src/defineResolver.d.ts
572
- /**
573
- * Type/string pattern filter for include/exclude/override matching.
574
- */
575
- type PatternFilter = {
576
- type: string;
577
- pattern: string | RegExp;
578
- };
579
- /**
580
- * Pattern filter with partial option overrides applied when the pattern matches.
581
- */
582
- type PatternOverride<TOptions> = PatternFilter & {
583
- options: Omit<Partial<TOptions>, 'override'>;
584
- };
476
+ //#region src/Resolver.d.ts
585
477
  /**
586
478
  * Context for resolving filtered options for a given operation or schema node.
587
479
  *
@@ -589,43 +481,33 @@ type PatternOverride<TOptions> = PatternFilter & {
589
481
  */
590
482
  type ResolveOptionsContext<TOptions> = {
591
483
  options: TOptions;
592
- exclude?: Array<PatternFilter>;
593
- include?: Array<PatternFilter>;
594
- override?: Array<PatternOverride<TOptions>>;
484
+ exclude?: Array<Filter>;
485
+ include?: Array<Filter>;
486
+ override?: Array<Override<TOptions>>;
595
487
  };
596
488
  /**
597
- * Base constraint for all plugin resolver objects.
598
- *
599
- * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
600
- * are injected automatically by `defineResolver`. Extend this type to add custom resolution methods.
601
- *
602
- * @example
603
- * ```ts
604
- * type MyResolver = Resolver & {
605
- * resolveName(node: SchemaNode): string
606
- * resolveTypedName(node: SchemaNode): string
607
- * }
608
- * ```
489
+ * The built-in resolution machinery exposed on every resolver as `resolver.default`.
490
+ * Plugins delegate to it via `this.default.*` and set their own conventions through
491
+ * the top-level `name` and `file` entries.
609
492
  */
610
- type Resolver = {
611
- name: string;
612
- pluginName: string;
613
- default(name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
614
- resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null;
615
- resolvePath(params: ResolverPathParams, context: ResolverContext): string;
616
- resolveFile(params: ResolverFileParams, context: ResolverContext): FileNode;
617
- resolveBanner(meta: InputMeta | undefined, context: ResolveBannerContext): string | null;
618
- resolveFooter(meta: InputMeta | undefined, context: ResolveBannerContext): string | null;
493
+ type ResolverDefault = {
494
+ /**
495
+ * Built-in camelCase casing for a generated identifier.
496
+ */
497
+ name(name: string): string;
498
+ options<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null;
499
+ path(params: ResolverPathParams, context: ResolverContext): string;
500
+ file(params: ResolverFileParams, context: ResolverContext): FileNode;
501
+ banner(meta: InputMeta | undefined, context: ResolveBannerContext): string | null;
502
+ footer(meta: InputMeta | undefined, context: ResolveBannerContext): string | null;
619
503
  };
620
504
  /**
621
- * File-specific parameters for `Resolver.resolvePath`.
622
- *
623
- * Pass alongside a `ResolverContext` to identify which file to resolve.
505
+ * File-specific parameters for `resolver.default.path`.
624
506
  * Provide `tag` for tag-based grouping or `path` for path-based grouping.
625
507
  *
626
508
  * @example
627
509
  * ```ts
628
- * resolver.resolvePath(
510
+ * resolver.default.path(
629
511
  * { baseName: 'petTypes.ts', tag: 'pets' },
630
512
  * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
631
513
  * )
@@ -644,38 +526,22 @@ type ResolverPathParams = {
644
526
  path?: string;
645
527
  };
646
528
  /**
647
- * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
648
- *
649
- * Describes where on disk output is rooted, which output config is active, and the optional
650
- * grouping strategy that controls subdirectory layout.
651
- *
652
- * @example
653
- * ```ts
654
- * const context: ResolverContext = {
655
- * root: config.root,
656
- * output,
657
- * group,
658
- * }
659
- * ```
529
+ * Shared context passed as the second argument to `resolver.default.path` and
530
+ * `resolver.default.file`: where output is rooted, which output config is active,
531
+ * and the optional grouping strategy.
660
532
  */
661
533
  type ResolverContext = {
662
534
  root: string;
663
535
  output: Output;
664
536
  group?: Group;
665
- /**
666
- * Plugin name used to populate `meta.pluginName` on the resolved file.
667
- */
668
- pluginName?: string;
669
537
  };
670
538
  /**
671
- * File-specific parameters for `Resolver.resolveFile`.
672
- *
673
- * Pass alongside a `ResolverContext` to fully describe the file to resolve.
539
+ * File-specific parameters for `resolver.default.file`.
674
540
  * `tag` and `path` are used only when a matching `group` is present in the context.
675
541
  *
676
542
  * @example
677
543
  * ```ts
678
- * resolver.resolveFile(
544
+ * resolver.default.file(
679
545
  * { name: 'listPets', extname: '.ts', tag: 'pets' },
680
546
  * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
681
547
  * )
@@ -693,13 +559,18 @@ type ResolverFileParams = {
693
559
  * Path value used when `group.type === 'path'`.
694
560
  */
695
561
  path?: string;
562
+ /**
563
+ * Casing applied to `name` to build the file base name. A plugin's `file` override
564
+ * threads its own caser here to change file naming without reimplementing the builder.
565
+ *
566
+ * @default toFilePath
567
+ */
568
+ resolveName?: (name: string) => string;
696
569
  };
697
570
  /**
698
- * Per-file context describing the file a banner/footer is being resolved for.
699
- *
700
- * Supplied by the generator (or the barrel plugin) at resolve-time and merged
701
- * into `BannerMeta` so a `banner`/`footer` function can branch on the file kind,
702
- * e.g. omit a `'use server'` directive on re-export files.
571
+ * Per-file context describing the file a banner/footer is being resolved for, so a
572
+ * `banner`/`footer` function can branch on the file kind (e.g. skip a `'use server'`
573
+ * directive on re-export files).
703
574
  */
704
575
  type ResolveBannerFile = {
705
576
  /**
@@ -722,9 +593,6 @@ type ResolveBannerFile = {
722
593
  /**
723
594
  * Document metadata extended with per-file context, passed to a `banner`/`footer` function.
724
595
  *
725
- * Carries everything in {@link InputMeta} plus the file the banner is rendered into, so a
726
- * single function can decide per file (e.g. skip a directive on barrel/aggregation files).
727
- *
728
596
  * @example Skip a directive on re-export files
729
597
  * `banner: (meta) => (meta.isBarrel || meta.isAggregation) ? '' : "'use server'"`
730
598
  */
@@ -747,17 +615,9 @@ type BannerMeta = InputMeta & {
747
615
  isAggregation: boolean;
748
616
  };
749
617
  /**
750
- * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
751
- *
752
- * `output` is optional, since not every plugin configures a banner/footer.
753
- * `config` carries the global Kubb config, used to derive the default Kubb banner.
754
- * `file` carries per-file context forwarded to a `banner`/`footer` function.
755
- *
756
- * @example
757
- * ```ts
758
- * resolver.resolveBanner(meta, { output: { banner: '// generated' }, config })
759
- * // → '// generated'
760
- * ```
618
+ * Context passed to `resolver.default.banner` and `resolver.default.footer`.
619
+ * `output` is optional since not every plugin configures a banner/footer, and `config`
620
+ * carries the global Kubb config used to derive the default Kubb banner.
761
621
  */
762
622
  type ResolveBannerContext = {
763
623
  output?: Pick<Output, 'banner' | 'footer'>;
@@ -765,111 +625,67 @@ type ResolveBannerContext = {
765
625
  file?: ResolveBannerFile;
766
626
  };
767
627
  /**
768
- * Builder type for the plugin-specific resolver fields.
769
- *
770
- * `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
771
- * are optional, with built-in fallbacks injected when omitted.
772
- *
773
- * Methods in the returned object can call sibling resolver methods via `this`.
628
+ * Raw resolver fields passed to `createResolver` or patched through `Resolver.merge`.
629
+ * `default` is the built-in machinery and is not user-settable.
774
630
  */
775
- type ResolverBuilder<T extends PluginFactoryOptions> = () => Omit<T['resolver'], 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter' | 'name' | 'pluginName'> & Partial<Pick<T['resolver'], 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter'>> & {
776
- name: string;
777
- pluginName: T['name'];
778
- } & ThisType<T['resolver']>;
631
+ type ResolverBuildOptions = {
632
+ pluginName: string;
633
+ name?: (name: string) => string;
634
+ file?: (params: ResolverFileParams, context: ResolverContext) => FileNode;
635
+ [key: string]: unknown;
636
+ };
779
637
  /**
780
- * Default path resolver used by `defineResolver`.
781
- *
782
- * - `mode: 'file'` resolves directly to `output.path` (the full file path, extension included).
783
- * - `mode: 'directory'` (default) resolves to `output.path/{baseName}`, or into a
784
- * subdirectory when `group` and a `tag`/`path` value are provided.
785
- *
786
- * A custom `group.name` function overrides the default subdirectory naming.
787
- * For `tag` groups the default is the camelCased tag.
788
- * For `path` groups the default is the first path segment after `/`.
789
- *
790
- * @example Flat output
791
- * ```ts
792
- * defaultResolvePath({ baseName: 'petTypes.ts' }, { root: '/src', output: { path: 'types' } })
793
- * // → '/src/types/petTypes.ts'
794
- * ```
795
- *
796
- * @example Tag-based grouping
797
- * ```ts
798
- * defaultResolvePath(
799
- * { baseName: 'petTypes.ts', tag: 'pets' },
800
- * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
801
- * )
802
- * // → '/src/types/pets/petTypes.ts'
803
- * ```
804
- *
805
- * @example Path-based grouping
806
- * ```ts
807
- * defaultResolvePath(
808
- * { baseName: 'petTypes.ts', path: '/pets/list' },
809
- * { root: '/src', output: { path: 'types' }, group: { type: 'path' } },
810
- * )
811
- * // → '/src/types/pets/petTypes.ts'
812
- * ```
813
- *
814
- * @example Single file (`mode: 'file'`)
815
- * ```ts
816
- * defaultResolvePath(
817
- * { baseName: 'petTypes.ts' },
818
- * { root: '/src', output: { path: 'types.ts', mode: 'file' } },
819
- * )
820
- * // → '/src/types.ts'
821
- * ```
638
+ * Partial resolver fields accepted by `Resolver.merge` and `setResolver`. Parameterize with a
639
+ * concrete resolver type (e.g. `ResolverPatch<ResolverTs>`) to type-check namespace overrides
640
+ * and bind `this` to the full resolver. The bare form accepts any resolver's fields.
822
641
  */
642
+ type ResolverPatch<T extends Resolver = Resolver> = Partial<Omit<T, keyof Resolver>> & {
643
+ name?: T['name'];
644
+ file?: T['file'];
645
+ } & ThisType<T>;
823
646
  /**
824
- * Defines a plugin resolver. The resolver is the object that decides what
825
- * every generated symbol and file path is called. Built-in defaults handle
826
- * name casing, include/exclude/override filtering, output path computation,
827
- * and file construction. Supply your own to override any of them:
828
- *
829
- * - `default` sets the name casing strategy (camelCase or PascalCase).
830
- * - `resolveOptions` does include/exclude/override filtering.
831
- * - `resolvePath` computes the output path.
832
- * - `resolveFile` builds the full `FileNode`.
833
- * - `resolveBanner` and `resolveFooter` produce the top and bottom of file text.
647
+ * Base constraint for all plugin resolver objects.
834
648
  *
835
- * Methods in the returned object can call sibling resolver methods via `this`.
836
- * A custom rule can delegate to a default, for example `this.default(name, 'type')`.
649
+ * The built-in machinery lives under `default`. Generators call the top-level `name` and
650
+ * `file`, and a plugin overrides them to set its conventions. Extend with top-level helpers
651
+ * (`typeName`, …) and/or grouped namespaces (`query`, `schema`, …).
837
652
  *
838
- * @example Basic resolver with naming helpers
653
+ * @example Top-level helper
839
654
  * ```ts
840
- * export const resolverTs = defineResolver<PluginTs>(() => ({
841
- * name: 'default',
842
- * resolveName(name) {
843
- * return this.default(name, 'function')
844
- * },
845
- * resolveTypeName(name) {
846
- * return this.default(name, 'type')
847
- * },
848
- * }))
655
+ * type MyResolver = Resolver & {
656
+ * typeName(name: string): string
657
+ * }
849
658
  * ```
850
659
  *
851
- * @example Custom output path
660
+ * @example Grouped namespace
852
661
  * ```ts
853
- * import path from 'node:path'
854
- *
855
- * export const resolverTs = defineResolver<PluginTs>(() => ({
856
- * name: 'custom',
857
- * resolvePath({ baseName }, { root, output }) {
858
- * return path.resolve(root, output.path, 'generated', baseName)
859
- * },
860
- * }))
662
+ * type MyResolver = Resolver & {
663
+ * query: {
664
+ * name(node: OperationNode): string
665
+ * keyName(node: OperationNode): string
666
+ * }
667
+ * }
861
668
  * ```
862
669
  */
863
- declare function defineResolver<T extends PluginFactoryOptions>(build: ResolverBuilder<T>): T['resolver'];
670
+ declare class Resolver {
671
+ #private;
672
+ readonly pluginName: string;
673
+ constructor(options: ResolverBuildOptions);
674
+ /**
675
+ * The built-in resolution machinery. Always reaches the untouched defaults, even when a
676
+ * plugin overrides the top-level `name` or `file`.
677
+ */
678
+ get default(): ResolverDefault;
679
+ name(name: string): string;
680
+ file(params: ResolverFileParams, context: ResolverContext): FileNode;
681
+ /**
682
+ * Merges `override` over `base` and returns a new resolver with helpers re-bound.
683
+ * Each key is replaced wholesale. Used when applying `setResolver` partial overrides.
684
+ */
685
+ static merge<T extends Resolver>(base: T, override: ResolverPatch<T> | Resolver): T;
686
+ }
864
687
  //#endregion
865
688
  //#region src/definePlugin.d.ts
866
- /**
867
- * Reads a type from a registry, falling back to `{}` when the key is absent. Lets
868
- * `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry` be augmented without
869
- * touching core.
870
- *
871
- * @internal
872
- */
873
689
  type ExtractRegistryKey$1<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
874
690
  /**
875
691
  * How a plugin consolidates its generated code into files.
@@ -881,7 +697,7 @@ type OutputMode = 'directory' | 'file';
881
697
  * Output configuration shared by every plugin. Each plugin extends this with
882
698
  * its own keys via the `Kubb.PluginOptionsRegistry.output` interface merge.
883
699
  */
884
- type Output<_TOptions = unknown> = {
700
+ type Output = {
885
701
  /**
886
702
  * Directory where the plugin writes its generated code, resolved against the global
887
703
  * `output.path` set on `defineConfig`. With `mode: 'file'`, this is the full output file
@@ -1023,6 +839,11 @@ type ByContentType = {
1023
839
  */
1024
840
  pattern: string | RegExp;
1025
841
  };
842
+ /**
843
+ * Pattern filter for include, exclude, and override rules. Matches operations or schemas
844
+ * by tag, operationId, path, method, content type, or schema name.
845
+ */
846
+ type Filter = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
1026
847
  /**
1027
848
  * Filter that skips matching operations or schemas during generation, for example
1028
849
  * deprecated endpoints or internal-only schemas.
@@ -1036,7 +857,7 @@ type ByContentType = {
1036
857
  * ]
1037
858
  * ```
1038
859
  */
1039
- type Exclude$1 = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
860
+ type Exclude$1 = Filter;
1040
861
  /**
1041
862
  * Filter that restricts generation to operations or schemas matching at least
1042
863
  * one entry. Useful for partial builds (one tag, one API version).
@@ -1049,7 +870,7 @@ type Exclude$1 = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | ByS
1049
870
  * ]
1050
871
  * ```
1051
872
  */
1052
- type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName;
873
+ type Include = Filter;
1053
874
  /**
1054
875
  * Filter paired with a partial options object. When the filter matches, the
1055
876
  * options are merged on top of the plugin defaults for that operation only.
@@ -1073,7 +894,7 @@ type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySch
1073
894
  * ]
1074
895
  * ```
1075
896
  */
1076
- type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
897
+ type Override<TOptions> = Filter & {
1077
898
  options: Omit<Partial<TOptions>, 'override'>;
1078
899
  };
1079
900
  type PluginFactoryOptions<
@@ -1091,7 +912,7 @@ TOptions extends object = object,
1091
912
  TResolvedOptions extends object = TOptions,
1092
913
  /**
1093
914
  * Resolver that encapsulates naming and path-resolution helpers.
1094
- * Define with `defineResolver` and export alongside the plugin.
915
+ * Define with `createResolver` and export alongside the plugin.
1095
916
  */
1096
917
  TResolver extends Resolver = Resolver> = {
1097
918
  name: TName;
@@ -1120,9 +941,10 @@ type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactor
1120
941
  addGenerator<TElement = unknown>(...generators: Array<Generator<TFactory, TElement>>): void;
1121
942
  /**
1122
943
  * Set or override the resolver for this plugin.
1123
- * The resolver controls file naming and path resolution.
944
+ * The resolver controls file naming and path resolution. Overrides merge over the built-in
945
+ * defaults, so a partial `core` or a single namespace method replaces only what it names.
1124
946
  */
1125
- setResolver(resolver: Partial<TFactory['resolver']>): void;
947
+ setResolver(resolver: ResolverPatch<TFactory['resolver']> | TFactory['resolver']): void;
1126
948
  /**
1127
949
  * Add a macro that rewrites AST nodes before they reach generators. Macros run in the order they
1128
950
  * are added, after any macros from earlier `addMacro` calls.
@@ -1186,8 +1008,8 @@ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1186
1008
  */
1187
1009
  options?: TFactory['options'];
1188
1010
  /**
1189
- * Lifecycle event handlers for this plugin.
1190
- * Any event from the global `KubbHooks` map can be subscribed to here.
1011
+ * Lifecycle hook handlers for this plugin.
1012
+ * Any hook from the global `KubbHooks` map can be subscribed to here.
1191
1013
  */
1192
1014
  hooks: { [K in keyof KubbHooks as K extends 'kubb:plugin:setup' ? never : K]?: (...args: KubbHooks[K]) => void | Promise<void> } & {
1193
1015
  'kubb:plugin:setup'?(ctx: KubbPluginSetupContext<TFactory>): void | Promise<void>;
@@ -1209,6 +1031,11 @@ type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1209
1031
  resolver: TOptions['resolver'];
1210
1032
  macros?: Array<Macro>;
1211
1033
  generators?: Array<Generator>;
1034
+ /**
1035
+ * Set by the driver when the plugin registers a generator via `addGenerator()` in
1036
+ * `kubb:plugin:setup`. Drives whether the build walks the AST for this plugin.
1037
+ */
1038
+ hasHookGenerators?: boolean;
1212
1039
  apply?: (config: Config) => boolean;
1213
1040
  version?: string;
1214
1041
  };
@@ -1255,55 +1082,233 @@ type KubbPluginEndContext = {
1255
1082
  */
1256
1083
  declare function definePlugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>(factory: (options: TFactory['options']) => Plugin<TFactory>): (options?: TFactory['options']) => Plugin<TFactory>;
1257
1084
  //#endregion
1258
- //#region src/FileManager.d.ts
1085
+ //#region src/defineParser.d.ts
1086
+ type PrintOptions = {
1087
+ extname?: FileNode['extname'];
1088
+ };
1089
+ /**
1090
+ * Converts a resolved {@link FileNode} into the final source string that gets
1091
+ * written to disk. Kubb ships with TypeScript and TSX parsers. Add your own
1092
+ * for new file types (JSON, Markdown, ...).
1093
+ */
1094
+ type Parser<TMeta extends object = object, TNode = unknown> = {
1095
+ /**
1096
+ * Display name used in diagnostics and the parser registry.
1097
+ */
1098
+ name: string;
1099
+ /**
1100
+ * File extensions this parser handles. The driver registers the parser for each
1101
+ * extension in this list. A parser with `undefined` here is not registered, so
1102
+ * files of an unclaimed extension fall back to joining their sources verbatim.
1103
+ *
1104
+ * @example
1105
+ * `['.ts', '.js']`
1106
+ */
1107
+ extNames: Array<FileNode['extname']> | undefined;
1108
+ /**
1109
+ * Serialize the file's AST into source code.
1110
+ */
1111
+ parse(file: FileNode<TMeta>, options?: PrintOptions): string;
1112
+ /**
1113
+ * Render compiler AST nodes for this parser's language into source text.
1114
+ * Plugins call this to format the nodes they assemble before handing them
1115
+ * back to the parser as `FileNode.sources`.
1116
+ */
1117
+ print(...nodes: Array<TNode>): string;
1118
+ };
1259
1119
  /**
1260
- * Hooks fired by a `FileManager`.
1120
+ * Defines a parser with type-safe `this`. Used to register handlers for new
1121
+ * file extensions or to plug a non-TypeScript output into the build.
1122
+ *
1123
+ * @example
1124
+ * ```ts
1125
+ * import { defineParser } from '@kubb/core'
1126
+ * import { extractStringsFromNodes } from '@kubb/ast'
1261
1127
  *
1262
- * - `upsert` fires once per resolved file added through `add` or `upsert`.
1128
+ * export const jsonParser = defineParser({
1129
+ * name: 'json',
1130
+ * extNames: ['.json'],
1131
+ * parse(file) {
1132
+ * return file.sources
1133
+ * .map((source) => extractStringsFromNodes(source.nodes ?? []))
1134
+ * .join('\n')
1135
+ * },
1136
+ * print(...nodes) {
1137
+ * return nodes.map(String).join('\n')
1138
+ * },
1139
+ * })
1140
+ * ```
1141
+ */
1142
+ declare function defineParser<T extends Parser>(parser: T): T;
1143
+ //#endregion
1144
+ //#region src/Hookable.d.ts
1145
+ /**
1146
+ * A function that can be registered as a hook listener, synchronous or async. Any return value is
1147
+ * allowed and ignored, so handlers that return a result for their own callers still register.
1148
+ */
1149
+ type AsyncListener<TArgs extends Array<unknown>> = (...args: TArgs) => unknown;
1150
+ /**
1151
+ * Typed hook emitter that awaits all async listeners before resolving.
1152
+ * Wraps Node's `EventEmitter` with full TypeScript hook-map inference.
1153
+ *
1154
+ * @example
1155
+ * ```ts
1156
+ * const hooks = new Hookable<{ build: [name: string] }>()
1157
+ * hooks.hook('build', async (name) => { console.log(name) })
1158
+ * await hooks.callHook('build', 'petstore') // all listeners awaited
1159
+ * ```
1160
+ */
1161
+ declare class Hookable<THooks extends { [K in keyof THooks]: Array<unknown> }> {
1162
+ #private;
1163
+ /**
1164
+ * Maximum number of listeners per hook before Node emits a memory-leak warning.
1165
+ * @default 10
1166
+ */
1167
+ constructor(maxListener?: number);
1168
+ /**
1169
+ * Calls `hookName` and awaits all registered listeners sequentially.
1170
+ * Throws if any listener rejects, wrapping the cause with the hook name and serialized arguments.
1171
+ *
1172
+ * @example
1173
+ * ```ts
1174
+ * await hooks.callHook('build', 'petstore')
1175
+ * ```
1176
+ */
1177
+ callHook<THookName extends keyof THooks & string>(hookName: THookName, ...hookArgs: THooks[THookName]): Promise<void> | void;
1178
+ /**
1179
+ * Registers a persistent listener for `hookName` and returns a function that removes it.
1180
+ *
1181
+ * @example
1182
+ * ```ts
1183
+ * const unhook = hooks.hook('build', async (name) => { console.log(name) })
1184
+ * unhook() // removes it
1185
+ * ```
1186
+ */
1187
+ hook<THookName extends keyof THooks & string>(hookName: THookName, handler: AsyncListener<THooks[THookName]>): () => void;
1188
+ /**
1189
+ * Registers every handler in `configHooks` at once and returns a function that removes them
1190
+ * all. Undefined entries are skipped, so a partial hook object registers only its present keys.
1191
+ *
1192
+ * @example
1193
+ * ```ts
1194
+ * const unhook = hooks.addHooks({ build: onBuild, done: onDone })
1195
+ * unhook() // removes both
1196
+ * ```
1197
+ */
1198
+ addHooks(configHooks: Partial<{ [K in keyof THooks & string]: AsyncListener<THooks[K]> }>): () => void;
1199
+ /**
1200
+ * Removes a previously registered listener.
1201
+ *
1202
+ * @example
1203
+ * ```ts
1204
+ * hooks.removeHook('build', handler)
1205
+ * ```
1206
+ */
1207
+ removeHook<THookName extends keyof THooks & string>(hookName: THookName, handler: AsyncListener<THooks[THookName]>): void;
1208
+ /**
1209
+ * Returns the number of listeners registered for `hookName`.
1210
+ *
1211
+ * @example
1212
+ * ```ts
1213
+ * hooks.hook('build', handler)
1214
+ * hooks.listenerCount('build') // 1
1215
+ * ```
1216
+ */
1217
+ listenerCount<THookName extends keyof THooks & string>(hookName: THookName): number;
1218
+ /**
1219
+ * Raises or lowers the per-hook listener ceiling before Node warns about a memory leak.
1220
+ * Set this above the expected listener count when many listeners attach by design.
1221
+ *
1222
+ * @example
1223
+ * ```ts
1224
+ * hooks.setMaxListeners(40)
1225
+ * ```
1226
+ */
1227
+ setMaxListeners(max: number): void;
1228
+ /**
1229
+ * Removes all listeners from every hook channel.
1230
+ *
1231
+ * @example
1232
+ * ```ts
1233
+ * hooks.removeAllHooks()
1234
+ * ```
1235
+ */
1236
+ removeAllHooks(): void;
1237
+ }
1238
+ //#endregion
1239
+ //#region src/FileManager.d.ts
1240
+ /**
1241
+ * Hooks fired around a `FileManager#write` batch: `start` before it, `update` per file, `end` after.
1263
1242
  */
1264
1243
  type FileManagerHooks = {
1265
- upsert: [file: FileNode];
1244
+ start: [files: Array<FileNode>];
1245
+ update: [params: {
1246
+ file: FileNode;
1247
+ source?: string;
1248
+ processed: number;
1249
+ total: number;
1250
+ percentage: number;
1251
+ }];
1252
+ end: [files: Array<FileNode>];
1253
+ };
1254
+ type ParseOptions = {
1255
+ parsers?: Map<FileNode['extname'], Parser>;
1256
+ extension?: Record<FileNode['extname'], FileNode['extname'] | ''>;
1257
+ };
1258
+ type WriteOptions = ParseOptions & {
1259
+ storage: Storage;
1266
1260
  };
1267
1261
  /**
1268
- * In-memory file store for generated files. Files sharing a `path` are merged
1269
- * (sources/imports/exports concatenated). The `files` getter is sorted by
1270
- * path length (barrel `index.ts` last within a bucket).
1262
+ * In-memory file store for generated files, and the writer that turns them into source
1263
+ * strings on `storage`. Files sharing a `path` are merged (sources/imports/exports
1264
+ * concatenated). The `files` getter is sorted by path length (barrel `index.ts` last
1265
+ * within a bucket).
1271
1266
  *
1272
1267
  * @example
1273
1268
  * ```ts
1274
1269
  * const manager = new FileManager()
1275
1270
  * manager.upsert(myFile)
1276
1271
  * manager.files // sorted view
1272
+ * await manager.write(manager.files, { storage: fsStorage() })
1277
1273
  * ```
1278
1274
  */
1279
1275
  declare class FileManager {
1280
1276
  #private;
1281
- /**
1282
- * Subscribe to file-store changes. Listeners on `upsert` see each resolved file as it lands
1283
- * through `add` or `upsert`.
1284
- */
1285
- readonly hooks: AsyncEventEmitter<FileManagerHooks>;
1277
+ readonly hooks: Hookable<FileManagerHooks>;
1286
1278
  add(...files: Array<FileNode>): Array<FileNode>;
1287
1279
  upsert(...files: Array<FileNode>): Array<FileNode>;
1288
- getByPath(path: string): FileNode | null;
1289
- deleteByPath(path: string): void;
1290
1280
  clear(): void;
1291
1281
  /**
1292
1282
  * Releases all stored files and clears every `hooks` listener. Called by the core after
1293
1283
  * `kubb:build:end`.
1294
1284
  */
1295
1285
  dispose(): void;
1296
- [Symbol.dispose](): void;
1297
1286
  /**
1298
1287
  * All stored files in stable sort order (shortest path first, barrel files
1299
1288
  * last within a length bucket). Returns a cached view, do not mutate.
1300
1289
  */
1301
1290
  get files(): Array<FileNode>;
1291
+ /**
1292
+ * Converts a file's AST sources (or its `copy` source) into the final on-disk string.
1293
+ */
1294
+ parse(file: FileNode, {
1295
+ parsers,
1296
+ extension
1297
+ }?: ParseOptions): Promise<string>;
1298
+ /**
1299
+ * Converts and writes every file at once, letting `storage.setItem` decide how much of
1300
+ * that runs concurrently.
1301
+ */
1302
+ write(files: Array<FileNode>, {
1303
+ storage,
1304
+ parsers,
1305
+ extension
1306
+ }: WriteOptions): Promise<void>;
1302
1307
  }
1303
1308
  //#endregion
1304
1309
  //#region src/KubbDriver.d.ts
1305
1310
  type Options = {
1306
- hooks: AsyncEventEmitter<KubbHooks>;
1311
+ hooks: Hookable<KubbHooks>;
1307
1312
  };
1308
1313
  type RequirePluginContext = {
1309
1314
  /**
@@ -1317,10 +1322,9 @@ declare class KubbDriver {
1317
1322
  readonly config: Config;
1318
1323
  readonly options: Options;
1319
1324
  /**
1320
- * The streaming `InputNode<true>` produced by the adapter. Set after adapter setup.
1321
- * Parse-only adapters are wrapped automatically.
1325
+ * The `InputNode` produced by the adapter. Set after adapter setup.
1322
1326
  */
1323
- inputNode: InputNode<true> | null;
1327
+ inputNode: InputNode | null;
1324
1328
  adapter: Adapter | null;
1325
1329
  /**
1326
1330
  * Central file store for all generated files.
@@ -1337,16 +1341,16 @@ declare class KubbDriver {
1337
1341
  * so `run` can parse it later.
1338
1342
  */
1339
1343
  setup(): Promise<void>;
1340
- get hooks(): AsyncEventEmitter<KubbHooks>;
1344
+ get hooks(): Hookable<KubbHooks>;
1341
1345
  /**
1342
- * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
1343
- * can configure generators, resolvers, macros and renderers before `buildStart` runs.
1344
- *
1345
- * Called once from `run` before the plugin execution loop begins.
1346
+ * Runs each plugin's `kubb:plugin:setup` handler, in plugin order, with a context scoped to that
1347
+ * plugin so `addGenerator`, `setResolver`, `addMacro`, `setMacros`, and `setOptions` target its
1348
+ * `NormalizedPlugin` entry. Called once from `run` before the plugin execution loop begins, so
1349
+ * plugins can configure generators, resolvers, macros, and options before `buildStart`.
1346
1350
  */
1347
- emitSetupHooks(): Promise<void>;
1351
+ setupHooks(): Promise<void>;
1348
1352
  /**
1349
- * Registers a generator for the given plugin on the shared event emitter.
1353
+ * Registers a generator for the given plugin on the shared hook emitter.
1350
1354
  *
1351
1355
  * The generator's `schema`, `operation`, and `operations` methods are registered as
1352
1356
  * listeners on `kubb:generate:schema`, `kubb:generate:operation`, and `kubb:generate:operations`
@@ -1361,12 +1365,12 @@ declare class KubbDriver {
1361
1365
  registerGenerator(pluginName: string, generator: Generator): void;
1362
1366
  /**
1363
1367
  * Returns `true` when at least one generator was registered for the given plugin
1364
- * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
1368
+ * via `addGenerator()` in `kubb:plugin:setup`.
1365
1369
  *
1366
- * Used by the build loop to decide whether to walk the AST and emit generator events
1367
- * for a plugin that has no static `plugin.generators`.
1370
+ * Used by the build loop to decide whether to walk the AST and emit generator hooks
1371
+ * for a plugin.
1368
1372
  */
1369
- hasEventGenerators(pluginName: string): boolean;
1373
+ hasHookGenerators(pluginName: string): boolean;
1370
1374
  /**
1371
1375
  * Runs the full plugin pipeline. Returns the diagnostics collected so far even
1372
1376
  * when an outer hook throws, since the orchestrator preserves partial state by capturing
@@ -1412,12 +1416,12 @@ declare class KubbDriver {
1412
1416
  * Also mirrors it onto `plugin.resolver` so callers using `getPlugin(name).resolver`
1413
1417
  * get the up-to-date resolver without going through `getResolver()`.
1414
1418
  */
1415
- setPluginResolver(pluginName: string, partial: Partial<Resolver>): void;
1419
+ setPluginResolver(pluginName: string, partial: ResolverPatch | Resolver): void;
1416
1420
  /**
1417
1421
  * Returns the resolver for the given plugin.
1418
1422
  *
1419
- * Resolution order: dynamic resolver set via `setPluginResolver` → static resolver on the
1420
- * plugin → lazily created default resolver (identity name, no path transforms).
1423
+ * Resolution order: resolver set via `setPluginResolver` → lazily created default
1424
+ * resolver (identity name, no path transforms).
1421
1425
  */
1422
1426
  getResolver<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Kubb.PluginRegistry[TName]['resolver'];
1423
1427
  getResolver<TResolver extends Resolver = Resolver>(pluginName: string): TResolver;
@@ -1478,10 +1482,10 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1478
1482
  */
1479
1483
  upsertFile: (...file: Array<FileNode>) => Promise<void>;
1480
1484
  /**
1481
- * The build's event bus. Emit or listen to any `KubbHooks` event, for example to react to
1485
+ * The build's hook bus. Emit or listen to any `KubbHooks` hook, for example to react to
1482
1486
  * `kubb:build:end` from inside a generator.
1483
1487
  */
1484
- hooks: AsyncEventEmitter<KubbHooks>;
1488
+ hooks: Hookable<KubbHooks>;
1485
1489
  /**
1486
1490
  * The current plugin instance.
1487
1491
  */
@@ -1491,11 +1495,11 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1491
1495
  * called. Kubb picks a `setResolver` registration first, then the plugin's static
1492
1496
  * `resolver`, then the built-in default.
1493
1497
  *
1494
- * @example Resolve a type name
1495
- * `ctx.resolver.default('pet', 'type') // 'Pet'`
1498
+ * @example Resolve a name
1499
+ * `ctx.resolver.name('pet') // 'pet'`
1496
1500
  *
1497
1501
  * @example Resolve an output file
1498
- * `ctx.resolver.resolveFile({ name: 'pet', extname: '.ts' }, { root, output })`
1502
+ * `ctx.resolver.file({ name: 'pet', extname: '.ts' }, { root, output })`
1499
1503
  */
1500
1504
  resolver: TOptions['resolver'];
1501
1505
  /**
@@ -1628,68 +1632,9 @@ type Generator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TEl
1628
1632
  */
1629
1633
  declare function defineGenerator<TOptions extends PluginFactoryOptions = PluginFactoryOptions, TElement = unknown>(generator: Generator<TOptions, TElement>): Generator<TOptions, TElement>;
1630
1634
  //#endregion
1631
- //#region src/defineParser.d.ts
1632
- type PrintOptions = {
1633
- extname?: FileNode['extname'];
1634
- };
1635
- /**
1636
- * Converts a resolved {@link FileNode} into the final source string that gets
1637
- * written to disk. Kubb ships with TypeScript and TSX parsers. Add your own
1638
- * for new file types (JSON, Markdown, ...).
1639
- */
1640
- type Parser<TMeta extends object = object, TNode = unknown> = {
1641
- /**
1642
- * Display name used in diagnostics and the parser registry.
1643
- */
1644
- name: string;
1645
- /**
1646
- * File extensions this parser handles. The driver registers the parser for each
1647
- * extension in this list. A parser with `undefined` here is not registered, so
1648
- * files of an unclaimed extension fall back to joining their sources verbatim.
1649
- *
1650
- * @example
1651
- * `['.ts', '.js']`
1652
- */
1653
- extNames: Array<FileNode['extname']> | undefined;
1654
- /**
1655
- * Serialize the file's AST into source code.
1656
- */
1657
- parse(file: FileNode<TMeta>, options?: PrintOptions): string;
1658
- /**
1659
- * Render compiler AST nodes for this parser's language into source text.
1660
- * Plugins call this to format the nodes they assemble before handing them
1661
- * back to the parser as `FileNode.sources`.
1662
- */
1663
- print(...nodes: Array<TNode>): string;
1664
- };
1665
- /**
1666
- * Defines a parser with type-safe `this`. Used to register handlers for new
1667
- * file extensions or to plug a non-TypeScript output into the build.
1668
- *
1669
- * @example
1670
- * ```ts
1671
- * import { defineParser } from '@kubb/core'
1672
- * import { extractStringsFromNodes } from '@kubb/ast'
1673
- *
1674
- * export const jsonParser = defineParser({
1675
- * name: 'json',
1676
- * extNames: ['.json'],
1677
- * parse(file) {
1678
- * return file.sources
1679
- * .map((source) => extractStringsFromNodes(source.nodes ?? []))
1680
- * .join('\n')
1681
- * },
1682
- * print(...nodes) {
1683
- * return nodes.map(String).join('\n')
1684
- * },
1685
- * })
1686
- * ```
1687
- */
1688
- declare function defineParser<T extends Parser>(parser: T): T;
1689
- //#endregion
1690
1635
  //#region src/createKubb.d.ts
1691
1636
  type CreateKubbOptions = {
1692
- hooks?: AsyncEventEmitter<KubbHooks>;
1637
+ hooks?: Hookable<KubbHooks>;
1693
1638
  };
1694
1639
  /**
1695
1640
  * Kubb code-generation instance bound to a single config entry. Resolves the user
@@ -1699,18 +1644,18 @@ type CreateKubbOptions = {
1699
1644
  * `createKubb` takes a plain config object (the shape `defineConfig` produces),
1700
1645
  * not a fluent builder.
1701
1646
  *
1702
- * Attach event listeners to `.hooks` before calling `setup()` or `build()`.
1647
+ * Attach hook listeners to `.hooks` before calling `setup()` or `build()`.
1703
1648
  *
1704
1649
  * @example
1705
1650
  * ```ts
1706
1651
  * const kubb = createKubb(userConfig)
1707
- * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
1652
+ * kubb.hooks.hook('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
1708
1653
  * const { files, diagnostics } = await kubb.safeBuild()
1709
1654
  * ```
1710
1655
  */
1711
1656
  declare class Kubb$1 {
1712
1657
  #private;
1713
- readonly hooks: AsyncEventEmitter<KubbHooks>;
1658
+ readonly hooks: Hookable<KubbHooks>;
1714
1659
  readonly config: Config;
1715
1660
  constructor(userConfig: UserConfig, options?: CreateKubbOptions);
1716
1661
  get storage(): Storage;
@@ -1755,46 +1700,8 @@ declare class Kubb$1 {
1755
1700
  */
1756
1701
  declare function createKubb(userConfig: UserConfig, options?: CreateKubbOptions): Kubb$1;
1757
1702
  //#endregion
1758
- //#region src/FileProcessor.d.ts
1759
- /**
1760
- * Hooks fired by a `FileProcessor`.
1761
- *
1762
- * - `start` opens a batch, from `run` or a queue flush.
1763
- * - `update` fires once per file as it is converted.
1764
- * - `end` closes a batch.
1765
- * - `enqueue` fires for every `enqueue` call.
1766
- * - `drain` fires when `drain()` empties the queue with no in-flight batch left.
1767
- */
1768
- type FileProcessorHooks = {
1769
- start: [files: Array<FileNode>];
1770
- update: [params: {
1771
- file: FileNode;
1772
- source?: string;
1773
- processed: number;
1774
- total: number;
1775
- percentage: number;
1776
- }];
1777
- end: [files: Array<FileNode>];
1778
- enqueue: [file: FileNode];
1779
- drain: [];
1780
- };
1781
- /**
1782
- * Per-file progress record yielded by `stream` and surfaced through the `update` event.
1783
- */
1784
- type ParsedFile = {
1785
- file: FileNode;
1786
- source: string;
1787
- processed: number;
1788
- total: number;
1789
- percentage: number;
1790
- };
1791
- //#endregion
1792
1703
  //#region src/types.d.ts
1793
1704
  /**
1794
- * Extracts a type from a registry, falling back to `{}` when the key doesn't exist.
1795
- * Lets plugins augment `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
1796
- * without changing core.
1797
- *
1798
1705
  * @internal
1799
1706
  */
1800
1707
  type ExtractRegistryKey<T, K extends PropertyKey> = K extends keyof T ? T[K] : {};
@@ -2007,7 +1914,7 @@ type Config<TInput = Input> = {
2007
1914
  */
2008
1915
  plugins: Array<Plugin>;
2009
1916
  /**
2010
- * Lifecycle hooks that run external tools (prettier, eslint, a custom script) on build events.
1917
+ * Lifecycle hooks that run external tools (prettier, eslint, a custom script) at points in the build.
2011
1918
  *
2012
1919
  * Currently supports the `done` hook, which fires after all plugins complete.
2013
1920
  *
@@ -2166,16 +2073,16 @@ declare global {
2166
2073
  }
2167
2074
  }
2168
2075
  /**
2169
- * Lifecycle events emitted during Kubb code generation.
2076
+ * Lifecycle hooks emitted during Kubb code generation.
2170
2077
  * Attach listeners before calling `setup()` or `build()` to observe and react to build progress.
2171
2078
  *
2172
2079
  * @example
2173
2080
  * ```ts
2174
- * kubb.hooks.on('kubb:lifecycle:start', () => {
2081
+ * kubb.hooks.hook('kubb:lifecycle:start', () => {
2175
2082
  * console.log('Starting Kubb generation')
2176
2083
  * })
2177
2084
  *
2178
- * kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
2085
+ * kubb.hooks.hook('kubb:plugin:end', ({ plugin, duration }) => {
2179
2086
  * console.log(`${plugin.name} completed in ${duration}ms`)
2180
2087
  * })
2181
2088
  * ```
@@ -2411,7 +2318,7 @@ type KubbFilesProcessingEndContext = {
2411
2318
  };
2412
2319
  type KubbHookStartContext = {
2413
2320
  /**
2414
- * Optional identifier for correlating start/end events.
2321
+ * Optional identifier for correlating start/end hooks.
2415
2322
  */
2416
2323
  id?: string;
2417
2324
  /**
@@ -2429,7 +2336,7 @@ type KubbHookStartContext = {
2429
2336
  */
2430
2337
  type KubbHookLineContext = {
2431
2338
  /**
2432
- * Identifier matching the corresponding `kubb:hook:start` event.
2339
+ * Identifier matching the corresponding `kubb:hook:start` hook.
2433
2340
  */
2434
2341
  id: string;
2435
2342
  /**
@@ -2439,7 +2346,7 @@ type KubbHookLineContext = {
2439
2346
  };
2440
2347
  type KubbHookEndContext = {
2441
2348
  /**
2442
- * Optional identifier matching the corresponding `kubb:hook:start` event.
2349
+ * Optional identifier matching the corresponding `kubb:hook:start` hook.
2443
2350
  */
2444
2351
  id?: string;
2445
2352
  /**
@@ -2520,19 +2427,16 @@ type BuildOutput = {
2520
2427
  */
2521
2428
  driver: KubbDriver;
2522
2429
  /**
2523
- * Read-only view of every file written during this build.
2524
- * Reads go straight to `config.storage`, nothing extra is held in memory.
2430
+ * The configured `Storage` backend, for reading back a generated file's final content.
2431
+ * Use `files` to list what this build produced.
2525
2432
  *
2526
2433
  * @example Read a generated file
2527
2434
  * `const code = await buildOutput.storage.getItem('/src/gen/pet.ts')`
2528
- *
2529
- * @example List all generated file paths
2530
- * `const paths = await buildOutput.storage.getKeys()`
2531
2435
  */
2532
2436
  storage: Storage;
2533
2437
  };
2534
2438
  //#endregion
2535
- //#region src/diagnostics.d.ts
2439
+ //#region src/Diagnostics.d.ts
2536
2440
  /**
2537
2441
  * How serious a diagnostic is. `error` fails the build, `warning` and `info`
2538
2442
  * are reported but do not.
@@ -2707,8 +2611,8 @@ type SerializedDiagnostic = {
2707
2611
  *
2708
2612
  * The sink lives in a single `AsyncLocalStorage` in the `@kubb/core` bundle.
2709
2613
  * `Diagnostics.scope` activates it for a run, so anything inside that run (the
2710
- * adapter parse, a lazily consumed stream, a generator) reports through
2711
- * `Diagnostics.report` and lands in the same run.
2614
+ * adapter parse, a generator) reports through `Diagnostics.report` and lands
2615
+ * in the same run.
2712
2616
  */
2713
2617
  declare class Diagnostics {
2714
2618
  #private;
@@ -2795,11 +2699,11 @@ declare class Diagnostics {
2795
2699
  */
2796
2700
  static report(diagnostic: Diagnostic): boolean;
2797
2701
  /**
2798
- * Emits a diagnostic on the run's `kubb:diagnostic` event so the loggers render it live.
2799
- * Use it instead of calling `hooks.emit('kubb:diagnostic', ...)` directly. To collect a
2702
+ * Emits a diagnostic on the run's `kubb:diagnostic` hook so the loggers render it live.
2703
+ * Use it instead of calling `hooks.callHook('kubb:diagnostic', ...)` directly. To collect a
2800
2704
  * diagnostic into the build result from deep in a run, use {@link Diagnostics.report} instead.
2801
2705
  */
2802
- static emit(hooks: AsyncEventEmitter<KubbHooks>, diagnostic: ProblemDiagnostic | UpdateDiagnostic): Promise<void>;
2706
+ static emit(hooks: Hookable<KubbHooks>, diagnostic: ProblemDiagnostic | UpdateDiagnostic): Promise<void>;
2803
2707
  /**
2804
2708
  * Coerces any thrown value into a {@link ProblemDiagnostic}. A {@link Diagnostics.Error}
2805
2709
  * keeps its structured data, and anything else becomes a `KUBB_UNKNOWN` error.
@@ -2885,5 +2789,5 @@ declare class Diagnostics {
2885
2789
  static formatLines(diagnostic: Diagnostic): Array<string>;
2886
2790
  }
2887
2791
  //#endregion
2888
- export { KubbPluginEndContext as $, KubbHookStartContext as A, logLevel as At, ParsedFile as B, KubbFilesProcessingEndContext as C, createStorage as Ct, KubbGenerationStartContext as D, ReporterName as Dt, KubbGenerationEndContext as E, ReporterContext as Et, KubbSuccessContext as F, AsyncEventEmitter as Ft, defineParser as G, Kubb$1 as H, KubbWarnContext as I, defineGenerator as J, Generator as K, PossibleConfig as L, KubbInfoContext as M, AdapterFactoryOptions as Mt, KubbLifecycleStartContext as N, AdapterSource as Nt, KubbHookEndContext as O, UserReporter as Ot, KubbPluginsEndContext as P, createAdapter as Pt, Include as Q, UserConfig as R, KubbFileProcessingUpdate as S, Storage as St, KubbFilesProcessingUpdateContext as T, Reporter as Tt, createKubb as U, CreateKubbOptions as V, Parser as W, Exclude$1 as X, KubbDriver as Y, Group as Z, InputPath as _, ResolverPathParams as _t, DiagnosticLocation as a, OutputOptions as at, KubbDiagnosticContext as b, RendererFactory as bt, PerformanceDiagnostic as c, PluginFactoryOptions as ct, SerializedDiagnostic as d, ResolveBannerContext as dt, KubbPluginSetupContext as et, UpdateDiagnostic as f, ResolveBannerFile as ft, InputData as g, ResolverFileParams as gt, Config as h, ResolverContext as ht, DiagnosticKind as i, OutputMode as it, KubbHooks as j, Adapter as jt, KubbHookLineContext as k, createReporter as kt, ProblemCode as l, definePlugin as lt, CLIOptions as m, Resolver as mt, DiagnosticByCode as n, NormalizedPlugin as nt, DiagnosticSeverity as o, Override as ot, BuildOutput as p, ResolveOptionsContext as pt, GeneratorContext as q, DiagnosticDoc as r, Output as rt, Diagnostics as s, Plugin as st, Diagnostic as t, KubbPluginStartContext as tt, ProblemDiagnostic as u, BannerMeta as ut, KubbBuildEndContext as v, defineResolver as vt, KubbFilesProcessingStartContext as w, GenerationResult as wt, KubbErrorContext as x, createRenderer as xt, KubbBuildStartContext as y, Renderer as yt, FileProcessorHooks as z };
2889
- //# sourceMappingURL=diagnostics-DuaXn2bT.d.ts.map
2792
+ export { Include as $, KubbHookStartContext as A, UserReporter as At, Kubb$1 as B, KubbFilesProcessingEndContext as C, createRenderer as Ct, KubbGenerationStartContext as D, Reporter as Dt, KubbGenerationEndContext as E, GenerationResult as Et, KubbSuccessContext as F, AdapterSource as Ft, KubbDriver as G, Generator as H, KubbWarnContext as I, createAdapter as It, Parser as J, FileManagerHooks as K, PossibleConfig as L, KubbInfoContext as M, logLevel as Mt, KubbLifecycleStartContext as N, Adapter as Nt, KubbHookEndContext as O, ReporterContext as Ot, KubbPluginsEndContext as P, AdapterFactoryOptions as Pt, Group as Q, UserConfig as R, KubbFileProcessingUpdate as S, RendererFactory as St, KubbFilesProcessingUpdateContext as T, createStorage as Tt, GeneratorContext as U, createKubb as V, defineGenerator as W, Exclude$1 as X, defineParser as Y, Filter as Z, InputPath as _, ResolverDefault as _t, DiagnosticLocation as a, OutputMode as at, KubbDiagnosticContext as b, ResolverPathParams as bt, PerformanceDiagnostic as c, Plugin as ct, SerializedDiagnostic as d, BannerMeta as dt, KubbPluginEndContext as et, UpdateDiagnostic as f, ResolveBannerContext as ft, InputData as g, ResolverContext as gt, Config as h, Resolver as ht, DiagnosticKind as i, Output as it, KubbHooks as j, createReporter as jt, KubbHookLineContext as k, ReporterName as kt, ProblemCode as l, PluginFactoryOptions as lt, CLIOptions as m, ResolveOptionsContext as mt, DiagnosticByCode as n, KubbPluginStartContext as nt, DiagnosticSeverity as o, OutputOptions as ot, BuildOutput as p, ResolveBannerFile as pt, Hookable as q, DiagnosticDoc as r, NormalizedPlugin as rt, Diagnostics as s, Override as st, Diagnostic as t, KubbPluginSetupContext as tt, ProblemDiagnostic as u, definePlugin as ut, KubbBuildEndContext as v, ResolverFileParams as vt, KubbFilesProcessingStartContext as w, Storage as wt, KubbErrorContext as x, Renderer as xt, KubbBuildStartContext as y, ResolverPatch as yt, CreateKubbOptions as z };
2793
+ //# sourceMappingURL=Diagnostics-aWJg-H2d.d.ts.map