@kubb/core 3.0.0-alpha.3 → 3.0.0-alpha.30

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 (112) hide show
  1. package/README.md +13 -4
  2. package/dist/{FileManager-Bw-FNS3q.d.cts → FileManager-CqvmdzNO.d.cts} +128 -90
  3. package/dist/{FileManager-BW--rO8q.d.ts → FileManager-DIArE3b0.d.ts} +128 -90
  4. package/dist/chunk-2EU7DMPM.js +96 -0
  5. package/dist/chunk-2EU7DMPM.js.map +1 -0
  6. package/dist/{chunk-34BPAXR2.cjs → chunk-2UQARE2O.cjs} +54 -37
  7. package/dist/chunk-2UQARE2O.cjs.map +1 -0
  8. package/dist/chunk-4X5FFJPJ.js +8 -13
  9. package/dist/chunk-4X5FFJPJ.js.map +1 -1
  10. package/dist/{chunk-3OXCZ5DJ.js → chunk-E6CN2CZC.js} +63 -54
  11. package/dist/chunk-E6CN2CZC.js.map +1 -0
  12. package/dist/{chunk-25NKJ3DV.js → chunk-HBQM723K.js} +13 -27
  13. package/dist/chunk-HBQM723K.js.map +1 -0
  14. package/dist/{chunk-LM2YQC3T.cjs → chunk-LLKRRIBF.cjs} +81 -51
  15. package/dist/chunk-LLKRRIBF.cjs.map +1 -0
  16. package/dist/chunk-MD2LDZ3Z.js +889 -0
  17. package/dist/chunk-MD2LDZ3Z.js.map +1 -0
  18. package/dist/chunk-OX2X7B4Z.cjs +101 -0
  19. package/dist/chunk-OX2X7B4Z.cjs.map +1 -0
  20. package/dist/{chunk-67C6RBGQ.cjs → chunk-RIW2LFFQ.cjs} +28 -29
  21. package/dist/chunk-RIW2LFFQ.cjs.map +1 -0
  22. package/dist/chunk-SX5FHSVT.cjs +1532 -0
  23. package/dist/chunk-SX5FHSVT.cjs.map +1 -0
  24. package/dist/chunk-VBGWLAET.cjs +42 -0
  25. package/dist/chunk-VBGWLAET.cjs.map +1 -0
  26. package/dist/index.cjs +553 -619
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +7 -22
  29. package/dist/index.d.ts +7 -22
  30. package/dist/index.js +444 -525
  31. package/dist/index.js.map +1 -1
  32. package/dist/{logger-DChjnJMn.d.cts → logger-DvbHXjIO.d.cts} +29 -19
  33. package/dist/{logger-DChjnJMn.d.ts → logger-DvbHXjIO.d.ts} +29 -19
  34. package/dist/logger.cjs +25 -15
  35. package/dist/logger.cjs.map +1 -1
  36. package/dist/logger.d.cts +1 -2
  37. package/dist/logger.d.ts +1 -2
  38. package/dist/logger.js +3 -15
  39. package/dist/logger.js.map +1 -1
  40. package/dist/mocks.cjs +42 -31
  41. package/dist/mocks.cjs.map +1 -1
  42. package/dist/mocks.d.cts +7 -9
  43. package/dist/mocks.d.ts +7 -9
  44. package/dist/mocks.js +35 -33
  45. package/dist/mocks.js.map +1 -1
  46. package/dist/{prompt-6FWP747F.cjs → prompt-2PN2F25D.cjs} +89 -89
  47. package/dist/prompt-2PN2F25D.cjs.map +1 -0
  48. package/dist/{prompt-HK3MWREM.js → prompt-WQQUN22Z.js} +9 -15
  49. package/dist/prompt-WQQUN22Z.js.map +1 -0
  50. package/dist/transformers.cjs +216 -49
  51. package/dist/transformers.cjs.map +1 -1
  52. package/dist/transformers.d.cts +2 -4
  53. package/dist/transformers.d.ts +2 -4
  54. package/dist/transformers.js +149 -35
  55. package/dist/transformers.js.map +1 -1
  56. package/dist/utils.cjs +65 -26
  57. package/dist/utils.cjs.map +1 -1
  58. package/dist/utils.d.cts +29 -3
  59. package/dist/utils.d.ts +29 -3
  60. package/dist/utils.js +3 -26
  61. package/dist/utils.js.map +1 -1
  62. package/package.json +11 -14
  63. package/src/BarrelManager.ts +95 -109
  64. package/src/{Generator.ts → BaseGenerator.ts} +1 -1
  65. package/src/FileManager.ts +199 -304
  66. package/src/PackageManager.ts +1 -1
  67. package/src/PluginManager.ts +152 -93
  68. package/src/PromiseManager.ts +1 -1
  69. package/src/__snapshots__/barrel.json +73 -0
  70. package/src/__snapshots__/grouped.json +120 -0
  71. package/src/__snapshots__/ordered.json +68 -0
  72. package/src/build.ts +86 -131
  73. package/src/config.ts +2 -4
  74. package/src/errors.ts +0 -11
  75. package/src/index.ts +2 -3
  76. package/src/logger.ts +76 -34
  77. package/src/plugin.ts +2 -5
  78. package/src/transformers/escape.ts +0 -10
  79. package/src/transformers/index.ts +2 -3
  80. package/src/transformers/stringify.ts +1 -1
  81. package/src/transformers/trim.ts +0 -4
  82. package/src/types.ts +52 -20
  83. package/src/utils/TreeNode.ts +132 -50
  84. package/src/utils/executeStrategies.ts +3 -3
  85. package/src/utils/index.ts +2 -1
  86. package/src/utils/parser.ts +156 -0
  87. package/dist/chunk-25NKJ3DV.js.map +0 -1
  88. package/dist/chunk-34BPAXR2.cjs.map +0 -1
  89. package/dist/chunk-3OXCZ5DJ.js.map +0 -1
  90. package/dist/chunk-5JZNFPUP.js +0 -309
  91. package/dist/chunk-5JZNFPUP.js.map +0 -1
  92. package/dist/chunk-67C6RBGQ.cjs.map +0 -1
  93. package/dist/chunk-ADC5UNZ5.cjs +0 -1227
  94. package/dist/chunk-ADC5UNZ5.cjs.map +0 -1
  95. package/dist/chunk-HMLY7DHA.js +0 -16
  96. package/dist/chunk-HMLY7DHA.js.map +0 -1
  97. package/dist/chunk-JKZG2IJR.js +0 -283
  98. package/dist/chunk-JKZG2IJR.js.map +0 -1
  99. package/dist/chunk-LM2YQC3T.cjs.map +0 -1
  100. package/dist/chunk-PZT4CTBV.cjs +0 -299
  101. package/dist/chunk-PZT4CTBV.cjs.map +0 -1
  102. package/dist/chunk-SA2GZKXS.js +0 -596
  103. package/dist/chunk-SA2GZKXS.js.map +0 -1
  104. package/dist/chunk-XCPFG6DO.cjs +0 -66
  105. package/dist/chunk-XCPFG6DO.cjs.map +0 -1
  106. package/dist/chunk-YTSNYMHW.cjs +0 -320
  107. package/dist/chunk-YTSNYMHW.cjs.map +0 -1
  108. package/dist/prompt-6FWP747F.cjs.map +0 -1
  109. package/dist/prompt-HK3MWREM.js.map +0 -1
  110. package/schema.json +0 -86
  111. package/src/utils/cache.ts +0 -35
  112. package/src/utils/getParser.ts +0 -17
@@ -1,11 +1,7 @@
1
- import PQueue from 'p-queue'
2
-
3
- import { readSync } from '@kubb/fs'
4
- import { FileManager, type ResolvedFile } from './FileManager.ts'
1
+ import { FileManager } from './FileManager.ts'
5
2
  import { isPromise, isPromiseRejectedResult } from './PromiseManager.ts'
6
3
  import { PromiseManager } from './PromiseManager.ts'
7
4
  import { ValidationPluginError } from './errors.ts'
8
- import { LogLevel } from './logger.ts'
9
5
  import { pluginCore } from './plugin.ts'
10
6
  import { transformReservedWord } from './transformers/transformReservedWord.ts'
11
7
  import { EventEmitter } from './utils/EventEmitter.ts'
@@ -41,6 +37,7 @@ type Argument0<H extends keyof PluginLifecycle> = Parameters<RequiredPluginLifec
41
37
  type Strategy = 'hookFirst' | 'hookForPlugin' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'
42
38
 
43
39
  type Executer<H extends PluginLifecycleHooks = PluginLifecycleHooks> = {
40
+ message: string
44
41
  strategy: Strategy
45
42
  hookName: H
46
43
  plugin: Plugin
@@ -59,15 +56,10 @@ type SafeParseResult<H extends PluginLifecycleHooks, Result = ReturnType<ParseRe
59
56
 
60
57
  type Options = {
61
58
  logger: Logger
62
-
63
- /**
64
- * Task for the FileManager
65
- */
66
- task: (file: ResolvedFile) => Promise<ResolvedFile>
67
59
  }
68
60
 
69
61
  type Events = {
70
- execute: [executer: Executer]
62
+ executing: [executer: Executer]
71
63
  executed: [executer: Executer]
72
64
  error: [error: Error]
73
65
  }
@@ -75,13 +67,13 @@ type Events = {
75
67
  type GetFileProps<TOptions = object> = {
76
68
  name: string
77
69
  mode?: KubbFile.Mode
78
- extName: KubbFile.Extname
70
+ extname: KubbFile.Extname
79
71
  pluginKey: Plugin['key']
80
72
  options?: TOptions
81
73
  }
82
74
 
83
75
  export class PluginManager {
84
- readonly plugins: PluginWithLifeCycle[]
76
+ readonly plugins = new Set<Plugin<GetPluginFactoryOptions<any>>>()
85
77
  readonly fileManager: FileManager
86
78
  readonly events: EventEmitter<Events> = new EventEmitter()
87
79
 
@@ -89,27 +81,21 @@ export class PluginManager {
89
81
 
90
82
  readonly executed: Array<Executer> = []
91
83
  readonly logger: Logger
84
+ readonly options: Options
92
85
  readonly #core: Plugin<PluginCore>
93
86
 
94
87
  readonly #usedPluginNames: Record<string, number> = {}
95
88
  readonly #promiseManager: PromiseManager
96
89
 
97
- readonly queue: PQueue
98
-
99
90
  constructor(config: Config, options: Options) {
100
91
  this.config = config
92
+ this.options = options
101
93
  this.logger = options.logger
102
- this.queue = new PQueue({ concurrency: 1 })
103
- this.fileManager = new FileManager({
104
- task: options.task,
105
- queue: this.queue,
106
- })
94
+ this.fileManager = new FileManager()
107
95
  this.#promiseManager = new PromiseManager({
108
96
  nullCheck: (state: SafeParseResult<'resolveName'> | null) => !!state?.result,
109
97
  })
110
98
 
111
- const plugins = config.plugins || []
112
-
113
99
  const core = pluginCore({
114
100
  config,
115
101
  logger: this.logger,
@@ -122,36 +108,30 @@ export class PluginManager {
122
108
 
123
109
  // call core.context.call with empty context so we can transform `context()` to `context: {}`
124
110
  this.#core = this.#parse(core as unknown as UserPlugin, this as any, core.context.call(null as any)) as Plugin<PluginCore>
111
+ ;[this.#core, ...(config.plugins || [])].forEach((plugin) => {
112
+ const parsedPlugin = this.#parse(plugin as UserPlugin, this, this.#core.context)
125
113
 
126
- this.plugins = [this.#core, ...plugins].map((plugin) => {
127
- return this.#parse(plugin as UserPlugin, this, this.#core.context)
114
+ this.plugins.add(parsedPlugin)
128
115
  })
129
116
 
130
117
  return this
131
118
  }
132
119
 
133
- getFile<TOptions = object>({ name, mode, extName, pluginKey, options }: GetFileProps<TOptions>): KubbFile.File<{ pluginKey: Plugin['key'] }> {
134
- let source = ''
135
- const baseName = `${name}${extName}` as const
120
+ getFile<TOptions = object>({ name, mode, extname, pluginKey, options }: GetFileProps<TOptions>): KubbFile.File<{ pluginKey: Plugin['key'] }> {
121
+ const baseName = `${name}${extname}` as const
136
122
  const path = this.resolvePath({ baseName, mode, pluginKey, options })
137
123
 
138
124
  if (!path) {
139
125
  throw new Error(`Filepath should be defined for resolvedName "${name}" and pluginKey [${JSON.stringify(pluginKey)}]`)
140
126
  }
141
127
 
142
- try {
143
- source = readSync(path)
144
- } catch (_e) {
145
- //
146
- }
147
-
148
128
  return {
149
129
  path,
150
130
  baseName,
151
131
  meta: {
152
132
  pluginKey,
153
133
  },
154
- source,
134
+ sources: [],
155
135
  }
156
136
  }
157
137
 
@@ -161,14 +141,18 @@ export class PluginManager {
161
141
  pluginKey: params.pluginKey,
162
142
  hookName: 'resolvePath',
163
143
  parameters: [params.baseName, params.mode, params.options as object],
144
+ message: `Resolving path '${params.baseName}'`,
164
145
  })
165
146
 
166
147
  if (paths && paths?.length > 1) {
167
- this.logger.emit('debug', [
168
- `Cannot return a path where the 'pluginKey' ${
169
- params.pluginKey ? JSON.stringify(params.pluginKey) : '"'
170
- } is not unique enough\n\nPaths: ${JSON.stringify(paths, undefined, 2)}\n\nFalling back on the first item.\n`,
171
- ])
148
+ this.logger.emit('debug', {
149
+ date: new Date(),
150
+ logs: [
151
+ `Cannot return a path where the 'pluginKey' ${
152
+ params.pluginKey ? JSON.stringify(params.pluginKey) : '"'
153
+ } is not unique enough\n\nPaths: ${JSON.stringify(paths, undefined, 2)}\n\nFalling back on the first item.\n`,
154
+ ],
155
+ })
172
156
  }
173
157
 
174
158
  return paths?.at(0)
@@ -176,22 +160,28 @@ export class PluginManager {
176
160
  return this.hookFirstSync({
177
161
  hookName: 'resolvePath',
178
162
  parameters: [params.baseName, params.mode, params.options as object],
163
+ message: `Resolving path '${params.baseName}'`,
179
164
  }).result
180
165
  }
166
+ //TODO refactor by using the order of plugins and the cache of the fileManager instead of guessing and recreating the name/path
181
167
  resolveName = (params: ResolveNameParams): string => {
182
168
  if (params.pluginKey) {
183
169
  const names = this.hookForPluginSync({
184
170
  pluginKey: params.pluginKey,
185
171
  hookName: 'resolveName',
186
172
  parameters: [params.name, params.type],
173
+ message: `Resolving name '${params.name}' and type '${params.type}'`,
187
174
  })
188
175
 
189
176
  if (names && names?.length > 1) {
190
- this.logger.emit('debug', [
191
- `Cannot return a name where the 'pluginKey' ${
192
- params.pluginKey ? JSON.stringify(params.pluginKey) : '"'
193
- } is not unique enough\n\nNames: ${JSON.stringify(names, undefined, 2)}\n\nFalling back on the first item.\n`,
194
- ])
177
+ this.logger.emit('debug', {
178
+ date: new Date(),
179
+ logs: [
180
+ `Cannot return a name where the 'pluginKey' ${
181
+ params.pluginKey ? JSON.stringify(params.pluginKey) : '"'
182
+ } is not unique enough\n\nNames: ${JSON.stringify(names, undefined, 2)}\n\nFalling back on the first item.\n`,
183
+ ],
184
+ })
195
185
  }
196
186
 
197
187
  return transformReservedWord(names?.at(0) || params.name)
@@ -200,6 +190,7 @@ export class PluginManager {
200
190
  const name = this.hookFirstSync({
201
191
  hookName: 'resolveName',
202
192
  parameters: [params.name, params.type],
193
+ message: `Resolving name '${params.name}' and type '${params.type}'`,
203
194
  }).result
204
195
 
205
196
  return transformReservedWord(name)
@@ -215,17 +206,21 @@ export class PluginManager {
215
206
  /**
216
207
  * Run a specific hookName for plugin x.
217
208
  */
218
- hookForPlugin<H extends PluginLifecycleHooks>({
209
+ async hookForPlugin<H extends PluginLifecycleHooks>({
219
210
  pluginKey,
220
211
  hookName,
221
212
  parameters,
213
+ message,
222
214
  }: {
223
215
  pluginKey: Plugin['key']
224
216
  hookName: H
225
217
  parameters: PluginParameter<H>
226
- }): Promise<Array<ReturnType<ParseResult<H>> | null>> | null {
218
+ message: string
219
+ }): Promise<Array<ReturnType<ParseResult<H>> | null>> {
227
220
  const plugins = this.getPluginsByKey(hookName, pluginKey)
228
221
 
222
+ this.logger.emit('progress_start', { id: hookName, size: plugins.length, message: 'Running plugins...' })
223
+
229
224
  const promises = plugins
230
225
  .map((plugin) => {
231
226
  return this.#execute<H>({
@@ -233,11 +228,16 @@ export class PluginManager {
233
228
  hookName,
234
229
  parameters,
235
230
  plugin,
231
+ message,
236
232
  })
237
233
  })
238
234
  .filter(Boolean)
239
235
 
240
- return Promise.all(promises)
236
+ const items = await Promise.all(promises)
237
+
238
+ this.logger.emit('progress_stop', { id: hookName })
239
+
240
+ return items
241
241
  }
242
242
  /**
243
243
  * Run a specific hookName for plugin x.
@@ -247,23 +247,28 @@ export class PluginManager {
247
247
  pluginKey,
248
248
  hookName,
249
249
  parameters,
250
+ message,
250
251
  }: {
251
252
  pluginKey: Plugin['key']
252
253
  hookName: H
253
254
  parameters: PluginParameter<H>
255
+ message: string
254
256
  }): Array<ReturnType<ParseResult<H>>> | null {
255
257
  const plugins = this.getPluginsByKey(hookName, pluginKey)
256
258
 
257
- return plugins
259
+ const result = plugins
258
260
  .map((plugin) => {
259
261
  return this.#executeSync<H>({
260
262
  strategy: 'hookFirst',
261
263
  hookName,
262
264
  parameters,
263
265
  plugin,
266
+ message,
264
267
  })
265
268
  })
266
269
  .filter(Boolean)
270
+
271
+ return result
267
272
  }
268
273
 
269
274
  /**
@@ -273,32 +278,41 @@ export class PluginManager {
273
278
  hookName,
274
279
  parameters,
275
280
  skipped,
281
+ message,
276
282
  }: {
277
283
  hookName: H
278
284
  parameters: PluginParameter<H>
279
285
  skipped?: ReadonlySet<Plugin> | null
286
+ message: string
280
287
  }): Promise<SafeParseResult<H>> {
281
- const promises = this.#getSortedPlugins()
282
- .filter((plugin) => {
283
- return skipped ? skipped.has(plugin) : true
284
- })
285
- .map((plugin) => {
286
- return async () => {
287
- const value = await this.#execute<H>({
288
- strategy: 'hookFirst',
289
- hookName,
290
- parameters,
291
- plugin,
292
- })
288
+ const plugins = this.#getSortedPlugins(hookName).filter((plugin) => {
289
+ return skipped ? skipped.has(plugin) : true
290
+ })
293
291
 
294
- return Promise.resolve({
295
- plugin,
296
- result: value,
297
- } as SafeParseResult<H>)
298
- }
299
- })
292
+ this.logger.emit('progress_start', { id: hookName, size: plugins.length })
293
+
294
+ const promises = plugins.map((plugin) => {
295
+ return async () => {
296
+ const value = await this.#execute<H>({
297
+ strategy: 'hookFirst',
298
+ hookName,
299
+ parameters,
300
+ plugin,
301
+ message,
302
+ })
300
303
 
301
- return this.#promiseManager.run('first', promises)
304
+ return Promise.resolve({
305
+ plugin,
306
+ result: value,
307
+ } as SafeParseResult<H>)
308
+ }
309
+ })
310
+
311
+ const result = await this.#promiseManager.run('first', promises)
312
+
313
+ this.logger.emit('progress_stop', { id: hookName })
314
+
315
+ return result
302
316
  }
303
317
 
304
318
  /**
@@ -308,24 +322,26 @@ export class PluginManager {
308
322
  hookName,
309
323
  parameters,
310
324
  skipped,
325
+ message,
311
326
  }: {
312
327
  hookName: H
313
328
  parameters: PluginParameter<H>
314
329
  skipped?: ReadonlySet<Plugin> | null
330
+ message: string
315
331
  }): SafeParseResult<H> {
316
332
  let parseResult: SafeParseResult<H> = null as unknown as SafeParseResult<H>
333
+ const plugins = this.#getSortedPlugins(hookName).filter((plugin) => {
334
+ return skipped ? skipped.has(plugin) : true
335
+ })
317
336
 
318
- for (const plugin of this.#getSortedPlugins()) {
319
- if (skipped?.has(plugin)) {
320
- continue
321
- }
322
-
337
+ for (const plugin of plugins) {
323
338
  parseResult = {
324
339
  result: this.#executeSync<H>({
325
340
  strategy: 'hookFirst',
326
341
  hookName,
327
342
  parameters,
328
343
  plugin,
344
+ message,
329
345
  }),
330
346
  plugin,
331
347
  } as SafeParseResult<H>
@@ -334,6 +350,7 @@ export class PluginManager {
334
350
  break
335
351
  }
336
352
  }
353
+
337
354
  return parseResult
338
355
  }
339
356
 
@@ -343,17 +360,23 @@ export class PluginManager {
343
360
  async hookParallel<H extends PluginLifecycleHooks, TOuput = void>({
344
361
  hookName,
345
362
  parameters,
363
+ message,
346
364
  }: {
347
365
  hookName: H
348
366
  parameters?: Parameters<RequiredPluginLifecycle[H]> | undefined
367
+ message: string
349
368
  }): Promise<Awaited<TOuput>[]> {
350
- const promises = this.#getSortedPlugins().map((plugin) => {
369
+ const plugins = this.#getSortedPlugins(hookName)
370
+ this.logger.emit('progress_start', { id: hookName, size: plugins.length })
371
+
372
+ const promises = plugins.map((plugin) => {
351
373
  return () =>
352
374
  this.#execute({
353
375
  strategy: 'hookParallel',
354
376
  hookName,
355
377
  parameters,
356
378
  plugin,
379
+ message,
357
380
  }) as Promise<TOuput>
358
381
  })
359
382
 
@@ -361,12 +384,14 @@ export class PluginManager {
361
384
 
362
385
  results.forEach((result, index) => {
363
386
  if (isPromiseRejectedResult<Error>(result)) {
364
- const plugin = this.#getSortedPlugins()[index]
387
+ const plugin = this.#getSortedPlugins(hookName)[index]
365
388
 
366
389
  this.#catcher<H>(result.reason, plugin, hookName)
367
390
  }
368
391
  })
369
392
 
393
+ this.logger.emit('progress_stop', { id: hookName })
394
+
370
395
  return results.filter((result) => result.status === 'fulfilled').map((result) => (result as PromiseFulfilledResult<Awaited<TOuput>>).value)
371
396
  }
372
397
 
@@ -377,15 +402,18 @@ export class PluginManager {
377
402
  hookName,
378
403
  parameters,
379
404
  reduce,
405
+ message,
380
406
  }: {
381
407
  hookName: H
382
408
  parameters: PluginParameter<H>
383
409
  reduce: (reduction: Argument0<H>, result: ReturnType<ParseResult<H>>, plugin: Plugin) => PossiblePromise<Argument0<H> | null>
410
+ message: string
384
411
  }): Promise<Argument0<H>> {
385
412
  const [argument0, ...rest] = parameters
413
+ const plugins = this.#getSortedPlugins(hookName)
386
414
 
387
415
  let promise: Promise<Argument0<H>> = Promise.resolve(argument0)
388
- for (const plugin of this.#getSortedPlugins()) {
416
+ for (const plugin of plugins) {
389
417
  promise = promise
390
418
  .then((arg0) => {
391
419
  const value = this.#execute({
@@ -393,6 +421,7 @@ export class PluginManager {
393
421
  hookName,
394
422
  parameters: [arg0, ...rest] as PluginParameter<H>,
395
423
  plugin,
424
+ message,
396
425
  })
397
426
  return value
398
427
  })
@@ -405,32 +434,35 @@ export class PluginManager {
405
434
  /**
406
435
  * Chains plugins
407
436
  */
408
- async hookSeq<H extends PluginLifecycleHooks>({ hookName, parameters }: { hookName: H; parameters?: PluginParameter<H> }): Promise<void> {
409
- const promises = this.#getSortedPlugins().map((plugin) => {
437
+ async hookSeq<H extends PluginLifecycleHooks>({
438
+ hookName,
439
+ parameters,
440
+ message,
441
+ }: { hookName: H; parameters?: PluginParameter<H>; message: string }): Promise<void> {
442
+ const plugins = this.#getSortedPlugins(hookName)
443
+ this.logger.emit('progress_start', { id: hookName, size: plugins.length })
444
+
445
+ const promises = plugins.map((plugin) => {
410
446
  return () =>
411
447
  this.#execute({
412
448
  strategy: 'hookSeq',
413
449
  hookName,
414
450
  parameters,
415
451
  plugin,
452
+ message,
416
453
  })
417
454
  })
418
455
 
419
- return this.#promiseManager.run('seq', promises)
456
+ await this.#promiseManager.run('seq', promises)
457
+
458
+ this.logger.emit('progress_stop', { id: hookName })
420
459
  }
421
460
 
422
461
  #getSortedPlugins(hookName?: keyof PluginLifecycle): Plugin[] {
423
462
  const plugins = [...this.plugins].filter((plugin) => plugin.name !== 'core')
424
463
 
425
464
  if (hookName) {
426
- if (this.logger.logLevel === LogLevel.info) {
427
- const containsHookName = plugins.some((item) => item[hookName])
428
- if (!containsHookName) {
429
- this.logger.emit('warning', `No hook ${hookName} found`)
430
- }
431
- }
432
-
433
- return plugins.filter((item) => item[hookName])
465
+ return plugins.filter((plugin) => hookName in plugin)
434
466
  }
435
467
  // TODO add test case for sorting with pre/post
436
468
 
@@ -462,7 +494,7 @@ export class PluginManager {
462
494
  const [searchPluginName, searchIdentifier] = pluginKey
463
495
 
464
496
  const pluginByPluginName = plugins
465
- .filter((plugin) => plugin[hookName])
497
+ .filter((plugin) => hookName in plugin)
466
498
  .filter((item) => {
467
499
  const [name, identifier] = item.key
468
500
 
@@ -479,12 +511,18 @@ export class PluginManager {
479
511
  if (!pluginByPluginName?.length) {
480
512
  // fallback on the core plugin when there is no match
481
513
 
482
- const corePlugin = plugins.find((plugin) => plugin.name === 'core' && plugin[hookName])
514
+ const corePlugin = plugins.find((plugin) => plugin.name === 'core' && hookName in plugin)
483
515
 
484
516
  if (corePlugin) {
485
- this.logger.emit('debug', [`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`])
517
+ this.logger.emit('debug', {
518
+ date: new Date(),
519
+ logs: [`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`],
520
+ })
486
521
  } else {
487
- this.logger.emit('debug', [`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, no fallback found in the '@kubb/core' plugin`])
522
+ this.logger.emit('debug', {
523
+ date: new Date(),
524
+ logs: [`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, no fallback found in the '@kubb/core' plugin`],
525
+ })
488
526
  }
489
527
  return corePlugin ? [corePlugin] : []
490
528
  }
@@ -496,6 +534,8 @@ export class PluginManager {
496
534
  if (executer) {
497
535
  this.events.emit('executed', executer)
498
536
  this.executed.push(executer)
537
+
538
+ this.logger.emit('progressed', { id: executer.hookName, message: `${executer.plugin.name}: ${executer.message}` })
499
539
  }
500
540
  }
501
541
 
@@ -511,11 +551,13 @@ export class PluginManager {
511
551
  hookName,
512
552
  parameters,
513
553
  plugin,
554
+ message,
514
555
  }: {
515
556
  strategy: Strategy
516
557
  hookName: H
517
558
  parameters: unknown[] | undefined
518
559
  plugin: PluginWithLifeCycle
560
+ message: string
519
561
  }): Promise<ReturnType<ParseResult<H>> | null> | null {
520
562
  const hook = plugin[hookName]
521
563
  let output: unknown
@@ -524,9 +566,12 @@ export class PluginManager {
524
566
  return null
525
567
  }
526
568
 
527
- this.events.emit('execute', { strategy, hookName, parameters, plugin })
569
+ this.events.emit('executing', { strategy, hookName, parameters, plugin, message })
570
+ const promise = new Promise((resolve) => {
571
+ resolve(undefined)
572
+ })
528
573
 
529
- const task = Promise.resolve()
574
+ const task = promise
530
575
  .then(() => {
531
576
  if (typeof hook === 'function') {
532
577
  const possiblePromiseResult = (hook as Function).apply({ ...this.#core.context, plugin }, parameters) as Promise<ReturnType<ParseResult<H>>>
@@ -548,6 +593,7 @@ export class PluginManager {
548
593
  strategy,
549
594
  hookName,
550
595
  plugin,
596
+ message,
551
597
  })
552
598
 
553
599
  return result
@@ -573,11 +619,13 @@ export class PluginManager {
573
619
  hookName,
574
620
  parameters,
575
621
  plugin,
622
+ message,
576
623
  }: {
577
624
  strategy: Strategy
578
625
  hookName: H
579
626
  parameters: PluginParameter<H>
580
627
  plugin: PluginWithLifeCycle
628
+ message: string
581
629
  }): ReturnType<ParseResult<H>> | null {
582
630
  const hook = plugin[hookName]
583
631
  let output: unknown
@@ -586,13 +634,23 @@ export class PluginManager {
586
634
  return null
587
635
  }
588
636
 
589
- this.events.emit('execute', { strategy, hookName, parameters, plugin })
637
+ this.events.emit('executing', { strategy, hookName, parameters, plugin, message })
590
638
 
591
639
  try {
592
640
  if (typeof hook === 'function') {
593
641
  const fn = (hook as Function).apply({ ...this.#core.context, plugin }, parameters) as ReturnType<ParseResult<H>>
594
642
 
595
643
  output = fn
644
+
645
+ this.#addExecutedToCallStack({
646
+ parameters,
647
+ output,
648
+ strategy,
649
+ hookName,
650
+ plugin,
651
+ message,
652
+ })
653
+
596
654
  return fn
597
655
  }
598
656
 
@@ -604,6 +662,7 @@ export class PluginManager {
604
662
  strategy,
605
663
  hookName,
606
664
  plugin,
665
+ message,
607
666
  })
608
667
 
609
668
  return hook
@@ -42,7 +42,7 @@ export function isPromise<T>(result: PossiblePromise<T>): result is Promise<T> {
42
42
  return !!result && typeof (result as Promise<unknown>)?.then === 'function'
43
43
  }
44
44
 
45
- export function isPromiseFulfilledResult<T = unknown>(result: PromiseSettledResult<unknown>): result is PromiseFulfilledResult<T> {
45
+ function isPromiseFulfilledResult<T = unknown>(result: PromiseSettledResult<unknown>): result is PromiseFulfilledResult<T> {
46
46
  return result.status === 'fulfilled'
47
47
  }
48
48
 
@@ -0,0 +1,73 @@
1
+ [
2
+ {
3
+ "path": "src/index.ts",
4
+ "baseName": "index.ts",
5
+ "exports": [
6
+ {
7
+ "path": "./sub/hello.ts"
8
+ },
9
+ {
10
+ "path": "./sub/world.ts"
11
+ },
12
+ {
13
+ "path": "./test.ts"
14
+ }
15
+ ],
16
+ "sources": [
17
+ {
18
+ "name": "test",
19
+ "value": "",
20
+ "isExportable": false,
21
+ "isIndexable": false
22
+ },
23
+ {
24
+ "name": "hello",
25
+ "value": "",
26
+ "isExportable": false,
27
+ "isIndexable": false
28
+ },
29
+ {
30
+ "name": "world",
31
+ "value": "",
32
+ "isExportable": false,
33
+ "isIndexable": false
34
+ }
35
+ ],
36
+ "id": "feabc02536bd6630458e734990f7e2a21a55c469",
37
+ "name": "index",
38
+ "extname": ".ts",
39
+ "imports": [],
40
+ "meta": {}
41
+ },
42
+ {
43
+ "path": "src/sub/index.ts",
44
+ "baseName": "index.ts",
45
+ "exports": [
46
+ {
47
+ "path": "./hello.ts"
48
+ },
49
+ {
50
+ "path": "./world.ts"
51
+ }
52
+ ],
53
+ "sources": [
54
+ {
55
+ "name": "hello",
56
+ "value": "",
57
+ "isExportable": false,
58
+ "isIndexable": false
59
+ },
60
+ {
61
+ "name": "world",
62
+ "value": "",
63
+ "isExportable": false,
64
+ "isIndexable": false
65
+ }
66
+ ],
67
+ "id": "c67967bd2363dd9637437671f6fe1ed146debdbf",
68
+ "name": "index",
69
+ "extname": ".ts",
70
+ "imports": [],
71
+ "meta": {}
72
+ }
73
+ ]