@kubb/core 1.1.7 → 1.1.8

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/README.md CHANGED
@@ -5,38 +5,45 @@
5
5
 
6
6
  <p>
7
7
  Core utils for other packages.
8
- </p>
8
+ </p>
9
+ <img src="https://raw.githubusercontent.com/kubb-project/kubb/main/assets/banner.png" alt="logo" height="auto" />
9
10
 
10
- <!-- Badges -->
11
- <p>
12
- <a href="https://www.npmjs.com/package/@kubb/core">
11
+ <!-- Badges -->
12
+ <p>
13
+ <a href="https://www.npmjs.com/package/@kubb/core" target="_blank">
13
14
  <img alt="npm version" src="https://img.shields.io/npm/v/@kubb/core?style=for-the-badge"/>
14
15
  </a>
15
- <a href="https://www.npmjs.com/package/@kubb/core">
16
- <img alt="npm downloads" src="https://img.shields.io/bundlephobia/min/@kubb/core?style=for-the-badge"/>
17
- </a>
18
- <a href="https://www.npmjs.com/package/@kubb/core">
16
+
17
+ <a href="https://www.npmjs.com/package/@kubb/core" target="_blank">
19
18
  <img alt="npm downloads" src="https://img.shields.io/npm/dm/@kubb/core?style=for-the-badge"/>
20
19
  </a>
21
- </p>
20
+ </p>
21
+
22
+ <p>
23
+ <a href="https://www.npmjs.com/package/@kubb/core" target="_blank">
24
+ <img alt="Minified size" src="https://img.shields.io/bundlephobia/min/@kubb/core?style=for-the-badge"/>
25
+ </a>
26
+
27
+ <a href="https://www.npmjs.com/package/@kubb/core" target="_blank">
28
+ <img alt="Coverage" src="https://img.shields.io/codecov/c/github/kubb-project/kubb?style=for-the-badge"/>
29
+ </a>
30
+
31
+ <a href="https://www.npmjs.com/package/@kubb/core" target="_blank">
32
+ <img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/kubb-project/kubb/ci.yaml?style=for-the-badge"/>
33
+ </a>
34
+
35
+
36
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
37
+ <!-- ALL-CONTRIBUTORS-BADGE:END -->
38
+ </p>
22
39
 
23
- <h4>
24
- <a href="https://codesandbox.io/s/github/kubb-project/kubb/tree/main/examples/simple">View Demo</a>
25
- <span> · </span>
26
- <a href="https://kubb.dev/" target="_blank">Documentation</a>
27
- <span> · </span>
28
- <a href="https://github.com/kubb-project/kubb/issues/">Report Bug</a>
29
- <span> · </span>
30
- <a href="https://github.com/kubb-project/kubb/issues/">Request Feature</a>
40
+ <h4>
41
+ <a href="https://codesandbox.io/s/github/kubb-project/kubb/tree/main/examples/simple" target="_blank">View Demo</a>
42
+ <span> · </span>
43
+ <a href="https://kubb.dev/" target="_blank">Documentation</a>
44
+ <span> · </span>
45
+ <a href="https://github.com/kubb-project/kubb/issues/" target="_blank">Report Bug</a>
46
+ <span> · </span>
47
+ <a href="https://github.com/kubb-project/kubb/issues/" target="_blank">Request Feature</a>
31
48
  </h4>
32
49
  </div>
33
-
34
- <br />
35
-
36
- <!-- About the Project
37
- ## :star2: About the Project
38
-
39
- <div align="center">
40
- <img src="assets/screenshot.jpg" alt="screenshot" />
41
- </div>
42
- -->
package/dist/index.cjs CHANGED
@@ -66,19 +66,19 @@ function createPluginCache(cache) {
66
66
  }
67
67
  };
68
68
  }
69
- function slash(path) {
69
+ function slash(path, platform = "linux") {
70
70
  const isExtendedLengthPath = /^\\\\\?\\/.test(path);
71
- if (isExtendedLengthPath) {
72
- return path;
71
+ if (isExtendedLengthPath || platform === "linux" || platform === "mac") {
72
+ return path.replace("../", "").trimEnd();
73
73
  }
74
- return path.replace(/\\/g, "/");
74
+ return path.replace(/\\/g, "/").replace("../", "").trimEnd();
75
75
  }
76
- function getRelativePath(rootDir, filePath) {
76
+ function getRelativePath(rootDir, filePath, platform = "linux") {
77
77
  if (!rootDir || !filePath) {
78
78
  throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir} ${filePath}`);
79
79
  }
80
80
  const relativePath = pathParser2__default.default.relative(rootDir, filePath);
81
- const path = slash(relativePath).replace("../", "").trimEnd();
81
+ const path = slash(relativePath, platform);
82
82
  if (path.startsWith("../")) {
83
83
  return path.replace(pathParser2__default.default.basename(path), pathParser2__default.default.basename(path, pathParser2__default.default.extname(filePath)));
84
84
  }
@@ -91,12 +91,7 @@ function getPathMode(path) {
91
91
  return pathParser2__default.default.extname(path) ? "file" : "directory";
92
92
  }
93
93
  async function read(path) {
94
- try {
95
- return fs.promises.readFile(path, { encoding: "utf8" });
96
- } catch (err) {
97
- console.error(err);
98
- throw err;
99
- }
94
+ return fs.promises.readFile(path, { encoding: "utf8" });
100
95
  }
101
96
 
102
97
  // src/utils/isURL.ts
@@ -233,10 +228,13 @@ var TreeNode = class {
233
228
  return child;
234
229
  }
235
230
  find(data) {
231
+ if (!data) {
232
+ return null;
233
+ }
236
234
  if (data === this.data) {
237
235
  return this;
238
236
  }
239
- if (this.children) {
237
+ if (this.children?.length) {
240
238
  for (let i = 0, { length } = this.children, target = null; i < length; i++) {
241
239
  target = this.children[i].find(data);
242
240
  if (target) {
@@ -246,23 +244,23 @@ var TreeNode = class {
246
244
  }
247
245
  return null;
248
246
  }
249
- leaves() {
247
+ get leaves() {
250
248
  if (!this.children || this.children.length === 0) {
251
249
  return [this];
252
250
  }
253
251
  const leaves = [];
254
252
  if (this.children) {
255
253
  for (let i = 0, { length } = this.children; i < length; i++) {
256
- leaves.push.apply(leaves, this.children[i].leaves());
254
+ leaves.push.apply(leaves, this.children[i].leaves);
257
255
  }
258
256
  }
259
257
  return leaves;
260
258
  }
261
- root() {
259
+ get root() {
262
260
  if (!this.parent) {
263
261
  return this;
264
262
  }
265
- return this.parent.root();
263
+ return this.parent.root;
266
264
  }
267
265
  forEach(callback) {
268
266
  if (typeof callback !== "function") {
@@ -277,21 +275,26 @@ var TreeNode = class {
277
275
  return this;
278
276
  }
279
277
  static build(path, options = {}) {
280
- const filteredTree = dirTree__default.default(path, { extensions: options?.extensions, exclude: options.exclude });
281
- if (!filteredTree) {
282
- return null;
283
- }
284
- const treeNode = new TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type });
285
- const recurse = (node, item) => {
286
- const subNode = node.addChild({ name: item.name, path: item.path, type: item.type });
287
- if (item.children?.length) {
288
- item.children?.forEach((child) => {
289
- recurse(subNode, child);
290
- });
278
+ try {
279
+ const exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude].filter(Boolean);
280
+ const filteredTree = dirTree__default.default(path, { extensions: options.extensions, exclude: [/node_modules/, ...exclude] });
281
+ if (!filteredTree) {
282
+ return null;
291
283
  }
292
- };
293
- filteredTree.children?.forEach((child) => recurse(treeNode, child));
294
- return treeNode;
284
+ const treeNode = new TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type || getPathMode(filteredTree.path) });
285
+ const recurse = (node, item) => {
286
+ const subNode = node.addChild({ name: item.name, path: item.path, type: item.type || getPathMode(item.path) });
287
+ if (item.children?.length) {
288
+ item.children?.forEach((child) => {
289
+ recurse(subNode, child);
290
+ });
291
+ }
292
+ };
293
+ filteredTree.children?.forEach((child) => recurse(treeNode, child));
294
+ return treeNode;
295
+ } catch (e) {
296
+ throw new Error("Something went wrong with creating index files with the TreehNode class", { cause: e });
297
+ }
295
298
  }
296
299
  };
297
300
 
@@ -404,6 +407,9 @@ function getStackTrace(belowFn) {
404
407
  return v8StackTrace;
405
408
  }
406
409
 
410
+ // src/utils/uniqueId.ts
411
+ var uniqueId = ((counter) => (str = "") => `${str}${++counter}`)(0);
412
+
407
413
  // src/managers/fileManager/FileManager.ts
408
414
  var FileManager = class {
409
415
  cache = /* @__PURE__ */ new Map();
@@ -496,18 +502,18 @@ ${file.source}`,
496
502
  return read(...params);
497
503
  }
498
504
  };
499
- function writeIndexes(root, options) {
505
+ function writeIndexes(root, options = {}) {
500
506
  const tree = TreeNode.build(root, { extensions: /\.ts/, ...options });
501
507
  if (!tree) {
502
- return void 0;
508
+ return null;
503
509
  }
504
- const fileReducer = (files2, item) => {
505
- if (!item.children) {
510
+ const fileReducer = (files2, currentTree) => {
511
+ if (!currentTree.children) {
506
512
  return [];
507
513
  }
508
- if (item.children?.length > 1) {
509
- const path = pathParser2__default.default.resolve(item.data.path, "index.ts");
510
- const exports = item.children.map((file) => {
514
+ if (currentTree.children?.length > 1) {
515
+ const path = pathParser2__default.default.resolve(currentTree.data.path, "index.ts");
516
+ const exports = currentTree.children.map((file) => {
511
517
  if (!file) {
512
518
  return void 0;
513
519
  }
@@ -524,8 +530,8 @@ function writeIndexes(root, options) {
524
530
  exports
525
531
  });
526
532
  } else {
527
- item.children?.forEach((child) => {
528
- const path = pathParser2__default.default.resolve(item.data.path, "index.ts");
533
+ currentTree.children?.forEach((child) => {
534
+ const path = pathParser2__default.default.resolve(currentTree.data.path, "index.ts");
529
535
  const importPath = child.data.type === "directory" ? `./${child.data.name}` : `./${child.data.name.replace(/\.[^.]*$/, "")}`;
530
536
  files2.push({
531
537
  path,
@@ -535,7 +541,7 @@ function writeIndexes(root, options) {
535
541
  });
536
542
  });
537
543
  }
538
- item.children.forEach((childItem) => {
544
+ currentTree.children.forEach((childItem) => {
539
545
  fileReducer(files2, childItem);
540
546
  });
541
547
  return files2;
@@ -545,9 +551,6 @@ function writeIndexes(root, options) {
545
551
  }
546
552
  function combineFiles(files) {
547
553
  return files.filter(Boolean).reduce((acc, curr) => {
548
- if (!curr) {
549
- return acc;
550
- }
551
554
  const prevIndex = acc.findIndex((item) => item.path === curr.path);
552
555
  if (prevIndex !== -1) {
553
556
  const prev = acc[prevIndex];
@@ -572,19 +575,19 @@ function getFileSource(file) {
572
575
  const imports = [];
573
576
  const exports = [];
574
577
  file.imports?.forEach((curr) => {
575
- const exists = imports.find((imp) => imp.path === curr.path);
576
- if (!exists) {
578
+ const existingImport = imports.find((imp) => imp.path === curr.path);
579
+ if (!existingImport) {
577
580
  imports.push({
578
581
  ...curr,
579
582
  name: Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name
580
583
  });
581
584
  }
582
- if (exists && !Array.isArray(exists.name) && exists.name !== curr.name) {
585
+ if (existingImport && !Array.isArray(existingImport.name) && existingImport.name !== curr.name) {
583
586
  imports.push(curr);
584
587
  }
585
- if (exists && Array.isArray(exists.name)) {
588
+ if (existingImport && Array.isArray(existingImport.name)) {
586
589
  if (Array.isArray(curr.name)) {
587
- exists.name = [.../* @__PURE__ */ new Set([...exists.name, ...curr.name])];
590
+ existingImport.name = [.../* @__PURE__ */ new Set([...existingImport.name, ...curr.name])];
588
591
  }
589
592
  }
590
593
  });
@@ -610,7 +613,7 @@ function getFileSource(file) {
610
613
  }, []);
611
614
  const importSource = tsCodegen.print(importNodes);
612
615
  const exportNodes = exports.reduce((prev, curr) => {
613
- return [...prev, tsCodegen.createExportDeclaration({ name: curr.name, path: curr.path, asAlias: curr.asAlias })];
616
+ return [...prev, tsCodegen.createExportDeclaration({ name: curr.name, path: curr.path, isTypeOnly: curr.isTypeOnly, asAlias: curr.asAlias })];
614
617
  }, []);
615
618
  const exportSource = tsCodegen.print(exportNodes);
616
619
  if (importSource) {
@@ -1081,7 +1084,7 @@ async function build(options) {
1081
1084
  await read(config.input.path);
1082
1085
  }
1083
1086
  } catch (e) {
1084
- throw new Error("Cannot read file defined in `input.path` or set with --input in the CLI of your Kubb config", { cause: e });
1087
+ throw new Error("Cannot read file/URL defined in `input.path` or set with --input in the CLI of your Kubb config", { cause: e });
1085
1088
  }
1086
1089
  if (config.output.clean) {
1087
1090
  await clean(config.output.path);
@@ -1197,6 +1200,7 @@ exports.read = read;
1197
1200
  exports.renderTemplate = renderTemplate;
1198
1201
  exports.timeout = timeout;
1199
1202
  exports.transformReservedWord = transformReservedWord;
1203
+ exports.uniqueId = uniqueId;
1200
1204
  exports.validatePlugins = validatePlugins;
1201
1205
  exports.write = write;
1202
1206
  exports.writeIndexes = writeIndexes;
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ interface Cache<T extends object = object> {
13
13
  }
14
14
  declare function createPluginCache<T extends Record<string, [number, unknown]>>(cache: T): Cache<T>;
15
15
 
16
- declare function getRelativePath(rootDir?: string | null, filePath?: string | null): string;
16
+ declare function getRelativePath(rootDir?: string | null, filePath?: string | null, platform?: 'windows' | 'mac' | 'linux'): string;
17
17
  type PathMode = 'file' | 'directory';
18
18
  declare function getPathMode(path: string | undefined | null): PathMode;
19
19
  declare function read(path: string): Promise<string>;
@@ -67,9 +67,9 @@ declare class TreeNode<T = unknown> {
67
67
  children: Array<TreeNode<T>>;
68
68
  constructor(data: T, parent?: TreeNode<T>);
69
69
  addChild(data: T): TreeNode<T>;
70
- find(data: T): {} | null;
71
- leaves(): TreeNode<T>[];
72
- root(): TreeNode<T>;
70
+ find(data?: T): TreeNode<T> | null;
71
+ get leaves(): TreeNode<T>[];
72
+ get root(): TreeNode<T>;
73
73
  forEach(callback: (treeNode: TreeNode<T>) => void): this;
74
74
  static build<T = unknown>(path: string, options?: TreeNodeOptions): TreeNode<T> | null;
75
75
  }
@@ -78,6 +78,8 @@ declare function transformReservedWord(word?: string | null): string | null | un
78
78
 
79
79
  declare function getStackTrace(belowFn?: Function): NodeJS.CallSite[];
80
80
 
81
+ declare const uniqueId: (str?: string) => string;
82
+
81
83
  type Import = {
82
84
  name: string | string[];
83
85
  path: string;
@@ -139,7 +141,7 @@ declare class FileManager {
139
141
  read(...params: Parameters<typeof read>): Promise<string>;
140
142
  }
141
143
 
142
- declare function writeIndexes(root: string, options: TreeNodeOptions): File[] | undefined;
144
+ declare function writeIndexes(root: string, options?: TreeNodeOptions): File[] | null;
143
145
  declare function combineFiles(files: Array<File | null>): File[];
144
146
  declare function getFileSource(file: File): string;
145
147
 
@@ -553,4 +555,4 @@ declare abstract class SchemaGenerator<TOptions extends object, TInput, TOutput>
553
555
  abstract build(schema: TInput, name: string, description?: string): TOutput;
554
556
  }
555
557
 
556
- export { Argument0, BuildOutput, CLIOptions, Cache, CacheStore, CorePluginOptions, Executer, File, FileManager, FileName, Generator, KubbConfig, KubbJSONPlugin, KubbObjectPlugin, KubbPlugin, KubbPluginKind, KubbUserConfig, LogLevel, Logger, MaybePromise, OnExecute, OptionalPath, ParallelPluginError, ParseResult, Path, PathMode, PluginContext, PluginError, PluginFactoryOptions, PluginLifecycle, PluginLifecycleHooks, PluginManager, Queue, QueueTask, Register, ResolveNameParams, ResolvePathParams, SafeParseResult, SchemaGenerator, Status, Strategy, TransformResult, TreeNode, TreeNodeOptions, UUID, ValidationPluginError, build, clean, combineFiles, createJSDocBlockText, createPlugin, createPluginCache, build as default, defineConfig, getEncodedText, getFileSource, getPathMode, getRelativePath, getStackTrace, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, renderTemplate, timeout, transformReservedWord, validatePlugins, write, writeIndexes };
558
+ export { Argument0, BuildOutput, CLIOptions, Cache, CacheStore, CorePluginOptions, Executer, File, FileManager, FileName, Generator, KubbConfig, KubbJSONPlugin, KubbObjectPlugin, KubbPlugin, KubbPluginKind, KubbUserConfig, LogLevel, Logger, MaybePromise, OnExecute, OptionalPath, ParallelPluginError, ParseResult, Path, PathMode, PluginContext, PluginError, PluginFactoryOptions, PluginLifecycle, PluginLifecycleHooks, PluginManager, Queue, QueueTask, Register, ResolveNameParams, ResolvePathParams, SafeParseResult, SchemaGenerator, Status, Strategy, TransformResult, TreeNode, TreeNodeOptions, UUID, ValidationPluginError, build, clean, combineFiles, createJSDocBlockText, createPlugin, createPluginCache, build as default, defineConfig, getEncodedText, getFileSource, getPathMode, getRelativePath, getStackTrace, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, renderTemplate, timeout, transformReservedWord, uniqueId, validatePlugins, write, writeIndexes };
package/dist/index.js CHANGED
@@ -56,19 +56,19 @@ function createPluginCache(cache) {
56
56
  }
57
57
  };
58
58
  }
59
- function slash(path) {
59
+ function slash(path, platform = "linux") {
60
60
  const isExtendedLengthPath = /^\\\\\?\\/.test(path);
61
- if (isExtendedLengthPath) {
62
- return path;
61
+ if (isExtendedLengthPath || platform === "linux" || platform === "mac") {
62
+ return path.replace("../", "").trimEnd();
63
63
  }
64
- return path.replace(/\\/g, "/");
64
+ return path.replace(/\\/g, "/").replace("../", "").trimEnd();
65
65
  }
66
- function getRelativePath(rootDir, filePath) {
66
+ function getRelativePath(rootDir, filePath, platform = "linux") {
67
67
  if (!rootDir || !filePath) {
68
68
  throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir} ${filePath}`);
69
69
  }
70
70
  const relativePath = pathParser2.relative(rootDir, filePath);
71
- const path = slash(relativePath).replace("../", "").trimEnd();
71
+ const path = slash(relativePath, platform);
72
72
  if (path.startsWith("../")) {
73
73
  return path.replace(pathParser2.basename(path), pathParser2.basename(path, pathParser2.extname(filePath)));
74
74
  }
@@ -81,12 +81,7 @@ function getPathMode(path) {
81
81
  return pathParser2.extname(path) ? "file" : "directory";
82
82
  }
83
83
  async function read(path) {
84
- try {
85
- return promises.readFile(path, { encoding: "utf8" });
86
- } catch (err) {
87
- console.error(err);
88
- throw err;
89
- }
84
+ return promises.readFile(path, { encoding: "utf8" });
90
85
  }
91
86
 
92
87
  // src/utils/isURL.ts
@@ -223,10 +218,13 @@ var TreeNode = class {
223
218
  return child;
224
219
  }
225
220
  find(data) {
221
+ if (!data) {
222
+ return null;
223
+ }
226
224
  if (data === this.data) {
227
225
  return this;
228
226
  }
229
- if (this.children) {
227
+ if (this.children?.length) {
230
228
  for (let i = 0, { length } = this.children, target = null; i < length; i++) {
231
229
  target = this.children[i].find(data);
232
230
  if (target) {
@@ -236,23 +234,23 @@ var TreeNode = class {
236
234
  }
237
235
  return null;
238
236
  }
239
- leaves() {
237
+ get leaves() {
240
238
  if (!this.children || this.children.length === 0) {
241
239
  return [this];
242
240
  }
243
241
  const leaves = [];
244
242
  if (this.children) {
245
243
  for (let i = 0, { length } = this.children; i < length; i++) {
246
- leaves.push.apply(leaves, this.children[i].leaves());
244
+ leaves.push.apply(leaves, this.children[i].leaves);
247
245
  }
248
246
  }
249
247
  return leaves;
250
248
  }
251
- root() {
249
+ get root() {
252
250
  if (!this.parent) {
253
251
  return this;
254
252
  }
255
- return this.parent.root();
253
+ return this.parent.root;
256
254
  }
257
255
  forEach(callback) {
258
256
  if (typeof callback !== "function") {
@@ -267,21 +265,26 @@ var TreeNode = class {
267
265
  return this;
268
266
  }
269
267
  static build(path, options = {}) {
270
- const filteredTree = dirTree(path, { extensions: options?.extensions, exclude: options.exclude });
271
- if (!filteredTree) {
272
- return null;
273
- }
274
- const treeNode = new TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type });
275
- const recurse = (node, item) => {
276
- const subNode = node.addChild({ name: item.name, path: item.path, type: item.type });
277
- if (item.children?.length) {
278
- item.children?.forEach((child) => {
279
- recurse(subNode, child);
280
- });
268
+ try {
269
+ const exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude].filter(Boolean);
270
+ const filteredTree = dirTree(path, { extensions: options.extensions, exclude: [/node_modules/, ...exclude] });
271
+ if (!filteredTree) {
272
+ return null;
281
273
  }
282
- };
283
- filteredTree.children?.forEach((child) => recurse(treeNode, child));
284
- return treeNode;
274
+ const treeNode = new TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type || getPathMode(filteredTree.path) });
275
+ const recurse = (node, item) => {
276
+ const subNode = node.addChild({ name: item.name, path: item.path, type: item.type || getPathMode(item.path) });
277
+ if (item.children?.length) {
278
+ item.children?.forEach((child) => {
279
+ recurse(subNode, child);
280
+ });
281
+ }
282
+ };
283
+ filteredTree.children?.forEach((child) => recurse(treeNode, child));
284
+ return treeNode;
285
+ } catch (e) {
286
+ throw new Error("Something went wrong with creating index files with the TreehNode class", { cause: e });
287
+ }
285
288
  }
286
289
  };
287
290
 
@@ -394,6 +397,9 @@ function getStackTrace(belowFn) {
394
397
  return v8StackTrace;
395
398
  }
396
399
 
400
+ // src/utils/uniqueId.ts
401
+ var uniqueId = ((counter) => (str = "") => `${str}${++counter}`)(0);
402
+
397
403
  // src/managers/fileManager/FileManager.ts
398
404
  var FileManager = class {
399
405
  cache = /* @__PURE__ */ new Map();
@@ -486,18 +492,18 @@ ${file.source}`,
486
492
  return read(...params);
487
493
  }
488
494
  };
489
- function writeIndexes(root, options) {
495
+ function writeIndexes(root, options = {}) {
490
496
  const tree = TreeNode.build(root, { extensions: /\.ts/, ...options });
491
497
  if (!tree) {
492
- return void 0;
498
+ return null;
493
499
  }
494
- const fileReducer = (files2, item) => {
495
- if (!item.children) {
500
+ const fileReducer = (files2, currentTree) => {
501
+ if (!currentTree.children) {
496
502
  return [];
497
503
  }
498
- if (item.children?.length > 1) {
499
- const path = pathParser2.resolve(item.data.path, "index.ts");
500
- const exports = item.children.map((file) => {
504
+ if (currentTree.children?.length > 1) {
505
+ const path = pathParser2.resolve(currentTree.data.path, "index.ts");
506
+ const exports = currentTree.children.map((file) => {
501
507
  if (!file) {
502
508
  return void 0;
503
509
  }
@@ -514,8 +520,8 @@ function writeIndexes(root, options) {
514
520
  exports
515
521
  });
516
522
  } else {
517
- item.children?.forEach((child) => {
518
- const path = pathParser2.resolve(item.data.path, "index.ts");
523
+ currentTree.children?.forEach((child) => {
524
+ const path = pathParser2.resolve(currentTree.data.path, "index.ts");
519
525
  const importPath = child.data.type === "directory" ? `./${child.data.name}` : `./${child.data.name.replace(/\.[^.]*$/, "")}`;
520
526
  files2.push({
521
527
  path,
@@ -525,7 +531,7 @@ function writeIndexes(root, options) {
525
531
  });
526
532
  });
527
533
  }
528
- item.children.forEach((childItem) => {
534
+ currentTree.children.forEach((childItem) => {
529
535
  fileReducer(files2, childItem);
530
536
  });
531
537
  return files2;
@@ -535,9 +541,6 @@ function writeIndexes(root, options) {
535
541
  }
536
542
  function combineFiles(files) {
537
543
  return files.filter(Boolean).reduce((acc, curr) => {
538
- if (!curr) {
539
- return acc;
540
- }
541
544
  const prevIndex = acc.findIndex((item) => item.path === curr.path);
542
545
  if (prevIndex !== -1) {
543
546
  const prev = acc[prevIndex];
@@ -562,19 +565,19 @@ function getFileSource(file) {
562
565
  const imports = [];
563
566
  const exports = [];
564
567
  file.imports?.forEach((curr) => {
565
- const exists = imports.find((imp) => imp.path === curr.path);
566
- if (!exists) {
568
+ const existingImport = imports.find((imp) => imp.path === curr.path);
569
+ if (!existingImport) {
567
570
  imports.push({
568
571
  ...curr,
569
572
  name: Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name
570
573
  });
571
574
  }
572
- if (exists && !Array.isArray(exists.name) && exists.name !== curr.name) {
575
+ if (existingImport && !Array.isArray(existingImport.name) && existingImport.name !== curr.name) {
573
576
  imports.push(curr);
574
577
  }
575
- if (exists && Array.isArray(exists.name)) {
578
+ if (existingImport && Array.isArray(existingImport.name)) {
576
579
  if (Array.isArray(curr.name)) {
577
- exists.name = [.../* @__PURE__ */ new Set([...exists.name, ...curr.name])];
580
+ existingImport.name = [.../* @__PURE__ */ new Set([...existingImport.name, ...curr.name])];
578
581
  }
579
582
  }
580
583
  });
@@ -600,7 +603,7 @@ function getFileSource(file) {
600
603
  }, []);
601
604
  const importSource = print(importNodes);
602
605
  const exportNodes = exports.reduce((prev, curr) => {
603
- return [...prev, createExportDeclaration({ name: curr.name, path: curr.path, asAlias: curr.asAlias })];
606
+ return [...prev, createExportDeclaration({ name: curr.name, path: curr.path, isTypeOnly: curr.isTypeOnly, asAlias: curr.asAlias })];
604
607
  }, []);
605
608
  const exportSource = print(exportNodes);
606
609
  if (importSource) {
@@ -1071,7 +1074,7 @@ async function build(options) {
1071
1074
  await read(config.input.path);
1072
1075
  }
1073
1076
  } catch (e) {
1074
- throw new Error("Cannot read file defined in `input.path` or set with --input in the CLI of your Kubb config", { cause: e });
1077
+ throw new Error("Cannot read file/URL defined in `input.path` or set with --input in the CLI of your Kubb config", { cause: e });
1075
1078
  }
1076
1079
  if (config.output.clean) {
1077
1080
  await clean(config.output.path);
@@ -1154,4 +1157,4 @@ var SchemaGenerator = class extends Generator {
1154
1157
  // src/index.ts
1155
1158
  var src_default = build;
1156
1159
 
1157
- export { FileManager, Generator, ParallelPluginError, PluginError, PluginManager, Queue, SchemaGenerator, 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, timeout, transformReservedWord, validatePlugins, write, writeIndexes };
1160
+ export { FileManager, Generator, ParallelPluginError, PluginError, PluginManager, Queue, SchemaGenerator, 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, timeout, transformReservedWord, uniqueId, validatePlugins, write, writeIndexes };
package/package.json CHANGED
@@ -1,7 +1,13 @@
1
1
  {
2
2
  "name": "@kubb/core",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "Generator core",
5
+ "keywords": [
6
+ "typescript",
7
+ "plugins",
8
+ "kubb",
9
+ "codegen"
10
+ ],
5
11
  "repository": {
6
12
  "type": "git",
7
13
  "url": "git://github.com/kubb-project/kubb.git",
@@ -9,17 +15,8 @@
9
15
  },
10
16
  "license": "MIT",
11
17
  "author": "Stijn Van Hulle <stijn@stijnvanhulle.be",
12
- "keywords": [
13
- "typescript",
14
- "plugins",
15
- "kubb",
16
- "codegen"
17
- ],
18
18
  "sideEffects": false,
19
19
  "type": "module",
20
- "main": "dist/index.js",
21
- "module": "dist/index.js",
22
- "types": "./dist/index.d.ts",
23
20
  "exports": {
24
21
  ".": {
25
22
  "types": "./dist/index.d.ts",
@@ -29,6 +26,9 @@
29
26
  },
30
27
  "./package.json": "./package.json"
31
28
  },
29
+ "main": "dist/index.js",
30
+ "module": "dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
32
  "typesVersions": {
33
33
  "*": {}
34
34
  },
@@ -43,32 +43,35 @@
43
43
  "change-case": "^4.1.2",
44
44
  "directory-tree": "^3.5.1",
45
45
  "rimraf": "^5.0.1",
46
- "@kubb/ts-codegen": "1.1.7"
46
+ "@kubb/ts-codegen": "1.1.8"
47
47
  },
48
48
  "devDependencies": {
49
49
  "eslint": "^8.42.0",
50
- "tsup": "^6.7.0",
51
50
  "ora": "^6.3.1",
51
+ "tsup": "^6.7.0",
52
52
  "typescript": "^5.1.3",
53
+ "@kubb/eslint-config": "0.1.0",
53
54
  "@kubb/tsup-config": "0.1.0",
54
- "@kubb/eslint-config": "0.1.0"
55
+ "@kubb/typescript-config": "0.1.0"
56
+ },
57
+ "packageManager": "pnpm@8.3.0",
58
+ "engines": {
59
+ "node": ">=18",
60
+ "pnpm": ">=8.3.0"
55
61
  },
56
62
  "publishConfig": {
57
63
  "access": "public",
58
64
  "registry": "https://registry.npmjs.org/"
59
65
  },
60
- "engines": {
61
- "node": ">=18",
62
- "pnpm": ">=8"
63
- },
64
66
  "scripts": {
65
67
  "build": "tsup",
66
- "start": "tsup --watch",
67
- "release": "pnpm publish --no-git-check",
68
+ "clean": "rimraf ./dist",
68
69
  "lint": "eslint \"**/*.{ts,tsx}\"",
69
70
  "lint-fix": "eslint \"**/*.{ts,tsx}\" --quiet --fix",
71
+ "release": "pnpm publish --no-git-check",
72
+ "start": "tsup --watch",
70
73
  "test": "vitest --passWithNoTests",
71
- "upgrade": "pnpm update",
72
- "typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
74
+ "typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false",
75
+ "upgrade": "pnpm update"
73
76
  }
74
77
  }
package/src/build.ts CHANGED
@@ -36,7 +36,7 @@ export async function build(options: BuildOptions): Promise<BuildOutput> {
36
36
  await read(config.input.path)
37
37
  }
38
38
  } catch (e: any) {
39
- throw new Error('Cannot read file defined in `input.path` or set with --input in the CLI of your Kubb config', { cause: e })
39
+ throw new Error('Cannot read file/URL defined in `input.path` or set with --input in the CLI of your Kubb config', { cause: e })
40
40
  }
41
41
 
42
42
  if (config.output.clean) {
@@ -9,21 +9,23 @@ import type { Path } from '../../types.ts'
9
9
  import type { PathMode, TreeNodeOptions } from '../../utils/index.ts'
10
10
  import type { File } from './types.ts'
11
11
 
12
- export function writeIndexes(root: string, options: TreeNodeOptions) {
13
- const tree = TreeNode.build<{ type: PathMode; path: Path; name: string }>(root, { extensions: /\.ts/, ...options })
12
+ type TreeNodeData = { type: PathMode; path: Path; name: string }
13
+
14
+ export function writeIndexes(root: string, options: TreeNodeOptions = {}): File[] | null {
15
+ const tree = TreeNode.build<TreeNodeData>(root, { extensions: /\.ts/, ...options })
14
16
 
15
17
  if (!tree) {
16
- return undefined
18
+ return null
17
19
  }
18
20
 
19
- const fileReducer = (files: File[], item: typeof tree) => {
20
- if (!item.children) {
21
+ const fileReducer = (files: File[], currentTree: typeof tree) => {
22
+ if (!currentTree.children) {
21
23
  return []
22
24
  }
23
25
 
24
- if (item.children?.length > 1) {
25
- const path = pathParser.resolve(item.data.path, 'index.ts')
26
- const exports = item.children
26
+ if (currentTree.children?.length > 1) {
27
+ const path = pathParser.resolve(currentTree.data.path, 'index.ts')
28
+ const exports = currentTree.children
27
29
  .map((file) => {
28
30
  if (!file) {
29
31
  return undefined
@@ -47,8 +49,8 @@ export function writeIndexes(root: string, options: TreeNodeOptions) {
47
49
  exports,
48
50
  })
49
51
  } else {
50
- item.children?.forEach((child) => {
51
- const path = pathParser.resolve(item.data.path, 'index.ts')
52
+ currentTree.children?.forEach((child) => {
53
+ const path = pathParser.resolve(currentTree.data.path, 'index.ts')
52
54
  const importPath = child.data.type === 'directory' ? `./${child.data.name}` : `./${child.data.name.replace(/\.[^.]*$/, '')}`
53
55
 
54
56
  files.push({
@@ -60,7 +62,7 @@ export function writeIndexes(root: string, options: TreeNodeOptions) {
60
62
  })
61
63
  }
62
64
 
63
- item.children.forEach((childItem) => {
65
+ currentTree.children.forEach((childItem) => {
64
66
  fileReducer(files, childItem)
65
67
  })
66
68
 
@@ -72,11 +74,8 @@ export function writeIndexes(root: string, options: TreeNodeOptions) {
72
74
  return files
73
75
  }
74
76
 
75
- export function combineFiles(files: Array<File | null>) {
76
- return files.filter(Boolean).reduce((acc, curr: File | null) => {
77
- if (!curr) {
78
- return acc
79
- }
77
+ export function combineFiles(files: Array<File | null>): File[] {
78
+ return (files.filter(Boolean) as File[]).reduce((acc, curr: File) => {
80
79
  const prevIndex = acc.findIndex((item) => item.path === curr.path)
81
80
 
82
81
  if (prevIndex !== -1) {
@@ -95,7 +94,7 @@ export function combineFiles(files: Array<File | null>) {
95
94
  }, [] as File[])
96
95
  }
97
96
 
98
- export function getFileSource(file: File) {
97
+ export function getFileSource(file: File): string {
99
98
  let { source } = file
100
99
 
101
100
  // TODO make generic check
@@ -106,21 +105,22 @@ export function getFileSource(file: File) {
106
105
  const exports: File['exports'] = []
107
106
 
108
107
  file.imports?.forEach((curr) => {
109
- const exists = imports.find((imp) => imp.path === curr.path)
110
- if (!exists) {
108
+ const existingImport = imports.find((imp) => imp.path === curr.path)
109
+
110
+ if (!existingImport) {
111
111
  imports.push({
112
112
  ...curr,
113
113
  name: Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name,
114
114
  })
115
115
  }
116
116
 
117
- if (exists && !Array.isArray(exists.name) && exists.name !== curr.name) {
117
+ if (existingImport && !Array.isArray(existingImport.name) && existingImport.name !== curr.name) {
118
118
  imports.push(curr)
119
119
  }
120
120
 
121
- if (exists && Array.isArray(exists.name)) {
121
+ if (existingImport && Array.isArray(existingImport.name)) {
122
122
  if (Array.isArray(curr.name)) {
123
- exists.name = [...new Set([...exists.name, ...curr.name])]
123
+ existingImport.name = [...new Set([...existingImport.name, ...curr.name])]
124
124
  }
125
125
  }
126
126
  })
@@ -151,7 +151,7 @@ export function getFileSource(file: File) {
151
151
  const importSource = print(importNodes)
152
152
 
153
153
  const exportNodes = exports.reduce((prev, curr) => {
154
- return [...prev, createExportDeclaration({ name: curr.name, path: curr.path, asAlias: curr.asAlias })]
154
+ return [...prev, createExportDeclaration({ name: curr.name, path: curr.path, isTypeOnly: curr.isTypeOnly, asAlias: curr.asAlias })]
155
155
  }, [] as ts.ExportDeclaration[])
156
156
  const exportSource = print(exportNodes)
157
157
 
@@ -1,5 +1,7 @@
1
1
  import dirTree from 'directory-tree'
2
2
 
3
+ import { getPathMode } from '../utils/read.ts'
4
+
3
5
  import type { DirectoryTree, DirectoryTreeOptions } from 'directory-tree'
4
6
 
5
7
  export type TreeNodeOptions = DirectoryTreeOptions
@@ -26,13 +28,17 @@ export class TreeNode<T = unknown> {
26
28
  return child
27
29
  }
28
30
 
29
- find(data: T) {
31
+ find(data?: T): TreeNode<T> | null {
32
+ if (!data) {
33
+ return null
34
+ }
35
+
30
36
  if (data === this.data) {
31
37
  return this
32
38
  }
33
39
 
34
- if (this.children) {
35
- for (let i = 0, { length } = this.children, target: unknown = null; i < length; i++) {
40
+ if (this.children?.length) {
41
+ for (let i = 0, { length } = this.children, target: TreeNode<T> | null = null; i < length; i++) {
36
42
  target = this.children[i].find(data)
37
43
  if (target) {
38
44
  return target
@@ -43,7 +49,7 @@ export class TreeNode<T = unknown> {
43
49
  return null
44
50
  }
45
51
 
46
- leaves(): TreeNode<T>[] {
52
+ get leaves(): TreeNode<T>[] {
47
53
  if (!this.children || this.children.length === 0) {
48
54
  // this is a leaf
49
55
  return [this]
@@ -54,17 +60,17 @@ export class TreeNode<T = unknown> {
54
60
  if (this.children) {
55
61
  for (let i = 0, { length } = this.children; i < length; i++) {
56
62
  // eslint-disable-next-line prefer-spread
57
- leaves.push.apply(leaves, this.children[i].leaves())
63
+ leaves.push.apply(leaves, this.children[i].leaves)
58
64
  }
59
65
  }
60
66
  return leaves
61
67
  }
62
68
 
63
- root(): TreeNode<T> {
69
+ get root(): TreeNode<T> {
64
70
  if (!this.parent) {
65
71
  return this
66
72
  }
67
- return this.parent.root()
73
+ return this.parent.root
68
74
  }
69
75
 
70
76
  forEach(callback: (treeNode: TreeNode<T>) => void): this {
@@ -86,26 +92,31 @@ export class TreeNode<T = unknown> {
86
92
  }
87
93
 
88
94
  public static build<T = unknown>(path: string, options: TreeNodeOptions = {}): TreeNode<T> | null {
89
- const filteredTree = dirTree(path, { extensions: options?.extensions, exclude: options.exclude })
95
+ try {
96
+ const exclude = Array.isArray(options.exclude) ? options.exclude : ([options.exclude].filter(Boolean) as RegExp[])
97
+ const filteredTree = dirTree(path, { extensions: options.extensions, exclude: [/node_modules/, ...exclude] })
90
98
 
91
- if (!filteredTree) {
92
- return null
93
- }
99
+ if (!filteredTree) {
100
+ return null
101
+ }
94
102
 
95
- const treeNode = new TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type })
103
+ const treeNode = new TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type || getPathMode(filteredTree.path) })
96
104
 
97
- const recurse = (node: typeof treeNode, item: DirectoryTree) => {
98
- const subNode = node.addChild({ name: item.name, path: item.path, type: item.type })
105
+ const recurse = (node: typeof treeNode, item: DirectoryTree) => {
106
+ const subNode = node.addChild({ name: item.name, path: item.path, type: item.type || getPathMode(item.path) })
99
107
 
100
- if (item.children?.length) {
101
- item.children?.forEach((child) => {
102
- recurse(subNode, child)
103
- })
108
+ if (item.children?.length) {
109
+ item.children?.forEach((child) => {
110
+ recurse(subNode, child)
111
+ })
112
+ }
104
113
  }
105
- }
106
114
 
107
- filteredTree.children?.forEach((child) => recurse(treeNode, child))
115
+ filteredTree.children?.forEach((child) => recurse(treeNode, child))
108
116
 
109
- return treeNode as TreeNode<T>
117
+ return treeNode as TreeNode<T>
118
+ } catch (e) {
119
+ throw new Error('Something went wrong with creating index files with the TreehNode class', { cause: e })
120
+ }
110
121
  }
111
122
  }
@@ -15,3 +15,4 @@ export * from './clean.ts'
15
15
  export * from './TreeNode.ts'
16
16
  export * from './transformReservedWord.ts'
17
17
  export * from './getStackTrace.ts'
18
+ export * from './uniqueId.ts'
package/src/utils/read.ts CHANGED
@@ -1,17 +1,19 @@
1
1
  import { promises as fs } from 'node:fs'
2
2
  import pathParser from 'node:path'
3
3
 
4
- function slash(path: string) {
4
+ function slash(path: string, platform: 'windows' | 'mac' | 'linux' = 'linux') {
5
5
  const isExtendedLengthPath = /^\\\\\?\\/.test(path)
6
6
 
7
- if (isExtendedLengthPath) {
8
- return path
7
+ if (isExtendedLengthPath || platform === 'linux' || platform === 'mac') {
8
+ // linux and mac
9
+ return path.replace('../', '').trimEnd()
9
10
  }
10
11
 
11
- return path.replace(/\\/g, '/')
12
+ // windows
13
+ return path.replace(/\\/g, '/').replace('../', '').trimEnd()
12
14
  }
13
15
 
14
- export function getRelativePath(rootDir?: string | null, filePath?: string | null) {
16
+ export function getRelativePath(rootDir?: string | null, filePath?: string | null, platform: 'windows' | 'mac' | 'linux' = 'linux') {
15
17
  if (!rootDir || !filePath) {
16
18
  throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir} ${filePath}`)
17
19
  }
@@ -20,7 +22,7 @@ export function getRelativePath(rootDir?: string | null, filePath?: string | nul
20
22
 
21
23
  // On Windows, paths are separated with a "\"
22
24
  // However, web browsers use "/" no matter the platform
23
- const path = slash(relativePath).replace('../', '').trimEnd()
25
+ const path = slash(relativePath, platform)
24
26
 
25
27
  if (path.startsWith('../')) {
26
28
  return path.replace(pathParser.basename(path), pathParser.basename(path, pathParser.extname(filePath)))
@@ -39,10 +41,5 @@ export function getPathMode(path: string | undefined | null): PathMode {
39
41
  }
40
42
 
41
43
  export async function read(path: string) {
42
- try {
43
- return fs.readFile(path, { encoding: 'utf8' })
44
- } catch (err) {
45
- console.error(err)
46
- throw err
47
- }
44
+ return fs.readFile(path, { encoding: 'utf8' })
48
45
  }
@@ -0,0 +1,5 @@
1
+ export const uniqueId = (
2
+ (counter) =>
3
+ (str = '') =>
4
+ `${str}${++counter}`
5
+ )(0)