@kubb/core 5.0.0-alpha.2 → 5.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/{types-B7eZvqwD.d.ts → PluginDriver-CEQPafXV.d.ts} +687 -298
  2. package/dist/hooks.cjs +15 -9
  3. package/dist/hooks.cjs.map +1 -1
  4. package/dist/hooks.d.ts +11 -5
  5. package/dist/hooks.js +16 -10
  6. package/dist/hooks.js.map +1 -1
  7. package/dist/index.cjs +1131 -536
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +674 -89
  10. package/dist/index.js +1114 -532
  11. package/dist/index.js.map +1 -1
  12. package/package.json +6 -6
  13. package/src/Kubb.ts +37 -55
  14. package/src/{PluginManager.ts → PluginDriver.ts} +51 -40
  15. package/src/build.ts +74 -29
  16. package/src/config.ts +9 -8
  17. package/src/constants.ts +44 -1
  18. package/src/createAdapter.ts +25 -0
  19. package/src/createPlugin.ts +28 -0
  20. package/src/createStorage.ts +58 -0
  21. package/src/defineBuilder.ts +26 -0
  22. package/src/defineGenerator.ts +137 -0
  23. package/src/defineLogger.ts +13 -3
  24. package/src/definePreset.ts +27 -0
  25. package/src/definePresets.ts +16 -0
  26. package/src/defineResolver.ts +448 -0
  27. package/src/hooks/index.ts +1 -1
  28. package/src/hooks/useDriver.ts +8 -0
  29. package/src/hooks/useMode.ts +5 -2
  30. package/src/hooks/usePlugin.ts +5 -2
  31. package/src/index.ts +21 -6
  32. package/src/renderNode.tsx +105 -0
  33. package/src/storages/fsStorage.ts +2 -2
  34. package/src/storages/memoryStorage.ts +2 -2
  35. package/src/types.ts +342 -42
  36. package/src/utils/FunctionParams.ts +2 -2
  37. package/src/utils/TreeNode.ts +24 -1
  38. package/src/utils/diagnostics.ts +4 -1
  39. package/src/utils/executeStrategies.ts +23 -10
  40. package/src/utils/formatters.ts +10 -21
  41. package/src/utils/getBarrelFiles.ts +79 -9
  42. package/src/utils/getConfigs.ts +8 -22
  43. package/src/utils/getPreset.ts +52 -0
  44. package/src/utils/linters.ts +23 -3
  45. package/src/utils/mergeResolvers.ts +8 -0
  46. package/src/utils/packageJSON.ts +76 -0
  47. package/src/BarrelManager.ts +0 -74
  48. package/src/PackageManager.ts +0 -180
  49. package/src/PromiseManager.ts +0 -40
  50. package/src/defineAdapter.ts +0 -22
  51. package/src/definePlugin.ts +0 -12
  52. package/src/defineStorage.ts +0 -56
  53. package/src/errors.ts +0 -1
  54. package/src/hooks/usePluginManager.ts +0 -8
  55. package/src/utils/getPlugins.ts +0 -23
package/src/types.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type { AsyncEventEmitter, PossiblePromise } from '@internals/utils'
2
- import type { RootNode } from '@kubb/ast/types'
3
- import type { KubbFile } from '@kubb/fabric-core/types'
4
- import type { Fabric } from '@kubb/react-fabric'
2
+ import type { Node, RootNode, SchemaNode, Visitor } from '@kubb/ast/types'
3
+ import type { Fabric as FabricType, KubbFile } from '@kubb/fabric-core/types'
4
+ import type { HttpMethod } from '@kubb/oas'
5
5
  import type { DEFAULT_STUDIO_URL, logLevel } from './constants.ts'
6
- import type { DefineStorage } from './defineStorage.ts'
6
+ import type { Storage } from './createStorage.ts'
7
+ import type { Generator } from './defineGenerator.ts'
7
8
  import type { KubbEvents } from './Kubb.ts'
8
- import type { PluginManager } from './PluginManager.ts'
9
+ import type { PluginDriver } from './PluginDriver.ts'
9
10
 
10
11
  export type { Printer, PrinterFactoryOptions } from '@kubb/ast/types'
11
12
 
@@ -33,7 +34,7 @@ export type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins'
33
34
  /**
34
35
  * An array of Kubb plugins used for generation. Each plugin may have additional configurable options (defined within the plugin itself). If a plugin relies on another plugin, an error will occur if the required dependency is missing. Refer to “pre” for more details.
35
36
  */
36
- // inject needs to be omitted because else we have a clash with the PluginManager instance
37
+ // inject needs to be omitted because else we have a clash with the PluginDriver instance
37
38
  plugins?: Array<Omit<UnknownUserPlugin, 'inject'>>
38
39
  }
39
40
 
@@ -66,11 +67,18 @@ export type AdapterSource = { type: 'path'; path: string } | { type: 'data'; dat
66
67
  * - `TName` — unique string identifier (e.g. `'oas'`, `'asyncapi'`)
67
68
  * - `TOptions` — raw user-facing options passed to the adapter factory
68
69
  * - `TResolvedOptions` — defaults applied; what the adapter stores as `options`
70
+ * - `TDocument` — type of the raw source document exposed by the adapter after `parse()`
69
71
  */
70
- export type AdapterFactoryOptions<TName extends string = string, TOptions extends object = object, TResolvedOptions extends object = TOptions> = {
72
+ export type AdapterFactoryOptions<
73
+ TName extends string = string,
74
+ TOptions extends object = object,
75
+ TResolvedOptions extends object = TOptions,
76
+ TDocument = unknown,
77
+ > = {
71
78
  name: TName
72
79
  options: TOptions
73
80
  resolvedOptions: TResolvedOptions
81
+ document: TDocument
74
82
  }
75
83
 
76
84
  /**
@@ -92,12 +100,32 @@ export type AdapterFactoryOptions<TName extends string = string, TOptions extend
92
100
  * ```
93
101
  */
94
102
  export type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
95
- /** Human-readable identifier, e.g. `'oas'`, `'drizzle'`, `'asyncapi'`. */
103
+ /**
104
+ * Human-readable identifier, e.g. `'oas'`, `'drizzle'`, `'asyncapi'`.
105
+ */
96
106
  name: TOptions['name']
97
- /** Resolved options (after defaults have been applied). */
107
+ /**
108
+ * Resolved options (after defaults have been applied).
109
+ */
98
110
  options: TOptions['resolvedOptions']
99
- /** Convert the raw source into a universal `RootNode`. */
111
+ /**
112
+ * The raw source document produced after the first `parse()` call.
113
+ * `undefined` before parsing; typed by the adapter's `TDocument` generic.
114
+ */
115
+ document: TOptions['document'] | null
116
+ rootNode: RootNode | null
117
+ /**
118
+ * Convert the raw source into a universal `RootNode`.
119
+ */
100
120
  parse: (source: AdapterSource) => PossiblePromise<RootNode>
121
+ /**
122
+ * Extracts `KubbFile.Import` entries needed by a `SchemaNode` tree.
123
+ * Populated after the first `parse()` call. Returns an empty array before that.
124
+ *
125
+ * The `resolve` callback receives the collision-corrected schema name and must
126
+ * return the `{ name, path }` pair for the import, or `undefined` to skip it.
127
+ */
128
+ getImports: (node: SchemaNode, resolve: (schemaName: string) => { name: string; path: string }) => Array<KubbFile.Import>
101
129
  }
102
130
 
103
131
  export type BarrelType = 'all' | 'named' | 'propagate'
@@ -165,16 +193,16 @@ export type Config<TInput = Input> = {
165
193
  /**
166
194
  * Storage backend for generated files.
167
195
  * Defaults to `fsStorage()` — the built-in filesystem driver.
168
- * Accepts any object implementing the {@link DefineStorage} interface.
196
+ * Accepts any object implementing the {@link Storage} interface.
169
197
  * Keys are root-relative paths (e.g. `src/gen/api/getPets.ts`).
170
198
  * @default fsStorage()
171
199
  * @example
172
200
  * ```ts
173
- * import { defineStorage, fsStorage } from '@kubb/core'
174
- * storage: defineStorage(fsStorage())
201
+ * import { memoryStorage } from '@kubb/core'
202
+ * storage: memoryStorage()
175
203
  * ```
176
204
  */
177
- storage?: DefineStorage
205
+ storage?: Storage
178
206
  /**
179
207
  * Specifies the formatting tool to be used.
180
208
  * - 'auto' automatically detects and uses biome or prettier (in that order of preference).
@@ -204,7 +232,7 @@ export type Config<TInput = Input> = {
204
232
  * Configures how `index.ts` files are created, including disabling barrel file generation. Each plugin has its own `barrelType` option; this setting controls the root barrel file (e.g., `src/gen/index.ts`).
205
233
  * @default 'named'
206
234
  */
207
- barrelType?: Exclude<BarrelType, 'propagate'> | false
235
+ barrelType?: 'all' | 'named' | false
208
236
  /**
209
237
  * Adds a default banner to the start of every generated file indicating it was generated by Kubb.
210
238
  * - 'simple' adds banner with link to Kubb.
@@ -253,6 +281,73 @@ export type Config<TInput = Input> = {
253
281
 
254
282
  // plugin
255
283
 
284
+ type PatternFilter = {
285
+ type: string
286
+ pattern: string | RegExp
287
+ }
288
+
289
+ type PatternOverride<TOptions> = PatternFilter & {
290
+ options: Omit<Partial<TOptions>, 'override'>
291
+ }
292
+
293
+ export type ResolveOptionsContext<TOptions> = {
294
+ options: TOptions
295
+ exclude?: Array<PatternFilter>
296
+ include?: Array<PatternFilter>
297
+ override?: Array<PatternOverride<TOptions>>
298
+ }
299
+
300
+ /**
301
+ * Base constraint for all plugin resolver objects.
302
+ *
303
+ * `default`, `resolveOptions`, `resolvePath`, and `resolveFile` are injected automatically
304
+ * by `defineResolver` — plugin authors may override them but never need to implement them
305
+ * from scratch.
306
+ *
307
+ * @example
308
+ * ```ts
309
+ * type MyResolver = Resolver & {
310
+ * resolveName(node: SchemaNode): string
311
+ * resolveTypedName(node: SchemaNode): string
312
+ * }
313
+ * ```
314
+ */
315
+ export type Resolver = {
316
+ name: string
317
+ pluginName: Plugin['name']
318
+ default(name: ResolveNameParams['name'], type?: ResolveNameParams['type']): string
319
+ resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null
320
+ resolvePath(params: ResolverPathParams, context: ResolverContext): KubbFile.Path
321
+ resolveFile(params: ResolverFileParams, context: ResolverContext): KubbFile.File
322
+ resolveBanner(node: RootNode | null, context: ResolveBannerContext): string | undefined
323
+ resolveFooter(node: RootNode | null, context: ResolveBannerContext): string | undefined
324
+ }
325
+
326
+ /**
327
+ * The user-facing subset of a `Resolver` — everything except the four methods injected by
328
+ * `defineResolver` (`default`, `resolveOptions`, `resolvePath`, and `resolveFile`).
329
+ *
330
+ * All four injected methods can still be overridden by providing them explicitly in the builder.
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * export const resolver = defineResolver<PluginTs>(() => ({
335
+ * name: 'default',
336
+ * resolveName(node) { return this.default(node.name, 'function') },
337
+ * }))
338
+ * ```
339
+ */
340
+ export type UserResolver = Omit<Resolver, 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter'>
341
+
342
+ /**
343
+ * Base type for plugin builder objects.
344
+ * Concrete plugin builder types extend this with their own schema-building helpers.
345
+ * Use `defineBuilder` to define a builder object and export it alongside the plugin.
346
+ */
347
+ export type Builder = {
348
+ name: string
349
+ }
350
+
256
351
  export type PluginFactoryOptions<
257
352
  /**
258
353
  * Name to be used for the plugin.
@@ -274,16 +369,26 @@ export type PluginFactoryOptions<
274
369
  * When calling `resolvePath` you can specify better types.
275
370
  */
276
371
  TResolvePathOptions extends object = object,
372
+ /**
373
+ * Resolver object that encapsulates the naming and path-resolution helpers used by this plugin.
374
+ * Use `defineResolver` to define the resolver object and export it alongside the plugin.
375
+ */
376
+ TResolver extends Resolver = Resolver,
377
+ /**
378
+ * Builder object that encapsulates the schema-building helpers used by this plugin.
379
+ * Use `defineBuilder` to define the builder object and export it alongside the plugin.
380
+ */
381
+ TBuilder extends Builder = Builder,
277
382
  > = {
278
383
  name: TName
279
384
  options: TOptions
280
385
  resolvedOptions: TResolvedOptions
281
386
  context: TContext
282
387
  resolvePathOptions: TResolvePathOptions
388
+ resolver: TResolver
389
+ builder: TBuilder
283
390
  }
284
391
 
285
- export type GetPluginFactoryOptions<TPlugin extends UserPlugin> = TPlugin extends UserPlugin<infer X> ? X : never
286
-
287
392
  export type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
288
393
  /**
289
394
  * Unique name used for the plugin
@@ -309,7 +414,7 @@ export type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOpti
309
414
 
310
415
  export type UserPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = UserPlugin<TOptions> & PluginLifecycle<TOptions>
311
416
 
312
- export type UnknownUserPlugin = UserPlugin<PluginFactoryOptions<any, any, any, any, any>>
417
+ type UnknownUserPlugin = UserPlugin<PluginFactoryOptions<string, object, object, unknown, object>>
313
418
 
314
419
  export type Plugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
315
420
  /**
@@ -333,7 +438,7 @@ export type Plugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>
333
438
 
334
439
  install: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => PossiblePromise<void>
335
440
  /**
336
- * Define a context that can be used by other plugins, see `PluginManager' where we convert from `UserPlugin` to `Plugin`(used when calling `definePlugin`).
441
+ * Defines a context that can be used by other plugins, see `PluginDriver` where we convert from `UserPlugin` to `Plugin` (used when calling `createPlugin`).
337
442
  */
338
443
  inject: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => TOptions['context']
339
444
  }
@@ -351,6 +456,7 @@ export type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactor
351
456
  * Options can als be included.
352
457
  * @type hookFirst
353
458
  * @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
459
+ * @deprecated this will be replaced by resolvers
354
460
  */
355
461
  resolvePath?: (this: PluginContext<TOptions>, baseName: KubbFile.BaseName, mode?: KubbFile.Mode, options?: TOptions['resolvePathOptions']) => KubbFile.Path
356
462
  /**
@@ -358,6 +464,7 @@ export type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactor
358
464
  * Useful when converting to PascalCase or camelCase.
359
465
  * @type hookFirst
360
466
  * @example ('pet') => 'Pet'
467
+ * @deprecated this will be replaced by resolvers
361
468
  */
362
469
  resolveName?: (this: PluginContext<TOptions>, name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
363
470
  }
@@ -391,9 +498,9 @@ export type ResolveNameParams = {
391
498
  }
392
499
 
393
500
  export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
394
- fabric: Fabric
501
+ fabric: FabricType
395
502
  config: Config
396
- pluginManager: PluginManager
503
+ driver: PluginDriver
397
504
  /**
398
505
  * Only add when the file does not exist yet
399
506
  */
@@ -408,22 +515,35 @@ export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryO
408
515
  * Current plugin
409
516
  */
410
517
  plugin: Plugin<TOptions>
411
- /**
412
- * Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
413
- * Returns `undefined` when no adapter was set (legacy OAS-only usage).
414
- */
415
- rootNode: RootNode | undefined
518
+
416
519
  /**
417
520
  * Opens the Kubb Studio URL for the current `rootNode` in the default browser.
418
521
  * Falls back to printing the URL if the browser cannot be launched.
419
522
  * No-ops silently when no adapter has set a `rootNode`.
420
523
  */
421
524
  openInStudio: (options?: DevtoolsOptions) => Promise<void>
422
- } & Kubb.PluginContext
525
+ } & (
526
+ | {
527
+ /**
528
+ * Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
529
+ * Returns `undefined` when no adapter was set (legacy OAS-only usage).
530
+ */
531
+ rootNode: RootNode
532
+ /**
533
+ * Return the adapter from `@kubb/ast`
534
+ */
535
+ adapter: Adapter
536
+ }
537
+ | {
538
+ rootNode?: never
539
+ adapter?: never
540
+ }
541
+ ) &
542
+ Kubb.PluginContext
423
543
  /**
424
544
  * Specify the export location for the files and define the behavior of the output
425
545
  */
426
- export type Output<TOptions> = {
546
+ export type Output<_TOptions = unknown> = {
427
547
  /**
428
548
  * Path to the output folder or file that will contain the generated code
429
549
  */
@@ -436,11 +556,11 @@ export type Output<TOptions> = {
436
556
  /**
437
557
  * Add a banner text in the beginning of every file
438
558
  */
439
- banner?: string | ((options: TOptions) => string)
559
+ banner?: string | ((node: RootNode) => string)
440
560
  /**
441
561
  * Add a footer text in the beginning of every file
442
562
  */
443
- footer?: string | ((options: TOptions) => string)
563
+ footer?: string | ((node: RootNode) => string)
444
564
  /**
445
565
  * Whether to override existing external files if they already exist.
446
566
  * @default false
@@ -448,10 +568,6 @@ export type Output<TOptions> = {
448
568
  override?: boolean
449
569
  }
450
570
 
451
- type GroupContext = {
452
- group: string
453
- }
454
-
455
571
  export type Group = {
456
572
  /**
457
573
  * Defines the type where to group the files.
@@ -461,9 +577,9 @@ export type Group = {
461
577
  */
462
578
  type: 'tag' | 'path'
463
579
  /**
464
- * Return the name of a group based on the group name, this used for the file and name generation
580
+ * Return the name of a group based on the group name, this is used for the file and name generation.
465
581
  */
466
- name?: (context: GroupContext) => string
582
+ name?: (context: { group: string }) => string
467
583
  }
468
584
 
469
585
  export type LoggerOptions = {
@@ -476,16 +592,200 @@ export type LoggerOptions = {
476
592
  /**
477
593
  * Shared context passed to all plugins, parsers, and Fabric internals.
478
594
  */
479
- export interface LoggerContext extends AsyncEventEmitter<KubbEvents> {}
480
-
481
- type Install<TOptions = unknown> = (context: LoggerContext, options?: TOptions) => void | Promise<void>
595
+ export type LoggerContext = AsyncEventEmitter<KubbEvents>
482
596
 
483
597
  export type Logger<TOptions extends LoggerOptions = LoggerOptions> = {
484
598
  name: string
485
- install: Install<TOptions>
599
+ install: (context: LoggerContext, options?: TOptions) => void | Promise<void>
486
600
  }
487
601
 
488
- export type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Omit<Logger<TOptions>, 'logLevel'>
602
+ export type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Logger<TOptions>
489
603
 
490
- export type { DefineStorage } from './defineStorage.ts'
604
+ /**
605
+ * Compatibility preset for code generation tools.
606
+ * - `'default'` – no compatibility adjustments (default behavior).
607
+ * - `'kubbV4'` – align generated names and structures with Kubb v4 output.
608
+ */
609
+ export type CompatibilityPreset = 'default' | 'kubbV4'
610
+
611
+ export type { Storage } from './createStorage.ts'
612
+ export type { CoreGeneratorV2, Generator, ReactGeneratorV2 } from './defineGenerator.ts'
491
613
  export type { KubbEvents } from './Kubb.ts'
614
+
615
+ /**
616
+ * A preset bundles a name, one or more resolvers, optional AST transformers,
617
+ * and optional generators into a single reusable configuration object.
618
+ *
619
+ * @template TResolver - The concrete resolver type for this preset.
620
+ */
621
+ export type Preset<TResolver extends Resolver = Resolver> = {
622
+ /**
623
+ * Unique identifier for this preset.
624
+ */
625
+ name: string
626
+ /**
627
+ * Ordered list of resolvers applied by this preset (last entry wins on merge).
628
+ */
629
+ resolvers: Array<TResolver>
630
+ /**
631
+ * Optional AST visitors / transformers applied after resolving.
632
+ */
633
+ transformers?: Array<Visitor>
634
+ /**
635
+ * Optional generators used by this preset. Plugin implementations cast this
636
+ * to their concrete generator type.
637
+ */
638
+ generators?: Array<Generator<any>>
639
+ }
640
+
641
+ /**
642
+ * A named registry of presets, keyed by preset name.
643
+ *
644
+ * @template TResolver - The concrete resolver type shared by all presets in this registry.
645
+ * @template TName - The union of valid preset name keys.
646
+ */
647
+ export type Presets<TResolver extends Resolver = Resolver> = Record<CompatibilityPreset, Preset<TResolver>>
648
+
649
+ type ByTag = {
650
+ type: 'tag'
651
+ pattern: string | RegExp
652
+ }
653
+
654
+ type ByOperationId = {
655
+ type: 'operationId'
656
+ pattern: string | RegExp
657
+ }
658
+
659
+ type ByPath = {
660
+ type: 'path'
661
+ pattern: string | RegExp
662
+ }
663
+
664
+ type ByMethod = {
665
+ type: 'method'
666
+ pattern: HttpMethod | RegExp
667
+ }
668
+ // TODO implement as alternative for ByMethod
669
+ // type ByMethods = {
670
+ // type: 'methods'
671
+ // pattern: Array<HttpMethod>
672
+ // }
673
+
674
+ type BySchemaName = {
675
+ type: 'schemaName'
676
+ pattern: string | RegExp
677
+ }
678
+
679
+ type ByContentType = {
680
+ type: 'contentType'
681
+ pattern: string | RegExp
682
+ }
683
+
684
+ export type Exclude = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName
685
+ export type Include = ByTag | ByOperationId | ByPath | ByMethod | ByContentType | BySchemaName
686
+
687
+ export type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | BySchemaName | ByContentType) & {
688
+ //TODO should be options: Omit<Partial<TOptions>, 'override'>
689
+ options: Partial<TOptions>
690
+ }
691
+
692
+ export type ResolvePathOptions = {
693
+ pluginName?: string
694
+ group?: {
695
+ tag?: string
696
+ path?: string
697
+ }
698
+ type?: ResolveNameParams['type']
699
+ }
700
+
701
+ /**
702
+ * File-specific parameters for `Resolver.resolvePath`.
703
+ *
704
+ * Pass alongside a `ResolverContext` to identify which file to resolve.
705
+ * Provide `tag` for tag-based grouping or `path` for path-based grouping.
706
+ *
707
+ * @example
708
+ * ```ts
709
+ * resolver.resolvePath(
710
+ * { baseName: 'petTypes.ts', tag: 'pets' },
711
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
712
+ * )
713
+ * // → '/src/types/petsController/petTypes.ts'
714
+ * ```
715
+ */
716
+ export type ResolverPathParams = {
717
+ baseName: KubbFile.BaseName
718
+ pathMode?: KubbFile.Mode
719
+ /**
720
+ * Tag value used when `group.type === 'tag'`.
721
+ */
722
+ tag?: string
723
+ /**
724
+ * Path value used when `group.type === 'path'`.
725
+ */
726
+ path?: string
727
+ }
728
+
729
+ /**
730
+ * Shared context passed as the second argument to `Resolver.resolvePath` and `Resolver.resolveFile`.
731
+ *
732
+ * Describes where on disk output is rooted, which output config is active, and the optional
733
+ * grouping strategy that controls subdirectory layout.
734
+ *
735
+ * @example
736
+ * ```ts
737
+ * const context: ResolverContext = {
738
+ * root: config.root,
739
+ * output,
740
+ * group,
741
+ * }
742
+ * ```
743
+ */
744
+ export type ResolverContext = {
745
+ root: string
746
+ output: Output
747
+ group?: Group
748
+ /** Plugin name used to populate `meta.pluginName` on the resolved file. */
749
+ pluginName?: string
750
+ }
751
+
752
+ /**
753
+ * File-specific parameters for `Resolver.resolveFile`.
754
+ *
755
+ * Pass alongside a `ResolverContext` to fully describe the file to resolve.
756
+ * `tag` and `path` are used only when a matching `group` is present in the context.
757
+ *
758
+ * @example
759
+ * ```ts
760
+ * resolver.resolveFile(
761
+ * { name: 'listPets', extname: '.ts', tag: 'pets' },
762
+ * { root: '/src', output: { path: 'types' }, group: { type: 'tag' } },
763
+ * )
764
+ * // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
765
+ * ```
766
+ */
767
+ export type ResolverFileParams = {
768
+ name: string
769
+ extname: KubbFile.Extname
770
+ /** Tag value used when `group.type === 'tag'`. */
771
+ tag?: string
772
+ /** Path value used when `group.type === 'path'`. */
773
+ path?: string
774
+ }
775
+
776
+ /**
777
+ * Context passed to `Resolver.resolveBanner` and `Resolver.resolveFooter`.
778
+ *
779
+ * `output` is optional — not every plugin configures a banner/footer.
780
+ * `config` carries the global Kubb config, used to derive the default Kubb banner.
781
+ *
782
+ * @example
783
+ * ```ts
784
+ * resolver.resolveBanner(rootNode, { output: { banner: '// generated' }, config })
785
+ * // → '// generated'
786
+ * ```
787
+ */
788
+ export type ResolveBannerContext = {
789
+ output?: Pick<Output, 'banner' | 'footer'>
790
+ config: Config
791
+ }
@@ -30,12 +30,12 @@ type FunctionParamsASTWithType = {
30
30
  default?: string
31
31
  }
32
32
  /**
33
- * @deprecated
33
+ * @deprecated use ast package instead
34
34
  */
35
35
  export type FunctionParamsAST = FunctionParamsASTWithoutType | FunctionParamsASTWithType
36
36
 
37
37
  /**
38
- * @deprecated
38
+ * @deprecated use ast package instead
39
39
  */
40
40
  export class FunctionParams {
41
41
  #items: Array<FunctionParamsAST | FunctionParamsAST[]> = []
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path'
2
2
  import type { KubbFile } from '@kubb/fabric-core/types'
3
- import { getMode } from '../PluginManager.ts'
3
+ import { getMode } from '../PluginDriver.ts'
4
4
 
5
5
  type BarrelData = {
6
6
  file?: KubbFile.File
@@ -12,6 +12,15 @@ type BarrelData = {
12
12
  name: string
13
13
  }
14
14
 
15
+ /**
16
+ * Tree structure used to build per-directory barrel (`index.ts`) files from a
17
+ * flat list of generated {@link KubbFile.File} entries.
18
+ *
19
+ * Each node represents either a directory or a file within the output tree.
20
+ * Use {@link TreeNode.build} to construct a root node from a file list, then
21
+ * traverse with {@link TreeNode.forEach}, {@link TreeNode.leaves}, or the
22
+ * `*Deep` helpers.
23
+ */
15
24
  export class TreeNode {
16
25
  data: BarrelData
17
26
  parent?: TreeNode
@@ -32,6 +41,9 @@ export class TreeNode {
32
41
  return child
33
42
  }
34
43
 
44
+ /**
45
+ * Returns the root ancestor of this node, walking up via `parent` links.
46
+ */
35
47
  get root(): TreeNode {
36
48
  if (!this.parent) {
37
49
  return this
@@ -39,6 +51,11 @@ export class TreeNode {
39
51
  return this.parent.root
40
52
  }
41
53
 
54
+ /**
55
+ * Returns all leaf descendants (nodes with no children) of this node.
56
+ *
57
+ * Results are cached after the first traversal.
58
+ */
42
59
  get leaves(): Array<TreeNode> {
43
60
  if (!this.children || this.children.length === 0) {
44
61
  // this is a leaf
@@ -105,6 +122,12 @@ export class TreeNode {
105
122
  return this.leaves.map(callback)
106
123
  }
107
124
 
125
+ /**
126
+ * Builds a {@link TreeNode} tree from a flat list of files.
127
+ *
128
+ * - Filters to files under `root` (when provided) and skips `.json` files.
129
+ * - Returns `null` when no files match.
130
+ */
108
131
  public static build(files: KubbFile.File[], root?: string): TreeNode | null {
109
132
  try {
110
133
  const filteredTree = buildDirectoryTree(files, root)
@@ -2,7 +2,10 @@ import { version as nodeVersion } from 'node:process'
2
2
  import { version as KubbVersion } from '../../package.json'
3
3
 
4
4
  /**
5
- * Get diagnostic information for debugging
5
+ * Returns a snapshot of the current runtime environment.
6
+ *
7
+ * Useful for attaching context to debug logs and error reports so that
8
+ * issues can be reproduced without manual information gathering.
6
9
  */
7
10
  export function getDiagnosticInfo() {
8
11
  return {
@@ -7,7 +7,11 @@ type ValueOfPromiseFuncArray<TInput extends Array<unknown>> = TInput extends Arr
7
7
  type SeqOutput<TInput extends Array<PromiseFunc<TValue, null>>, TValue> = Promise<Array<Awaited<ValueOfPromiseFuncArray<TInput>>>>
8
8
 
9
9
  /**
10
- * Chains promises
10
+ * Runs promise functions in sequence, threading each result into the next call.
11
+ *
12
+ * - Each function receives the accumulated state from the previous call.
13
+ * - Skips functions that return a falsy value (acts as a no-op for that step).
14
+ * - Returns an array of all individual results.
11
15
  */
12
16
  export function hookSeq<TInput extends Array<PromiseFunc<TValue, null>>, TValue, TOutput = SeqOutput<TInput, TValue>>(promises: TInput): TOutput {
13
17
  return promises.filter(Boolean).reduce(
@@ -33,7 +37,10 @@ export function hookSeq<TInput extends Array<PromiseFunc<TValue, null>>, TValue,
33
37
  type HookFirstOutput<TInput extends Array<PromiseFunc<TValue, null>>, TValue = unknown> = ValueOfPromiseFuncArray<TInput>
34
38
 
35
39
  /**
36
- * Chains promises, first non-null result stops and returns
40
+ * Runs promise functions in sequence and returns the first non-null result.
41
+ *
42
+ * - Stops as soon as `nullCheck` passes for a result (default: `!== null`).
43
+ * - Subsequent functions are skipped once a match is found.
37
44
  */
38
45
  export function hookFirst<TInput extends Array<PromiseFunc<TValue, null>>, TValue = unknown, TOutput = HookFirstOutput<TInput, TValue>>(
39
46
  promises: TInput,
@@ -57,7 +64,10 @@ export function hookFirst<TInput extends Array<PromiseFunc<TValue, null>>, TValu
57
64
  type HookParallelOutput<TInput extends Array<PromiseFunc<TValue, null>>, TValue> = Promise<PromiseSettledResult<Awaited<ValueOfPromiseFuncArray<TInput>>>[]>
58
65
 
59
66
  /**
60
- * Runs an array of promise functions with optional concurrency limit.
67
+ * Runs promise functions concurrently and returns all settled results.
68
+ *
69
+ * - Limits simultaneous executions to `concurrency` (default: unlimited).
70
+ * - Uses `Promise.allSettled` so individual failures do not cancel other tasks.
61
71
  */
62
72
  export function hookParallel<TInput extends Array<PromiseFunc<TValue, null>>, TValue = unknown, TOutput = HookParallelOutput<TInput, TValue>>(
63
73
  promises: TInput,
@@ -70,12 +80,15 @@ export function hookParallel<TInput extends Array<PromiseFunc<TValue, null>>, TV
70
80
  return Promise.allSettled(tasks) as TOutput
71
81
  }
72
82
 
83
+ /**
84
+ * Execution strategy used when dispatching plugin hook calls.
85
+ */
73
86
  export type Strategy = 'seq' | 'first' | 'parallel'
74
87
 
75
- export type StrategySwitch<TStrategy extends Strategy, TInput extends Array<PromiseFunc<TValue, null>>, TValue> = TStrategy extends 'first'
76
- ? HookFirstOutput<TInput, TValue>
77
- : TStrategy extends 'seq'
78
- ? SeqOutput<TInput, TValue>
79
- : TStrategy extends 'parallel'
80
- ? HookParallelOutput<TInput, TValue>
81
- : never
88
+ type StrategyOutputMap<TInput extends Array<PromiseFunc<TValue, null>>, TValue> = {
89
+ first: HookFirstOutput<TInput, TValue>
90
+ seq: SeqOutput<TInput, TValue>
91
+ parallel: HookParallelOutput<TInput, TValue>
92
+ }
93
+
94
+ export type StrategySwitch<TStrategy extends Strategy, TInput extends Array<PromiseFunc<TValue, null>>, TValue> = StrategyOutputMap<TInput, TValue>[TStrategy]