@kubb/core 1.1.13 → 1.2.1

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.
package/dist/index.js CHANGED
@@ -3,8 +3,14 @@ import crypto from 'node:crypto';
3
3
  import fs from 'fs-extra';
4
4
  import pathParser2 from 'node:path';
5
5
  import { camelCase, camelCaseTransformMerge } from 'change-case';
6
+ import { performance } from 'node:perf_hooks';
6
7
  import { rimraf } from 'rimraf';
7
8
  import dirTree from 'directory-tree';
9
+ import mod from 'node:module';
10
+ import { pathToFileURL } from 'node:url';
11
+ import pc2 from 'picocolors';
12
+ export { default as pc } from 'picocolors';
13
+ import seedrandom from 'seedrandom';
8
14
  import { createImportDeclaration, print, createExportDeclaration } from '@kubb/ts-codegen';
9
15
 
10
16
  createRequire(import.meta.url);
@@ -13,6 +19,12 @@ createRequire(import.meta.url);
13
19
  function isPromise(result) {
14
20
  return typeof result?.then === "function";
15
21
  }
22
+ function isPromiseFulfilledResult(result) {
23
+ return result.status === "fulfilled";
24
+ }
25
+ function isPromiseRejectedResult(result) {
26
+ return result.status === "rejected";
27
+ }
16
28
  async function safeWriteFileToPath(path, data) {
17
29
  const passedPath = pathParser2.dirname(pathParser2.resolve(path));
18
30
  await fs.mkdir(passedPath, { recursive: true });
@@ -155,18 +167,18 @@ async function timeout(ms) {
155
167
  }, ms);
156
168
  });
157
169
  }
158
-
159
- // src/utils/Queue.ts
160
170
  var Queue = class {
161
171
  queue = [];
162
172
  workerCount = 0;
163
173
  maxParallel;
164
- constructor(maxParallel) {
174
+ debug = false;
175
+ constructor(maxParallel, debug = false) {
165
176
  this.maxParallel = maxParallel;
177
+ this.debug = debug;
166
178
  }
167
- run(task) {
179
+ run(task, options = { name: crypto.randomUUID(), description: "" }) {
168
180
  return new Promise((resolve, reject) => {
169
- const item = { reject, resolve, task };
181
+ const item = { reject, resolve, task, name: options.name, description: options.description || options.name };
170
182
  this.queue.push(item);
171
183
  this.work();
172
184
  });
@@ -178,8 +190,17 @@ var Queue = class {
178
190
  this.workerCount++;
179
191
  let entry;
180
192
  while (entry = this.queue.shift()) {
181
- const { reject, resolve, task } = entry;
182
- task().then((result) => resolve(result)).catch((err) => reject(err));
193
+ const { reject, resolve, task, name, description } = entry;
194
+ if (this.debug) {
195
+ performance.mark(name + "_start");
196
+ }
197
+ task().then((result) => {
198
+ resolve(result);
199
+ if (this.debug) {
200
+ performance.mark(name + "_stop");
201
+ performance.measure(description, name + "_start", name + "_stop");
202
+ }
203
+ }).catch((err) => reject(err));
183
204
  }
184
205
  this.workerCount--;
185
206
  }
@@ -402,6 +423,31 @@ function getStackTrace(belowFn) {
402
423
 
403
424
  // src/utils/uniqueId.ts
404
425
  var uniqueId = ((counter) => (str = "") => `${str}${++counter}`)(0);
426
+ var SLASHES = /* @__PURE__ */ new Set(["/", "\\"]);
427
+ function normalizeDirectory(directory) {
428
+ if (!SLASHES.has(directory[directory.length - 1])) {
429
+ return `${directory}/`;
430
+ }
431
+ return directory;
432
+ }
433
+ function getLocation(path, cwd) {
434
+ let location = path;
435
+ if (cwd) {
436
+ const require2 = mod.createRequire(normalizeDirectory(cwd));
437
+ location = require2.resolve(path);
438
+ }
439
+ return location;
440
+ }
441
+ async function importModule(path, cwd) {
442
+ try {
443
+ const location = getLocation(path, cwd);
444
+ const module = await import(pathToFileURL(location).href);
445
+ return module?.default ?? module;
446
+ } catch (e) {
447
+ console.log(e);
448
+ return void 0;
449
+ }
450
+ }
405
451
 
406
452
  // src/utils/throttle.ts
407
453
  var throttle = (fn, delay) => {
@@ -430,108 +476,85 @@ var throttle = (fn, delay) => {
430
476
  ];
431
477
  };
432
478
 
433
- // src/managers/fileManager/FileManager.ts
434
- var FileManager = class {
435
- cache = /* @__PURE__ */ new Map();
436
- task;
437
- queue;
438
- constructor(options) {
439
- if (options) {
440
- this.task = options.task;
441
- this.queue = options.queue;
442
- }
443
- }
444
- getCache(id) {
445
- return this.cache.get(id);
446
- }
447
- getCacheByPath(path) {
448
- let cache;
449
- this.cache.forEach((item) => {
450
- if (item.file.path === path) {
451
- cache = item;
452
- }
453
- });
454
- return cache;
455
- }
456
- get files() {
457
- const files = [];
458
- this.cache.forEach((item) => {
459
- files.push(item.file);
460
- });
461
- return files;
479
+ // src/utils/SummaryError.ts
480
+ var SummaryError = class extends Error {
481
+ summary;
482
+ constructor(message, options) {
483
+ super(message, { cause: options.cause });
484
+ this.name = "SummaryError";
485
+ this.summary = options.summary || [];
462
486
  }
463
- get cachedFiles() {
464
- const files = [];
465
- this.cache.forEach((item) => {
466
- files.push(item);
467
- });
468
- return files;
487
+ };
488
+
489
+ // src/utils/Warning.ts
490
+ var Warning = class extends Error {
491
+ constructor(message, options) {
492
+ super(message, { cause: options?.cause });
493
+ this.name = "Warning";
469
494
  }
470
- async add(file) {
471
- const cacheItem = { id: crypto.randomUUID(), file, status: "new" };
472
- this.cache.set(cacheItem.id, cacheItem);
473
- if (this.queue) {
474
- await this.queue.run(async () => {
475
- await this.task?.(cacheItem.id, file);
476
- });
495
+ };
496
+ function createLogger(spinner) {
497
+ const log = (message) => {
498
+ if (message && spinner) {
499
+ spinner.text = message;
477
500
  }
478
- return file;
479
- }
480
- addOrAppend(file) {
481
- if (!file.path.endsWith(file.fileName)) ;
482
- const previousCache = this.getCacheByPath(file.path);
483
- if (previousCache) {
484
- const sourceAlreadyExists = file.source && previousCache.file.source.includes(file.source);
485
- if (sourceAlreadyExists) {
486
- return Promise.resolve(file);
487
- }
488
- this.cache.delete(previousCache.id);
489
- return this.add({
490
- ...file,
491
- source: `${previousCache.file.source}
492
- ${file.source}`,
493
- imports: [...previousCache.file.imports || [], ...file.imports || []],
494
- exports: [...previousCache.file.exports || [], ...file.exports || []]
495
- });
501
+ };
502
+ const error = (message) => {
503
+ if (message) {
504
+ throw new Error(message || "Something went wrong");
496
505
  }
497
- return this.add(file);
498
- }
499
- setStatus(id, status) {
500
- const cacheItem = this.getCache(id);
501
- if (!cacheItem) {
502
- return;
506
+ };
507
+ const warn = (message) => {
508
+ if (message && spinner) {
509
+ spinner.warn(pc2.yellow(message));
510
+ }
511
+ };
512
+ const info = (message) => {
513
+ if (message && spinner) {
514
+ spinner.info(message);
503
515
  }
504
- cacheItem.status = status;
505
- this.cache.set(id, cacheItem);
516
+ };
517
+ const logger = {
518
+ log,
519
+ error,
520
+ warn,
521
+ info,
522
+ spinner
523
+ };
524
+ return logger;
525
+ }
526
+ function canLogHierarchy(input, compareTo) {
527
+ if (input === "stacktrace") {
528
+ return canLogHierarchy("info", compareTo);
506
529
  }
507
- get(id) {
508
- const cacheItem = this.getCache(id);
509
- return cacheItem?.file;
530
+ return input === compareTo;
531
+ }
532
+ var defaultColours = ["black", "blue", "darkBlue", "cyan", "gray", "green", "darkGreen", "magenta", "red", "darkRed", "yellow", "darkYellow"];
533
+ function randomColour(text, colours = defaultColours) {
534
+ if (!text) {
535
+ return "white";
510
536
  }
511
- remove(id) {
512
- const cacheItem = this.getCache(id);
513
- if (!cacheItem) {
514
- return;
515
- }
516
- this.setStatus(id, "removed");
537
+ const random = seedrandom(text);
538
+ const colour = colours.at(Math.floor(random() * colours.length)) || "white";
539
+ return colour;
540
+ }
541
+ function randomPicoColour(text, colors = defaultColours) {
542
+ const colours = pc2.createColors(true);
543
+ if (!text) {
544
+ return colours.white(text);
517
545
  }
518
- async write(...params) {
519
- if (this.queue) {
520
- return this.queue.run(async () => {
521
- return write(...params);
522
- });
523
- }
524
- return write(...params);
546
+ const colour = randomColour(text, colors);
547
+ const isDark = colour.includes("dark");
548
+ const key = colour.replace("dark", "").toLowerCase();
549
+ const formatter = colours[key];
550
+ if (isDark) {
551
+ return pc2.bold(formatter(text));
525
552
  }
526
- async read(...params) {
527
- if (this.queue) {
528
- return this.queue.run(async () => {
529
- return read(...params);
530
- });
531
- }
532
- return read(...params);
553
+ if (typeof formatter !== "function") {
554
+ throw new Error("Formatter for picoColor is not of type function/Formatter");
533
555
  }
534
- };
556
+ return formatter(text);
557
+ }
535
558
  function writeIndexes(root, options = {}) {
536
559
  const tree = TreeNode.build(root, { extensions: /\.ts/, ...options });
537
560
  if (!tree) {
@@ -587,9 +610,10 @@ function combineFiles(files) {
587
610
  acc[prevIndex] = {
588
611
  ...curr,
589
612
  source: prev.source && curr.source ? `${prev.source}
590
- ${curr.source}` : "'",
613
+ ${curr.source}` : "",
591
614
  imports: [...prev.imports || [], ...curr.imports || []],
592
- exports: [...prev.exports || [], ...curr.exports || []]
615
+ exports: [...prev.exports || [], ...curr.exports || []],
616
+ env: { ...prev.env || {}, ...curr.env || {} }
593
617
  };
594
618
  } else {
595
619
  acc.push(curr);
@@ -597,9 +621,10 @@ ${curr.source}` : "'",
597
621
  return acc;
598
622
  }, []);
599
623
  }
624
+ var extensions = [".js", ".ts"];
600
625
  function getFileSource(file) {
601
626
  let { source } = file;
602
- if (!file.fileName.endsWith(".ts")) {
627
+ if (!extensions.some((extension) => file.fileName.endsWith(extension))) {
603
628
  return file.source;
604
629
  }
605
630
  const imports = [];
@@ -646,6 +671,7 @@ function getFileSource(file) {
646
671
  return [...prev, createExportDeclaration({ name: curr.name, path: curr.path, isTypeOnly: curr.isTypeOnly, asAlias: curr.asAlias })];
647
672
  }, []);
648
673
  const exportSource = print(exportNodes);
674
+ source = getEnvSource(source, file.env);
649
675
  if (importSource) {
650
676
  source = `${importSource}
651
677
  ${source}`;
@@ -656,6 +682,133 @@ ${source}`;
656
682
  }
657
683
  return source;
658
684
  }
685
+ function searchAndReplace(options) {
686
+ const { text, replaceBy, prefix = "", key } = options;
687
+ const searchValues = options.searchValues?.(prefix, key) || [
688
+ `${prefix}["${key}"]`,
689
+ `${prefix}['${key}']`,
690
+ `${prefix}[\`${key}\`]`,
691
+ `${prefix}"${key}"`,
692
+ `${prefix}'${key}'`,
693
+ `${prefix}\`${key}\``,
694
+ new RegExp(`${prefix}${key}`, "g")
695
+ ];
696
+ return searchValues.reduce((prev, searchValue) => {
697
+ return prev.toString().replaceAll(searchValue, replaceBy);
698
+ }, text);
699
+ }
700
+ function getEnvSource(source, env) {
701
+ if (!env) {
702
+ return source;
703
+ }
704
+ const keys = Object.keys(env);
705
+ if (!keys.length) {
706
+ return source;
707
+ }
708
+ return keys.reduce((prev, key) => {
709
+ const environmentValue = env[key];
710
+ const replaceBy = environmentValue ? `'${environmentValue.replaceAll('"', "")?.replaceAll("'", "")}'` : "undefined";
711
+ if (key.toUpperCase() !== key) {
712
+ throw new TypeError(`Environment should be in upperCase for ${key}`);
713
+ }
714
+ if (typeof replaceBy === "string") {
715
+ prev = searchAndReplace({ text: prev.replaceAll(`process.env.${key}`, replaceBy), replaceBy, prefix: "process.env", key });
716
+ prev = searchAndReplace({ text: prev.replaceAll(new RegExp(`(declare const).*
717
+ `, "ig"), ""), replaceBy, key });
718
+ }
719
+ return prev;
720
+ }, source);
721
+ }
722
+
723
+ // src/managers/fileManager/FileManager.ts
724
+ var FileManager = class {
725
+ cache = /* @__PURE__ */ new Map();
726
+ task;
727
+ queue;
728
+ constructor(options) {
729
+ if (options) {
730
+ this.task = options.task;
731
+ this.queue = options.queue;
732
+ }
733
+ }
734
+ get extensions() {
735
+ return extensions;
736
+ }
737
+ get files() {
738
+ const files = [];
739
+ this.cache.forEach((item) => {
740
+ files.push(...item.flat(1));
741
+ });
742
+ return files;
743
+ }
744
+ async add(file) {
745
+ const resolvedFile = { id: crypto.randomUUID(), ...file };
746
+ this.cache.set(resolvedFile.path, [resolvedFile]);
747
+ if (this.queue) {
748
+ await this.queue.run(async () => {
749
+ await this.task?.(resolvedFile);
750
+ });
751
+ }
752
+ return resolvedFile;
753
+ }
754
+ addOrAppend(file) {
755
+ const previousCaches = this.cache.get(file.path);
756
+ const previousCache = previousCaches ? previousCaches.at(previousCaches.length - 1) : void 0;
757
+ if (previousCache) {
758
+ const sourceAlreadyExists = file.source && previousCache.source.includes(file.source);
759
+ if (sourceAlreadyExists) {
760
+ return Promise.resolve(previousCache);
761
+ }
762
+ this.cache.delete(previousCache.path);
763
+ return this.add({
764
+ ...file,
765
+ source: previousCache.source && file.source ? `${previousCache.source}
766
+ ${file.source}` : "",
767
+ imports: [...previousCache.imports || [], ...file.imports || []],
768
+ exports: [...previousCache.exports || [], ...file.exports || []],
769
+ env: { ...previousCache.env || {}, ...file.env || {} }
770
+ });
771
+ }
772
+ return this.add(file);
773
+ }
774
+ append(path, file) {
775
+ const previousFiles = this.cache.get(path) || [];
776
+ this.cache.set(path, [...previousFiles, file]);
777
+ }
778
+ getCacheByUUID(UUID) {
779
+ let cache;
780
+ this.cache.forEach((files) => {
781
+ cache = files.find((item) => item.id === UUID);
782
+ });
783
+ return cache;
784
+ }
785
+ get(path) {
786
+ return this.cache.get(path);
787
+ }
788
+ remove(path) {
789
+ const cacheItem = this.get(path);
790
+ if (!cacheItem) {
791
+ return;
792
+ }
793
+ this.cache.delete(path);
794
+ }
795
+ async write(...params) {
796
+ if (this.queue) {
797
+ return this.queue.run(async () => {
798
+ return write(...params);
799
+ });
800
+ }
801
+ return write(...params);
802
+ }
803
+ async read(...params) {
804
+ if (this.queue) {
805
+ return this.queue.run(async () => {
806
+ return read(...params);
807
+ });
808
+ }
809
+ return read(...params);
810
+ }
811
+ };
659
812
  function createPlugin(factory) {
660
813
  return (options) => {
661
814
  const plugin = factory(options);
@@ -670,67 +823,69 @@ function createPlugin(factory) {
670
823
  return plugin;
671
824
  };
672
825
  }
673
- var name = "core";
826
+ var pluginName = "core";
674
827
  var definePlugin = createPlugin((options) => {
675
- const { fileManager, resolvePath, resolveName, load } = options;
676
- const api = {
677
- get config() {
678
- return options.config;
679
- },
680
- fileManager,
681
- async addFile(...files) {
682
- const trace = getStackTrace();
683
- const plugins = options.config.plugins?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name)).sort((a, b) => {
684
- if (a.name.length < b.name.length) {
685
- return 1;
686
- }
687
- if (a.name.length > b.name.length) {
688
- return -1;
689
- }
690
- return 0;
691
- });
692
- const pluginName = plugins?.[0]?.name;
693
- return Promise.all(
694
- files.map((file) => {
695
- const fileWithMeta = {
696
- ...file,
697
- meta: {
698
- ...file.meta || {},
699
- pluginName
700
- }
701
- };
702
- if (file.override) {
703
- return fileManager.add(fileWithMeta);
704
- }
705
- return fileManager.addOrAppend(fileWithMeta);
706
- })
707
- );
708
- },
709
- resolvePath,
710
- resolveName: (params) => {
711
- const name2 = resolveName(params);
712
- return transformReservedWord(name2);
713
- },
714
- load,
715
- cache: createPluginCache(/* @__PURE__ */ Object.create(null))
716
- };
828
+ const { fileManager, resolvePath, resolveName, load, logger } = options;
717
829
  return {
718
- name,
830
+ name: pluginName,
719
831
  options,
720
- api,
832
+ api() {
833
+ return {
834
+ get config() {
835
+ return options.config;
836
+ },
837
+ logger,
838
+ fileManager,
839
+ async addFile(...files) {
840
+ const trace = getStackTrace();
841
+ const plugins = options.config.plugins?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name)).sort((a, b) => {
842
+ if (a.name.length < b.name.length) {
843
+ return 1;
844
+ }
845
+ if (a.name.length > b.name.length) {
846
+ return -1;
847
+ }
848
+ return 0;
849
+ });
850
+ const pluginName2 = plugins?.[0]?.name;
851
+ return Promise.all(
852
+ files.map((file) => {
853
+ const fileWithMeta = {
854
+ ...file,
855
+ meta: {
856
+ ...file.meta || {},
857
+ pluginName: pluginName2
858
+ }
859
+ };
860
+ if (file.override) {
861
+ return fileManager.add(fileWithMeta);
862
+ }
863
+ return fileManager.addOrAppend(fileWithMeta);
864
+ })
865
+ );
866
+ },
867
+ resolvePath,
868
+ resolveName: (params) => {
869
+ const name = resolveName(params);
870
+ return transformReservedWord(name);
871
+ },
872
+ load,
873
+ cache: createPluginCache(/* @__PURE__ */ Object.create(null))
874
+ };
875
+ },
721
876
  resolvePath(fileName) {
722
877
  const root = pathParser2.resolve(this.config.root, this.config.output.path);
723
878
  return pathParser2.resolve(root, fileName);
724
879
  },
725
- resolveName(name2) {
726
- return name2;
880
+ resolveName(name) {
881
+ return name;
727
882
  }
728
883
  };
729
884
  });
730
885
 
731
886
  // src/managers/pluginManager/ParallelPluginError.ts
732
887
  var ParallelPluginError = class extends Error {
733
- errors;
888
+ errors = [];
734
889
  pluginManager;
735
890
  constructor(message, options) {
736
891
  super(message, { cause: options.cause });
@@ -738,14 +893,27 @@ var ParallelPluginError = class extends Error {
738
893
  this.errors = options.errors;
739
894
  this.pluginManager = options.pluginManager;
740
895
  }
896
+ findError(searchError) {
897
+ return this.errors.find((error) => {
898
+ if (error.cause) {
899
+ if (error.cause.name == searchError.name) {
900
+ return true;
901
+ }
902
+ return !!this.findError(error.cause);
903
+ }
904
+ return error.name === searchError.name;
905
+ })?.cause;
906
+ }
741
907
  };
742
908
 
743
909
  // src/managers/pluginManager/PluginError.ts
744
910
  var PluginError = class extends Error {
745
911
  pluginManager;
912
+ cause;
746
913
  constructor(message, options) {
747
914
  super(message, { cause: options.cause });
748
915
  this.name = "PluginError";
916
+ this.cause = options.cause;
749
917
  this.pluginManager = options.pluginManager;
750
918
  }
751
919
  };
@@ -762,30 +930,46 @@ var hookNames = {
762
930
  buildEnd: 1
763
931
  };
764
932
  var hooks = Object.keys(hookNames);
933
+ var convertKubbUserPluginToKubbPlugin = (plugin, context) => {
934
+ if (plugin.api && typeof plugin.api === "function") {
935
+ const api = plugin.api.call(context);
936
+ return {
937
+ ...plugin,
938
+ api
939
+ };
940
+ }
941
+ return null;
942
+ };
765
943
  var PluginManager = class {
766
944
  plugins;
767
945
  fileManager;
768
946
  onExecute;
769
947
  core;
770
948
  queue;
771
- executer;
772
949
  executed = [];
950
+ logger;
773
951
  constructor(config, options) {
774
952
  this.onExecute = options.onExecute?.bind(this);
775
- this.queue = new Queue(10);
953
+ this.logger = options.logger;
954
+ this.queue = new Queue(100, options.debug);
776
955
  this.fileManager = new FileManager({ task: options.task, queue: this.queue });
777
- this.core = definePlugin({
956
+ const core = definePlugin({
778
957
  config,
958
+ logger: this.logger,
779
959
  fileManager: this.fileManager,
780
960
  load: this.load,
781
961
  resolvePath: this.resolvePath,
782
- resolveName: this.resolveName,
783
- getExecuter: this.getExecuter.bind(this)
962
+ resolveName: this.resolveName
784
963
  });
785
- this.plugins = [this.core, ...config.plugins || []];
786
- }
787
- getExecuter() {
788
- return this.executer;
964
+ const convertedCore = convertKubbUserPluginToKubbPlugin(core, core.api.call(null));
965
+ this.core = convertedCore;
966
+ this.plugins = [this.core, ...config.plugins || []].reduce((prev, plugin) => {
967
+ const convertedApi = convertKubbUserPluginToKubbPlugin(plugin, convertedCore?.api);
968
+ if (convertedApi) {
969
+ return [...prev, convertedApi];
970
+ }
971
+ return [...prev, plugin];
972
+ }, []);
789
973
  }
790
974
  resolvePath = (params) => {
791
975
  if (params.pluginName) {
@@ -824,11 +1008,11 @@ var PluginManager = class {
824
1008
  * Run only hook for a specific plugin name
825
1009
  */
826
1010
  hookForPlugin({
827
- pluginName,
1011
+ pluginName: pluginName2,
828
1012
  hookName,
829
1013
  parameters
830
1014
  }) {
831
- const plugin = this.getPlugin(hookName, pluginName);
1015
+ const plugin = this.getPlugin(hookName, pluginName2);
832
1016
  return this.execute({
833
1017
  strategy: "hookFirst",
834
1018
  hookName,
@@ -837,11 +1021,11 @@ var PluginManager = class {
837
1021
  });
838
1022
  }
839
1023
  hookForPluginSync({
840
- pluginName,
1024
+ pluginName: pluginName2,
841
1025
  hookName,
842
1026
  parameters
843
1027
  }) {
844
- const plugin = this.getPlugin(hookName, pluginName);
1028
+ const plugin = this.getPlugin(hookName, pluginName2);
845
1029
  return this.executeSync({
846
1030
  strategy: "hookFirst",
847
1031
  hookName,
@@ -926,7 +1110,12 @@ var PluginManager = class {
926
1110
  }
927
1111
  }
928
1112
  const results = await Promise.allSettled(parallelPromises);
929
- const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
1113
+ const errors = results.map((result) => {
1114
+ if (isPromiseRejectedResult(result) && result.reason instanceof PluginError) {
1115
+ return result.reason;
1116
+ }
1117
+ return void 0;
1118
+ }).filter(Boolean);
930
1119
  if (errors.length) {
931
1120
  throw new ParallelPluginError("Error", { errors, pluginManager: this });
932
1121
  }
@@ -977,15 +1166,15 @@ var PluginManager = class {
977
1166
  const plugins = [...this.plugins].filter((plugin) => plugin.name !== "core");
978
1167
  return plugins;
979
1168
  }
980
- getPlugin(hookName, pluginName) {
1169
+ getPlugin(hookName, pluginName2) {
981
1170
  const plugins = [...this.plugins];
982
- const pluginByPluginName = plugins.find((item) => item.name === pluginName && item[hookName]);
1171
+ const pluginByPluginName = plugins.find((item) => item.name === pluginName2 && item[hookName]);
983
1172
  if (!pluginByPluginName) {
984
1173
  return this.core;
985
1174
  }
986
1175
  return pluginByPluginName;
987
1176
  }
988
- addExecuter(executer) {
1177
+ addExecutedToCallStack(executer) {
989
1178
  this.onExecute?.call(this, executer, this);
990
1179
  if (executer) {
991
1180
  this.executed.push(executer);
@@ -1005,38 +1194,35 @@ var PluginManager = class {
1005
1194
  plugin
1006
1195
  }) {
1007
1196
  const hook = plugin[hookName];
1197
+ let output;
1008
1198
  if (!hook) {
1009
1199
  return null;
1010
1200
  }
1011
- return Promise.resolve().then(() => {
1012
- this.executer = {
1013
- strategy,
1014
- hookName,
1015
- plugin
1016
- };
1201
+ const task = Promise.resolve().then(() => {
1017
1202
  if (typeof hook === "function") {
1018
- const hookResult = hook.apply(this.core.api, parameters);
1019
- if (isPromise(hookResult)) {
1020
- return Promise.resolve(hookResult).then((result) => {
1021
- this.addExecuter({
1022
- strategy,
1023
- hookName,
1024
- plugin
1025
- });
1026
- return result;
1027
- });
1203
+ const possiblePromiseResult = hook.apply(this.core.api, parameters);
1204
+ if (isPromise(possiblePromiseResult)) {
1205
+ return Promise.resolve(possiblePromiseResult);
1028
1206
  }
1029
- return hookResult;
1207
+ return possiblePromiseResult;
1030
1208
  }
1031
- this.addExecuter({
1209
+ return hook;
1210
+ }).then((result) => {
1211
+ output = result;
1212
+ return result;
1213
+ }).catch((e) => {
1214
+ this.catcher(e, plugin, hookName);
1215
+ return null;
1216
+ }).finally(() => {
1217
+ this.addExecutedToCallStack({
1218
+ input: parameters,
1219
+ output,
1032
1220
  strategy,
1033
1221
  hookName,
1034
1222
  plugin
1035
1223
  });
1036
- return hook;
1037
- }).catch((e) => {
1038
- this.catcher(e, plugin, hookName);
1039
1224
  });
1225
+ return this.queue.run(() => task);
1040
1226
  }
1041
1227
  /**
1042
1228
  * Run a sync plugin hook and return the result.
@@ -1052,33 +1238,29 @@ var PluginManager = class {
1052
1238
  plugin
1053
1239
  }) {
1054
1240
  const hook = plugin[hookName];
1241
+ let output;
1055
1242
  if (!hook) {
1056
1243
  return null;
1057
1244
  }
1058
1245
  try {
1059
- this.executer = {
1060
- strategy,
1061
- hookName,
1062
- plugin
1063
- };
1064
1246
  if (typeof hook === "function") {
1065
1247
  const fn = hook.apply(this.core.api, parameters);
1066
- this.addExecuter({
1067
- strategy,
1068
- hookName,
1069
- plugin
1070
- });
1248
+ output = fn;
1071
1249
  return fn;
1072
1250
  }
1073
- this.addExecuter({
1074
- strategy,
1075
- hookName,
1076
- plugin
1077
- });
1251
+ output = hook;
1078
1252
  return hook;
1079
1253
  } catch (e) {
1080
1254
  this.catcher(e, plugin, hookName);
1081
1255
  return null;
1256
+ } finally {
1257
+ this.addExecutedToCallStack({
1258
+ input: parameters,
1259
+ output,
1260
+ strategy,
1261
+ hookName,
1262
+ plugin
1263
+ });
1082
1264
  }
1083
1265
  }
1084
1266
  catcher(e, plugin, hookName) {
@@ -1100,23 +1282,20 @@ function validatePlugins(plugins, dependedPluginNames) {
1100
1282
  } else {
1101
1283
  pluginNames = dependedPluginNames;
1102
1284
  }
1103
- pluginNames.forEach((pluginName) => {
1104
- const exists = plugins.some((plugin) => plugin.name === pluginName);
1285
+ pluginNames.forEach((pluginName2) => {
1286
+ const exists = plugins.some((plugin) => plugin.name === pluginName2);
1105
1287
  if (!exists) {
1106
- throw new ValidationPluginError(`This plugin depends on the ${pluginName} plugin.`);
1288
+ throw new ValidationPluginError(`This plugin depends on the ${pluginName2} plugin.`);
1107
1289
  }
1108
1290
  });
1109
1291
  return true;
1110
1292
  }
1111
1293
 
1112
- // src/managers/pluginManager/SummaryError.ts
1113
- var SummaryError = class extends Error {
1114
- summary;
1115
- constructor(message, options) {
1116
- super(message, { cause: options.cause });
1117
- this.name = "SummaryError";
1118
- this.summary = options.summary || [];
1119
- }
1294
+ // src/types.ts
1295
+ var LogLevel = {
1296
+ silent: "silent",
1297
+ info: "info",
1298
+ stacktrace: "stacktrace"
1120
1299
  };
1121
1300
 
1122
1301
  // src/build.ts
@@ -1124,7 +1303,7 @@ async function transformReducer(_previousCode, result, _plugin) {
1124
1303
  return result;
1125
1304
  }
1126
1305
  async function build(options) {
1127
- const { config, logger } = options;
1306
+ const { config, debug, logger = createLogger() } = options;
1128
1307
  try {
1129
1308
  if (!isURL(config.input.path)) {
1130
1309
  await read(config.input.path);
@@ -1135,7 +1314,7 @@ async function build(options) {
1135
1314
  if (config.output.clean) {
1136
1315
  await clean(config.output.path);
1137
1316
  }
1138
- const queueTask = async (id, file) => {
1317
+ const queueTask = async (file) => {
1139
1318
  const { path } = file;
1140
1319
  let code = getFileSource(file);
1141
1320
  const { result: loadedResult } = await pluginManager.hookFirst({
@@ -1166,12 +1345,27 @@ async function build(options) {
1166
1345
  if (!executer) {
1167
1346
  return;
1168
1347
  }
1169
- const { hookName, plugin } = executer;
1170
- if (config.logLevel === "info" && logger) {
1171
- logger.log(null, { logLevel: config.logLevel, params: { hookName, pluginName: plugin.name } });
1348
+ const { hookName, plugin, output, input } = executer;
1349
+ const messsage = `${randomPicoColour(plugin.name)} Executing ${hookName}`;
1350
+ if (config.logLevel === LogLevel.info && logger?.spinner && input) {
1351
+ if (debug) {
1352
+ logger.info(messsage);
1353
+ } else {
1354
+ logger.spinner.suffixText = messsage;
1355
+ }
1356
+ }
1357
+ if (config.logLevel === LogLevel.stacktrace && logger?.spinner && input) {
1358
+ logger.info(messsage);
1359
+ const logs = [
1360
+ input && `${pc2.bgWhite(`Input`)} ${randomPicoColour(plugin.name)} ${hookName}`,
1361
+ JSON.stringify(input, void 0, 2),
1362
+ output && `${pc2.bgWhite("Output")} ${randomPicoColour(plugin.name)} ${hookName}`,
1363
+ output
1364
+ ].filter(Boolean);
1365
+ console.log(logs.join("\n"));
1172
1366
  }
1173
1367
  };
1174
- const pluginManager = new PluginManager(config, { task: queueTask, onExecute });
1368
+ const pluginManager = new PluginManager(config, { debug, logger, task: queueTask, onExecute });
1175
1369
  const { plugins, fileManager } = pluginManager;
1176
1370
  await pluginManager.hookParallel({
1177
1371
  hookName: "validate",
@@ -1212,6 +1406,6 @@ var SchemaGenerator = class extends Generator {
1212
1406
  // src/index.ts
1213
1407
  var src_default = build;
1214
1408
 
1215
- export { FileManager, Generator, ParallelPluginError, PluginError, PluginManager, Queue, SchemaGenerator, SummaryError, TreeNode, ValidationPluginError, build, clean, combineFiles, createJSDocBlockText, createPlugin, createPluginCache, src_default as default, defineConfig, getEncodedText, getFileSource, getPathMode, getRelativePath, getStackTrace, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, renderTemplate, throttle, timeout, transformReservedWord, uniqueId, validatePlugins, write, writeIndexes };
1409
+ export { FileManager, Generator, LogLevel, ParallelPluginError, PluginError, PluginManager, Queue, SchemaGenerator, SummaryError, TreeNode, ValidationPluginError, Warning, build, canLogHierarchy, clean, combineFiles, createJSDocBlockText, createLogger, createPlugin, createPluginCache, src_default as default, defaultColours, defineConfig, extensions, getEncodedText, getFileSource, getLocation, getPathMode, getRelativePath, getStackTrace, getUniqueName, hooks, importModule, isPromise, isPromiseFulfilledResult, isPromiseRejectedResult, isURL, pluginName as name, nameSorter, normalizeDirectory, objectToParameters, pluginName, randomColour, randomPicoColour, read, renderTemplate, throttle, timeout, transformReservedWord, uniqueId, validatePlugins, write, writeIndexes };
1216
1410
  //# sourceMappingURL=out.js.map
1217
1411
  //# sourceMappingURL=index.js.map