@kubb/plugin-barrel 5.7.0 → 5.8.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/OVERVIEW.md +30 -0
- package/dist/index.cjs +166 -234
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +166 -234
- package/dist/index.js.map +1 -1
- package/kubb-extension.json +18 -0
- package/package.json +6 -3
package/OVERVIEW.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Barrel plugin
|
|
2
|
+
|
|
3
|
+
The barrel plugin writes `index.ts` files that re-export generated code, one for each plugin's output and one root barrel, so you can import everything from a single entry point.
|
|
4
|
+
|
|
5
|
+
Kubb adds it to `plugins` for you. Do not add it yourself. It generates nothing until you configure `output.barrel`.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
Set `output.barrel` on `defineConfig` to write a root barrel. Plugins without a barrel setting of their own inherit it.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { defineConfig } from 'kubb/config'
|
|
13
|
+
import { pluginTs } from '@kubb/plugin-ts'
|
|
14
|
+
|
|
15
|
+
export default defineConfig({
|
|
16
|
+
input: './petStore.yaml',
|
|
17
|
+
output: { path: './src/gen', barrel: { type: 'named' } },
|
|
18
|
+
plugins: [pluginTs()],
|
|
19
|
+
})
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Options
|
|
23
|
+
|
|
24
|
+
The plugin takes no arguments. You configure it through `output.barrel`, on `defineConfig` or on a single plugin.
|
|
25
|
+
|
|
26
|
+
- `type: 'named'` re-exports each symbol by name, which suits tree-shaking. `type: 'all'` writes `export *`.
|
|
27
|
+
- `nested: true`, on a plugin only, makes each barrel re-export just its own directory and the barrels below it. The root barrel is always flat.
|
|
28
|
+
- `false` on a plugin turns its barrel off and leaves its files out of the root barrel.
|
|
29
|
+
|
|
30
|
+
A plugin with `output.mode: 'file'` gets no barrel of its own. The root barrel re-exports that file directly. Passing your own `output` object to a plugin replaces its default `barrel: { type: 'named' }`, so it falls back to the root setting.
|
package/dist/index.cjs
CHANGED
|
@@ -64,6 +64,15 @@ function isPathInside(path, parent) {
|
|
|
64
64
|
return rel !== "" && !rel.startsWith("..") && !(0, node_path.isAbsolute)(rel);
|
|
65
65
|
}
|
|
66
66
|
//#endregion
|
|
67
|
+
//#region kubb-extension.json
|
|
68
|
+
var compatibility = {
|
|
69
|
+
"kubb": ">=5.8.0",
|
|
70
|
+
"node": ">=22"
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region package.json
|
|
74
|
+
var version = "5.8.1";
|
|
75
|
+
//#endregion
|
|
67
76
|
//#region src/utils.ts
|
|
68
77
|
const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
69
78
|
".ts",
|
|
@@ -73,219 +82,124 @@ const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
73
82
|
]);
|
|
74
83
|
const BARREL_SUFFIX = `/index.ts`;
|
|
75
84
|
/**
|
|
76
|
-
*
|
|
77
|
-
* Paths outside `rootPath` are silently ignored. Children are sorted alphabetically
|
|
78
|
-
* by path so consumers (barrel exports, propagated indexes) emit a deterministic order.
|
|
79
|
-
*
|
|
80
|
-
* Both POSIX (`/`) and Windows (`\`) separators are accepted in input paths; emitted node
|
|
81
|
-
* paths are always POSIX-normalized so downstream prefix/lookup operations behave the same
|
|
82
|
-
* across platforms.
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* ```ts
|
|
86
|
-
* buildTree('/src/gen/types', [
|
|
87
|
-
* '/src/gen/types/pet.ts',
|
|
88
|
-
* '/src/gen/types/pets/listPets.ts',
|
|
89
|
-
* ])
|
|
90
|
-
* ```
|
|
85
|
+
* Orders paths split into segments the way a directory listing sorts them: by name at each level.
|
|
91
86
|
*/
|
|
92
|
-
function
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
isFile: false
|
|
98
|
-
};
|
|
99
|
-
const childIndex = /* @__PURE__ */ new WeakMap();
|
|
100
|
-
childIndex.set(root, /* @__PURE__ */ new Map());
|
|
101
|
-
const rootPrefix = `${normalizedRoot}/`;
|
|
102
|
-
for (const filePath of filePaths) {
|
|
103
|
-
const normalized = toPosixPath(filePath);
|
|
104
|
-
if (!normalized.startsWith(rootPrefix)) continue;
|
|
105
|
-
const parts = normalized.slice(rootPrefix.length).split("/");
|
|
106
|
-
let current = root;
|
|
107
|
-
const lastIndex = parts.length - 1;
|
|
108
|
-
for (const [i, part] of parts.entries()) {
|
|
109
|
-
if (!part) continue;
|
|
110
|
-
const isLast = i === lastIndex;
|
|
111
|
-
const siblings = childIndex.get(current);
|
|
112
|
-
let child = siblings.get(part);
|
|
113
|
-
if (!child) {
|
|
114
|
-
child = {
|
|
115
|
-
path: `${current.path}/${part}`,
|
|
116
|
-
children: [],
|
|
117
|
-
isFile: isLast
|
|
118
|
-
};
|
|
119
|
-
current.children.push(child);
|
|
120
|
-
siblings.set(part, child);
|
|
121
|
-
if (!isLast) childIndex.set(child, /* @__PURE__ */ new Map());
|
|
122
|
-
}
|
|
123
|
-
current = child;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
sortTree(root);
|
|
127
|
-
return root;
|
|
87
|
+
function compareSegments(a, b) {
|
|
88
|
+
const index = a.findIndex((segment, i) => segment !== b[i]);
|
|
89
|
+
if (index === -1) return a.length - b.length;
|
|
90
|
+
if (index >= b.length) return 1;
|
|
91
|
+
return a[index] < b[index] ? -1 : 1;
|
|
128
92
|
}
|
|
129
|
-
function
|
|
130
|
-
if (node.children.length === 0) return;
|
|
131
|
-
node.children.sort(compareByPath);
|
|
132
|
-
for (const child of node.children) if (!child.isFile) sortTree(child);
|
|
133
|
-
}
|
|
134
|
-
function compareByPath(a, b) {
|
|
135
|
-
return a.path < b.path ? -1 : a.path > b.path ? 1 : 0;
|
|
136
|
-
}
|
|
137
|
-
function toRelativeModulePath({ fromDir, filePath }) {
|
|
93
|
+
function toRelativeModulePath(fromDir, filePath) {
|
|
138
94
|
return `./${node_path.posix.relative(fromDir, filePath)}`;
|
|
139
95
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
function makeBarrel(
|
|
144
|
-
const
|
|
145
|
-
const uniqueExports =
|
|
146
|
-
for (const item of exports) {
|
|
96
|
+
/**
|
|
97
|
+
* Builds the `index.ts` for `dirPath`. Keeps the first export of each name and reports later duplicates once per build.
|
|
98
|
+
*/
|
|
99
|
+
function makeBarrel(dirPath, exports, { sourceFiles, reportedCollisions }) {
|
|
100
|
+
const owners = /* @__PURE__ */ new Map();
|
|
101
|
+
const uniqueExports = exports.flatMap((item) => {
|
|
147
102
|
const itemPath = node_path.posix.join(dirPath, item.path);
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
for (const name of itemNames ?? []) {
|
|
151
|
-
const first = names.get(name);
|
|
103
|
+
const uniqueNames = (item.name == null ? sourceFiles.get(itemPath)?.sources.flatMap((source) => source.name || []) ?? [] : [item.name].flat()).filter((name) => {
|
|
104
|
+
const first = owners.get(name);
|
|
152
105
|
if (!first) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
continue;
|
|
106
|
+
owners.set(name, item.path);
|
|
107
|
+
return true;
|
|
156
108
|
}
|
|
157
109
|
const key = [
|
|
158
110
|
name,
|
|
159
111
|
node_path.posix.join(dirPath, first),
|
|
160
112
|
itemPath
|
|
161
113
|
].join("\0");
|
|
162
|
-
if (reportedCollisions.has(key))
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
114
|
+
if (!reportedCollisions.has(key)) {
|
|
115
|
+
reportedCollisions.add(key);
|
|
116
|
+
_kubb_kit.Diagnostics.report({
|
|
117
|
+
code: _kubb_kit.Diagnostics.code.barrelDuplicateExport,
|
|
118
|
+
severity: "error",
|
|
119
|
+
message: `"${name}" is exported by both "${first}" and "${item.path}", so "${dirPath}${BARREL_SUFFIX}" cannot re-export both.`,
|
|
120
|
+
help: "Rename one of the colliding declarations, or configure the plugin resolver to produce distinct names."
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
});
|
|
125
|
+
if (item.name == null) return [item];
|
|
126
|
+
return uniqueNames.length > 0 ? [_kubb_kit.ast.factory.createExport({
|
|
172
127
|
...item,
|
|
173
128
|
name: Array.isArray(item.name) ? uniqueNames : uniqueNames[0]
|
|
174
|
-
})
|
|
175
|
-
}
|
|
129
|
+
})] : [];
|
|
130
|
+
});
|
|
176
131
|
return _kubb_kit.ast.factory.createFile({
|
|
177
132
|
baseName: "index.ts",
|
|
178
133
|
path: `${dirPath}${BARREL_SUFFIX}`,
|
|
179
134
|
exports: uniqueExports
|
|
180
135
|
});
|
|
181
136
|
}
|
|
182
|
-
function indexableNames(
|
|
137
|
+
function indexableNames(sources, isTypeOnly) {
|
|
183
138
|
const names = sources.flatMap((source) => source.isIndexable && source.name && Boolean(source.isTypeOnly) === isTypeOnly ? [source.name] : []);
|
|
184
139
|
return [...new Set(names)].sort();
|
|
185
140
|
}
|
|
186
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Re-exports the whole module, unless it has sources and none of them is indexable.
|
|
143
|
+
*/
|
|
144
|
+
const allStrategy = (path, sourceFile) => {
|
|
187
145
|
const sources = sourceFile?.sources ?? [];
|
|
188
|
-
|
|
189
|
-
return [_kubb_kit.ast.factory.createExport({ path: toRelativeModulePath({
|
|
190
|
-
fromDir: dirPath,
|
|
191
|
-
filePath: leafPath
|
|
192
|
-
}) })];
|
|
146
|
+
return sources.length > 0 && !sources.some((source) => source.isIndexable) ? [] : [_kubb_kit.ast.factory.createExport({ path })];
|
|
193
147
|
};
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
isTypeOnly: false
|
|
203
|
-
});
|
|
204
|
-
const typeNames = indexableNames({
|
|
205
|
-
sources: sourceFile.sources,
|
|
206
|
-
isTypeOnly: true
|
|
207
|
-
});
|
|
208
|
-
if (valueNames.length === 0 && typeNames.length === 0) {
|
|
209
|
-
if (sourceFile.sources.length > 0) return [];
|
|
210
|
-
return [_kubb_kit.ast.factory.createExport({ path: modulePath })];
|
|
211
|
-
}
|
|
212
|
-
const exports = [];
|
|
213
|
-
if (valueNames.length > 0) exports.push(_kubb_kit.ast.factory.createExport({
|
|
148
|
+
/**
|
|
149
|
+
* Re-exports the indexable names, values and types separately, or the whole module when it has no sources.
|
|
150
|
+
*/
|
|
151
|
+
const namedStrategy = (path, sourceFile) => {
|
|
152
|
+
if (!sourceFile?.sources.length) return [_kubb_kit.ast.factory.createExport({ path })];
|
|
153
|
+
const valueNames = indexableNames(sourceFile.sources, false);
|
|
154
|
+
const typeNames = indexableNames(sourceFile.sources, true);
|
|
155
|
+
return [...valueNames.length > 0 ? [_kubb_kit.ast.factory.createExport({
|
|
214
156
|
name: valueNames,
|
|
215
|
-
path
|
|
216
|
-
})
|
|
217
|
-
if (typeNames.length > 0) exports.push(_kubb_kit.ast.factory.createExport({
|
|
157
|
+
path
|
|
158
|
+
})] : [], ...typeNames.length > 0 ? [_kubb_kit.ast.factory.createExport({
|
|
218
159
|
name: typeNames,
|
|
219
|
-
path
|
|
160
|
+
path,
|
|
220
161
|
isTypeOnly: true
|
|
221
|
-
})
|
|
222
|
-
return exports;
|
|
162
|
+
})] : []];
|
|
223
163
|
};
|
|
224
164
|
/**
|
|
225
|
-
* Post-order walk that
|
|
226
|
-
*
|
|
165
|
+
* Post-order walk that builds a barrel re-exporting every leaf below the visited directory, for
|
|
166
|
+
* the start node and, with `recursive`, every sub-directory. Also returns the subtree's leaf paths.
|
|
227
167
|
*/
|
|
228
|
-
function
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (!isBarrelPath(child.path)) subtreeLeaves.push(child.path);
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
const childLeaves = yield* walkAllOrNamed(child, params, {
|
|
236
|
-
isRoot: false,
|
|
237
|
-
recursive
|
|
238
|
-
});
|
|
239
|
-
for (const leaf of childLeaves) subtreeLeaves.push(leaf);
|
|
240
|
-
}
|
|
241
|
-
if (!isRoot && !recursive) return subtreeLeaves;
|
|
242
|
-
const exports = subtreeLeaves.flatMap((leafPath) => params.strategy({
|
|
243
|
-
dirPath: node.path,
|
|
244
|
-
leafPath,
|
|
245
|
-
sourceFile: params.sourceFiles.get(leafPath)
|
|
246
|
-
}));
|
|
247
|
-
if (exports.length > 0) yield makeBarrel({
|
|
248
|
-
dirPath: node.path,
|
|
249
|
-
exports,
|
|
250
|
-
sourceFiles: params.sourceFiles,
|
|
251
|
-
reportedCollisions: params.reportedCollisions
|
|
168
|
+
function walkFlat(node, ctx, isRoot = true) {
|
|
169
|
+
const results = [...node.children.values()].map((child) => child.children ? walkFlat(child, ctx, false) : {
|
|
170
|
+
barrels: [],
|
|
171
|
+
leaves: [child.path]
|
|
252
172
|
});
|
|
253
|
-
|
|
173
|
+
const barrels = results.flatMap((result) => result.barrels);
|
|
174
|
+
const leaves = results.flatMap((result) => result.leaves);
|
|
175
|
+
const exports = isRoot || ctx.recursive ? leaves.flatMap((leaf) => ctx.leafExports(node.path, leaf)) : [];
|
|
176
|
+
return {
|
|
177
|
+
barrels: exports.length > 0 ? [...barrels, makeBarrel(node.path, exports, ctx)] : barrels,
|
|
178
|
+
leaves
|
|
179
|
+
};
|
|
254
180
|
}
|
|
255
181
|
/**
|
|
256
|
-
* Recursive walk that
|
|
182
|
+
* Recursive walk that builds one barrel per directory, re-exporting files and sub-barrels.
|
|
257
183
|
* Used when nested: true. Leaf files honor the barrel `strategy`, so `named` emits explicit
|
|
258
184
|
* named exports instead of wildcards. Sub-directory barrels are chained with a wildcard
|
|
259
|
-
* re-export, which forwards the names the child barrel already curated.
|
|
260
|
-
*
|
|
185
|
+
* re-export, which forwards the names the child barrel already curated. A sub-directory that
|
|
186
|
+
* produced no barrel is never re-exported.
|
|
261
187
|
*/
|
|
262
|
-
function
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}))
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}) }));
|
|
278
|
-
}
|
|
279
|
-
if (exports.length > 0) {
|
|
280
|
-
yield makeBarrel({
|
|
281
|
-
dirPath: node.path,
|
|
282
|
-
exports,
|
|
283
|
-
sourceFiles: params.sourceFiles,
|
|
284
|
-
reportedCollisions: params.reportedCollisions
|
|
285
|
-
});
|
|
286
|
-
return true;
|
|
287
|
-
}
|
|
288
|
-
return false;
|
|
188
|
+
function walkNested(node, ctx) {
|
|
189
|
+
const results = [...node.children.values()].map((child) => {
|
|
190
|
+
if (!child.children) return {
|
|
191
|
+
barrels: [],
|
|
192
|
+
exports: ctx.leafExports(node.path, child.path)
|
|
193
|
+
};
|
|
194
|
+
const barrels = walkNested(child, ctx);
|
|
195
|
+
return {
|
|
196
|
+
barrels,
|
|
197
|
+
exports: barrels.length > 0 ? [_kubb_kit.ast.factory.createExport({ path: toRelativeModulePath(node.path, `${child.path}${BARREL_SUFFIX}`) })] : []
|
|
198
|
+
};
|
|
199
|
+
});
|
|
200
|
+
const barrels = results.flatMap((result) => result.barrels);
|
|
201
|
+
const exports = results.flatMap((result) => result.exports);
|
|
202
|
+
return exports.length > 0 ? [...barrels, makeBarrel(node.path, exports, ctx)] : barrels;
|
|
289
203
|
}
|
|
290
204
|
/**
|
|
291
205
|
* Indexes `files` once for the directory rooted at `outputPath`: filters to indexable source
|
|
@@ -293,62 +207,62 @@ function* walkNested(node, params) {
|
|
|
293
207
|
* derived from the same root rather than re-filtering and re-building per barrel.
|
|
294
208
|
*/
|
|
295
209
|
function buildBarrelIndex(outputPath, files) {
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
210
|
+
const tree = {
|
|
211
|
+
path: toPosixPath(outputPath),
|
|
212
|
+
children: /* @__PURE__ */ new Map()
|
|
213
|
+
};
|
|
214
|
+
const sourceFiles = new Map(files.flatMap((file) => {
|
|
215
|
+
const filePath = toPosixPath(file.path);
|
|
216
|
+
return filePath.startsWith(`${tree.path}/`) && !filePath.endsWith(BARREL_SUFFIX) && SOURCE_EXTENSIONS.has((0, node_path.extname)(filePath)) ? [[filePath, file]] : [];
|
|
217
|
+
}));
|
|
218
|
+
[...sourceFiles.keys()].map((filePath) => filePath.slice(tree.path.length + 1).split("/").filter(Boolean)).sort(compareSegments).forEach((parts) => {
|
|
219
|
+
parts.reduce((dir, part, i) => {
|
|
220
|
+
const path = `${dir.path}/${part}`;
|
|
221
|
+
const child = dir.children.get(part) ?? (i === parts.length - 1 ? { path } : {
|
|
222
|
+
path,
|
|
223
|
+
children: /* @__PURE__ */ new Map()
|
|
224
|
+
});
|
|
225
|
+
dir.children.set(part, child);
|
|
226
|
+
return child.children ? child : dir;
|
|
227
|
+
}, tree);
|
|
228
|
+
});
|
|
305
229
|
return {
|
|
306
|
-
tree
|
|
230
|
+
tree,
|
|
307
231
|
sourceFiles
|
|
308
232
|
};
|
|
309
233
|
}
|
|
310
234
|
/**
|
|
311
|
-
* Locates the node for `targetPath` within an index tree
|
|
312
|
-
*
|
|
235
|
+
* Locates the directory node for `targetPath` within an index tree. Returns `undefined` when no
|
|
236
|
+
* file exists under `targetPath` (nothing to barrel).
|
|
313
237
|
*/
|
|
314
|
-
function
|
|
315
|
-
if (
|
|
316
|
-
if (
|
|
317
|
-
|
|
238
|
+
function findDirectory(tree, targetPath) {
|
|
239
|
+
if (targetPath === tree.path) return tree;
|
|
240
|
+
if (!targetPath.startsWith(`${tree.path}/`)) return void 0;
|
|
241
|
+
const node = targetPath.slice(tree.path.length + 1).split("/").reduce((current, part) => current?.children?.get(part), tree);
|
|
242
|
+
return node?.children ? node : void 0;
|
|
318
243
|
}
|
|
319
244
|
/**
|
|
320
|
-
*
|
|
245
|
+
* Returns the barrel `ast.FileNode`s for `targetPath` (or the index root), derived from a shared index.
|
|
321
246
|
* Locating the subtree is a bounded walk down from the root, so deriving many barrels (one per
|
|
322
247
|
* plugin, plus the root) from one index avoids re-scanning the full file set for each.
|
|
323
248
|
*
|
|
324
249
|
* @example
|
|
325
250
|
* ```ts
|
|
326
251
|
* const index = buildBarrelIndex(outputPath, files)
|
|
327
|
-
*
|
|
328
|
-
* upsertFile(file)
|
|
329
|
-
* }
|
|
252
|
+
* getBarrelFiles({ index, targetPath, barrelType }).forEach((file) => upsertFile(file))
|
|
330
253
|
* ```
|
|
331
254
|
*/
|
|
332
|
-
function
|
|
333
|
-
const node = targetPath ?
|
|
334
|
-
if (!node) return;
|
|
255
|
+
function getBarrelFiles({ index, targetPath, barrelType, nested = false, recursive = false, reportedCollisions = /* @__PURE__ */ new Set() }) {
|
|
256
|
+
const node = targetPath ? findDirectory(index.tree, toPosixPath(targetPath)) : index.tree;
|
|
257
|
+
if (!node) return [];
|
|
335
258
|
const strategy = barrelType === "named" ? namedStrategy : allStrategy;
|
|
336
|
-
|
|
337
|
-
yield* walkNested(node, {
|
|
338
|
-
sourceFiles: index.sourceFiles,
|
|
339
|
-
strategy,
|
|
340
|
-
reportedCollisions
|
|
341
|
-
});
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
yield* walkAllOrNamed(node, {
|
|
259
|
+
const ctx = {
|
|
345
260
|
sourceFiles: index.sourceFiles,
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
});
|
|
261
|
+
reportedCollisions,
|
|
262
|
+
recursive,
|
|
263
|
+
leafExports: (dirPath, leafPath) => strategy(toRelativeModulePath(dirPath, leafPath), index.sourceFiles.get(leafPath))
|
|
264
|
+
};
|
|
265
|
+
return nested ? walkNested(node, ctx) : walkFlat(node, ctx).barrels;
|
|
352
266
|
}
|
|
353
267
|
//#endregion
|
|
354
268
|
//#region src/plugin.ts
|
|
@@ -388,6 +302,7 @@ const pluginBarrelName = "plugin-barrel";
|
|
|
388
302
|
const states = /* @__PURE__ */ new WeakMap();
|
|
389
303
|
function getState(config) {
|
|
390
304
|
const state = states.get(config) ?? {
|
|
305
|
+
excludedPlugins: /* @__PURE__ */ new Set(),
|
|
391
306
|
excludedTargets: [],
|
|
392
307
|
pendingBarrels: []
|
|
393
308
|
};
|
|
@@ -428,19 +343,25 @@ function getState(config) {
|
|
|
428
343
|
* ```
|
|
429
344
|
*/
|
|
430
345
|
const pluginBarrel = (0, _kubb_kit.definePlugin)({
|
|
431
|
-
meta: {
|
|
346
|
+
meta: {
|
|
347
|
+
name: pluginBarrelName,
|
|
348
|
+
version,
|
|
349
|
+
compatibility
|
|
350
|
+
},
|
|
432
351
|
enforce: "post",
|
|
433
352
|
hooks: {
|
|
434
353
|
"kubb:plugin:end"({ plugin, config }) {
|
|
435
354
|
if (plugin.name === "plugin-barrel") return;
|
|
436
|
-
const { excludedTargets, pendingBarrels } = getState(config);
|
|
355
|
+
const { excludedPlugins, excludedTargets, pendingBarrels } = getState(config);
|
|
437
356
|
const barrelConfig = plugin.options.output?.barrel ?? config.output.barrel ?? false;
|
|
438
357
|
const base = node_path.default.resolve(config.root, config.output.path);
|
|
439
|
-
const target = node_path.default.resolve(base, plugin.options.output.path);
|
|
358
|
+
const target = node_path.default.resolve(base, plugin.options.output.path ?? ".");
|
|
440
359
|
if (barrelConfig === false) {
|
|
441
|
-
|
|
360
|
+
excludedPlugins.add(plugin.name);
|
|
361
|
+
if (target !== base && isPathInside(target, base)) excludedTargets.push(target);
|
|
442
362
|
return;
|
|
443
363
|
}
|
|
364
|
+
if (target === base) return;
|
|
444
365
|
if (plugin.options.output.mode === "file") return;
|
|
445
366
|
if (!isPathInside(target, base)) throw new _kubb_kit.Diagnostics.Error({
|
|
446
367
|
code: _kubb_kit.Diagnostics.code.pathTraversal,
|
|
@@ -457,32 +378,43 @@ const pluginBarrel = (0, _kubb_kit.definePlugin)({
|
|
|
457
378
|
});
|
|
458
379
|
},
|
|
459
380
|
"kubb:plugins:end"({ files, config, upsertFile }) {
|
|
460
|
-
const { excludedTargets, pendingBarrels } = getState(config);
|
|
381
|
+
const { excludedPlugins, excludedTargets, pendingBarrels } = getState(config);
|
|
461
382
|
const rootBarrelConfig = config.output.barrel ?? false;
|
|
462
383
|
const outputPath = node_path.default.resolve(config.root, config.output.path);
|
|
463
|
-
const relevantFiles = files.filter((file) =>
|
|
384
|
+
const relevantFiles = files.filter((file) => {
|
|
385
|
+
const owner = file.meta?.pluginName;
|
|
386
|
+
if (owner) return !excludedPlugins.has(owner);
|
|
387
|
+
return !excludedTargets.some((target) => isPathInside(file.path, target));
|
|
388
|
+
});
|
|
389
|
+
excludedPlugins.clear();
|
|
464
390
|
excludedTargets.length = 0;
|
|
465
391
|
const index = buildBarrelIndex(outputPath, relevantFiles);
|
|
466
392
|
const reportedCollisions = /* @__PURE__ */ new Set();
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
file
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
393
|
+
pendingBarrels.forEach(({ plugin, target, barrelType, nested }) => {
|
|
394
|
+
getBarrelFiles({
|
|
395
|
+
index,
|
|
396
|
+
targetPath: target,
|
|
397
|
+
barrelType,
|
|
398
|
+
nested,
|
|
399
|
+
recursive: true,
|
|
400
|
+
reportedCollisions
|
|
401
|
+
}).forEach((file) => {
|
|
402
|
+
upsertFile(withBarrelBannerFooter({
|
|
403
|
+
file,
|
|
404
|
+
plugin,
|
|
405
|
+
config
|
|
406
|
+
}));
|
|
407
|
+
});
|
|
408
|
+
});
|
|
479
409
|
pendingBarrels.length = 0;
|
|
480
410
|
if (rootBarrelConfig === false) return;
|
|
481
|
-
|
|
411
|
+
getBarrelFiles({
|
|
482
412
|
index,
|
|
483
413
|
barrelType: rootBarrelConfig.type,
|
|
484
414
|
reportedCollisions
|
|
485
|
-
})
|
|
415
|
+
}).forEach((file) => {
|
|
416
|
+
upsertFile(file);
|
|
417
|
+
});
|
|
486
418
|
}
|
|
487
419
|
}
|
|
488
420
|
});
|