@kubb/core 2.0.0-beta.12 → 2.0.0-beta.14

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 (73) hide show
  1. package/dist/chunk-35FDNG5F.cjs +71 -0
  2. package/dist/chunk-35FDNG5F.cjs.map +1 -0
  3. package/dist/chunk-7CNPSL5M.js +85 -0
  4. package/dist/chunk-7CNPSL5M.js.map +1 -0
  5. package/dist/chunk-DKYWBKNH.js +18 -0
  6. package/dist/chunk-DKYWBKNH.js.map +1 -0
  7. package/dist/chunk-EZSRGYAY.js +128 -0
  8. package/dist/chunk-EZSRGYAY.js.map +1 -0
  9. package/dist/chunk-GBX7KRCX.cjs +162 -0
  10. package/dist/chunk-GBX7KRCX.cjs.map +1 -0
  11. package/dist/chunk-ICRPOCV4.cjs +2290 -0
  12. package/dist/chunk-ICRPOCV4.cjs.map +1 -0
  13. package/dist/chunk-LAS7UYTK.cjs +129 -0
  14. package/dist/chunk-LAS7UYTK.cjs.map +1 -0
  15. package/dist/chunk-LJHT3DNH.js +67 -0
  16. package/dist/chunk-LJHT3DNH.js.map +1 -0
  17. package/dist/chunk-MM42A6GN.cjs +91 -0
  18. package/dist/chunk-MM42A6GN.cjs.map +1 -0
  19. package/dist/chunk-SRGTC4FJ.js +129 -0
  20. package/dist/chunk-SRGTC4FJ.js.map +1 -0
  21. package/dist/chunk-ST7GHHSU.cjs +104 -0
  22. package/dist/chunk-ST7GHHSU.cjs.map +1 -0
  23. package/dist/chunk-U4C2WTCI.cjs +131 -0
  24. package/dist/chunk-U4C2WTCI.cjs.map +1 -0
  25. package/dist/chunk-UIQUKFF4.js +155 -0
  26. package/dist/chunk-UIQUKFF4.js.map +1 -0
  27. package/dist/chunk-WTSDXEWD.js +71 -0
  28. package/dist/chunk-WTSDXEWD.js.map +1 -0
  29. package/dist/fs.cjs +20 -2372
  30. package/dist/fs.cjs.map +1 -1
  31. package/dist/fs.d.cts +1 -1
  32. package/dist/fs.d.ts +1 -1
  33. package/dist/fs.js +4 -2373
  34. package/dist/fs.js.map +1 -1
  35. package/dist/index.cjs +930 -3261
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +17 -15
  38. package/dist/index.d.ts +17 -15
  39. package/dist/index.js +208 -3490
  40. package/dist/index.js.map +1 -1
  41. package/dist/logger.cjs +19 -141
  42. package/dist/logger.cjs.map +1 -1
  43. package/dist/logger.d.cts +1 -0
  44. package/dist/logger.d.ts +1 -0
  45. package/dist/logger.js +3 -135
  46. package/dist/logger.js.map +1 -1
  47. package/dist/transformers.cjs +40 -208
  48. package/dist/transformers.cjs.map +1 -1
  49. package/dist/transformers.js +15 -201
  50. package/dist/transformers.js.map +1 -1
  51. package/dist/utils.cjs +22 -524
  52. package/dist/utils.cjs.map +1 -1
  53. package/dist/utils.d.cts +0 -1
  54. package/dist/utils.d.ts +0 -1
  55. package/dist/utils.js +11 -517
  56. package/dist/utils.js.map +1 -1
  57. package/dist/{write-46ytbnu9.d.cts → write-A6VgHkYA.d.cts} +4 -1
  58. package/dist/{write-46ytbnu9.d.ts → write-A6VgHkYA.d.ts} +4 -1
  59. package/package.json +9 -8
  60. package/src/BarrelManager.ts +3 -3
  61. package/src/FileManager.ts +66 -62
  62. package/src/PluginManager.ts +11 -18
  63. package/src/build.ts +57 -32
  64. package/src/fs/clean.ts +2 -2
  65. package/src/fs/read.ts +1 -0
  66. package/src/fs/write.ts +40 -24
  67. package/src/logger.ts +10 -0
  68. package/src/utils/FunctionParams.ts +2 -2
  69. package/src/utils/URLPath.ts +5 -5
  70. package/src/utils/index.ts +0 -2
  71. package/dist/Queue-2-6pMcCx.d.cts +0 -32
  72. package/dist/Queue-2-6pMcCx.d.ts +0 -32
  73. package/src/utils/Queue.ts +0 -110
@@ -2,6 +2,9 @@ declare function getRelativePath(rootDir?: string | null, filePath?: string | nu
2
2
  declare function read(path: string): Promise<string>;
3
3
  declare function readSync(path: string): string;
4
4
 
5
- declare function write(data: string, path: string): Promise<string | undefined>;
5
+ type Options = {
6
+ sanity?: boolean;
7
+ };
8
+ declare function write(data: string, path: string, options?: Options): Promise<string | undefined>;
6
9
 
7
10
  export { readSync as a, getRelativePath as g, read as r, write as w };
@@ -2,6 +2,9 @@ declare function getRelativePath(rootDir?: string | null, filePath?: string | nu
2
2
  declare function read(path: string): Promise<string>;
3
3
  declare function readSync(path: string): string;
4
4
 
5
- declare function write(data: string, path: string): Promise<string | undefined>;
5
+ type Options = {
6
+ sanity?: boolean;
7
+ };
8
+ declare function write(data: string, path: string, options?: Options): Promise<string | undefined>;
6
9
 
7
10
  export { readSync as a, getRelativePath as g, read as r, write as w };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/core",
3
- "version": "2.0.0-beta.12",
3
+ "version": "2.0.0-beta.14",
4
4
  "description": "Generator core",
5
5
  "keywords": [
6
6
  "typescript",
@@ -62,27 +62,28 @@
62
62
  "!/**/__tests__/**"
63
63
  ],
64
64
  "dependencies": {
65
+ "change-case": "^5.3.0",
65
66
  "directory-tree": "^3.5.1",
67
+ "find-up": "^7.0.0",
66
68
  "js-runtime": "^0.0.7",
67
69
  "natural-orderby": "^3.0.2",
70
+ "p-queue": "^7.4.1",
68
71
  "seedrandom": "^3.0.5",
69
72
  "semver": "^7.5.4",
70
- "@kubb/parser": "2.0.0-beta.12",
71
- "@kubb/types": "2.0.0-beta.12"
73
+ "fs-extra": "^11.2.0",
74
+ "@kubb/parser": "2.0.0-beta.14",
75
+ "@kubb/types": "2.0.0-beta.14"
72
76
  },
73
77
  "devDependencies": {
74
78
  "@types/fs-extra": "^11.0.4",
75
79
  "@types/lodash.isequal": "4.5.6",
76
- "@types/react": "^18.2.41",
80
+ "@types/react": "^18.2.42",
77
81
  "@types/seedrandom": "^3.0.8",
78
82
  "@types/semver": "^7.5.6",
79
- "change-case": "^5.2.0",
80
83
  "eslint": "^8.55.0",
81
- "find-up": "^7.0.0",
82
- "tinyrainbow": "^1.1.0",
83
- "fs-extra": "^11.2.0",
84
84
  "lodash.isequal": "^4.5.0",
85
85
  "ora": "^7.0.1",
86
+ "tinyrainbow": "^1.1.1",
86
87
  "tsup": "^8.0.1",
87
88
  "typescript": "^5.3.2",
88
89
  "@kubb/eslint-config": "1.1.8",
@@ -1,6 +1,6 @@
1
1
  import path from 'path'
2
2
 
3
- import transformers from './transformers/index.ts'
3
+ import { trimExtName } from './transformers/trim.ts'
4
4
  import { TreeNode } from './utils/TreeNode.ts'
5
5
 
6
6
  import type { DirectoryTreeOptions } from 'directory-tree'
@@ -51,7 +51,7 @@ export class BarrelManager {
51
51
  const exports: KubbFile.Export[] = treeNode.children
52
52
  .filter(Boolean)
53
53
  .map((file) => {
54
- const importPath: string = file.data.type === 'directory' ? `./${file.data.name}/index` : `./${transformers.trimExtName(file.data.name)}`
54
+ const importPath: string = file.data.type === 'directory' ? `./${file.data.name}/index` : `./${trimExtName(file.data.name)}`
55
55
 
56
56
  if (importPath.endsWith('index') && file.data.type === 'file') {
57
57
  return undefined
@@ -79,7 +79,7 @@ export class BarrelManager {
79
79
  const indexPath = path.resolve(treeNode.data.path, 'index.ts')
80
80
  const importPath = treeNodeChild.data.type === 'directory'
81
81
  ? `./${treeNodeChild.data.name}/index`
82
- : `./${transformers.trimExtName(treeNodeChild.data.name)}`
82
+ : `./${trimExtName(treeNodeChild.data.name)}`
83
83
 
84
84
  const exports = [
85
85
  {
@@ -7,17 +7,17 @@ import * as factory from '@kubb/parser/factory'
7
7
 
8
8
  import isEqual from 'lodash.isequal'
9
9
  import { orderBy } from 'natural-orderby'
10
+ import PQueue from 'p-queue'
10
11
 
11
12
  import { getRelativePath, read } from './fs/read.ts'
12
13
  import { write } from './fs/write.ts'
13
- import transformers from './transformers/index.ts'
14
- import { timeout } from './utils/timeout.ts'
14
+ import { searchAndReplace } from './transformers/searchAndReplace.ts'
15
+ import { trimExtName } from './transformers/trim.ts'
15
16
  import { BarrelManager } from './BarrelManager.ts'
16
17
 
17
18
  import type { GreaterThan } from '@kubb/types'
18
19
  import type { BarrelManagerOptions } from './BarrelManager.ts'
19
20
  import type { KubbPlugin } from './types.ts'
20
- import type { Queue, QueueJob } from './utils/Queue.ts'
21
21
 
22
22
  type BasePath<T extends string = string> = `${T}/`
23
23
 
@@ -191,31 +191,19 @@ type AddIndexesProps = {
191
191
  }
192
192
 
193
193
  type Options = {
194
- queue?: Queue
195
- task?: QueueJob<KubbFile.ResolvedFile>
196
- /**
197
- * Timeout between writes
198
- */
199
- timeout?: number
194
+ queue?: PQueue
195
+ task?: (file: KubbFile.ResolvedFile) => Promise<KubbFile.ResolvedFile>
200
196
  }
201
197
 
202
198
  export class FileManager {
203
199
  #cache: Map<KubbFile.Path, CacheItem[]> = new Map()
204
200
 
205
- #task?: QueueJob<KubbFile.ResolvedFile>
206
- #isWriting = false
207
- /**
208
- * Timeout between writes
209
- */
210
- #timeout: number = 0
211
- #queue?: Queue
212
-
213
- constructor(options?: Options) {
214
- if (options) {
215
- this.#task = options.task
216
- this.#queue = options.queue
217
- this.#timeout = options.timeout || 0
218
- }
201
+ #task: Options['task']
202
+ #queue: PQueue
203
+
204
+ constructor({ task = async (file) => file, queue = new PQueue() }: Options = {}) {
205
+ this.#task = task
206
+ this.#queue = queue
219
207
 
220
208
  return this
221
209
  }
@@ -229,21 +217,13 @@ export class FileManager {
229
217
  return files
230
218
  }
231
219
  get isExecuting(): boolean {
232
- return this.#queue?.hasJobs ?? this.#isWriting ?? false
233
- }
234
-
235
- #validate(file: KubbFile.File): void {
236
- if (!file.path.toLowerCase().endsWith(file.baseName.toLowerCase())) {
237
- throw new Error(`${file.path} should end with the baseName ${file.baseName}`)
238
- }
220
+ return this.#queue.size !== 0 && this.#queue.pending !== 0
239
221
  }
240
222
 
241
223
  async add<T extends Array<KubbFile.File> = Array<KubbFile.File>>(
242
224
  ...files: T
243
225
  ): AddResult<T> {
244
- const promises = files.map((file) => {
245
- // this.#validate(file)
246
-
226
+ const promises = combineFiles(files).map((file) => {
247
227
  if (file.override) {
248
228
  return this.#add(file)
249
229
  }
@@ -262,20 +242,16 @@ export class FileManager {
262
242
 
263
243
  async #add(file: KubbFile.File): Promise<KubbFile.ResolvedFile> {
264
244
  const controller = new AbortController()
265
- const resolvedFile: KubbFile.ResolvedFile = { id: crypto.randomUUID(), name: transformers.trimExtName(file.baseName), ...file }
245
+ const resolvedFile: KubbFile.ResolvedFile = { id: crypto.randomUUID(), name: trimExtName(file.baseName), ...file }
266
246
 
267
247
  this.#cache.set(resolvedFile.path, [{ cancel: () => controller.abort(), ...resolvedFile }])
268
248
 
269
- if (this.#queue) {
270
- await this.#queue.run(
271
- async () => {
272
- return this.#task?.(resolvedFile)
273
- },
274
- { controller },
275
- )
276
- }
277
-
278
- return resolvedFile
249
+ return this.#queue.add(
250
+ async () => {
251
+ return this.#task?.(resolvedFile)
252
+ },
253
+ { signal: controller.signal },
254
+ ) as Promise<KubbFile.ResolvedFile>
279
255
  }
280
256
 
281
257
  async #addOrAppend(file: KubbFile.File): Promise<KubbFile.ResolvedFile> {
@@ -303,7 +279,7 @@ export class FileManager {
303
279
  return undefined
304
280
  }
305
281
 
306
- const exportPath = output.path.startsWith('./') ? output.path : `./${output.path}`
282
+ const exportPath = output.path.startsWith('./') ? trimExtName(output.path) : `./${trimExtName(output.path)}`
307
283
  const barrelManager = new BarrelManager({ extName: output.extName, ...options })
308
284
  const files = barrelManager.getIndexes(resolve(root, output.path))
309
285
 
@@ -320,11 +296,11 @@ export class FileManager {
320
296
  ? {
321
297
  name: output.exportAs,
322
298
  asAlias: true,
323
- path: exportPath,
299
+ path: output.extName ? `${exportPath}${output.extName}` : exportPath,
324
300
  isTypeOnly: options.isTypeOnly,
325
301
  }
326
302
  : {
327
- path: exportPath,
303
+ path: output.extName ? `${exportPath}${output.extName}` : exportPath,
328
304
  isTypeOnly: options.isTypeOnly,
329
305
  },
330
306
  ],
@@ -368,18 +344,7 @@ export class FileManager {
368
344
  }
369
345
 
370
346
  async write(...params: Parameters<typeof write>): Promise<string | undefined> {
371
- if (!this.#isWriting) {
372
- this.#isWriting = true
373
-
374
- const text = await write(...params)
375
-
376
- this.#isWriting = false
377
- return text
378
- }
379
-
380
- await timeout(this.#timeout)
381
-
382
- return this.write(...params)
347
+ return write(...params)
383
348
  }
384
349
 
385
350
  async read(...params: Parameters<typeof read>): Promise<string> {
@@ -391,6 +356,10 @@ export class FileManager {
391
356
  static getSource<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(file: KubbFile.File<TMeta>): string {
392
357
  return getSource<TMeta>(file)
393
358
  }
359
+
360
+ static combineFiles<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(files: Array<KubbFile.File<TMeta> | null>): Array<KubbFile.File<TMeta>> {
361
+ return combineFiles<TMeta>(files)
362
+ }
394
363
  static getMode(path: string | undefined | null): KubbFile.Mode {
395
364
  if (!path) {
396
365
  return 'directory'
@@ -407,6 +376,41 @@ export class FileManager {
407
376
  }
408
377
  }
409
378
 
379
+ function combineFiles<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(
380
+ files: Array<KubbFile.File<TMeta> | null>,
381
+ ): Array<KubbFile.File<TMeta>> {
382
+ return files.filter(Boolean).reduce((acc, file: KubbFile.File<TMeta>) => {
383
+ const prevIndex = acc.findIndex((item) => item.path === file.path)
384
+
385
+ if (prevIndex === -1) {
386
+ return [...acc, file]
387
+ }
388
+
389
+ const prev = acc[prevIndex]
390
+
391
+ if (prev && file.override) {
392
+ acc[prevIndex] = {
393
+ imports: [],
394
+ exports: [],
395
+ ...file,
396
+ }
397
+ return acc
398
+ }
399
+
400
+ if (prev) {
401
+ acc[prevIndex] = {
402
+ ...file,
403
+ source: prev.source && file.source ? `${prev.source}\n${file.source}` : '',
404
+ imports: [...(prev.imports || []), ...(file.imports || [])],
405
+ exports: [...(prev.exports || []), ...(file.exports || [])],
406
+ env: { ...(prev.env || {}), ...(file.env || {}) },
407
+ }
408
+ }
409
+
410
+ return acc
411
+ }, [] as Array<KubbFile.File<TMeta>>)
412
+ }
413
+
410
414
  export function getSource<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(file: KubbFile.File<TMeta>): string {
411
415
  if (!FileManager.isExtensionAllowed(file.baseName)) {
412
416
  return file.source
@@ -418,7 +422,7 @@ export function getSource<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMet
418
422
  const importNodes = imports.filter(item => {
419
423
  // isImportNotNeeded
420
424
  // trim extName
421
- return item.path !== transformers.trimExtName(file.path)
425
+ return item.path !== trimExtName(file.path)
422
426
  }).map((item) => {
423
427
  return factory.createImportDeclaration({
424
428
  name: item.name,
@@ -555,9 +559,9 @@ function getEnvSource(source: string, env: NodeJS.ProcessEnv | undefined): strin
555
559
  }
556
560
 
557
561
  if (typeof replaceBy === 'string') {
558
- prev = transformers.searchAndReplace({ text: prev.replaceAll(`process.env.${key}`, replaceBy), replaceBy, prefix: 'process.env', key })
562
+ prev = searchAndReplace({ text: prev.replaceAll(`process.env.${key}`, replaceBy), replaceBy, prefix: 'process.env', key })
559
563
  // removes `declare const ...`
560
- prev = transformers.searchAndReplace({ text: prev.replaceAll(new RegExp(`(declare const).*\n`, 'ig'), ''), replaceBy, key })
564
+ prev = searchAndReplace({ text: prev.replaceAll(new RegExp(`(declare const).*\n`, 'ig'), ''), replaceBy, key })
561
565
  }
562
566
 
563
567
  return prev
@@ -1,8 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/ban-types, @typescript-eslint/no-unsafe-argument */
2
2
 
3
+ import PQueue from 'p-queue'
4
+
3
5
  import { transformReservedWord } from './transformers/transformReservedWord.ts'
4
6
  import { EventEmitter } from './utils/EventEmitter.ts'
5
- import { Queue } from './utils/Queue.ts'
6
7
  import { setUniqueName } from './utils/uniqueName.ts'
7
8
  import { ValidationPluginError } from './errors.ts'
8
9
  import { FileManager } from './FileManager.ts'
@@ -29,7 +30,6 @@ import type {
29
30
  ResolveNameParams,
30
31
  ResolvePathParams,
31
32
  } from './types.ts'
32
- import type { QueueJob } from './utils/Queue.ts'
33
33
 
34
34
  type RequiredPluginLifecycle = Required<PluginLifecycle>
35
35
 
@@ -64,11 +64,7 @@ type Options = {
64
64
  /**
65
65
  * Task for the FileManager
66
66
  */
67
- task: QueueJob<KubbFile.ResolvedFile>
68
- /**
69
- * Timeout between writes in the FileManager
70
- */
71
- writeTimeout?: number
67
+ task: (file: KubbFile.ResolvedFile) => Promise<KubbFile.ResolvedFile>
72
68
  }
73
69
 
74
70
  type Events = {
@@ -82,7 +78,6 @@ export class PluginManager {
82
78
  readonly fileManager: FileManager
83
79
  readonly events: EventEmitter<Events> = new EventEmitter()
84
80
 
85
- readonly queue: Queue
86
81
  readonly config: KubbConfig
87
82
 
88
83
  readonly executed: Array<Executer> = []
@@ -92,11 +87,13 @@ export class PluginManager {
92
87
  readonly #usedPluginNames: Record<string, number> = {}
93
88
  readonly #promiseManager: PromiseManager
94
89
 
90
+ readonly queue: PQueue
91
+
95
92
  constructor(config: KubbConfig, options: Options) {
96
93
  this.config = config
97
94
  this.logger = options.logger
98
- this.queue = new Queue(100, this.logger.logLevel === LogLevel.debug)
99
- this.fileManager = new FileManager({ task: options.task, queue: this.queue, timeout: options.writeTimeout })
95
+ this.queue = new PQueue({ concurrency: 1 })
96
+ this.fileManager = new FileManager({ task: options.task, queue: this.queue })
100
97
  this.#promiseManager = new PromiseManager({ nullCheck: (state: SafeParseResult<'resolveName'> | null) => !!state?.result })
101
98
 
102
99
  const plugins = config.plugins || []
@@ -130,7 +127,7 @@ export class PluginManager {
130
127
  })
131
128
 
132
129
  if (paths && paths?.length > 1 && this.logger.logLevel === LogLevel.debug) {
133
- this.logger.warn(
130
+ this.logger.debug(
134
131
  `Cannot return a path where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough\n\nPaths: ${
135
132
  JSON.stringify(paths, undefined, 2)
136
133
  }\n\nFalling back on the first item.\n`,
@@ -153,7 +150,7 @@ export class PluginManager {
153
150
  })
154
151
 
155
152
  if (names && names?.length > 1 && this.logger.logLevel === LogLevel.debug) {
156
- this.logger.warn(
153
+ this.logger.debug(
157
154
  `Cannot return a name where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough\n\nNames: ${
158
155
  JSON.stringify(names, undefined, 2)
159
156
  }\n\nFalling back on the first item.\n`,
@@ -442,9 +439,9 @@ export class PluginManager {
442
439
 
443
440
  if (this.logger.logLevel === LogLevel.debug) {
444
441
  if (corePlugin) {
445
- this.logger.warn(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`)
442
+ this.logger.debug(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`)
446
443
  } else {
447
- this.logger.warn(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, no fallback found in the '@kubb/core' plugin`)
444
+ this.logger.debug(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, no fallback found in the '@kubb/core' plugin`)
448
445
  }
449
446
  }
450
447
 
@@ -594,10 +591,6 @@ export class PluginManager {
594
591
 
595
592
  const key = [plugin.name, usedPluginNames[plugin.name]].filter(Boolean) as [typeof plugin.name, string]
596
593
 
597
- if (plugin.name !== 'core' && usedPluginNames[plugin.name]! >= 2) {
598
- pluginManager.logger.warn('Using multiple of the same plugin is an experimental feature')
599
- }
600
-
601
594
  // default transform
602
595
  if (!plugin.transform) {
603
596
  plugin.transform = function transform(code) {
package/src/build.ts CHANGED
@@ -12,7 +12,6 @@ import { isPromise } from './PromiseManager.ts'
12
12
  import type { KubbFile } from './FileManager.ts'
13
13
  import type { Logger } from './logger.ts'
14
14
  import type { KubbPlugin, PluginContext, PluginParameter, TransformResult } from './types.ts'
15
- import type { QueueJob } from './utils/Queue.ts'
16
15
 
17
16
  type BuildOptions = {
18
17
  config: PluginContext['config']
@@ -42,6 +41,7 @@ async function transformReducer(
42
41
 
43
42
  async function setup(options: BuildOptions): Promise<PluginManager> {
44
43
  const { config, logger = createLogger({ logLevel: LogLevel.silent }) } = options
44
+ let count = 0
45
45
 
46
46
  try {
47
47
  if (isInputPath(config) && !new URLPath(config.input.path).isURL) {
@@ -62,48 +62,53 @@ async function setup(options: BuildOptions): Promise<PluginManager> {
62
62
  await clean(config.output.path)
63
63
  }
64
64
 
65
- const queueTask = async (file: KubbFile.File) => {
65
+ const task = async (file: KubbFile.ResolvedFile): Promise<KubbFile.ResolvedFile> => {
66
66
  const { path } = file
67
67
 
68
- let code: string | null = FileManager.getSource(file)
68
+ let source: string | null = FileManager.getSource(file)
69
69
 
70
70
  const { result: loadedResult } = await pluginManager.hookFirst({
71
71
  hookName: 'load',
72
72
  parameters: [path],
73
73
  })
74
74
  if (loadedResult && isPromise(loadedResult)) {
75
- code = await loadedResult
75
+ source = await loadedResult
76
76
  }
77
77
  if (loadedResult && !isPromise(loadedResult)) {
78
- code = loadedResult
78
+ source = loadedResult
79
79
  }
80
80
 
81
- if (code) {
82
- const transformedCode = await pluginManager.hookReduceArg0({
81
+ if (source) {
82
+ source = await pluginManager.hookReduceArg0({
83
83
  hookName: 'transform',
84
- parameters: [code, path],
84
+ parameters: [source, path],
85
85
  reduce: transformReducer,
86
86
  })
87
87
 
88
88
  if (config.output.write || config.output.write === undefined) {
89
89
  if (file.meta?.pluginKey) {
90
90
  // run only for pluginKey defined in the meta of the file
91
- return pluginManager.hookForPlugin({
91
+ await pluginManager.hookForPlugin({
92
92
  pluginKey: file.meta?.pluginKey,
93
93
  hookName: 'writeFile',
94
- parameters: [transformedCode, path],
94
+ parameters: [source, path],
95
95
  })
96
96
  }
97
97
 
98
- return pluginManager.hookFirst({
98
+ await pluginManager.hookFirst({
99
99
  hookName: 'writeFile',
100
- parameters: [transformedCode, path],
100
+ parameters: [source, path],
101
101
  })
102
102
  }
103
103
  }
104
+
105
+ return {
106
+ ...file,
107
+ source: source || '',
108
+ }
104
109
  }
105
110
 
106
- const pluginManager = new PluginManager(config, { logger, task: queueTask as QueueJob<KubbFile.ResolvedFile>, writeTimeout: 0 })
111
+ const pluginManager = new PluginManager(config, { logger, task })
107
112
 
108
113
  pluginManager.on('execute', (executer) => {
109
114
  const { hookName, parameters, plugin } = executer
@@ -111,40 +116,60 @@ async function setup(options: BuildOptions): Promise<PluginManager> {
111
116
  if (hookName === 'writeFile' && logger.spinner) {
112
117
  const [code] = parameters as PluginParameter<'writeFile'>
113
118
 
114
- if (logger.logLevel === LogLevel.info) {
115
- logger.spinner.start(`💾 Writing`)
116
- }
117
-
118
119
  if (logger.logLevel === LogLevel.debug) {
119
- logger.info(`PluginKey ${c.dim(JSON.stringify(plugin.key))} \nwith source\n\n${code}`)
120
+ logger.debug(`PluginKey ${c.dim(JSON.stringify(plugin.key))} \nwith source\n\n${code}`)
120
121
  }
121
122
  }
122
123
  })
123
124
 
124
- pluginManager.on('executed', (executer) => {
125
- const { hookName, plugin, output, parameters } = executer
126
- const messsage = `${randomCliColour(plugin.name)} Executing ${hookName}`
125
+ pluginManager.queue.on('add', () => {
126
+ if (logger.logLevel !== LogLevel.info) {
127
+ return
128
+ }
127
129
 
128
- if (logger.logLevel === LogLevel.info && logger.spinner) {
129
- if (hookName === 'writeFile') {
130
- const [_code, path] = parameters as PluginParameter<'writeFile'>
130
+ if (logger.spinner && count === 0) {
131
+ logger.spinner?.start(`💾 Writing`)
132
+ }
133
+ })
131
134
 
132
- logger.spinner.suffixText = c.dim(path)
133
- } else {
134
- logger.spinner.suffixText = messsage
135
- }
135
+ pluginManager.queue.on('active', () => {
136
+ if (logger.logLevel !== LogLevel.info) {
137
+ return
136
138
  }
137
139
 
140
+ if (logger.spinner && pluginManager.queue.size > 0) {
141
+ const text = `Item: ${count} Size: ${pluginManager.queue.size} Pending: ${pluginManager.queue.pending}`
142
+
143
+ logger.spinner.suffixText = c.dim(text)
144
+ }
145
+ ;++count
146
+ })
147
+
148
+ pluginManager.queue.on('completed', () => {
149
+ if (logger.logLevel !== LogLevel.info) {
150
+ return
151
+ }
152
+
153
+ if (logger.spinner) {
154
+ const text = `Item: ${count} Size: ${pluginManager.queue.size} Pending: ${pluginManager.queue.pending}`
155
+
156
+ logger.spinner.suffixText = c.dim(text)
157
+ }
158
+ })
159
+
160
+ pluginManager.on('executed', (executer) => {
161
+ const { hookName, plugin, output, parameters } = executer
162
+
138
163
  if (logger.logLevel === LogLevel.debug) {
139
- logger.info(messsage)
140
164
  const logs = [
165
+ `${randomCliColour(plugin.name)} Executing ${hookName}`,
141
166
  parameters && `${c.bgWhite(`Parameters`)} ${randomCliColour(plugin.name)} ${hookName}`,
142
167
  JSON.stringify(parameters, undefined, 2),
143
168
  output && `${c.bgWhite('Output')} ${randomCliColour(plugin.name)} ${hookName}`,
144
169
  output,
145
170
  ].filter(Boolean)
146
171
 
147
- console.log(logs.join('\n'))
172
+ logger.debug(logs.join('\n'))
148
173
  }
149
174
  })
150
175
 
@@ -163,7 +188,7 @@ export async function build(options: BuildOptions): Promise<BuildOutput> {
163
188
 
164
189
  await pluginManager.hookParallel({ hookName: 'buildEnd' })
165
190
 
166
- if (!fileManager.isExecuting && logger.spinner) {
191
+ if (logger.logLevel === LogLevel.info && logger.spinner) {
167
192
  logger.spinner.suffixText = ''
168
193
  logger.spinner.succeed(`💾 Writing completed`)
169
194
  }
@@ -184,7 +209,7 @@ export async function safeBuild(options: BuildOptions): Promise<BuildOutput> {
184
209
 
185
210
  await pluginManager.hookParallel({ hookName: 'buildEnd' })
186
211
 
187
- if (!fileManager.isExecuting && logger.spinner) {
212
+ if (logger.logLevel === LogLevel.info && logger.spinner) {
188
213
  logger.spinner.suffixText = ''
189
214
  logger.spinner.succeed(`💾 Writing completed`)
190
215
  }
package/src/fs/clean.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { remove } from 'fs-extra'
1
+ import fs from 'fs-extra'
2
2
 
3
3
  export async function clean(path: string): Promise<void> {
4
- return remove(path)
4
+ return fs.remove(path)
5
5
  }
package/src/fs/read.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { basename, extname, relative } from 'node:path'
2
2
 
3
3
  import fs from 'fs-extra'
4
+
4
5
  import { switcher } from 'js-runtime'
5
6
 
6
7
  function slash(path: string, platform: 'windows' | 'mac' | 'linux' = 'linux') {