@kubb/core 5.0.0-alpha.33 → 5.0.0-alpha.35

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.
@@ -2,17 +2,24 @@ import { basename, extname, resolve } from 'node:path'
2
2
  import { performance } from 'node:perf_hooks'
3
3
  import type { AsyncEventEmitter } from '@internals/utils'
4
4
  import { isPromiseRejectedResult, transformReservedWord } from '@internals/utils'
5
+ import type { FileNode, InputNode } from '@kubb/ast'
5
6
  import { createFile } from '@kubb/ast'
6
- import type { FileNode, InputNode } from '@kubb/ast/types'
7
7
  import { DEFAULT_STUDIO_URL } from './constants.ts'
8
+ import type { Generator } from './defineGenerator.ts'
9
+ import { type HookStylePlugin, isHookStylePlugin } from './definePlugin.ts'
10
+ import { defineResolver } from './defineResolver.ts'
8
11
  import { openInStudio as openInStudioFn } from './devtools.ts'
9
12
  import { FileManager } from './FileManager.ts'
13
+ import { applyHookResult } from './renderNode.ts'
10
14
 
11
15
  import type {
12
16
  Adapter,
13
17
  Config,
14
18
  DevtoolsOptions,
15
- KubbEvents,
19
+ Group,
20
+ KubbHooks,
21
+ KubbPluginSetupContext,
22
+ Output,
16
23
  Plugin,
17
24
  PluginContext,
18
25
  PluginFactoryOptions,
@@ -22,6 +29,7 @@ import type {
22
29
  PluginWithLifeCycle,
23
30
  ResolveNameParams,
24
31
  ResolvePathParams,
32
+ Resolver,
25
33
  } from './types.ts'
26
34
  import { hookFirst, hookParallel, hookSeq } from './utils/executeStrategies.ts'
27
35
 
@@ -47,7 +55,7 @@ type SafeParseResult<H extends PluginLifecycleHooks, Result = ReturnType<ParseRe
47
55
  // inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#
48
56
 
49
57
  type Options = {
50
- events: AsyncEventEmitter<KubbEvents>
58
+ hooks?: AsyncEventEmitter<KubbHooks>
51
59
  /**
52
60
  * @default Number.POSITIVE_INFINITY
53
61
  */
@@ -104,11 +112,28 @@ export class PluginDriver {
104
112
 
105
113
  readonly plugins = new Map<string, Plugin>()
106
114
 
115
+ /**
116
+ * Tracks which plugins have generators registered via `addGenerator()` (event-based path).
117
+ * Used by the build loop to decide whether to emit generator events for a given plugin.
118
+ */
119
+ readonly #pluginsWithEventGenerators = new Set<string>()
120
+ readonly #resolvers = new Map<string, Resolver>()
121
+ readonly #defaultResolvers = new Map<string, Resolver>()
122
+ readonly #hookListeners = new Map<keyof KubbHooks, Set<(...args: never[]) => void | Promise<void>>>()
123
+
107
124
  constructor(config: Config, options: Options) {
108
125
  this.config = config
109
- this.options = options
126
+ this.options = {
127
+ ...options,
128
+ hooks: options.hooks,
129
+ }
110
130
  config.plugins
111
- .map((plugin) => Object.assign({ buildStart() {}, buildEnd() {} }, plugin) as unknown as Plugin)
131
+ .map((rawPlugin) => {
132
+ if (isHookStylePlugin(rawPlugin)) {
133
+ return this.#normalizeHookStylePlugin(rawPlugin as HookStylePlugin)
134
+ }
135
+ return { ...rawPlugin, buildStart: rawPlugin.buildStart ?? (() => {}), buildEnd: rawPlugin.buildEnd ?? (() => {}) } as unknown as Plugin
136
+ })
112
137
  .filter((plugin) => {
113
138
  if (typeof plugin.apply === 'function') {
114
139
  return plugin.apply(config)
@@ -116,8 +141,8 @@ export class PluginDriver {
116
141
  return true
117
142
  })
118
143
  .sort((a, b) => {
119
- if (b.pre?.includes(a.name)) return 1
120
- if (b.post?.includes(a.name)) return -1
144
+ if (b.dependencies?.includes(a.name)) return -1
145
+ if (a.dependencies?.includes(b.name)) return 1
121
146
  return 0
122
147
  })
123
148
  .forEach((plugin) => {
@@ -125,8 +150,267 @@ export class PluginDriver {
125
150
  })
126
151
  }
127
152
 
128
- get events() {
129
- return this.options.events
153
+ get hooks() {
154
+ if (!this.options.hooks) {
155
+ throw new Error('hooks are not defined')
156
+ }
157
+ return this.options.hooks
158
+ }
159
+
160
+ /**
161
+ * Creates a `Plugin`-compatible object from a hook-style plugin and registers
162
+ * its lifecycle handlers on the `AsyncEventEmitter`.
163
+ *
164
+ * The normalized plugin has an empty `buildStart` — generators registered via
165
+ * `addGenerator()` in `kubb:plugin:setup` are stored on `normalizedPlugin.generators`
166
+ * and used by `runPluginAstHooks` during the build.
167
+ */
168
+ #normalizeHookStylePlugin(hookPlugin: HookStylePlugin): Plugin {
169
+ const generators: Plugin['generators'] = []
170
+ const driver = this
171
+ // The options shape is the minimal struct required by Plugin. Hook-style plugins
172
+ // use generators registered via addGenerator() and resolvers set via setResolver().
173
+ // `inject` and `resolver` are required by the Plugin type but are irrelevant for hook-style
174
+ // plugins: inject is a no-op and resolver is set dynamically via setResolver() in kubb:plugin:setup.
175
+ //
176
+ // `resolveName` and `resolvePath` bridge the legacy PluginDriver.resolveName/resolvePath
177
+ // lifecycle so that other plugins calling `driver.resolveName({ pluginName })` or
178
+ // `driver.getFile({ pluginName })` still get correct results from hook-style plugins.
179
+ const normalizedPlugin = {
180
+ name: hookPlugin.name,
181
+ dependencies: hookPlugin.dependencies,
182
+ options: { output: { path: '.' }, exclude: [], override: [] },
183
+ generators,
184
+ inject: () => undefined,
185
+ resolveName(name: string, type?: ResolveNameParams['type']) {
186
+ const resolver = driver.getResolver(hookPlugin.name)
187
+ return resolver.default(name, type)
188
+ },
189
+ resolvePath(baseName: FileNode['baseName'], pathMode?: 'single' | 'split', resolveOptions?: Record<string, unknown>) {
190
+ const resolver = driver.getResolver(hookPlugin.name)
191
+ const opts = normalizedPlugin.options as Record<string, unknown>
192
+ const group = resolveOptions?.group as Record<string, string> | undefined
193
+ return resolver.resolvePath(
194
+ { baseName, pathMode, tag: group?.tag, path: group?.path },
195
+ { root: resolve(driver.config.root, driver.config.output.path), output: opts.output as Output, group: opts.group as Group | undefined },
196
+ )
197
+ },
198
+ buildStart() {},
199
+ buildEnd() {},
200
+ } as unknown as Plugin
201
+ this.registerPluginHooks(hookPlugin, normalizedPlugin)
202
+ return normalizedPlugin
203
+ }
204
+
205
+ /**
206
+ * Registers a hook-style plugin's lifecycle handlers on the shared `AsyncEventEmitter`.
207
+ *
208
+ * For `kubb:plugin:setup`, the registered listener wraps the globally emitted context with a
209
+ * plugin-specific one so that `addGenerator`, `setResolver`, `setTransformer`, and
210
+ * `setRenderer` all target the correct `normalizedPlugin` entry in the plugins map.
211
+ *
212
+ * All other hooks are iterated and registered directly as pass-through listeners.
213
+ * Any event key present in the global `KubbHooks` interface can be subscribed to.
214
+ *
215
+ * External tooling can subscribe to any of these events via `hooks.on(...)` to observe
216
+ * the plugin lifecycle without modifying plugin behavior.
217
+ */
218
+ registerPluginHooks(hookPlugin: HookStylePlugin, normalizedPlugin: Plugin): void {
219
+ const { hooks } = hookPlugin
220
+
221
+ // kubb:plugin:setup gets special treatment: the globally emitted context is wrapped with
222
+ // plugin-specific implementations so that addGenerator / setResolver / etc. target
223
+ // this plugin's normalizedPlugin entry rather than being no-ops.
224
+ if (hooks['kubb:plugin:setup']) {
225
+ const setupHandler = (globalCtx: KubbPluginSetupContext) => {
226
+ const pluginCtx: KubbPluginSetupContext = {
227
+ ...globalCtx,
228
+ options: hookPlugin.options ?? {},
229
+ addGenerator: (gen) => {
230
+ this.registerGenerator(normalizedPlugin.name, gen)
231
+ },
232
+ setResolver: (resolver) => {
233
+ this.setPluginResolver(normalizedPlugin.name, resolver)
234
+ },
235
+ setTransformer: (visitor) => {
236
+ normalizedPlugin.transformer = visitor
237
+ },
238
+ setRenderer: (renderer) => {
239
+ normalizedPlugin.renderer = renderer
240
+ },
241
+ setOptions: (opts) => {
242
+ normalizedPlugin.options = { ...normalizedPlugin.options, ...opts }
243
+ },
244
+ injectFile: (file) => {
245
+ const fileNode = createFile({
246
+ baseName: file.baseName,
247
+ path: file.path,
248
+ sources: file.sources ?? [],
249
+ imports: [],
250
+ exports: [],
251
+ })
252
+ this.fileManager.add(fileNode)
253
+ },
254
+ }
255
+ return hooks['kubb:plugin:setup']!(pluginCtx)
256
+ }
257
+
258
+ this.hooks.on('kubb:plugin:setup', setupHandler)
259
+ this.#trackHookListener('kubb:plugin:setup', setupHandler as (...args: never[]) => void | Promise<void>)
260
+ }
261
+
262
+ // All other hooks are registered as direct pass-through listeners on the shared emitter.
263
+ for (const [event, handler] of Object.entries(hooks) as Array<[keyof KubbHooks, ((...args: never[]) => void | Promise<void>) | undefined]>) {
264
+ if (event === 'kubb:plugin:setup' || !handler) continue
265
+ this.hooks.on(event, handler as never)
266
+ this.#trackHookListener(event, handler as (...args: never[]) => void | Promise<void>)
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
272
+ * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
273
+ *
274
+ * Call this once from `safeBuild` before the plugin execution loop begins.
275
+ */
276
+ async emitSetupHooks(): Promise<void> {
277
+ await this.hooks.emit('kubb:plugin:setup', {
278
+ config: this.config,
279
+ addGenerator: () => {},
280
+ setResolver: () => {},
281
+ setTransformer: () => {},
282
+ setRenderer: () => {},
283
+ setOptions: () => {},
284
+ injectFile: () => {},
285
+ updateConfig: () => {},
286
+ options: {},
287
+ })
288
+ }
289
+
290
+ /**
291
+ * Registers a generator for the given plugin on the shared event emitter.
292
+ *
293
+ * The generator's `schema`, `operation`, and `operations` methods are registered as
294
+ * listeners on `kubb:generate:schema`, `kubb:generate:operation`, and `kubb:generate:operations`
295
+ * respectively. Each listener is scoped to the owning plugin via a `ctx.plugin.name` check
296
+ * so that generators from different plugins do not cross-fire.
297
+ *
298
+ * The renderer resolution chain is: `generator.renderer → plugin.renderer → config.renderer`.
299
+ * Set `generator.renderer = null` to explicitly opt out of rendering even when the plugin
300
+ * declares a renderer.
301
+ *
302
+ * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
303
+ */
304
+ registerGenerator(pluginName: string, gen: Generator<any>): void {
305
+ const resolveRenderer = () => {
306
+ const plugin = this.plugins.get(pluginName)
307
+ return gen.renderer === null ? undefined : (gen.renderer ?? plugin?.renderer ?? this.config.renderer)
308
+ }
309
+
310
+ if (gen.schema) {
311
+ const schemaHandler = async (node: Parameters<NonNullable<typeof gen.schema>>[0], ctx: Parameters<NonNullable<typeof gen.schema>>[1]) => {
312
+ if (ctx.plugin.name !== pluginName) return
313
+ const result = await gen.schema!(node, ctx)
314
+ await applyHookResult(result, this, resolveRenderer())
315
+ }
316
+
317
+ this.hooks.on('kubb:generate:schema', schemaHandler)
318
+ this.#trackHookListener('kubb:generate:schema', schemaHandler as (...args: never[]) => void | Promise<void>)
319
+ }
320
+
321
+ if (gen.operation) {
322
+ const operationHandler = async (node: Parameters<NonNullable<typeof gen.operation>>[0], ctx: Parameters<NonNullable<typeof gen.operation>>[1]) => {
323
+ if (ctx.plugin.name !== pluginName) return
324
+ const result = await gen.operation!(node, ctx)
325
+ await applyHookResult(result, this, resolveRenderer())
326
+ }
327
+
328
+ this.hooks.on('kubb:generate:operation', operationHandler)
329
+ this.#trackHookListener('kubb:generate:operation', operationHandler as (...args: never[]) => void | Promise<void>)
330
+ }
331
+
332
+ if (gen.operations) {
333
+ const operationsHandler = async (nodes: Parameters<NonNullable<typeof gen.operations>>[0], ctx: Parameters<NonNullable<typeof gen.operations>>[1]) => {
334
+ if (ctx.plugin.name !== pluginName) return
335
+ const result = await gen.operations!(nodes, ctx)
336
+ await applyHookResult(result, this, resolveRenderer())
337
+ }
338
+
339
+ this.hooks.on('kubb:generate:operations', operationsHandler)
340
+ this.#trackHookListener('kubb:generate:operations', operationsHandler as (...args: never[]) => void | Promise<void>)
341
+ }
342
+
343
+ this.#pluginsWithEventGenerators.add(pluginName)
344
+ }
345
+
346
+ /**
347
+ * Returns `true` when at least one generator was registered for the given plugin
348
+ * via `addGenerator()` in `kubb:plugin:setup` (event-based path).
349
+ *
350
+ * Used by the build loop to decide whether to walk the AST and emit generator events
351
+ * for a plugin that has no static `plugin.generators`.
352
+ */
353
+ hasRegisteredGenerators(pluginName: string): boolean {
354
+ return this.#pluginsWithEventGenerators.has(pluginName)
355
+ }
356
+
357
+ dispose(): void {
358
+ for (const [event, handlers] of this.#hookListeners) {
359
+ for (const handler of handlers) {
360
+ this.hooks.off(event, handler as never)
361
+ }
362
+ }
363
+ this.#hookListeners.clear()
364
+ this.#pluginsWithEventGenerators.clear()
365
+ }
366
+
367
+ #trackHookListener(event: keyof KubbHooks, handler: (...args: never[]) => void | Promise<void>): void {
368
+ let handlers = this.#hookListeners.get(event)
369
+ if (!handlers) {
370
+ handlers = new Set()
371
+ this.#hookListeners.set(event, handlers)
372
+ }
373
+ handlers.add(handler)
374
+ }
375
+
376
+ #createDefaultResolver(pluginName: string): Resolver {
377
+ const existingResolver = this.#defaultResolvers.get(pluginName)
378
+ if (existingResolver) {
379
+ return existingResolver
380
+ }
381
+
382
+ const resolver = defineResolver<PluginFactoryOptions>(() => ({
383
+ name: 'default',
384
+ pluginName,
385
+ }))
386
+ this.#defaultResolvers.set(pluginName, resolver)
387
+ return resolver
388
+ }
389
+
390
+ setPluginResolver(pluginName: string, partial: Partial<Resolver>): void {
391
+ const defaultResolver = this.#createDefaultResolver(pluginName)
392
+ const merged = { ...defaultResolver, ...partial }
393
+ this.#resolvers.set(pluginName, merged)
394
+ // Mirror the resolved resolver onto the plugin so that consumers using
395
+ // `getPlugin(name).resolver` get the correct resolver without going through getResolver().
396
+ const plugin = this.plugins.get(pluginName)
397
+ if (plugin) {
398
+ plugin.resolver = merged
399
+ }
400
+ }
401
+
402
+ getResolver(pluginName: string): Resolver {
403
+ const dynamicResolver = this.#resolvers.get(pluginName)
404
+ if (dynamicResolver) {
405
+ return dynamicResolver
406
+ }
407
+
408
+ const pluginResolver = this.plugins.get(pluginName)?.resolver
409
+ if (pluginResolver) {
410
+ return pluginResolver
411
+ }
412
+
413
+ return this.#createDefaultResolver(pluginName)
130
414
  }
131
415
 
132
416
  getContext<TOptions extends PluginFactoryOptions>(plugin: Plugin<TOptions>): PluginContext<TOptions> & Record<string, unknown> {
@@ -140,7 +424,7 @@ export class PluginDriver {
140
424
  getMode(output: { path: string }): 'single' | 'split' {
141
425
  return getMode(resolve(driver.config.root, driver.config.output.path, output.path))
142
426
  },
143
- events: driver.options.events,
427
+ hooks: driver.hooks,
144
428
  plugin,
145
429
  getPlugin: driver.getPlugin.bind(driver),
146
430
  requirePlugin: driver.requirePlugin.bind(driver),
@@ -158,19 +442,19 @@ export class PluginDriver {
158
442
  return driver.adapter
159
443
  },
160
444
  get resolver() {
161
- return plugin.resolver
445
+ return driver.getResolver(plugin.name)
162
446
  },
163
447
  get transformer() {
164
448
  return plugin.transformer
165
449
  },
166
450
  warn(message: string) {
167
- driver.events.emit('warn', message)
451
+ driver.hooks.emit('kubb:warn', message)
168
452
  },
169
453
  error(error: string | Error) {
170
- driver.events.emit('error', typeof error === 'string' ? new Error(error) : error)
454
+ driver.hooks.emit('kubb:error', typeof error === 'string' ? new Error(error) : error)
171
455
  },
172
456
  info(message: string) {
173
- driver.events.emit('info', message)
457
+ driver.hooks.emit('kubb:info', message)
174
458
  },
175
459
  openInStudio(options?: DevtoolsOptions) {
176
460
  if (!driver.config.devtools || driver.#studioIsOpen) {
@@ -193,13 +477,13 @@ export class PluginDriver {
193
477
  },
194
478
  } as unknown as PluginContext<TOptions>
195
479
 
196
- const mergedExtras: Record<string, unknown> = {}
480
+ let mergedExtras: Record<string, unknown> = {}
197
481
 
198
482
  for (const p of this.plugins.values()) {
199
483
  if (typeof p.inject === 'function') {
200
484
  const result = (p.inject as (this: PluginContext) => unknown).call(baseContext as unknown as PluginContext)
201
485
  if (result !== null && typeof result === 'object') {
202
- Object.assign(mergedExtras, result)
486
+ mergedExtras = { ...mergedExtras, ...(result as Record<string, unknown>) }
203
487
  }
204
488
  }
205
489
  }
@@ -302,7 +586,7 @@ export class PluginDriver {
302
586
  return [null]
303
587
  }
304
588
 
305
- this.events.emit('plugins:hook:progress:start', {
589
+ this.hooks.emit('kubb:plugins:hook:progress:start', {
306
590
  hookName,
307
591
  plugins: [plugin],
308
592
  })
@@ -314,7 +598,7 @@ export class PluginDriver {
314
598
  plugin,
315
599
  })
316
600
 
317
- this.events.emit('plugins:hook:progress:end', { hookName })
601
+ this.hooks.emit('kubb:plugins:hook:progress:end', { hookName })
318
602
 
319
603
  return [result]
320
604
  }
@@ -364,7 +648,7 @@ export class PluginDriver {
364
648
  if (hookName in plugin && (skipped ? !skipped.has(plugin) : true)) plugins.push(plugin)
365
649
  }
366
650
 
367
- this.events.emit('plugins:hook:progress:start', { hookName, plugins })
651
+ this.hooks.emit('kubb:plugins:hook:progress:start', { hookName, plugins })
368
652
 
369
653
  const promises = plugins.map((plugin) => {
370
654
  return async () => {
@@ -384,7 +668,7 @@ export class PluginDriver {
384
668
 
385
669
  const result = await hookFirst(promises, hookFirstNullCheck)
386
670
 
387
- this.events.emit('plugins:hook:progress:end', { hookName })
671
+ this.hooks.emit('kubb:plugins:hook:progress:end', { hookName })
388
672
 
389
673
  return result
390
674
  }
@@ -424,7 +708,7 @@ export class PluginDriver {
424
708
  }
425
709
 
426
710
  /**
427
- * Runs all plugins in parallel based on `this.plugin` order and `pre`/`post` settings.
711
+ * Runs all plugins in parallel based on `this.plugin` order and `dependencies` settings.
428
712
  */
429
713
  async hookParallel<H extends PluginLifecycleHooks, TOutput = void>({
430
714
  hookName,
@@ -437,7 +721,7 @@ export class PluginDriver {
437
721
  for (const plugin of this.plugins.values()) {
438
722
  if (hookName in plugin) plugins.push(plugin)
439
723
  }
440
- this.events.emit('plugins:hook:progress:start', { hookName, plugins })
724
+ this.hooks.emit('kubb:plugins:hook:progress:start', { hookName, plugins })
441
725
 
442
726
  const pluginStartTimes = new Map<Plugin, number>()
443
727
 
@@ -461,7 +745,7 @@ export class PluginDriver {
461
745
 
462
746
  if (plugin) {
463
747
  const startTime = pluginStartTimes.get(plugin) ?? performance.now()
464
- this.events.emit('error', result.reason, {
748
+ this.hooks.emit('kubb:error', result.reason, {
465
749
  plugin,
466
750
  hookName,
467
751
  strategy: 'hookParallel',
@@ -472,7 +756,7 @@ export class PluginDriver {
472
756
  }
473
757
  })
474
758
 
475
- this.events.emit('plugins:hook:progress:end', { hookName })
759
+ this.hooks.emit('kubb:plugins:hook:progress:end', { hookName })
476
760
 
477
761
  return results.reduce((acc, result) => {
478
762
  if (result.status === 'fulfilled') {
@@ -483,14 +767,14 @@ export class PluginDriver {
483
767
  }
484
768
 
485
769
  /**
486
- * Chains plugins
770
+ * Execute a lifecycle hook sequentially for all plugins that implement it.
487
771
  */
488
772
  async hookSeq<H extends PluginLifecycleHooks>({ hookName, parameters }: { hookName: H; parameters?: PluginParameter<H> }): Promise<void> {
489
773
  const plugins: Array<Plugin> = []
490
774
  for (const plugin of this.plugins.values()) {
491
775
  if (hookName in plugin) plugins.push(plugin)
492
776
  }
493
- this.events.emit('plugins:hook:progress:start', { hookName, plugins })
777
+ this.hooks.emit('kubb:plugins:hook:progress:start', { hookName, plugins })
494
778
 
495
779
  const promises = plugins.map((plugin) => {
496
780
  return () =>
@@ -504,7 +788,7 @@ export class PluginDriver {
504
788
 
505
789
  await hookSeq(promises)
506
790
 
507
- this.events.emit('plugins:hook:progress:end', { hookName })
791
+ this.hooks.emit('kubb:plugins:hook:progress:end', { hookName })
508
792
  }
509
793
 
510
794
  getPlugin<TName extends keyof Kubb.PluginRegistry>(pluginName: TName): Plugin<Kubb.PluginRegistry[TName]> | undefined
@@ -527,10 +811,7 @@ export class PluginDriver {
527
811
  }
528
812
 
529
813
  /**
530
- * Run an async plugin hook and return the result.
531
- * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.
532
- * @param args Arguments passed to the plugin hook.
533
- * @param plugin The actual pluginObject to run.
814
+ * Emit hook-processing completion metadata after a plugin hook resolves.
534
815
  */
535
816
  #emitProcessingEnd<H extends PluginLifecycleHooks>({
536
817
  startTime,
@@ -547,7 +828,7 @@ export class PluginDriver {
547
828
  plugin: PluginWithLifeCycle
548
829
  parameters: unknown[] | undefined
549
830
  }): void {
550
- this.events.emit('plugins:hook:processing:end', {
831
+ this.hooks.emit('kubb:plugins:hook:processing:end', {
551
832
  duration: Math.round(performance.now() - startTime),
552
833
  parameters,
553
834
  output,
@@ -575,7 +856,7 @@ export class PluginDriver {
575
856
  return null
576
857
  }
577
858
 
578
- this.events.emit('plugins:hook:processing:start', {
859
+ this.hooks.emit('kubb:plugins:hook:processing:start', {
579
860
  strategy,
580
861
  hookName,
581
862
  parameters,
@@ -593,7 +874,7 @@ export class PluginDriver {
593
874
 
594
875
  return output as ReturnType<ParseResult<H>>
595
876
  } catch (error) {
596
- this.events.emit('error', error as Error, {
877
+ this.hooks.emit('kubb:error', error as Error, {
597
878
  plugin,
598
879
  hookName,
599
880
  strategy,
@@ -608,10 +889,7 @@ export class PluginDriver {
608
889
  }
609
890
 
610
891
  /**
611
- * Run a sync plugin hook and return the result.
612
- * @param hookName Name of the plugin hook. Must be in `PluginHooks`.
613
- * @param args Arguments passed to the plugin hook.
614
- * @param plugin The actual plugin
892
+ * Execute a plugin lifecycle hook synchronously and return its output.
615
893
  */
616
894
  #executeSync<H extends PluginLifecycleHooks>({
617
895
  strategy,
@@ -630,7 +908,7 @@ export class PluginDriver {
630
908
  return null
631
909
  }
632
910
 
633
- this.events.emit('plugins:hook:processing:start', {
911
+ this.hooks.emit('kubb:plugins:hook:processing:start', {
634
912
  strategy,
635
913
  hookName,
636
914
  parameters,
@@ -649,7 +927,7 @@ export class PluginDriver {
649
927
 
650
928
  return output
651
929
  } catch (error) {
652
- this.events.emit('error', error as Error, {
930
+ this.hooks.emit('kubb:error', error as Error, {
653
931
  plugin,
654
932
  hookName,
655
933
  strategy,
package/src/constants.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { FileNode } from '@kubb/ast/types'
1
+ import type { FileNode } from '@kubb/ast'
2
2
 
3
3
  /**
4
4
  * Base URL for the Kubb Studio web app.