@kubb/core 1.0.0-beta.1 → 1.0.0-beta.11

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
@@ -2,9 +2,9 @@ import { createRequire } from 'module';
2
2
  import pathParser2 from 'path';
3
3
  import { promises } from 'fs';
4
4
  import rimraf from 'rimraf';
5
- import uniq from 'lodash.uniq';
6
5
  import { v4 } from 'uuid';
7
6
  import dirTree from 'directory-tree';
7
+ import uniq from 'lodash.uniq';
8
8
 
9
9
  createRequire(import.meta.url);
10
10
 
@@ -139,7 +139,7 @@ function nameSorter(a, b) {
139
139
  function createJSDocBlockText({ comments }) {
140
140
  const filteredComments = comments.filter(Boolean);
141
141
  if (!filteredComments.length) {
142
- return void 0;
142
+ return "";
143
143
  }
144
144
  const text = filteredComments.reduce((acc, comment) => {
145
145
  return `${acc}
@@ -197,6 +197,22 @@ var Queue = class {
197
197
  }
198
198
  };
199
199
 
200
+ // src/utils/getEncodedText.ts
201
+ function getEncodedText(text) {
202
+ return text ? text.replaceAll("`", "\\`") : "";
203
+ }
204
+
205
+ // src/utils/renderTemplate.ts
206
+ function renderTemplate(template, data = void 0) {
207
+ if (!data) {
208
+ return template.replace(/{{(.*?)}}/g, "");
209
+ }
210
+ return template.replace(/{{(.*?)}}/g, (match) => {
211
+ const value = data[match.split(/{{|}}/).filter(Boolean)[0].trim()];
212
+ return value || "";
213
+ });
214
+ }
215
+
200
216
  // src/plugin.ts
201
217
  function createPlugin(factory) {
202
218
  return (options) => {
@@ -214,7 +230,7 @@ function createPlugin(factory) {
214
230
  }
215
231
  var name = "core";
216
232
  var definePlugin = createPlugin((options) => {
217
- const { fileManager, resolveId, load } = options;
233
+ const { fileManager, resolvePath, resolveName, load } = options;
218
234
  const api = {
219
235
  get config() {
220
236
  return options.config;
@@ -223,7 +239,8 @@ var definePlugin = createPlugin((options) => {
223
239
  async addFile(file) {
224
240
  return fileManager.addOrAppend(file);
225
241
  },
226
- resolveId,
242
+ resolvePath,
243
+ resolveName,
227
244
  load,
228
245
  cache: createPluginCache(/* @__PURE__ */ Object.create(null))
229
246
  };
@@ -231,11 +248,14 @@ var definePlugin = createPlugin((options) => {
231
248
  name,
232
249
  options,
233
250
  api,
234
- resolveId(fileName, directory) {
251
+ resolvePath(fileName, directory) {
235
252
  if (!directory) {
236
253
  return null;
237
254
  }
238
255
  return pathParser2.resolve(directory, fileName);
256
+ },
257
+ resolveName(name2) {
258
+ return name2;
239
259
  }
240
260
  };
241
261
  });
@@ -261,35 +281,6 @@ var FileManager = class {
261
281
  });
262
282
  return cache;
263
283
  }
264
- getSource(file) {
265
- if (!file.fileName.endsWith(".ts")) {
266
- return file.source;
267
- }
268
- const imports = [];
269
- file.imports?.forEach((curr) => {
270
- const exists = imports.find((imp) => imp.path === curr.path);
271
- if (!exists) {
272
- imports.push(curr);
273
- return;
274
- }
275
- if (exists && Array.isArray(curr.name)) {
276
- exists.name = uniq([...exists.name, ...curr.name]);
277
- }
278
- });
279
- const importSource = imports.reduce((prev, curr) => {
280
- if (Array.isArray(curr.name)) {
281
- return `${prev}
282
- import ${curr.isTypeOnly ? "type " : ""}{ ${curr.name.join(", ")} } from "${curr.path}";`;
283
- }
284
- return `${prev}
285
- import ${curr.isTypeOnly ? "type " : ""}${curr.name} from "${curr.path}";`;
286
- }, "");
287
- if (importSource) {
288
- return `${importSource}
289
- ${file.source}`;
290
- }
291
- return file.source;
292
- }
293
284
  get files() {
294
285
  const files = [];
295
286
  this.cache.forEach((item) => {
@@ -308,8 +299,13 @@ ${file.source}`;
308
299
  return file;
309
300
  }
310
301
  addOrAppend(file) {
302
+ if (!file.path.endsWith(file.fileName)) ;
311
303
  const previousCache = this.getCacheByPath(file.path);
312
304
  if (previousCache) {
305
+ const sourceAlreadyExists = previousCache.file.source.includes(file.source);
306
+ if (sourceAlreadyExists) {
307
+ return Promise.resolve(file);
308
+ }
313
309
  this.cache.delete(previousCache.id);
314
310
  return this.add({
315
311
  ...file,
@@ -320,26 +316,6 @@ ${file.source}`,
320
316
  }
321
317
  return this.add(file);
322
318
  }
323
- combine(files) {
324
- return files.filter(Boolean).reduce((acc, curr) => {
325
- if (!curr) {
326
- return acc;
327
- }
328
- const prevIndex = acc.findIndex((item) => item.path === curr.path);
329
- if (prevIndex !== -1) {
330
- const prev = acc[prevIndex];
331
- acc[prevIndex] = {
332
- ...curr,
333
- source: `${prev.source}
334
- ${curr.source}`,
335
- imports: [...prev.imports || [], ...curr.imports || []]
336
- };
337
- } else {
338
- acc.push(curr);
339
- }
340
- return acc;
341
- }, []);
342
- }
343
319
  setStatus(id, status) {
344
320
  const cacheItem = this.getCache(id);
345
321
  if (!cacheItem) {
@@ -445,12 +421,69 @@ var TreeNode = class {
445
421
  return treeNode;
446
422
  }
447
423
  };
424
+ function combineFiles(files) {
425
+ return files.filter(Boolean).reduce((acc, curr) => {
426
+ if (!curr) {
427
+ return acc;
428
+ }
429
+ const prevIndex = acc.findIndex((item) => item.path === curr.path);
430
+ if (prevIndex !== -1) {
431
+ const prev = acc[prevIndex];
432
+ acc[prevIndex] = {
433
+ ...curr,
434
+ source: `${prev.source}
435
+ ${curr.source}`,
436
+ imports: [...prev.imports || [], ...curr.imports || []]
437
+ };
438
+ } else {
439
+ acc.push(curr);
440
+ }
441
+ return acc;
442
+ }, []);
443
+ }
444
+ function getFileSource(file) {
445
+ if (!file.fileName.endsWith(".ts")) {
446
+ return file.source;
447
+ }
448
+ const imports = [];
449
+ file.imports?.forEach((curr) => {
450
+ const exists = imports.find((imp) => imp.path === curr.path);
451
+ if (!exists) {
452
+ imports.push({
453
+ ...curr,
454
+ name: Array.isArray(curr.name) ? uniq(curr.name) : curr.name
455
+ });
456
+ }
457
+ if (exists && !Array.isArray(exists.name) && exists.name !== curr.name) {
458
+ imports.push(curr);
459
+ }
460
+ if (exists && Array.isArray(exists.name)) {
461
+ if (Array.isArray(curr.name)) {
462
+ exists.name = uniq([...exists.name, ...curr.name]);
463
+ }
464
+ }
465
+ });
466
+ const importSource = imports.reduce((prev, curr) => {
467
+ if (Array.isArray(curr.name)) {
468
+ return `${prev}
469
+ import ${curr.isTypeOnly ? "type " : ""}{ ${curr.name.join(", ")} } from "${curr.path}";`;
470
+ }
471
+ return `${prev}
472
+ import ${curr.isTypeOnly ? "type " : ""}${curr.name} from "${curr.path}";`;
473
+ }, "");
474
+ if (importSource) {
475
+ return `${importSource}
476
+ ${file.source}`;
477
+ }
478
+ return file.source;
479
+ }
448
480
 
449
481
  // src/managers/pluginManager/PluginManager.ts
450
482
  var hookNames = {
451
483
  validate: 1,
452
484
  buildStart: 1,
453
- resolveId: 1,
485
+ resolvePath: 1,
486
+ resolveName: 1,
454
487
  load: 1,
455
488
  transform: 1,
456
489
  writeFile: 1,
@@ -473,95 +506,196 @@ var PluginManager = class {
473
506
  config,
474
507
  fileManager: this.fileManager,
475
508
  load: this.load,
476
- resolveId: this.resolveId
509
+ resolvePath: this.resolvePath,
510
+ resolveName: this.resolveName
477
511
  });
478
512
  this.plugins = [this.core, ...config.plugins || []];
479
513
  }
480
- resolveId = (params) => {
514
+ resolvePath = (params) => {
481
515
  if (params.pluginName) {
482
- return this.hookForPlugin(params.pluginName, "resolveId", [params.fileName, params.directory, params.options]);
516
+ return this.hookForPluginSync({
517
+ pluginName: params.pluginName,
518
+ hookName: "resolvePath",
519
+ parameters: [params.fileName, params.directory, params.options]
520
+ });
483
521
  }
484
- return this.hookFirst("resolveId", [params.fileName, params.directory, params.options]);
522
+ return this.hookFirstSync({
523
+ hookName: "resolvePath",
524
+ parameters: [params.fileName, params.directory, params.options]
525
+ });
526
+ };
527
+ resolveName = (params) => {
528
+ if (params.pluginName) {
529
+ return this.hookForPluginSync({
530
+ pluginName: params.pluginName,
531
+ hookName: "resolveName",
532
+ parameters: [params.name]
533
+ });
534
+ }
535
+ return this.hookFirstSync({
536
+ hookName: "resolveName",
537
+ parameters: [params.name]
538
+ });
485
539
  };
486
540
  load = async (id) => {
487
- return this.hookFirst("load", [id]);
541
+ return this.hookFirst({
542
+ hookName: "load",
543
+ parameters: [id]
544
+ });
488
545
  };
489
- // run only hook for a specific plugin name
490
- hookForPlugin(pluginName, hookName, parameters, skipped) {
546
+ /**
547
+ *
548
+ * Run only hook for a specific plugin name
549
+ */
550
+ hookForPlugin({
551
+ pluginName,
552
+ hookName,
553
+ parameters
554
+ }) {
555
+ const plugin = this.getPlugin(hookName, pluginName);
556
+ return this.run({
557
+ strategy: "hookFirst",
558
+ hookName,
559
+ parameters,
560
+ plugin
561
+ });
562
+ }
563
+ hookForPluginSync({
564
+ pluginName,
565
+ hookName,
566
+ parameters
567
+ }) {
568
+ const plugin = this.getPlugin(hookName, pluginName);
569
+ return this.runSync({
570
+ strategy: "hookFirst",
571
+ hookName,
572
+ parameters,
573
+ plugin
574
+ });
575
+ }
576
+ /**
577
+ *
578
+ * Chains, first non-null result stops and returns
579
+ */
580
+ hookFirst({
581
+ hookName,
582
+ parameters,
583
+ skipped
584
+ }) {
491
585
  let promise = Promise.resolve(null);
492
- for (const plugin of this.getSortedPlugins(hookName, pluginName)) {
586
+ for (const plugin of this.getSortedPlugins(hookName)) {
493
587
  if (skipped && skipped.has(plugin))
494
588
  continue;
495
589
  promise = promise.then((result) => {
496
590
  if (result != null)
497
591
  return result;
498
- return this.run("hookFirst", hookName, parameters, plugin);
592
+ return this.run({
593
+ strategy: "hookFirst",
594
+ hookName,
595
+ parameters,
596
+ plugin
597
+ });
499
598
  });
500
599
  }
501
600
  return promise;
502
601
  }
503
- // chains, first non-null result stops and returns
504
- hookFirst(hookName, parameters, skipped) {
505
- let promise = Promise.resolve(null);
602
+ /**
603
+ *
604
+ * Chains, first non-null result stops and returns
605
+ */
606
+ hookFirstSync({
607
+ hookName,
608
+ parameters,
609
+ skipped
610
+ }) {
611
+ let result = null;
506
612
  for (const plugin of this.getSortedPlugins(hookName)) {
507
613
  if (skipped && skipped.has(plugin))
508
614
  continue;
509
- promise = promise.then((result) => {
510
- if (result != null)
511
- return result;
512
- return this.run("hookFirst", hookName, parameters, plugin);
615
+ result = this.runSync({
616
+ strategy: "hookFirst",
617
+ hookName,
618
+ parameters,
619
+ plugin
513
620
  });
621
+ if (result != null) {
622
+ break;
623
+ }
514
624
  }
515
- return promise;
625
+ return result;
516
626
  }
517
627
  // parallel
518
- async hookParallel(hookName, parameters) {
628
+ async hookParallel({
629
+ hookName,
630
+ parameters
631
+ }) {
519
632
  const parallelPromises = [];
520
633
  for (const plugin of this.getSortedPlugins(hookName)) {
521
634
  if (plugin[hookName]?.sequential) {
522
635
  await Promise.all(parallelPromises);
523
636
  parallelPromises.length = 0;
524
- await this.run("hookParallel", hookName, parameters, plugin);
637
+ await this.run({
638
+ strategy: "hookParallel",
639
+ hookName,
640
+ parameters,
641
+ plugin
642
+ });
525
643
  } else {
526
- const promise = this.run("hookParallel", hookName, parameters, plugin);
644
+ const promise = this.run({ strategy: "hookParallel", hookName, parameters, plugin });
527
645
  parallelPromises.push(promise);
528
646
  }
529
647
  }
530
648
  return Promise.all(parallelPromises);
531
649
  }
532
650
  // chains, reduces returned value, handling the reduced value as the first hook argument
533
- hookReduceArg0(hookName, [argument0, ...rest], reduce) {
651
+ hookReduceArg0({
652
+ hookName,
653
+ parameters,
654
+ reduce
655
+ }) {
656
+ const [argument0, ...rest] = parameters;
534
657
  let promise = Promise.resolve(argument0);
535
658
  for (const plugin of this.getSortedPlugins(hookName)) {
536
659
  promise = promise.then(
537
- (argument02) => this.run("hookReduceArg0", hookName, [argument02, ...rest], plugin).then(
538
- (result) => reduce.call(this.core.api, argument02, result, plugin)
539
- )
660
+ (argument02) => this.run({
661
+ strategy: "hookReduceArg0",
662
+ hookName,
663
+ parameters: [argument02, ...rest],
664
+ plugin
665
+ }).then((result) => reduce.call(this.core.api, argument02, result, plugin))
540
666
  );
541
667
  }
542
668
  return promise;
543
669
  }
544
670
  // chains
545
- hookSeq(hookName, parameters) {
671
+ hookSeq({ hookName, parameters }) {
546
672
  let promise = Promise.resolve();
547
673
  for (const plugin of this.getSortedPlugins(hookName)) {
548
- promise = promise.then(() => this.run("hookSeq", hookName, parameters, plugin));
674
+ promise = promise.then(
675
+ () => this.run({
676
+ strategy: "hookSeq",
677
+ hookName,
678
+ parameters,
679
+ plugin
680
+ })
681
+ );
549
682
  }
550
683
  return promise.then(noReturn);
551
684
  }
552
- getSortedPlugins(hookName, pluginName) {
685
+ getSortedPlugins(_hookName) {
553
686
  const plugins = [...this.plugins];
554
- if (pluginName) {
555
- const pluginsByPluginName = plugins.filter((item) => item.name === pluginName && item[hookName]);
556
- if (pluginsByPluginName.length === 0) {
557
- if (this.config.logLevel === "warn" && this.logger?.spinner) {
558
- this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`);
559
- }
560
- return [this.core];
687
+ return plugins;
688
+ }
689
+ getPlugin(hookName, pluginName) {
690
+ const plugins = [...this.plugins];
691
+ const pluginByPluginName = plugins.find((item) => item.name === pluginName && item[hookName]);
692
+ if (!pluginByPluginName) {
693
+ if (this.config.logLevel === "warn" && this.logger?.spinner) {
694
+ this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`);
561
695
  }
562
- return pluginsByPluginName;
696
+ return this.core;
563
697
  }
564
- return plugins;
698
+ return pluginByPluginName;
565
699
  }
566
700
  /**
567
701
  * Run an async plugin hook and return the result.
@@ -570,7 +704,12 @@ var PluginManager = class {
570
704
  * @param plugin The actual pluginObject to run.
571
705
  */
572
706
  // Implementation signature
573
- run(strategy, hookName, parameters, plugin) {
707
+ run({
708
+ strategy,
709
+ hookName,
710
+ parameters,
711
+ plugin
712
+ }) {
574
713
  const hook = plugin[hookName];
575
714
  return Promise.resolve().then(() => {
576
715
  if (typeof hook !== "function") {
@@ -606,12 +745,21 @@ var PluginManager = class {
606
745
  * @param plugin The acutal plugin
607
746
  * @param replaceContext When passed, the plugin context can be overridden.
608
747
  */
609
- runSync(hookName, parameters, plugin) {
748
+ runSync({
749
+ strategy,
750
+ hookName,
751
+ parameters,
752
+ plugin
753
+ }) {
610
754
  const hook = plugin[hookName];
611
755
  try {
756
+ if (typeof hook !== "function") {
757
+ return hook;
758
+ }
612
759
  return hook.apply(this.core.api, parameters);
613
- } catch (error) {
614
- return error;
760
+ } catch (e) {
761
+ this.catcher(e, plugin, hookName);
762
+ return null;
615
763
  }
616
764
  }
617
765
  catcher(e, plugin, hookName) {
@@ -649,43 +797,60 @@ async function transformReducer(_previousCode, result, _plugin) {
649
797
  }
650
798
  return result;
651
799
  }
652
- async function buildImplementation(options, done) {
800
+ async function buildImplementation(options) {
653
801
  const { config, logger } = options;
654
802
  if (config.output.clean) {
655
803
  await clean(config.output.path);
656
804
  }
657
805
  const queueTask = async (id, file) => {
658
806
  const { path } = file;
659
- let code = fileManager.getSource(file);
660
- const loadedResult = await pluginManager.hookFirst("load", [path]);
807
+ let code = getFileSource(file);
808
+ const loadedResult = await pluginManager.hookFirst({
809
+ hookName: "load",
810
+ parameters: [path]
811
+ });
661
812
  if (loadedResult) {
662
813
  code = loadedResult;
663
814
  }
664
815
  if (code) {
665
- const transformedCode = await pluginManager.hookReduceArg0("transform", [code, path], transformReducer);
816
+ const transformedCode = await pluginManager.hookReduceArg0({
817
+ hookName: "transform",
818
+ parameters: [code, path],
819
+ reduce: transformReducer
820
+ });
666
821
  if (config.output.write || config.output.write === void 0) {
667
- await pluginManager.hookParallel("writeFile", [transformedCode, path]);
822
+ await pluginManager.hookParallel({
823
+ hookName: "writeFile",
824
+ parameters: [transformedCode, path]
825
+ });
668
826
  }
669
827
  }
670
828
  };
671
829
  const pluginManager = new PluginManager(config, { logger, task: queueTask });
672
830
  const { plugins, fileManager } = pluginManager;
673
- await pluginManager.hookParallel("validate", [plugins]);
674
- await pluginManager.hookParallel("buildStart", [config]);
675
- await pluginManager.hookParallel("buildEnd");
676
- setTimeout(() => {
677
- done({ files: fileManager.files.map((file) => ({ ...file, source: fileManager.getSource(file) })) });
678
- }, 500);
831
+ await pluginManager.hookParallel({
832
+ hookName: "validate",
833
+ parameters: [plugins]
834
+ });
835
+ await pluginManager.hookParallel({
836
+ hookName: "buildStart",
837
+ parameters: [config]
838
+ });
679
839
  pluginManager.fileManager.add({
680
840
  path: isURL(config.input.path) ? config.input.path : pathParser2.resolve(config.root, config.input.path),
681
841
  fileName: isURL(config.input.path) ? "input" : config.input.path,
682
842
  source: isURL(config.input.path) ? config.input.path : await read(pathParser2.resolve(config.root, config.input.path))
683
843
  });
844
+ await pluginManager.hookParallel({ hookName: "buildEnd" });
845
+ return { files: fileManager.files.map((file) => ({ ...file, source: getFileSource(file) })) };
684
846
  }
685
847
  function build(options) {
686
848
  return new Promise(async (resolve, reject) => {
687
849
  try {
688
- await buildImplementation(options, resolve);
850
+ const output = await buildImplementation(options);
851
+ setTimeout(() => {
852
+ resolve(output);
853
+ }, 500);
689
854
  } catch (e) {
690
855
  reject(e);
691
856
  }
@@ -719,6 +884,6 @@ var SchemaGenerator = class extends Generator {
719
884
  // src/index.ts
720
885
  var src_default = build;
721
886
 
722
- export { FileManager, Generator, PluginManager, Queue, SchemaGenerator, TreeNode, ValidationPluginError, build, clean, createJSDocBlockText, createPlugin, createPluginCache, src_default as default, defineConfig, getPathMode, getRelativePath, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, timeout, validatePlugins, write };
887
+ export { FileManager, Generator, PluginManager, Queue, SchemaGenerator, TreeNode, ValidationPluginError, build, clean, combineFiles, createJSDocBlockText, createPlugin, createPluginCache, src_default as default, defineConfig, getEncodedText, getFileSource, getPathMode, getRelativePath, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, renderTemplate, timeout, validatePlugins, write };
723
888
  //# sourceMappingURL=out.js.map
724
889
  //# sourceMappingURL=index.js.map