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