@kubb/core 2.0.0-beta.5 → 2.0.0-beta.7

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.
@@ -1,23 +1,28 @@
1
1
  import path from 'path'
2
2
 
3
+ import transformers from './transformers/index.ts'
3
4
  import { TreeNode } from './utils/TreeNode.ts'
4
5
 
5
6
  import type { DirectoryTreeOptions } from 'directory-tree'
6
7
  import type { KubbFile } from './FileManager.ts'
8
+ import type { KubbPlugin } from './index.ts'
7
9
 
8
- type BarrelData = { type: KubbFile.Mode; path: KubbFile.Path; name: string }
10
+ type FileMeta = {
11
+ pluginKey?: KubbPlugin['key']
12
+ treeNode: TreeNode
13
+ }
9
14
 
10
15
  export type BarrelManagerOptions = {
11
16
  treeNode?: DirectoryTreeOptions
12
17
  isTypeOnly?: boolean
13
- filter?: (file: KubbFile.File) => boolean
14
- map?: (file: KubbFile.File) => KubbFile.File
18
+ /**
19
+ * Add .ts or .js
20
+ */
15
21
  includeExt?: boolean
16
- output?: string
17
22
  }
18
23
 
19
24
  export class BarrelManager {
20
- #options: BarrelManagerOptions = {}
25
+ #options: BarrelManagerOptions
21
26
 
22
27
  constructor(options: BarrelManagerOptions = {}) {
23
28
  this.#options = options
@@ -26,10 +31,10 @@ export class BarrelManager {
26
31
  }
27
32
 
28
33
  getIndexes(
29
- root: string,
34
+ pathToBuild: string,
30
35
  extName?: KubbFile.Extname,
31
- ): Array<KubbFile.File> | null {
32
- const { treeNode = {}, isTypeOnly, filter, map, output, includeExt } = this.#options
36
+ ): Array<KubbFile.File<FileMeta>> | null {
37
+ const { treeNode = {}, isTypeOnly, includeExt } = this.#options
33
38
 
34
39
  const extMapper: Record<KubbFile.Extname, DirectoryTreeOptions> = {
35
40
  '.ts': {
@@ -41,25 +46,26 @@ export class BarrelManager {
41
46
  exclude: [],
42
47
  },
43
48
  }
44
- const tree = TreeNode.build<BarrelData>(root, { ...(extMapper[extName as keyof typeof extMapper] || {}), ...treeNode })
49
+ const tree = TreeNode.build(pathToBuild, { ...(extMapper[extName as keyof typeof extMapper] || {}), ...treeNode })
45
50
 
46
51
  if (!tree) {
47
52
  return null
48
53
  }
49
54
 
50
- const fileReducer = (files: Array<KubbFile.File>, currentTree: typeof tree) => {
51
- if (!currentTree.children) {
55
+ const fileReducer = (files: Array<KubbFile.File<FileMeta>>, treeNode: TreeNode) => {
56
+ if (!treeNode.children) {
52
57
  return []
53
58
  }
54
59
 
55
- if (currentTree.children?.length > 1) {
56
- const indexPath: KubbFile.Path = path.resolve(currentTree.data.path, 'index.ts')
57
- const exports: KubbFile.Export[] = currentTree.children
60
+ if (treeNode.children.length > 1) {
61
+ const indexPath: KubbFile.Path = path.resolve(treeNode.data.path, 'index.ts')
62
+
63
+ const exports: KubbFile.Export[] = treeNode.children
58
64
  .filter(Boolean)
59
65
  .map((file) => {
60
- const importPath: string = file.data.type === 'directory' ? `./${file.data.name}/index` : `./${file.data.name.replace(/\.[^.]*$/, '')}`
66
+ const importPath: string = file.data.type === 'directory' ? `./${file.data.name}/index` : `./${transformers.trimExtName(file.data.name)}`
61
67
 
62
- if (importPath.includes('index') && file.data.type === 'file') {
68
+ if (importPath.endsWith('index') && file.data.type === 'file') {
63
69
  return undefined
64
70
  }
65
71
 
@@ -74,50 +80,46 @@ export class BarrelManager {
74
80
  path: indexPath,
75
81
  baseName: 'index.ts',
76
82
  source: '',
77
- exports: output
78
- ? exports?.filter((item) => {
79
- return item.path.endsWith(output.replace(/\.[^.]*$/, ''))
80
- })
81
- : exports,
83
+ exports,
84
+ meta: {
85
+ treeNode,
86
+ },
82
87
  })
83
- } else {
84
- currentTree.children?.forEach((child) => {
85
- const indexPath = path.resolve(currentTree.data.path, 'index.ts')
86
- const importPath = child.data.type === 'directory' ? `./${child.data.name}/index` : `./${child.data.name.replace(/\.[^.]*$/, '')}`
87
-
88
- const exports = [
89
- {
90
- path: includeExt
91
- ? `${importPath}${extName}`
92
- : importPath,
93
- isTypeOnly,
94
- },
95
- ]
96
-
97
- files.push({
98
- path: indexPath,
99
- baseName: 'index.ts',
100
- source: '',
101
- exports: output
102
- ? exports?.filter((item) => {
103
- return item.path.endsWith(output.replace(/\.[^.]*$/, ''))
104
- })
105
- : exports,
106
- })
88
+ } else if (treeNode.children.length === 1) {
89
+ const [treeNodeChild] = treeNode.children as [TreeNode]
90
+
91
+ const indexPath = path.resolve(treeNode.data.path, 'index.ts')
92
+ const importPath = treeNodeChild.data.type === 'directory'
93
+ ? `./${treeNodeChild.data.name}/index`
94
+ : `./${transformers.trimExtName(treeNodeChild.data.name)}`
95
+
96
+ const exports = [
97
+ {
98
+ path: includeExt
99
+ ? `${importPath}${extName}`
100
+ : importPath,
101
+ isTypeOnly,
102
+ },
103
+ ]
104
+
105
+ files.push({
106
+ path: indexPath,
107
+ baseName: 'index.ts',
108
+ source: '',
109
+ exports,
110
+ meta: {
111
+ treeNode,
112
+ },
107
113
  })
108
114
  }
109
115
 
110
- currentTree.children.forEach((childItem) => {
116
+ treeNode.children.forEach((childItem) => {
111
117
  fileReducer(files, childItem)
112
118
  })
113
119
 
114
120
  return files
115
121
  }
116
122
 
117
- const files = fileReducer([], tree).reverse()
118
-
119
- const filteredFiles = filter ? files.filter(filter) : files
120
-
121
- return map ? filteredFiles.map(map) : filteredFiles
123
+ return fileReducer([], tree).reverse()
122
124
  }
123
125
  }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-namespace */
2
2
  import crypto from 'node:crypto'
3
- import { extname } from 'node:path'
3
+ import { extname, resolve } from 'node:path'
4
4
 
5
5
  import { print } from '@kubb/parser'
6
6
  import * as factory from '@kubb/parser/factory'
@@ -45,6 +45,10 @@ export namespace KubbFile {
45
45
  * Add `type` prefix to the import, this will result in: `import type { Type } from './path'`.
46
46
  */
47
47
  isTypeOnly?: boolean
48
+ /**
49
+ * Add `* as` prefix to the import, this will result in: `import * as path from './path'`.
50
+ */
51
+ isNameSpace?: boolean
48
52
  /**
49
53
  * When root is set it will get the path with relative getRelativePath(root, path).
50
54
  */
@@ -115,8 +119,8 @@ export namespace KubbFile {
115
119
  */
116
120
  id?: string
117
121
  /**
118
- * Name to be used to dynamicly create the baseName(based on input.path)
119
- * Based on UNIX basename
122
+ * Name to be used to create the path
123
+ * Based on UNIX basename, `${name}.extName`
120
124
  * @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
121
125
  */
122
126
  baseName: TBaseName
@@ -151,6 +155,12 @@ export namespace KubbFile {
151
155
  * @default crypto.randomUUID()
152
156
  */
153
157
  id: UUID
158
+ /**
159
+ * Contains the first part of the baseName, generated based on baseName
160
+ * @link https://nodejs.org/api/path.html#pathformatpathobject
161
+ */
162
+
163
+ name: string
154
164
  }
155
165
  }
156
166
 
@@ -163,7 +173,17 @@ type AddResult<T extends Array<KubbFile.File>> = Promise<
163
173
  >
164
174
 
165
175
  type AddIndexesProps = {
166
- root: KubbFile.Path
176
+ /**
177
+ * Root based on root and output.path specified in the config
178
+ */
179
+ root: string
180
+ /**
181
+ * Output for plugin
182
+ */
183
+ output: string | {
184
+ path: string
185
+ exportAs?: string
186
+ }
167
187
  extName?: KubbFile.Extname
168
188
  options?: BarrelManagerOptions
169
189
  meta?: KubbFile.File['meta']
@@ -241,7 +261,7 @@ export class FileManager {
241
261
 
242
262
  async #add(file: KubbFile.File): Promise<KubbFile.ResolvedFile> {
243
263
  const controller = new AbortController()
244
- const resolvedFile: KubbFile.ResolvedFile = { id: crypto.randomUUID(), ...file }
264
+ const resolvedFile: KubbFile.ResolvedFile = { id: crypto.randomUUID(), name: transformers.trimExtName(file.baseName), ...file }
245
265
 
246
266
  this.#cache.set(resolvedFile.path, [{ cancel: () => controller.abort(), ...resolvedFile }])
247
267
 
@@ -275,15 +295,44 @@ export class FileManager {
275
295
  return this.#add(file)
276
296
  }
277
297
 
278
- async addIndexes({ root, extName = '.ts', meta, options = {} }: AddIndexesProps): Promise<Array<KubbFile.File> | undefined> {
298
+ async addIndexes({ root, output, extName = '.ts', meta, options = {} }: AddIndexesProps): Promise<Array<KubbFile.File> | undefined> {
299
+ // TODO remove when all plugins are using path as object
300
+ const outputPath = typeof output === 'string' ? output : output.path
301
+ const exportAs = typeof output === 'string' ? undefined : output.exportAs
302
+ const exportPath = outputPath.startsWith('./') ? outputPath : `./${outputPath}`
303
+
279
304
  const barrelManager = new BarrelManager(options)
280
305
 
281
- const files = barrelManager.getIndexes(root, extName)
306
+ const files = barrelManager.getIndexes(resolve(root, outputPath), extName)
282
307
 
283
308
  if (!files) {
284
309
  return undefined
285
310
  }
286
311
 
312
+ const rootFile: KubbFile.File = {
313
+ path: resolve(root, 'index.ts'),
314
+ baseName: 'index.ts',
315
+ source: '',
316
+ exports: [
317
+ exportAs
318
+ ? {
319
+ name: exportAs,
320
+ asAlias: !!exportAs,
321
+ path: exportPath,
322
+ isTypeOnly: options.isTypeOnly,
323
+ }
324
+ : {
325
+ path: exportPath,
326
+ isTypeOnly: options.isTypeOnly,
327
+ },
328
+ ],
329
+ }
330
+
331
+ await this.#addOrAppend({
332
+ ...rootFile,
333
+ meta: meta ? meta : rootFile.meta,
334
+ })
335
+
287
336
  return await Promise.all(
288
337
  files.map((file) => {
289
338
  return this.#addOrAppend({
@@ -3,10 +3,13 @@ import dirTree from 'directory-tree'
3
3
  import { FileManager } from '../FileManager.ts'
4
4
 
5
5
  import type { DirectoryTree, DirectoryTreeOptions } from 'directory-tree'
6
+ import type { KubbFile } from '../FileManager.ts'
6
7
 
7
8
  export type TreeNodeOptions = DirectoryTreeOptions
8
9
 
9
- export class TreeNode<T = unknown> {
10
+ type BarrelData = { type: KubbFile.Mode; path: KubbFile.Path; name: string }
11
+
12
+ export class TreeNode<T = BarrelData> {
10
13
  public data: T
11
14
 
12
15
  public parent?: TreeNode<T>
@@ -91,7 +94,7 @@ export class TreeNode<T = unknown> {
91
94
  return this
92
95
  }
93
96
 
94
- public static build<T = unknown>(path: string, options: TreeNodeOptions = {}): TreeNode<T> | null {
97
+ public static build(path: string, options: TreeNodeOptions = {}): TreeNode | null {
95
98
  try {
96
99
  const exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude].filter(Boolean)
97
100
  const filteredTree = dirTree(path, { extensions: options.extensions, exclude: [/node_modules/, ...exclude] })
@@ -114,7 +117,7 @@ export class TreeNode<T = unknown> {
114
117
 
115
118
  filteredTree.children?.forEach((child) => recurse(treeNode, child))
116
119
 
117
- return treeNode as TreeNode<T>
120
+ return treeNode
118
121
  } catch (e) {
119
122
  throw new Error('Something went wrong with creating index files with the TreehNode class', { cause: e })
120
123
  }