@kubb/core 1.2.0 → 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.cjs CHANGED
@@ -6,11 +6,13 @@ var crypto = require('crypto');
6
6
  var fs = require('fs-extra');
7
7
  var pathParser2 = require('path');
8
8
  var changeCase = require('change-case');
9
+ var perf_hooks = require('perf_hooks');
9
10
  var rimraf = require('rimraf');
10
11
  var dirTree = require('directory-tree');
11
12
  var mod = require('module');
12
13
  var url = require('url');
13
- var pc = require('picocolors');
14
+ var pc2 = require('picocolors');
15
+ var seedrandom = require('seedrandom');
14
16
  var tsCodegen = require('@kubb/ts-codegen');
15
17
 
16
18
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -20,7 +22,8 @@ var fs__default = /*#__PURE__*/_interopDefault(fs);
20
22
  var pathParser2__default = /*#__PURE__*/_interopDefault(pathParser2);
21
23
  var dirTree__default = /*#__PURE__*/_interopDefault(dirTree);
22
24
  var mod__default = /*#__PURE__*/_interopDefault(mod);
23
- var pc__default = /*#__PURE__*/_interopDefault(pc);
25
+ var pc2__default = /*#__PURE__*/_interopDefault(pc2);
26
+ var seedrandom__default = /*#__PURE__*/_interopDefault(seedrandom);
24
27
 
25
28
  // src/managers/fileManager/FileManager.ts
26
29
 
@@ -176,18 +179,18 @@ async function timeout(ms) {
176
179
  }, ms);
177
180
  });
178
181
  }
179
-
180
- // src/utils/Queue.ts
181
182
  var Queue = class {
182
183
  queue = [];
183
184
  workerCount = 0;
184
185
  maxParallel;
185
- constructor(maxParallel) {
186
+ debug = false;
187
+ constructor(maxParallel, debug = false) {
186
188
  this.maxParallel = maxParallel;
189
+ this.debug = debug;
187
190
  }
188
- run(task) {
191
+ run(task, options = { name: crypto__default.default.randomUUID(), description: "" }) {
189
192
  return new Promise((resolve, reject) => {
190
- const item = { reject, resolve, task };
193
+ const item = { reject, resolve, task, name: options.name, description: options.description || options.name };
191
194
  this.queue.push(item);
192
195
  this.work();
193
196
  });
@@ -199,8 +202,17 @@ var Queue = class {
199
202
  this.workerCount++;
200
203
  let entry;
201
204
  while (entry = this.queue.shift()) {
202
- const { reject, resolve, task } = entry;
203
- task().then((result) => resolve(result)).catch((err) => reject(err));
205
+ const { reject, resolve, task, name, description } = entry;
206
+ if (this.debug) {
207
+ perf_hooks.performance.mark(name + "_start");
208
+ }
209
+ task().then((result) => {
210
+ resolve(result);
211
+ if (this.debug) {
212
+ perf_hooks.performance.mark(name + "_stop");
213
+ perf_hooks.performance.measure(description, name + "_start", name + "_stop");
214
+ }
215
+ }).catch((err) => reject(err));
204
216
  }
205
217
  this.workerCount--;
206
218
  }
@@ -494,26 +506,26 @@ var Warning = class extends Error {
494
506
  }
495
507
  };
496
508
  function createLogger(spinner) {
497
- const [log] = throttle((message) => {
509
+ const log = (message) => {
498
510
  if (message && spinner) {
499
511
  spinner.text = message;
500
512
  }
501
- }, 100);
502
- const [error] = throttle((message) => {
513
+ };
514
+ const error = (message) => {
503
515
  if (message) {
504
516
  throw new Error(message || "Something went wrong");
505
517
  }
506
- }, 100);
507
- const [warn] = throttle((message) => {
518
+ };
519
+ const warn = (message) => {
508
520
  if (message && spinner) {
509
- spinner.warn(pc__default.default.yellow(message));
521
+ spinner.warn(pc2__default.default.yellow(message));
510
522
  }
511
- }, 100);
512
- const [info] = throttle((message) => {
523
+ };
524
+ const info = (message) => {
513
525
  if (message && spinner) {
514
- spinner.text = message;
526
+ spinner.info(message);
515
527
  }
516
- }, 100);
528
+ };
517
529
  const logger = {
518
530
  log,
519
531
  error,
@@ -523,6 +535,38 @@ function createLogger(spinner) {
523
535
  };
524
536
  return logger;
525
537
  }
538
+ function canLogHierarchy(input, compareTo) {
539
+ if (input === "stacktrace") {
540
+ return canLogHierarchy("info", compareTo);
541
+ }
542
+ return input === compareTo;
543
+ }
544
+ var defaultColours = ["black", "blue", "darkBlue", "cyan", "gray", "green", "darkGreen", "magenta", "red", "darkRed", "yellow", "darkYellow"];
545
+ function randomColour(text, colours = defaultColours) {
546
+ if (!text) {
547
+ return "white";
548
+ }
549
+ const random = seedrandom__default.default(text);
550
+ const colour = colours.at(Math.floor(random() * colours.length)) || "white";
551
+ return colour;
552
+ }
553
+ function randomPicoColour(text, colors = defaultColours) {
554
+ const colours = pc2__default.default.createColors(true);
555
+ if (!text) {
556
+ return colours.white(text);
557
+ }
558
+ const colour = randomColour(text, colors);
559
+ const isDark = colour.includes("dark");
560
+ const key = colour.replace("dark", "").toLowerCase();
561
+ const formatter = colours[key];
562
+ if (isDark) {
563
+ return pc2__default.default.bold(formatter(text));
564
+ }
565
+ if (typeof formatter !== "function") {
566
+ throw new Error("Formatter for picoColor is not of type function/Formatter");
567
+ }
568
+ return formatter(text);
569
+ }
526
570
  function writeIndexes(root, options = {}) {
527
571
  const tree = TreeNode.build(root, { extensions: /\.ts/, ...options });
528
572
  if (!tree) {
@@ -578,7 +622,7 @@ function combineFiles(files) {
578
622
  acc[prevIndex] = {
579
623
  ...curr,
580
624
  source: prev.source && curr.source ? `${prev.source}
581
- ${curr.source}` : "'",
625
+ ${curr.source}` : "",
582
626
  imports: [...prev.imports || [], ...curr.imports || []],
583
627
  exports: [...prev.exports || [], ...curr.exports || []],
584
628
  env: { ...prev.env || {}, ...curr.env || {} }
@@ -699,82 +743,66 @@ var FileManager = class {
699
743
  this.queue = options.queue;
700
744
  }
701
745
  }
702
- getCache(id) {
703
- return this.cache.get(id);
704
- }
705
746
  get extensions() {
706
747
  return extensions;
707
748
  }
708
- getCacheByPath(path) {
709
- let cache;
710
- this.cache.forEach((item) => {
711
- if (item.file.path === path) {
712
- cache = item;
713
- }
714
- });
715
- return cache;
716
- }
717
749
  get files() {
718
750
  const files = [];
719
751
  this.cache.forEach((item) => {
720
- files.push(item.file);
721
- });
722
- return files;
723
- }
724
- get cachedFiles() {
725
- const files = [];
726
- this.cache.forEach((item) => {
727
- files.push(item);
752
+ files.push(...item.flat(1));
728
753
  });
729
754
  return files;
730
755
  }
731
756
  async add(file) {
732
- const cacheItem = { id: crypto__default.default.randomUUID(), file, status: "new" };
733
- this.cache.set(cacheItem.id, cacheItem);
757
+ const resolvedFile = { id: crypto__default.default.randomUUID(), ...file };
758
+ this.cache.set(resolvedFile.path, [resolvedFile]);
734
759
  if (this.queue) {
735
760
  await this.queue.run(async () => {
736
- await this.task?.(cacheItem.id, file);
761
+ await this.task?.(resolvedFile);
737
762
  });
738
763
  }
739
- return file;
764
+ return resolvedFile;
740
765
  }
741
766
  addOrAppend(file) {
742
- if (!file.path.endsWith(file.fileName)) ;
743
- const previousCache = this.getCacheByPath(file.path);
767
+ const previousCaches = this.cache.get(file.path);
768
+ const previousCache = previousCaches ? previousCaches.at(previousCaches.length - 1) : void 0;
744
769
  if (previousCache) {
745
- const sourceAlreadyExists = file.source && previousCache.file.source.includes(file.source);
770
+ const sourceAlreadyExists = file.source && previousCache.source.includes(file.source);
746
771
  if (sourceAlreadyExists) {
747
- return Promise.resolve(file);
772
+ return Promise.resolve(previousCache);
748
773
  }
749
- this.cache.delete(previousCache.id);
774
+ this.cache.delete(previousCache.path);
750
775
  return this.add({
751
776
  ...file,
752
- source: `${previousCache.file.source}
753
- ${file.source}`,
754
- imports: [...previousCache.file.imports || [], ...file.imports || []],
755
- exports: [...previousCache.file.exports || [], ...file.exports || []]
777
+ source: previousCache.source && file.source ? `${previousCache.source}
778
+ ${file.source}` : "",
779
+ imports: [...previousCache.imports || [], ...file.imports || []],
780
+ exports: [...previousCache.exports || [], ...file.exports || []],
781
+ env: { ...previousCache.env || {}, ...file.env || {} }
756
782
  });
757
783
  }
758
784
  return this.add(file);
759
785
  }
760
- setStatus(id, status) {
761
- const cacheItem = this.getCache(id);
762
- if (!cacheItem) {
763
- return;
764
- }
765
- cacheItem.status = status;
766
- this.cache.set(id, cacheItem);
786
+ append(path, file) {
787
+ const previousFiles = this.cache.get(path) || [];
788
+ this.cache.set(path, [...previousFiles, file]);
789
+ }
790
+ getCacheByUUID(UUID) {
791
+ let cache;
792
+ this.cache.forEach((files) => {
793
+ cache = files.find((item) => item.id === UUID);
794
+ });
795
+ return cache;
767
796
  }
768
- get(id) {
769
- const cacheItem = this.getCache(id);
770
- return cacheItem?.file;
797
+ get(path) {
798
+ return this.cache.get(path);
771
799
  }
772
- remove(id) {
773
- const cacheItem = this.getCache(id);
800
+ remove(path) {
801
+ const cacheItem = this.get(path);
774
802
  if (!cacheItem) {
775
803
  return;
776
804
  }
777
- this.setStatus(id, "removed");
805
+ this.cache.delete(path);
778
806
  }
779
807
  async write(...params) {
780
808
  if (this.queue) {
@@ -810,52 +838,53 @@ function createPlugin(factory) {
810
838
  var pluginName = "core";
811
839
  var definePlugin = createPlugin((options) => {
812
840
  const { fileManager, resolvePath, resolveName, load, logger } = options;
813
- const api = {
814
- get config() {
815
- return options.config;
816
- },
817
- fileManager,
818
- async addFile(...files) {
819
- const trace = getStackTrace();
820
- const plugins = options.config.plugins?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name)).sort((a, b) => {
821
- if (a.name.length < b.name.length) {
822
- return 1;
823
- }
824
- if (a.name.length > b.name.length) {
825
- return -1;
826
- }
827
- return 0;
828
- });
829
- const pluginName2 = plugins?.[0]?.name;
830
- return Promise.all(
831
- files.map((file) => {
832
- const fileWithMeta = {
833
- ...file,
834
- meta: {
835
- ...file.meta || {},
836
- pluginName: pluginName2
837
- }
838
- };
839
- if (file.override) {
840
- return fileManager.add(fileWithMeta);
841
- }
842
- return fileManager.addOrAppend(fileWithMeta);
843
- })
844
- );
845
- },
846
- resolvePath,
847
- resolveName: (params) => {
848
- const name = resolveName(params);
849
- return transformReservedWord(name);
850
- },
851
- load,
852
- logger,
853
- cache: createPluginCache(/* @__PURE__ */ Object.create(null))
854
- };
855
841
  return {
856
842
  name: pluginName,
857
843
  options,
858
- api,
844
+ api() {
845
+ return {
846
+ get config() {
847
+ return options.config;
848
+ },
849
+ logger,
850
+ fileManager,
851
+ async addFile(...files) {
852
+ const trace = getStackTrace();
853
+ const plugins = options.config.plugins?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name)).sort((a, b) => {
854
+ if (a.name.length < b.name.length) {
855
+ return 1;
856
+ }
857
+ if (a.name.length > b.name.length) {
858
+ return -1;
859
+ }
860
+ return 0;
861
+ });
862
+ const pluginName2 = plugins?.[0]?.name;
863
+ return Promise.all(
864
+ files.map((file) => {
865
+ const fileWithMeta = {
866
+ ...file,
867
+ meta: {
868
+ ...file.meta || {},
869
+ pluginName: pluginName2
870
+ }
871
+ };
872
+ if (file.override) {
873
+ return fileManager.add(fileWithMeta);
874
+ }
875
+ return fileManager.addOrAppend(fileWithMeta);
876
+ })
877
+ );
878
+ },
879
+ resolvePath,
880
+ resolveName: (params) => {
881
+ const name = resolveName(params);
882
+ return transformReservedWord(name);
883
+ },
884
+ load,
885
+ cache: createPluginCache(/* @__PURE__ */ Object.create(null))
886
+ };
887
+ },
859
888
  resolvePath(fileName) {
860
889
  const root = pathParser2__default.default.resolve(this.config.root, this.config.output.path);
861
890
  return pathParser2__default.default.resolve(root, fileName);
@@ -913,33 +942,46 @@ var hookNames = {
913
942
  buildEnd: 1
914
943
  };
915
944
  var hooks = Object.keys(hookNames);
945
+ var convertKubbUserPluginToKubbPlugin = (plugin, context) => {
946
+ if (plugin.api && typeof plugin.api === "function") {
947
+ const api = plugin.api.call(context);
948
+ return {
949
+ ...plugin,
950
+ api
951
+ };
952
+ }
953
+ return null;
954
+ };
916
955
  var PluginManager = class {
917
956
  plugins;
918
957
  fileManager;
919
958
  onExecute;
920
959
  core;
921
960
  queue;
922
- executer;
923
961
  executed = [];
924
962
  logger;
925
963
  constructor(config, options) {
926
964
  this.onExecute = options.onExecute?.bind(this);
927
965
  this.logger = options.logger;
928
- this.queue = new Queue(10);
966
+ this.queue = new Queue(100, options.debug);
929
967
  this.fileManager = new FileManager({ task: options.task, queue: this.queue });
930
- this.core = definePlugin({
968
+ const core = definePlugin({
931
969
  config,
932
970
  logger: this.logger,
933
971
  fileManager: this.fileManager,
934
972
  load: this.load,
935
973
  resolvePath: this.resolvePath,
936
- resolveName: this.resolveName,
937
- getExecuter: this.getExecuter.bind(this)
974
+ resolveName: this.resolveName
938
975
  });
939
- this.plugins = [this.core, ...config.plugins || []];
940
- }
941
- getExecuter() {
942
- return this.executer;
976
+ const convertedCore = convertKubbUserPluginToKubbPlugin(core, core.api.call(null));
977
+ this.core = convertedCore;
978
+ this.plugins = [this.core, ...config.plugins || []].reduce((prev, plugin) => {
979
+ const convertedApi = convertKubbUserPluginToKubbPlugin(plugin, convertedCore?.api);
980
+ if (convertedApi) {
981
+ return [...prev, convertedApi];
982
+ }
983
+ return [...prev, plugin];
984
+ }, []);
943
985
  }
944
986
  resolvePath = (params) => {
945
987
  if (params.pluginName) {
@@ -1144,7 +1186,7 @@ var PluginManager = class {
1144
1186
  }
1145
1187
  return pluginByPluginName;
1146
1188
  }
1147
- addExecuter(executer) {
1189
+ addExecutedToCallStack(executer) {
1148
1190
  this.onExecute?.call(this, executer, this);
1149
1191
  if (executer) {
1150
1192
  this.executed.push(executer);
@@ -1164,39 +1206,35 @@ var PluginManager = class {
1164
1206
  plugin
1165
1207
  }) {
1166
1208
  const hook = plugin[hookName];
1209
+ let output;
1167
1210
  if (!hook) {
1168
1211
  return null;
1169
1212
  }
1170
- return Promise.resolve().then(() => {
1171
- this.executer = {
1172
- strategy,
1173
- hookName,
1174
- plugin
1175
- };
1213
+ const task = Promise.resolve().then(() => {
1176
1214
  if (typeof hook === "function") {
1177
- const hookResult = hook.apply(this.core.api, parameters);
1178
- if (isPromise(hookResult)) {
1179
- return Promise.resolve(hookResult).then((result) => {
1180
- this.addExecuter({
1181
- strategy,
1182
- hookName,
1183
- plugin
1184
- });
1185
- return result;
1186
- });
1215
+ const possiblePromiseResult = hook.apply(this.core.api, parameters);
1216
+ if (isPromise(possiblePromiseResult)) {
1217
+ return Promise.resolve(possiblePromiseResult);
1187
1218
  }
1188
- return hookResult;
1219
+ return possiblePromiseResult;
1189
1220
  }
1190
- this.addExecuter({
1191
- strategy,
1192
- hookName,
1193
- plugin
1194
- });
1195
1221
  return hook;
1222
+ }).then((result) => {
1223
+ output = result;
1224
+ return result;
1196
1225
  }).catch((e) => {
1197
1226
  this.catcher(e, plugin, hookName);
1198
1227
  return null;
1228
+ }).finally(() => {
1229
+ this.addExecutedToCallStack({
1230
+ input: parameters,
1231
+ output,
1232
+ strategy,
1233
+ hookName,
1234
+ plugin
1235
+ });
1199
1236
  });
1237
+ return this.queue.run(() => task);
1200
1238
  }
1201
1239
  /**
1202
1240
  * Run a sync plugin hook and return the result.
@@ -1212,33 +1250,29 @@ var PluginManager = class {
1212
1250
  plugin
1213
1251
  }) {
1214
1252
  const hook = plugin[hookName];
1253
+ let output;
1215
1254
  if (!hook) {
1216
1255
  return null;
1217
1256
  }
1218
1257
  try {
1219
- this.executer = {
1220
- strategy,
1221
- hookName,
1222
- plugin
1223
- };
1224
1258
  if (typeof hook === "function") {
1225
1259
  const fn = hook.apply(this.core.api, parameters);
1226
- this.addExecuter({
1227
- strategy,
1228
- hookName,
1229
- plugin
1230
- });
1260
+ output = fn;
1231
1261
  return fn;
1232
1262
  }
1233
- this.addExecuter({
1234
- strategy,
1235
- hookName,
1236
- plugin
1237
- });
1263
+ output = hook;
1238
1264
  return hook;
1239
1265
  } catch (e) {
1240
1266
  this.catcher(e, plugin, hookName);
1241
1267
  return null;
1268
+ } finally {
1269
+ this.addExecutedToCallStack({
1270
+ input: parameters,
1271
+ output,
1272
+ strategy,
1273
+ hookName,
1274
+ plugin
1275
+ });
1242
1276
  }
1243
1277
  }
1244
1278
  catcher(e, plugin, hookName) {
@@ -1269,12 +1303,19 @@ function validatePlugins(plugins, dependedPluginNames) {
1269
1303
  return true;
1270
1304
  }
1271
1305
 
1306
+ // src/types.ts
1307
+ var LogLevel = {
1308
+ silent: "silent",
1309
+ info: "info",
1310
+ stacktrace: "stacktrace"
1311
+ };
1312
+
1272
1313
  // src/build.ts
1273
1314
  async function transformReducer(_previousCode, result, _plugin) {
1274
1315
  return result;
1275
1316
  }
1276
1317
  async function build(options) {
1277
- const { config, logger = createLogger() } = options;
1318
+ const { config, debug, logger = createLogger() } = options;
1278
1319
  try {
1279
1320
  if (!isURL(config.input.path)) {
1280
1321
  await read(config.input.path);
@@ -1285,7 +1326,7 @@ async function build(options) {
1285
1326
  if (config.output.clean) {
1286
1327
  await clean(config.output.path);
1287
1328
  }
1288
- const queueTask = async (id, file) => {
1329
+ const queueTask = async (file) => {
1289
1330
  const { path } = file;
1290
1331
  let code = getFileSource(file);
1291
1332
  const { result: loadedResult } = await pluginManager.hookFirst({
@@ -1316,13 +1357,27 @@ async function build(options) {
1316
1357
  if (!executer) {
1317
1358
  return;
1318
1359
  }
1319
- const { hookName, plugin } = executer;
1320
- if (config.logLevel === "info") {
1321
- const messsage = `\u{1FA82} Executing ${hookName || "unknown"}(${pc__default.default.yellow(plugin.name || "unknown")})`;
1322
- logger.log(messsage);
1360
+ const { hookName, plugin, output, input } = executer;
1361
+ const messsage = `${randomPicoColour(plugin.name)} Executing ${hookName}`;
1362
+ if (config.logLevel === LogLevel.info && logger?.spinner && input) {
1363
+ if (debug) {
1364
+ logger.info(messsage);
1365
+ } else {
1366
+ logger.spinner.suffixText = messsage;
1367
+ }
1368
+ }
1369
+ if (config.logLevel === LogLevel.stacktrace && logger?.spinner && input) {
1370
+ logger.info(messsage);
1371
+ const logs = [
1372
+ input && `${pc2__default.default.bgWhite(`Input`)} ${randomPicoColour(plugin.name)} ${hookName}`,
1373
+ JSON.stringify(input, void 0, 2),
1374
+ output && `${pc2__default.default.bgWhite("Output")} ${randomPicoColour(plugin.name)} ${hookName}`,
1375
+ output
1376
+ ].filter(Boolean);
1377
+ console.log(logs.join("\n"));
1323
1378
  }
1324
1379
  };
1325
- const pluginManager = new PluginManager(config, { logger, task: queueTask, onExecute });
1380
+ const pluginManager = new PluginManager(config, { debug, logger, task: queueTask, onExecute });
1326
1381
  const { plugins, fileManager } = pluginManager;
1327
1382
  await pluginManager.hookParallel({
1328
1383
  hookName: "validate",
@@ -1365,10 +1420,11 @@ var src_default = build;
1365
1420
 
1366
1421
  Object.defineProperty(exports, 'pc', {
1367
1422
  enumerable: true,
1368
- get: function () { return pc__default.default; }
1423
+ get: function () { return pc2__default.default; }
1369
1424
  });
1370
1425
  exports.FileManager = FileManager;
1371
1426
  exports.Generator = Generator;
1427
+ exports.LogLevel = LogLevel;
1372
1428
  exports.ParallelPluginError = ParallelPluginError;
1373
1429
  exports.PluginError = PluginError;
1374
1430
  exports.PluginManager = PluginManager;
@@ -1379,6 +1435,7 @@ exports.TreeNode = TreeNode;
1379
1435
  exports.ValidationPluginError = ValidationPluginError;
1380
1436
  exports.Warning = Warning;
1381
1437
  exports.build = build;
1438
+ exports.canLogHierarchy = canLogHierarchy;
1382
1439
  exports.clean = clean;
1383
1440
  exports.combineFiles = combineFiles;
1384
1441
  exports.createJSDocBlockText = createJSDocBlockText;
@@ -1386,6 +1443,7 @@ exports.createLogger = createLogger;
1386
1443
  exports.createPlugin = createPlugin;
1387
1444
  exports.createPluginCache = createPluginCache;
1388
1445
  exports.default = src_default;
1446
+ exports.defaultColours = defaultColours;
1389
1447
  exports.defineConfig = defineConfig;
1390
1448
  exports.extensions = extensions;
1391
1449
  exports.getEncodedText = getEncodedText;
@@ -1406,6 +1464,8 @@ exports.nameSorter = nameSorter;
1406
1464
  exports.normalizeDirectory = normalizeDirectory;
1407
1465
  exports.objectToParameters = objectToParameters;
1408
1466
  exports.pluginName = pluginName;
1467
+ exports.randomColour = randomColour;
1468
+ exports.randomPicoColour = randomPicoColour;
1409
1469
  exports.read = read;
1410
1470
  exports.renderTemplate = renderTemplate;
1411
1471
  exports.throttle = throttle;