@kubb/middleware-barrel 5.0.0-alpha.62 → 5.0.0-alpha.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +213 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +20 -29
- package/dist/index.js +214 -160
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
- package/src/constants.ts +0 -1
- package/src/middleware.ts +23 -33
- package/src/types.ts +5 -7
- package/src/utils/excludedPaths.ts +23 -0
- package/src/utils/generatePerPluginBarrel.ts +17 -7
- package/src/utils/generateRootBarrel.ts +14 -7
- package/src/utils/getBarrelFiles.ts +183 -154
- package/src/utils/resolveBarrelType.ts +20 -0
- package/src/utils/buildTree.ts +0 -67
package/dist/index.cjs
CHANGED
|
@@ -9,18 +9,18 @@ let _kubb_ast = require("@kubb/ast");
|
|
|
9
9
|
*/
|
|
10
10
|
const BARREL_FILENAME = "index.ts";
|
|
11
11
|
//#endregion
|
|
12
|
-
//#region
|
|
12
|
+
//#region ../../internals/utils/src/buildTree.ts
|
|
13
13
|
/**
|
|
14
|
-
* Builds a
|
|
14
|
+
* Builds a directory tree rooted at `rootPath` from a list of absolute file paths.
|
|
15
|
+
* Paths outside `rootPath` are silently ignored. Children are sorted alphabetically
|
|
16
|
+
* by path so consumers (barrel exports, propagated indexes) emit a deterministic order.
|
|
15
17
|
*
|
|
16
|
-
*
|
|
17
|
-
* the root or that equal the root are silently ignored.
|
|
18
|
+
* Both POSIX (`/`) and Windows (`\`) separators are accepted in input paths.
|
|
18
19
|
*
|
|
19
20
|
* @example
|
|
20
21
|
* ```ts
|
|
21
|
-
*
|
|
22
|
+
* buildTree('/src/gen/types', [
|
|
22
23
|
* '/src/gen/types/pet.ts',
|
|
23
|
-
* '/src/gen/types/user.ts',
|
|
24
24
|
* '/src/gen/types/pets/listPets.ts',
|
|
25
25
|
* ])
|
|
26
26
|
* ```
|
|
@@ -31,28 +31,45 @@ function buildTree(rootPath, filePaths) {
|
|
|
31
31
|
children: [],
|
|
32
32
|
isFile: false
|
|
33
33
|
};
|
|
34
|
+
const childIndex = /* @__PURE__ */ new Map();
|
|
35
|
+
childIndex.set(root, /* @__PURE__ */ new Map());
|
|
36
|
+
const rootPrefix = `${rootPath.replaceAll("\\", "/")}/`;
|
|
34
37
|
for (const filePath of filePaths) {
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
39
|
+
if (!normalized.startsWith(rootPrefix)) continue;
|
|
40
|
+
const parts = normalized.slice(rootPrefix.length).split("/");
|
|
41
|
+
if (parts.length === 0) continue;
|
|
37
42
|
let current = root;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
+
const lastIndex = parts.length - 1;
|
|
44
|
+
for (const [i, part] of parts.entries()) {
|
|
45
|
+
if (!part) continue;
|
|
46
|
+
const isLast = i === lastIndex;
|
|
47
|
+
const siblings = childIndex.get(current);
|
|
48
|
+
let child = siblings.get(part);
|
|
43
49
|
if (!child) {
|
|
44
50
|
child = {
|
|
45
|
-
path:
|
|
51
|
+
path: `${current.path}/${part}`,
|
|
46
52
|
children: [],
|
|
47
53
|
isFile: isLast
|
|
48
54
|
};
|
|
49
55
|
current.children.push(child);
|
|
56
|
+
siblings.set(part, child);
|
|
57
|
+
if (!isLast) childIndex.set(child, /* @__PURE__ */ new Map());
|
|
50
58
|
}
|
|
51
59
|
current = child;
|
|
52
60
|
}
|
|
53
61
|
}
|
|
62
|
+
sortTree(root);
|
|
54
63
|
return root;
|
|
55
64
|
}
|
|
65
|
+
function sortTree(node) {
|
|
66
|
+
if (node.children.length === 0) return;
|
|
67
|
+
node.children.sort(compareByPath);
|
|
68
|
+
for (const child of node.children) if (!child.isFile) sortTree(child);
|
|
69
|
+
}
|
|
70
|
+
function compareByPath(a, b) {
|
|
71
|
+
return a.path < b.path ? -1 : a.path > b.path ? 1 : 0;
|
|
72
|
+
}
|
|
56
73
|
//#endregion
|
|
57
74
|
//#region src/utils/getBarrelFiles.ts
|
|
58
75
|
const SOURCE_EXTENSIONS = new Set([
|
|
@@ -61,199 +78,236 @@ const SOURCE_EXTENSIONS = new Set([
|
|
|
61
78
|
".js",
|
|
62
79
|
".jsx"
|
|
63
80
|
]);
|
|
81
|
+
const BARREL_SUFFIX = `/${BARREL_FILENAME}`;
|
|
64
82
|
/**
|
|
65
|
-
* Derives a relative module specifier from
|
|
66
|
-
* The source extension is preserved so
|
|
67
|
-
* (e.g. `.ts` → `.js` for ESM output).
|
|
83
|
+
* Derives a relative module specifier from `filePath` relative to `fromDir`.
|
|
84
|
+
* The source extension is preserved so `@kubb/parser-ts` can apply its `extNames` mapping.
|
|
68
85
|
*
|
|
69
86
|
* @example
|
|
87
|
+
* ```ts
|
|
70
88
|
* toRelativeModulePath('/src/gen/types', '/src/gen/types/pet.ts') // './pet.ts'
|
|
71
89
|
* toRelativeModulePath('/src/gen/types', '/src/gen/types/tags/tag.ts') // './tags/tag.ts'
|
|
90
|
+
* ```
|
|
72
91
|
*/
|
|
73
92
|
function toRelativeModulePath(fromDir, filePath) {
|
|
74
|
-
return `./${filePath.slice(fromDir.length
|
|
93
|
+
return `./${filePath.slice(fromDir.length + 1)}`;
|
|
75
94
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* with their full relative path from `treeNode.path`.
|
|
82
|
-
*/
|
|
83
|
-
function getBarrelFilesAll(treeNode, sourceFiles) {
|
|
84
|
-
const leafPaths = collectLeafPaths(treeNode).filter((p) => !p.endsWith(`/${BARREL_FILENAME}`));
|
|
85
|
-
if (leafPaths.length === 0) return [];
|
|
86
|
-
const barrelPath = `${treeNode.path}/${BARREL_FILENAME}`;
|
|
87
|
-
const exports = [];
|
|
88
|
-
for (const filePath of leafPaths) {
|
|
89
|
-
const sourceFile = sourceFiles.find((f) => f.path === filePath);
|
|
90
|
-
if (sourceFile && sourceFile.sources.length > 0 && sourceFile.sources.every((s) => !s.isIndexable)) continue;
|
|
91
|
-
exports.push((0, _kubb_ast.createExport)({ path: toRelativeModulePath(treeNode.path, filePath) }));
|
|
92
|
-
}
|
|
93
|
-
if (exports.length === 0) return [];
|
|
94
|
-
return [(0, _kubb_ast.createFile)({
|
|
95
|
+
function isBarrelPath(path) {
|
|
96
|
+
return path.endsWith(BARREL_SUFFIX);
|
|
97
|
+
}
|
|
98
|
+
function makeBarrel(dirPath, exports) {
|
|
99
|
+
return (0, _kubb_ast.createFile)({
|
|
95
100
|
baseName: BARREL_FILENAME,
|
|
96
|
-
path:
|
|
101
|
+
path: `${dirPath}${BARREL_SUFFIX}`,
|
|
97
102
|
exports,
|
|
98
103
|
sources: [],
|
|
99
104
|
imports: []
|
|
100
|
-
})
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function hasOnlyNonIndexableSources(sources) {
|
|
108
|
+
if (sources.length === 0) return false;
|
|
109
|
+
for (const source of sources) if (source.isIndexable) return false;
|
|
110
|
+
return true;
|
|
101
111
|
}
|
|
112
|
+
function partitionIndexableNames(sources) {
|
|
113
|
+
const byTypeOnly = new Map([[false, /* @__PURE__ */ new Set()], [true, /* @__PURE__ */ new Set()]]);
|
|
114
|
+
for (const source of sources) {
|
|
115
|
+
if (!source.isIndexable || !source.name) continue;
|
|
116
|
+
byTypeOnly.get(Boolean(source.isTypeOnly)).add(source.name);
|
|
117
|
+
}
|
|
118
|
+
return byTypeOnly;
|
|
119
|
+
}
|
|
120
|
+
const allStrategy = ({ dirPath, leafPath, sourceFile }) => {
|
|
121
|
+
if (sourceFile && hasOnlyNonIndexableSources(sourceFile.sources)) return [];
|
|
122
|
+
return [(0, _kubb_ast.createExport)({ path: toRelativeModulePath(dirPath, leafPath) })];
|
|
123
|
+
};
|
|
124
|
+
const namedStrategy = ({ dirPath, leafPath, sourceFile }) => {
|
|
125
|
+
const modulePath = toRelativeModulePath(dirPath, leafPath);
|
|
126
|
+
if (!sourceFile) return [(0, _kubb_ast.createExport)({ path: modulePath })];
|
|
127
|
+
const namesByTypeOnly = partitionIndexableNames(sourceFile.sources);
|
|
128
|
+
const valueNames = namesByTypeOnly.get(false);
|
|
129
|
+
const typeNames = namesByTypeOnly.get(true);
|
|
130
|
+
if (valueNames.size === 0 && typeNames.size === 0) {
|
|
131
|
+
if (sourceFile.sources.length > 0) return [];
|
|
132
|
+
return [(0, _kubb_ast.createExport)({ path: modulePath })];
|
|
133
|
+
}
|
|
134
|
+
const exports = [];
|
|
135
|
+
if (valueNames.size > 0) exports.push((0, _kubb_ast.createExport)({
|
|
136
|
+
name: [...valueNames],
|
|
137
|
+
path: modulePath
|
|
138
|
+
}));
|
|
139
|
+
if (typeNames.size > 0) exports.push((0, _kubb_ast.createExport)({
|
|
140
|
+
name: [...typeNames],
|
|
141
|
+
path: modulePath,
|
|
142
|
+
isTypeOnly: true
|
|
143
|
+
}));
|
|
144
|
+
return exports;
|
|
145
|
+
};
|
|
146
|
+
const LEAF_STRATEGIES = new Map([["all", allStrategy], ["named", namedStrategy]]);
|
|
102
147
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
148
|
+
* Single-pass post-order traversal that emits a barrel for each visited directory and
|
|
149
|
+
* returns its leaf paths so parents don't have to re-walk the subtree.
|
|
105
150
|
*/
|
|
106
|
-
function
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
for (const filePath of leafPaths) {
|
|
112
|
-
const sourceFile = sourceFiles.find((f) => f.path === filePath);
|
|
113
|
-
if (!sourceFile) {
|
|
114
|
-
exports.push((0, _kubb_ast.createExport)({ path: toRelativeModulePath(treeNode.path, filePath) }));
|
|
151
|
+
function walkAllOrNamed(node, params, isRoot, out) {
|
|
152
|
+
const subtreeLeaves = [];
|
|
153
|
+
for (const child of node.children) {
|
|
154
|
+
if (child.isFile) {
|
|
155
|
+
if (!isBarrelPath(child.path)) subtreeLeaves.push(child.path);
|
|
115
156
|
continue;
|
|
116
157
|
}
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
158
|
+
const childLeaves = walkAllOrNamed(child, params, false, out);
|
|
159
|
+
for (const leaf of childLeaves) subtreeLeaves.push(leaf);
|
|
160
|
+
}
|
|
161
|
+
if (!isRoot && !params.recursive) return subtreeLeaves;
|
|
162
|
+
const exports = subtreeLeaves.flatMap((leafPath) => params.strategy({
|
|
163
|
+
dirPath: node.path,
|
|
164
|
+
leafPath,
|
|
165
|
+
sourceFile: params.sourceFiles.get(leafPath)
|
|
166
|
+
}));
|
|
167
|
+
if (exports.length > 0) out.push(makeBarrel(node.path, exports));
|
|
168
|
+
return subtreeLeaves;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Emits one barrel per directory: every direct child file is re-exported and every
|
|
172
|
+
* sub-directory is re-exported via its own barrel (recursive by design).
|
|
173
|
+
*/
|
|
174
|
+
function walkPropagate(node, out) {
|
|
175
|
+
const exports = [];
|
|
176
|
+
for (const child of node.children) {
|
|
177
|
+
if (child.isFile) {
|
|
178
|
+
if (isBarrelPath(child.path)) continue;
|
|
179
|
+
exports.push((0, _kubb_ast.createExport)({ path: toRelativeModulePath(node.path, child.path) }));
|
|
121
180
|
continue;
|
|
122
181
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const modulePath = toRelativeModulePath(treeNode.path, filePath);
|
|
126
|
-
if (valueNames.length > 0) exports.push((0, _kubb_ast.createExport)({
|
|
127
|
-
name: valueNames,
|
|
128
|
-
path: modulePath
|
|
129
|
-
}));
|
|
130
|
-
if (typeNames.length > 0) exports.push((0, _kubb_ast.createExport)({
|
|
131
|
-
name: typeNames,
|
|
132
|
-
path: modulePath,
|
|
133
|
-
isTypeOnly: true
|
|
134
|
-
}));
|
|
182
|
+
walkPropagate(child, out);
|
|
183
|
+
exports.push((0, _kubb_ast.createExport)({ path: toRelativeModulePath(node.path, `${child.path}${BARREL_SUFFIX}`) }));
|
|
135
184
|
}
|
|
136
|
-
if (exports.length
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
185
|
+
if (exports.length > 0) out.push(makeBarrel(node.path, exports));
|
|
186
|
+
}
|
|
187
|
+
function indexRelevantFiles(files, outputPath) {
|
|
188
|
+
const outputPrefix = `${outputPath.replaceAll("\\", "/")}/`;
|
|
189
|
+
const sourceFiles = /* @__PURE__ */ new Map();
|
|
190
|
+
const paths = [];
|
|
191
|
+
for (const file of files) {
|
|
192
|
+
const normalized = file.path.replaceAll("\\", "/");
|
|
193
|
+
if (!normalized.startsWith(outputPrefix)) continue;
|
|
194
|
+
if (isBarrelPath(normalized)) continue;
|
|
195
|
+
if (!SOURCE_EXTENSIONS.has((0, node_path.extname)(normalized))) continue;
|
|
196
|
+
sourceFiles.set(file.path, file);
|
|
197
|
+
paths.push(file.path);
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
sourceFiles,
|
|
201
|
+
paths
|
|
202
|
+
};
|
|
144
203
|
}
|
|
145
204
|
/**
|
|
146
|
-
* Generates barrel `FileNode
|
|
147
|
-
* like `'all'` but also generates intermediate barrel files for every sub-directory, so that
|
|
148
|
-
* consumers can import from any depth.
|
|
205
|
+
* Generates barrel `FileNode`s for the directory rooted at `outputPath`.
|
|
149
206
|
*
|
|
150
|
-
*
|
|
207
|
+
* Files outside `outputPath`, existing barrel files, and non-source extensions are filtered out
|
|
208
|
+
* before the tree is built.
|
|
151
209
|
*/
|
|
152
|
-
function
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
210
|
+
function getBarrelFiles({ outputPath, files, barrelType, recursive = false }) {
|
|
211
|
+
const { sourceFiles, paths } = indexRelevantFiles(files, outputPath);
|
|
212
|
+
if (paths.length === 0) return [];
|
|
213
|
+
const tree = buildTree(outputPath, paths);
|
|
156
214
|
const result = [];
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
} else {
|
|
161
|
-
const subBarrels = collectPropagatedBarrels(child);
|
|
162
|
-
result.push(...subBarrels);
|
|
163
|
-
const subBarrelPath = `${child.path}/${BARREL_FILENAME}`;
|
|
164
|
-
barrelExports.push((0, _kubb_ast.createExport)({ path: toRelativeModulePath(node.path, subBarrelPath) }));
|
|
215
|
+
if (barrelType === "propagate") {
|
|
216
|
+
walkPropagate(tree, result);
|
|
217
|
+
return result;
|
|
165
218
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
})
|
|
219
|
+
const strategy = LEAF_STRATEGIES.get(barrelType);
|
|
220
|
+
if (!strategy) return result;
|
|
221
|
+
walkAllOrNamed(tree, {
|
|
222
|
+
sourceFiles,
|
|
223
|
+
strategy,
|
|
224
|
+
recursive
|
|
225
|
+
}, true, result);
|
|
173
226
|
return result;
|
|
174
227
|
}
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region src/utils/generatePerPluginBarrel.ts
|
|
175
230
|
/**
|
|
176
|
-
*
|
|
231
|
+
* Generates barrel files for a single plugin's output directory.
|
|
232
|
+
*
|
|
233
|
+
* The barrel is placed at `<config.root>/<config.output.path>/<plugin.options.output.path>/index.ts`.
|
|
234
|
+
* When the plugin uses `group`, additional sub-directory barrels are generated so that grouped
|
|
235
|
+
* output (e.g. `petController/index.ts`) gets its own re-export entry point.
|
|
177
236
|
*/
|
|
178
|
-
function
|
|
179
|
-
|
|
180
|
-
|
|
237
|
+
function generatePerPluginBarrel({ barrelType, plugin, files, config }) {
|
|
238
|
+
return getBarrelFiles({
|
|
239
|
+
outputPath: (0, node_path.resolve)(config.root, config.output.path, plugin.options.output.path),
|
|
240
|
+
files,
|
|
241
|
+
barrelType,
|
|
242
|
+
recursive: true
|
|
243
|
+
});
|
|
181
244
|
}
|
|
245
|
+
//#endregion
|
|
246
|
+
//#region src/utils/generateRootBarrel.ts
|
|
182
247
|
/**
|
|
183
|
-
* Generates
|
|
184
|
-
* generated source `files`, using the specified `barrelType` strategy.
|
|
248
|
+
* Generates the root barrel file at `<config.root>/<config.output.path>/index.ts`.
|
|
185
249
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* @param outputPath Absolute path to the output directory.
|
|
189
|
-
* @param files All generated files (across all plugins).
|
|
190
|
-
* @param barrelType Barrel generation strategy.
|
|
250
|
+
* Unlike `generatePerPluginBarrel`, this does not recurse into sub-directories — each
|
|
251
|
+
* plugin is responsible for its own per-plugin barrels.
|
|
191
252
|
*/
|
|
192
|
-
function
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (normalizedFilePath.endsWith(`/index.ts`)) return false;
|
|
198
|
-
const dotIndex = normalizedFilePath.lastIndexOf(".");
|
|
199
|
-
const ext = dotIndex === -1 ? "" : normalizedFilePath.slice(dotIndex);
|
|
200
|
-
return SOURCE_EXTENSIONS.has(ext);
|
|
253
|
+
function generateRootBarrel({ barrelType, files, config }) {
|
|
254
|
+
return getBarrelFiles({
|
|
255
|
+
outputPath: (0, node_path.resolve)(config.root, config.output.path),
|
|
256
|
+
files,
|
|
257
|
+
barrelType
|
|
201
258
|
});
|
|
202
|
-
if (relevantFiles.length === 0) return [];
|
|
203
|
-
const tree = buildTree(outputPath, relevantFiles.map((f) => f.path));
|
|
204
|
-
switch (barrelType) {
|
|
205
|
-
case "all": return getBarrelFilesAll(tree, relevantFiles);
|
|
206
|
-
case "named": return getBarrelFilesNamed(tree, relevantFiles);
|
|
207
|
-
case "propagate": return getBarrelFilesPropagate(tree);
|
|
208
|
-
default: return [];
|
|
209
|
-
}
|
|
210
259
|
}
|
|
211
260
|
//#endregion
|
|
212
|
-
//#region src/utils/
|
|
261
|
+
//#region src/utils/excludedPaths.ts
|
|
213
262
|
/**
|
|
214
|
-
*
|
|
263
|
+
* Returns the absolute output directory of `plugin` with a trailing separator,
|
|
264
|
+
* suitable for prefix-based exclusion checks via {@link isExcludedPath}.
|
|
215
265
|
*
|
|
216
|
-
* The
|
|
217
|
-
*
|
|
266
|
+
* The trailing `/` ensures `startsWith` does not match unrelated siblings
|
|
267
|
+
* (e.g. `/foo/bar` vs `/foo/barbaz/x.ts`).
|
|
268
|
+
*/
|
|
269
|
+
function getPluginOutputPrefix(plugin, config) {
|
|
270
|
+
return `${(0, node_path.resolve)(config.root, config.output.path, plugin.options.output.path)}/`;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Returns `true` when `filePath` lies under any of the directory prefixes in `prefixes`.
|
|
274
|
+
* Prefixes must already include a trailing separator (see {@link getPluginOutputPrefix}).
|
|
218
275
|
*
|
|
219
|
-
*
|
|
220
|
-
* Files generated by plugins land at `config.root + config.output.path + plugin.output.path`,
|
|
221
|
-
* so the barrel directory must be resolved with all three segments.
|
|
276
|
+
* Uses Node 22 iterator helpers (`Iterator.prototype.some`) to avoid materializing the set.
|
|
222
277
|
*/
|
|
223
|
-
function
|
|
224
|
-
return
|
|
278
|
+
function isExcludedPath(filePath, prefixes) {
|
|
279
|
+
return prefixes.values().some((prefix) => filePath.startsWith(prefix));
|
|
225
280
|
}
|
|
226
281
|
//#endregion
|
|
227
|
-
//#region src/utils/
|
|
282
|
+
//#region src/utils/resolveBarrelType.ts
|
|
283
|
+
const DEFAULT_BARREL_TYPE = "named";
|
|
228
284
|
/**
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
* The root barrel re-exports from all files across all plugins that are located
|
|
232
|
-
* inside the root output directory, using the given `barrelType` strategy.
|
|
233
|
-
*
|
|
234
|
-
* In practice this re-exports the per-plugin barrels when `barrelType = 'propagate'`,
|
|
235
|
-
* or all individual files when `barrelType = 'all'` or `'named'`.
|
|
285
|
+
* Resolves the effective barrel style for a single plugin: explicit plugin option →
|
|
286
|
+
* root config option → `'named'` default. Returns `false` when barrel generation is disabled.
|
|
236
287
|
*/
|
|
237
|
-
function
|
|
238
|
-
return
|
|
288
|
+
function resolvePluginBarrelType(plugin, config) {
|
|
289
|
+
return plugin.options.output?.barrelType ?? config.output.barrelType ?? DEFAULT_BARREL_TYPE;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Resolves the effective barrel style for the root `index.ts`: root config option → `'named'` default.
|
|
293
|
+
* Returns `false` when the root barrel is disabled.
|
|
294
|
+
*/
|
|
295
|
+
function resolveRootBarrelType(config) {
|
|
296
|
+
return config.output.barrelType ?? DEFAULT_BARREL_TYPE;
|
|
239
297
|
}
|
|
240
298
|
//#endregion
|
|
241
299
|
//#region src/middleware.ts
|
|
242
300
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* When added to `config.middleware`, generates an `index.ts` barrel file for each
|
|
246
|
-
* plugin. When `output.barrelType` is omitted on a plugin it inherits from `config.output.barrelType`,
|
|
247
|
-
* and when that is also omitted both default to `'all'`. Set `barrelType: false` to disable
|
|
248
|
-
* barrel generation for a specific plugin or for the root entirely.
|
|
301
|
+
* Generates `index.ts` barrel files for each plugin's output directory and one root barrel
|
|
302
|
+
* at `config.output.path/index.ts`.
|
|
249
303
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* - `'propagate'` — like `'all'` with intermediate barrel files for sub-directories
|
|
304
|
+
* Plugins inherit `output.barrelType` from `config.output.barrelType` (which itself defaults to `'named'`).
|
|
305
|
+
* Setting `barrelType: false` on a plugin disables its barrel and excludes the plugin's files from the
|
|
306
|
+
* root barrel as well.
|
|
254
307
|
*
|
|
255
308
|
* @example
|
|
256
309
|
* ```ts
|
|
310
|
+
* import { defineConfig } from '@kubb/core'
|
|
257
311
|
* import { middlewareBarrel } from '@kubb/middleware-barrel'
|
|
258
312
|
*
|
|
259
313
|
* export default defineConfig({
|
|
@@ -270,15 +324,15 @@ const middlewareBarrel = (0, _kubb_core.defineMiddleware)({
|
|
|
270
324
|
name: "middleware-barrel",
|
|
271
325
|
install(hooks) {
|
|
272
326
|
let ctx;
|
|
273
|
-
const
|
|
327
|
+
const excludedPrefixes = /* @__PURE__ */ new Set();
|
|
274
328
|
hooks.on("kubb:build:start", (buildCtx) => {
|
|
275
329
|
ctx = buildCtx;
|
|
276
330
|
});
|
|
277
331
|
hooks.on("kubb:plugin:end", ({ plugin }) => {
|
|
278
332
|
if (!ctx) return;
|
|
279
|
-
const barrelType = plugin
|
|
333
|
+
const barrelType = resolvePluginBarrelType(plugin, ctx.config);
|
|
280
334
|
if (!barrelType) {
|
|
281
|
-
|
|
335
|
+
excludedPrefixes.add(getPluginOutputPrefix(plugin, ctx.config));
|
|
282
336
|
return;
|
|
283
337
|
}
|
|
284
338
|
const barrelFiles = generatePerPluginBarrel({
|
|
@@ -290,11 +344,11 @@ const middlewareBarrel = (0, _kubb_core.defineMiddleware)({
|
|
|
290
344
|
if (barrelFiles.length > 0) ctx.upsertFile(...barrelFiles);
|
|
291
345
|
});
|
|
292
346
|
hooks.on("kubb:plugins:end", ({ files, config, upsertFile }) => {
|
|
293
|
-
const rootBarrelType = config
|
|
347
|
+
const rootBarrelType = resolveRootBarrelType(config);
|
|
294
348
|
if (!rootBarrelType) return;
|
|
295
349
|
const rootBarrelFiles = generateRootBarrel({
|
|
296
350
|
barrelType: rootBarrelType,
|
|
297
|
-
files:
|
|
351
|
+
files: excludedPrefixes.size === 0 ? files : files.filter((f) => !isExcludedPath(f.path, excludedPrefixes)),
|
|
298
352
|
config
|
|
299
353
|
});
|
|
300
354
|
if (rootBarrelFiles.length > 0) upsertFile(...rootBarrelFiles);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["posix"],"sources":["../src/constants.ts","../src/utils/buildTree.ts","../src/utils/getBarrelFiles.ts","../src/utils/generatePerPluginBarrel.ts","../src/utils/generateRootBarrel.ts","../src/middleware.ts"],"sourcesContent":["\n/**\n * Full file name for barrel files (with extension).\n */\nexport const BARREL_FILENAME = 'index.ts' as const\n","import { posix } from 'node:path'\n\n/**\n * A node in a directory tree used to compute barrel file exports.\n *\n * Each `TreeNode` represents either a directory or a file entry.\n * Directory nodes have `children`; file nodes have an empty `children` array.\n */\nexport type BuildTree = {\n /**\n * Absolute path of the directory (root of this subtree) or file.\n */\n path: string\n /**\n * Child nodes (sub-directories and files) within this directory.\n */\n children: Array<BuildTree>\n /**\n * `true` when this node represents a file (leaf node).\n */\n isFile: boolean\n}\n\n/**\n * Builds a `TreeNode` directory tree from a list of absolute file paths.\n *\n * All `filePaths` must be inside `rootPath`. Paths that are outside\n * the root or that equal the root are silently ignored.\n *\n * @example\n * ```ts\n * const tree = buildTree('/src/gen/types', [\n * '/src/gen/types/pet.ts',\n * '/src/gen/types/user.ts',\n * '/src/gen/types/pets/listPets.ts',\n * ])\n * ```\n */\nexport function buildTree(rootPath: string, filePaths: ReadonlyArray<string>): BuildTree {\n const root: BuildTree = { path: rootPath, children: [], isFile: false }\n\n for (const filePath of filePaths) {\n // Only include files inside rootPath\n if (!filePath.startsWith(rootPath + posix.sep) && !filePath.startsWith(rootPath + '/')) {\n continue\n }\n\n const relative = filePath.slice(rootPath.length).replace(/^\\//g, '').replace(/^\\\\/g, '')\n const parts = relative.split(/[/\\\\]/).filter(Boolean)\n\n let current = root\n for (let i = 0; i < parts.length; i++) {\n const isLast = i === parts.length - 1\n const part = parts[i]!\n const childPath = `${current.path}/${part}`\n\n let child = current.children.find((c) => c.path === childPath)\n if (!child) {\n child = { path: childPath, children: [], isFile: isLast }\n current.children.push(child)\n }\n current = child\n }\n }\n\n return root\n}\n","import { createExport, createFile } from '@kubb/ast'\nimport type { FileNode } from '@kubb/ast'\nimport { BARREL_FILENAME } from '../constants.ts'\nimport type { BarrelType } from '../types.ts'\nimport { buildTree, type BuildTree } from './buildTree.ts'\n\nconst SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\n/**\n * Derives a relative module specifier from an absolute `filePath` relative to an absolute `fromDir`.\n * The source extension is preserved so that `@kubb/parser-ts` can apply the `extNames` mapping\n * (e.g. `.ts` → `.js` for ESM output).\n *\n * @example\n * toRelativeModulePath('/src/gen/types', '/src/gen/types/pet.ts') // './pet.ts'\n * toRelativeModulePath('/src/gen/types', '/src/gen/types/tags/tag.ts') // './tags/tag.ts'\n */\nfunction toRelativeModulePath(fromDir: string, filePath: string): string {\n const relative = filePath.slice(fromDir.length).replace(/^[/\\\\]/g, '')\n return `./${relative}`\n}\n\n/**\n * Generates barrel `FileNode[]` for a given directory tree node using the `'all'` strategy:\n * each leaf file gets a `export * from './relPath'` in the barrel of its nearest ancestor directory.\n *\n * Only a single barrel file (at `treeNode.path`) is generated — sub-directory files are referenced\n * with their full relative path from `treeNode.path`.\n */\nfunction getBarrelFilesAll(treeNode: BuildTree, sourceFiles: ReadonlyArray<FileNode>): Array<FileNode> {\n // Collect all source file paths under this node (excluding barrel files themselves)\n const leafPaths = collectLeafPaths(treeNode).filter((p) => !p.endsWith(`/${BARREL_FILENAME}`))\n\n if (leafPaths.length === 0) return []\n\n const barrelPath = `${treeNode.path}/${BARREL_FILENAME}`\n const exports: ReturnType<typeof createExport>[] = []\n\n for (const filePath of leafPaths) {\n const sourceFile = sourceFiles.find((f) => f.path === filePath)\n // Skip files whose sources all have isIndexable: false (e.g. internal injected files)\n if (sourceFile && sourceFile.sources.length > 0 && sourceFile.sources.every((s) => !s.isIndexable)) {\n continue\n }\n exports.push(createExport({ path: toRelativeModulePath(treeNode.path, filePath) }))\n }\n\n if (exports.length === 0) return []\n\n return [\n createFile({\n baseName: BARREL_FILENAME,\n path: barrelPath,\n exports,\n sources: [],\n imports: [],\n }),\n ]\n}\n\n/**\n * Generates barrel `FileNode[]` for a given directory tree node using the `'named'` strategy:\n * each indexable source in each leaf file gets an individual named `export { name } from '...'`.\n */\nfunction getBarrelFilesNamed(treeNode: BuildTree, sourceFiles: ReadonlyArray<FileNode>): Array<FileNode> {\n const leafPaths = collectLeafPaths(treeNode).filter((p) => !p.endsWith(`/${BARREL_FILENAME}`))\n\n if (leafPaths.length === 0) return []\n\n const barrelPath = `${treeNode.path}/${BARREL_FILENAME}`\n const exports: ReturnType<typeof createExport>[] = []\n\n for (const filePath of leafPaths) {\n const sourceFile = sourceFiles.find((f) => f.path === filePath)\n if (!sourceFile) {\n // Fall back to wildcard if the source file is not in our set\n exports.push(createExport({ path: toRelativeModulePath(treeNode.path, filePath) }))\n continue\n }\n\n const indexableSources = sourceFile.sources.filter((s) => s.isIndexable && s.name)\n if (indexableSources.length === 0) {\n // If the file has explicit sources but none are indexable, skip it entirely.\n // Only fall back to wildcard when there are no sources at all (unknown exports).\n if (sourceFile.sources.length > 0) continue\n exports.push(createExport({ path: toRelativeModulePath(treeNode.path, filePath) }))\n continue\n }\n\n const valueNames = indexableSources.filter((s) => !s.isTypeOnly).map((s) => s.name as string)\n const typeNames = indexableSources.filter((s) => s.isTypeOnly).map((s) => s.name as string)\n const modulePath = toRelativeModulePath(treeNode.path, filePath)\n\n if (valueNames.length > 0) {\n exports.push(createExport({ name: valueNames, path: modulePath }))\n }\n if (typeNames.length > 0) {\n exports.push(createExport({ name: typeNames, path: modulePath, isTypeOnly: true }))\n }\n }\n\n if (exports.length === 0) return []\n\n return [\n createFile({\n baseName: BARREL_FILENAME,\n path: barrelPath,\n exports,\n sources: [],\n imports: [],\n }),\n ]\n}\n\n/**\n * Generates barrel `FileNode[]` for a given directory tree node using the `'propagate'` strategy:\n * like `'all'` but also generates intermediate barrel files for every sub-directory, so that\n * consumers can import from any depth.\n *\n * Leaf barrels export directly from their files; parent barrels export from their sub-barrel files.\n */\nfunction getBarrelFilesPropagate(treeNode: BuildTree): Array<FileNode> {\n return collectPropagatedBarrels(treeNode)\n}\n\nfunction collectPropagatedBarrels(node: BuildTree): Array<FileNode> {\n const result: Array<FileNode> = []\n const barrelExports: ReturnType<typeof createExport>[] = []\n\n for (const child of node.children) {\n if (child.isFile) {\n if (!child.path.endsWith(`/${BARREL_FILENAME}`)) {\n barrelExports.push(createExport({ path: toRelativeModulePath(node.path, child.path) }))\n }\n } else {\n // Recurse into sub-directory\n const subBarrels = collectPropagatedBarrels(child)\n result.push(...subBarrels)\n\n // Export the sub-directory's barrel (not individual files)\n const subBarrelPath = `${child.path}/${BARREL_FILENAME}`\n barrelExports.push(createExport({ path: toRelativeModulePath(node.path, subBarrelPath) }))\n }\n }\n\n if (barrelExports.length > 0) {\n result.push(\n createFile({\n baseName: BARREL_FILENAME,\n path: `${node.path}/${BARREL_FILENAME}`,\n exports: barrelExports,\n sources: [],\n imports: [],\n }),\n )\n }\n\n return result\n}\n\n/**\n * Collects all leaf (file) paths within a tree node recursively.\n */\nfunction collectLeafPaths(node: BuildTree): Array<string> {\n if (node.isFile) return [node.path]\n return node.children.flatMap((c) => collectLeafPaths(c))\n}\n\n/**\n * Generates barrel `FileNode[]` for a directory rooted at `outputPath`, given the full set of\n * generated source `files`, using the specified `barrelType` strategy.\n *\n * Files not located inside `outputPath` are excluded automatically.\n *\n * @param outputPath Absolute path to the output directory.\n * @param files All generated files (across all plugins).\n * @param barrelType Barrel generation strategy.\n */\nexport function getBarrelFiles(outputPath: string, files: ReadonlyArray<FileNode>, barrelType: BarrelType): Array<FileNode> {\n // Only include files that live inside this outputPath and have a recognised source extension\n const relevantFiles = files.filter((f) => {\n const normalizedFilePath = f.path.replace(/\\\\/g, '/')\n const normalizedOutputPath = outputPath.replace(/\\\\/g, '/')\n if (!normalizedFilePath.startsWith(normalizedOutputPath + '/')) return false\n if (normalizedFilePath.endsWith(`/${BARREL_FILENAME}`)) return false\n const dotIndex = normalizedFilePath.lastIndexOf('.')\n const ext = dotIndex === -1 ? '' : normalizedFilePath.slice(dotIndex)\n return SOURCE_EXTENSIONS.has(ext)\n })\n\n if (relevantFiles.length === 0) return []\n\n const tree = buildTree(\n outputPath,\n relevantFiles.map((f) => f.path),\n )\n\n switch (barrelType) {\n case 'all':\n return getBarrelFilesAll(tree, relevantFiles)\n case 'named':\n return getBarrelFilesNamed(tree, relevantFiles)\n case 'propagate':\n return getBarrelFilesPropagate(tree)\n default:\n return []\n }\n}\n","import { resolve } from 'node:path'\nimport type { FileNode } from '@kubb/ast'\nimport type { Config, NormalizedPlugin } from '@kubb/core'\nimport type { BarrelType } from '../types.ts'\nimport { getBarrelFiles } from './getBarrelFiles.ts'\n\nexport type GeneratePerPluginBarrelParams = {\n barrelType: BarrelType\n plugin: NormalizedPlugin\n files: ReadonlyArray<FileNode>\n config: Config\n}\n\n/**\n * Generates barrel files for a single plugin's output directory.\n *\n * The barrel file is placed at `resolve(config.root, config.output.path, plugin.options.output.path)/index.ts`\n * and re-exports all files generated by that plugin, using the given `barrelType` strategy.\n *\n * Note: `plugin.options.output.path` is relative to `config.output.path`, not to `config.root`.\n * Files generated by plugins land at `config.root + config.output.path + plugin.output.path`,\n * so the barrel directory must be resolved with all three segments.\n */\nexport function generatePerPluginBarrel({ barrelType, plugin, files, config }: GeneratePerPluginBarrelParams): Array<FileNode> {\n const outputPath = resolve(config.root, config.output.path, plugin.options.output.path)\n\n return getBarrelFiles(outputPath, files, barrelType)\n}\n","import { resolve } from 'node:path'\nimport type { FileNode } from '@kubb/ast'\nimport type { Config } from '@kubb/core'\nimport type { BarrelType } from '../types.ts'\nimport { getBarrelFiles } from './getBarrelFiles.ts'\n\nexport type GenerateRootBarrelParams = {\n barrelType: BarrelType\n files: ReadonlyArray<FileNode>\n config: Config\n}\n\n/**\n * Generates a root barrel file at `resolve(config.root, config.output.path)/index.ts`.\n *\n * The root barrel re-exports from all files across all plugins that are located\n * inside the root output directory, using the given `barrelType` strategy.\n *\n * In practice this re-exports the per-plugin barrels when `barrelType = 'propagate'`,\n * or all individual files when `barrelType = 'all'` or `'named'`.\n */\nexport function generateRootBarrel({ barrelType, files, config }: GenerateRootBarrelParams): Array<FileNode> {\n const outputPath = resolve(config.root, config.output.path)\n\n return getBarrelFiles(outputPath, files, barrelType)\n}\n","import { defineMiddleware } from '@kubb/core'\nimport type { KubbBuildStartContext } from '@kubb/core'\nimport type { BarrelType } from './types.ts'\nimport { generatePerPluginBarrel } from './utils/generatePerPluginBarrel.ts'\nimport { generateRootBarrel } from './utils/generateRootBarrel.ts'\nimport {resolve} from \"node:path\";\n\ndeclare global {\n namespace Kubb {\n interface PluginOptionsRegistry {\n output: {\n /**\n * Controls which barrel file (index.ts) is generated for this plugin's output directory.\n *\n * - `'all'` — `export * from '...'` for every generated file.\n * - `'named'` — `export { … } from '...'` using the file's named exports.\n * - `'propagate'` — like `'all'` but also generates intermediate barrel files.\n * - `false` — disable barrel generation for this plugin.\n *\n * When omitted, the root `config.output.barrelType` is used as the default.\n */\n barrelType?: BarrelType | false\n }\n }\n interface ConfigOptionsRegistry {\n output: {\n /**\n * Controls the root barrel file (index.ts) generated at `config.output.path`.\n *\n * - `'all'` — `export * from '...'` for every plugin's barrel.\n * - `'named'` — `export { … } from '...'` using the barrel's named exports.\n * - `'propagate'` — like `'all'` but also generates intermediate barrel files.\n * - `false` — disable root barrel generation.\n *\n * Individual plugins can override this via their own `output.barrelType`.\n */\n barrelType?: BarrelType | false\n }\n }\n }\n}\n\n/**\n * Barrel-file generation middleware.\n *\n * When added to `config.middleware`, generates an `index.ts` barrel file for each\n * plugin. When `output.barrelType` is omitted on a plugin it inherits from `config.output.barrelType`,\n * and when that is also omitted both default to `'all'`. Set `barrelType: false` to disable\n * barrel generation for a specific plugin or for the root entirely.\n *\n * The `barrelType` option controls the re-export style:\n * - `'all'` — `export * from '...'` for each generated file\n * - `'named'` — `export { name1, name2 } from '...'` using each file's indexable sources\n * - `'propagate'` — like `'all'` with intermediate barrel files for sub-directories\n *\n * @example\n * ```ts\n * import { middlewareBarrel } from '@kubb/middleware-barrel'\n *\n * export default defineConfig({\n * output: { path: 'src/gen', barrelType: 'named' },\n * plugins: [\n * pluginTs({ output: { path: 'types', barrelType: 'all' } }),\n * pluginZod({ output: { path: 'schemas' } }),\n * ],\n * middleware: [middlewareBarrel],\n * })\n * ```\n */\nexport const middlewareBarrel = defineMiddleware({\n name: 'middleware-barrel',\n install(hooks) {\n let ctx: KubbBuildStartContext\n const excludedPaths = new Set<string>()\n\n hooks.on('kubb:build:start', (buildCtx) => {\n ctx = buildCtx\n })\n\n hooks.on('kubb:plugin:end', ({ plugin }) => {\n if (!ctx) return\n\n const barrelType = plugin.options.output?.barrelType ?? ctx.config.output.barrelType ?? 'all'\n\n if (!barrelType) {\n excludedPaths.add(resolve(ctx.config.root, ctx.config.output.path, plugin.options.output.path))\n return\n }\n\n const barrelFiles = generatePerPluginBarrel({\n barrelType,\n plugin,\n files: ctx.files,\n config: ctx.config,\n })\n\n if (barrelFiles.length > 0) {\n ctx.upsertFile(...barrelFiles)\n }\n })\n\n hooks.on('kubb:plugins:end', ({ files, config, upsertFile }) => {\n const rootBarrelType = config.output.barrelType ?? 'all'\n if (!rootBarrelType) return\n\n const filteredFiles =\n excludedPaths.size > 0\n ? files.filter((f) => ![...excludedPaths].some((excluded) => f.path.startsWith(excluded + '/')))\n : files\n\n const rootBarrelFiles = generateRootBarrel({\n barrelType: rootBarrelType,\n files: filteredFiles,\n config,\n })\n\n if (rootBarrelFiles.length > 0) {\n upsertFile(...rootBarrelFiles)\n }\n })\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/constants.ts","../../../internals/utils/src/buildTree.ts","../src/utils/getBarrelFiles.ts","../src/utils/generatePerPluginBarrel.ts","../src/utils/generateRootBarrel.ts","../src/utils/excludedPaths.ts","../src/utils/resolveBarrelType.ts","../src/middleware.ts"],"sourcesContent":["/**\n * Full file name for barrel files (with extension).\n */\nexport const BARREL_FILENAME = 'index.ts' as const\n","/**\n * A node in the directory tree used to compute barrel file exports.\n * Either represents a directory (with `children`) or a file (`isFile: true`, empty `children`).\n */\nexport type BuildTree = {\n /**\n * Absolute filesystem path of this directory or file.\n */\n path: string\n /**\n * Sub-directories and files contained within this directory.\n * Always empty for file nodes.\n */\n children: Array<BuildTree>\n /**\n * `true` when this node represents a file (leaf), `false` for directory nodes.\n */\n isFile: boolean\n}\n\n/**\n * Builds a directory tree rooted at `rootPath` from a list of absolute file paths.\n * Paths outside `rootPath` are silently ignored. Children are sorted alphabetically\n * by path so consumers (barrel exports, propagated indexes) emit a deterministic order.\n *\n * Both POSIX (`/`) and Windows (`\\`) separators are accepted in input paths.\n *\n * @example\n * ```ts\n * buildTree('/src/gen/types', [\n * '/src/gen/types/pet.ts',\n * '/src/gen/types/pets/listPets.ts',\n * ])\n * ```\n */\nexport function buildTree(rootPath: string, filePaths: ReadonlyArray<string>): BuildTree {\n const root: BuildTree = { path: rootPath, children: [], isFile: false }\n // Per-directory child lookup avoids the O(N) `Array.find` scan during insertion.\n const childIndex = new Map<BuildTree, Map<string, BuildTree>>()\n childIndex.set(root, new Map())\n\n const normalizedRoot = rootPath.replaceAll('\\\\', '/')\n const rootPrefix = `${normalizedRoot}/`\n\n for (const filePath of filePaths) {\n const normalized = filePath.replaceAll('\\\\', '/')\n if (!normalized.startsWith(rootPrefix)) continue\n\n const parts = normalized.slice(rootPrefix.length).split('/')\n if (parts.length === 0) continue\n\n let current = root\n const lastIndex = parts.length - 1\n for (const [i, part] of parts.entries()) {\n if (!part) continue\n\n const isLast = i === lastIndex\n const siblings = childIndex.get(current)!\n let child = siblings.get(part)\n if (!child) {\n child = { path: `${current.path}/${part}`, children: [], isFile: isLast }\n current.children.push(child)\n siblings.set(part, child)\n if (!isLast) childIndex.set(child, new Map())\n }\n current = child\n }\n }\n\n sortTree(root)\n\n return root\n}\n\nfunction sortTree(node: BuildTree): void {\n if (node.children.length === 0) return\n node.children.sort(compareByPath)\n for (const child of node.children) {\n if (!child.isFile) sortTree(child)\n }\n}\n\nfunction compareByPath(a: BuildTree, b: BuildTree): number {\n return a.path < b.path ? -1 : a.path > b.path ? 1 : 0\n}\n","import { extname } from 'node:path'\nimport { createExport, createFile } from '@kubb/ast'\nimport type { ExportNode, FileNode, SourceNode } from '@kubb/ast'\nimport { BARREL_FILENAME } from '../constants.ts'\nimport type { BarrelType } from '../types.ts'\nimport { type BuildTree, buildTree } from '@internals/utils'\n\nconst SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\nconst BARREL_SUFFIX = `/${BARREL_FILENAME}`\n\n/**\n * Derives a relative module specifier from `filePath` relative to `fromDir`.\n * The source extension is preserved so `@kubb/parser-ts` can apply its `extNames` mapping.\n *\n * @example\n * ```ts\n * toRelativeModulePath('/src/gen/types', '/src/gen/types/pet.ts') // './pet.ts'\n * toRelativeModulePath('/src/gen/types', '/src/gen/types/tags/tag.ts') // './tags/tag.ts'\n * ```\n */\nfunction toRelativeModulePath(fromDir: string, filePath: string): string {\n return `./${filePath.slice(fromDir.length + 1)}`\n}\n\nfunction isBarrelPath(path: string): boolean {\n return path.endsWith(BARREL_SUFFIX)\n}\n\nfunction makeBarrel(dirPath: string, exports: Array<ExportNode>): FileNode {\n return createFile({\n baseName: BARREL_FILENAME,\n path: `${dirPath}${BARREL_SUFFIX}`,\n exports,\n sources: [],\n imports: [],\n })\n}\n\ntype LeafContext = {\n dirPath: string\n leafPath: string\n sourceFile: FileNode | undefined\n}\n\ntype LeafStrategy = (ctx: LeafContext) => Array<ExportNode>\n\nfunction hasOnlyNonIndexableSources(sources: ReadonlyArray<SourceNode>): boolean {\n if (sources.length === 0) return false\n for (const source of sources) {\n if (source.isIndexable) return false\n }\n return true\n}\n\nfunction partitionIndexableNames(sources: ReadonlyArray<SourceNode>): Map<boolean, Set<string>> {\n const byTypeOnly = new Map<boolean, Set<string>>([\n [false, new Set()],\n [true, new Set()],\n ])\n for (const source of sources) {\n if (!source.isIndexable || !source.name) continue\n byTypeOnly.get(Boolean(source.isTypeOnly))!.add(source.name)\n }\n return byTypeOnly\n}\n\nconst allStrategy: LeafStrategy = ({ dirPath, leafPath, sourceFile }) => {\n if (sourceFile && hasOnlyNonIndexableSources(sourceFile.sources)) return []\n return [createExport({ path: toRelativeModulePath(dirPath, leafPath) })]\n}\n\nconst namedStrategy: LeafStrategy = ({ dirPath, leafPath, sourceFile }) => {\n const modulePath = toRelativeModulePath(dirPath, leafPath)\n\n if (!sourceFile) return [createExport({ path: modulePath })]\n\n const namesByTypeOnly = partitionIndexableNames(sourceFile.sources)\n const valueNames = namesByTypeOnly.get(false)!\n const typeNames = namesByTypeOnly.get(true)!\n\n if (valueNames.size === 0 && typeNames.size === 0) {\n if (sourceFile.sources.length > 0) return []\n return [createExport({ path: modulePath })]\n }\n\n const exports: Array<ExportNode> = []\n if (valueNames.size > 0) {\n exports.push(createExport({ name: [...valueNames], path: modulePath }))\n }\n if (typeNames.size > 0) {\n exports.push(createExport({ name: [...typeNames], path: modulePath, isTypeOnly: true }))\n }\n return exports\n}\n\nconst LEAF_STRATEGIES: ReadonlyMap<Exclude<BarrelType, 'propagate'>, LeafStrategy> = new Map([\n ['all', allStrategy],\n ['named', namedStrategy],\n])\n\ntype LeafWalkParams = {\n sourceFiles: ReadonlyMap<string, FileNode>\n strategy: LeafStrategy\n recursive: boolean\n}\n\n/**\n * Single-pass post-order traversal that emits a barrel for each visited directory and\n * returns its leaf paths so parents don't have to re-walk the subtree.\n */\nfunction walkAllOrNamed(node: BuildTree, params: LeafWalkParams, isRoot: boolean, out: Array<FileNode>): Array<string> {\n const subtreeLeaves: Array<string> = []\n\n for (const child of node.children) {\n if (child.isFile) {\n if (!isBarrelPath(child.path)) subtreeLeaves.push(child.path)\n continue\n }\n\n const childLeaves = walkAllOrNamed(child, params, false, out)\n for (const leaf of childLeaves) subtreeLeaves.push(leaf)\n }\n\n // Sub-directory barrels are only emitted when the caller asked for them.\n if (!isRoot && !params.recursive) return subtreeLeaves\n\n const exports = subtreeLeaves.flatMap((leafPath) => params.strategy({ dirPath: node.path, leafPath, sourceFile: params.sourceFiles.get(leafPath) }))\n\n if (exports.length > 0) {\n out.push(makeBarrel(node.path, exports))\n }\n\n return subtreeLeaves\n}\n\n/**\n * Emits one barrel per directory: every direct child file is re-exported and every\n * sub-directory is re-exported via its own barrel (recursive by design).\n */\nfunction walkPropagate(node: BuildTree, out: Array<FileNode>): void {\n const exports: Array<ExportNode> = []\n\n for (const child of node.children) {\n if (child.isFile) {\n if (isBarrelPath(child.path)) continue\n exports.push(createExport({ path: toRelativeModulePath(node.path, child.path) }))\n continue\n }\n\n walkPropagate(child, out)\n exports.push(createExport({ path: toRelativeModulePath(node.path, `${child.path}${BARREL_SUFFIX}`) }))\n }\n\n if (exports.length > 0) {\n out.push(makeBarrel(node.path, exports))\n }\n}\n\ntype IndexedFiles = {\n /**\n * `path → FileNode` lookup limited to files that participate in barrel generation.\n */\n sourceFiles: ReadonlyMap<string, FileNode>\n /**\n * Original (un-normalized) paths of `sourceFiles`, in input order — used as input for {@link buildTree}.\n */\n paths: ReadonlyArray<string>\n}\n\nfunction indexRelevantFiles(files: ReadonlyArray<FileNode>, outputPath: string): IndexedFiles {\n const outputPrefix = `${outputPath.replaceAll('\\\\', '/')}/`\n const sourceFiles = new Map<string, FileNode>()\n const paths: Array<string> = []\n\n for (const file of files) {\n const normalized = file.path.replaceAll('\\\\', '/')\n if (!normalized.startsWith(outputPrefix)) continue\n if (isBarrelPath(normalized)) continue\n if (!SOURCE_EXTENSIONS.has(extname(normalized))) continue\n\n sourceFiles.set(file.path, file)\n paths.push(file.path)\n }\n\n return { sourceFiles, paths }\n}\n\nexport type GetBarrelFilesParams = {\n /**\n * Absolute path to the directory the barrel(s) should be rooted at.\n * Files outside this directory are ignored.\n */\n outputPath: string\n /**\n * Full set of generated files across all plugins.\n * Used both to discover what to re-export and to read each file's indexable sources.\n */\n files: ReadonlyArray<FileNode>\n /**\n * Re-export style used in the generated barrel(s).\n */\n barrelType: BarrelType\n /**\n * When `true`, also generate a barrel for each sub-directory of `outputPath`.\n * Used by per-plugin barrels so that grouped output (e.g. `petController/`) gets its own `index.ts`.\n *\n * Has no effect for `barrelType: 'propagate'`, which always recurses by design.\n *\n * @default false\n */\n recursive?: boolean\n}\n\n/**\n * Generates barrel `FileNode`s for the directory rooted at `outputPath`.\n *\n * Files outside `outputPath`, existing barrel files, and non-source extensions are filtered out\n * before the tree is built.\n */\nexport function getBarrelFiles({ outputPath, files, barrelType, recursive = false }: GetBarrelFilesParams): Array<FileNode> {\n const { sourceFiles, paths } = indexRelevantFiles(files, outputPath)\n if (paths.length === 0) return []\n\n const tree = buildTree(outputPath, paths)\n const result: Array<FileNode> = []\n\n if (barrelType === 'propagate') {\n walkPropagate(tree, result)\n return result\n }\n\n const strategy = LEAF_STRATEGIES.get(barrelType)\n if (!strategy) return result\n\n walkAllOrNamed(tree, { sourceFiles, strategy, recursive }, true, result)\n return result\n}\n","import { resolve } from 'node:path'\nimport type { FileNode } from '@kubb/ast'\nimport type { Config, NormalizedPlugin } from '@kubb/core'\nimport type { BarrelType } from '../types.ts'\nimport { getBarrelFiles } from './getBarrelFiles.ts'\n\nexport type GeneratePerPluginBarrelParams = {\n /**\n * Re-export style used in the plugin's barrel file(s).\n */\n barrelType: BarrelType\n /**\n * Plugin whose `output.path` determines the barrel directory.\n */\n plugin: NormalizedPlugin\n /**\n * Full set of generated files across all plugins.\n * Files outside the plugin's output directory are filtered out automatically.\n */\n files: ReadonlyArray<FileNode>\n /**\n * Resolved Kubb config; used to compute the absolute output directory.\n */\n config: Config\n}\n\n/**\n * Generates barrel files for a single plugin's output directory.\n *\n * The barrel is placed at `<config.root>/<config.output.path>/<plugin.options.output.path>/index.ts`.\n * When the plugin uses `group`, additional sub-directory barrels are generated so that grouped\n * output (e.g. `petController/index.ts`) gets its own re-export entry point.\n */\nexport function generatePerPluginBarrel({ barrelType, plugin, files, config }: GeneratePerPluginBarrelParams): Array<FileNode> {\n const outputPath = resolve(config.root, config.output.path, plugin.options.output.path)\n\n return getBarrelFiles({ outputPath, files, barrelType, recursive: true })\n}\n","import { resolve } from 'node:path'\nimport type { FileNode } from '@kubb/ast'\nimport type { Config } from '@kubb/core'\nimport type { BarrelType } from '../types.ts'\nimport { getBarrelFiles } from './getBarrelFiles.ts'\n\nexport type GenerateRootBarrelParams = {\n /**\n * Re-export style used in the root barrel file.\n */\n barrelType: BarrelType\n /**\n * Files eligible for re-export. The middleware filters out files belonging to plugins\n * with `barrelType: false` before passing them in.\n */\n files: ReadonlyArray<FileNode>\n /**\n * Resolved Kubb config; used to compute the root output directory.\n */\n config: Config\n}\n\n/**\n * Generates the root barrel file at `<config.root>/<config.output.path>/index.ts`.\n *\n * Unlike `generatePerPluginBarrel`, this does not recurse into sub-directories — each\n * plugin is responsible for its own per-plugin barrels.\n */\nexport function generateRootBarrel({ barrelType, files, config }: GenerateRootBarrelParams): Array<FileNode> {\n const outputPath = resolve(config.root, config.output.path)\n\n return getBarrelFiles({ outputPath, files, barrelType })\n}\n","import { resolve } from 'node:path'\nimport type { Config, NormalizedPlugin } from '@kubb/core'\n\n/**\n * Returns the absolute output directory of `plugin` with a trailing separator,\n * suitable for prefix-based exclusion checks via {@link isExcludedPath}.\n *\n * The trailing `/` ensures `startsWith` does not match unrelated siblings\n * (e.g. `/foo/bar` vs `/foo/barbaz/x.ts`).\n */\nexport function getPluginOutputPrefix(plugin: NormalizedPlugin, config: Config): string {\n return `${resolve(config.root, config.output.path, plugin.options.output.path)}/`\n}\n\n/**\n * Returns `true` when `filePath` lies under any of the directory prefixes in `prefixes`.\n * Prefixes must already include a trailing separator (see {@link getPluginOutputPrefix}).\n *\n * Uses Node 22 iterator helpers (`Iterator.prototype.some`) to avoid materializing the set.\n */\nexport function isExcludedPath(filePath: string, prefixes: ReadonlySet<string>): boolean {\n return prefixes.values().some((prefix) => filePath.startsWith(prefix))\n}\n","import type { Config, NormalizedPlugin } from '@kubb/core'\nimport type { BarrelType } from '../types.ts'\n\nconst DEFAULT_BARREL_TYPE: BarrelType = 'named'\n\n/**\n * Resolves the effective barrel style for a single plugin: explicit plugin option →\n * root config option → `'named'` default. Returns `false` when barrel generation is disabled.\n */\nexport function resolvePluginBarrelType(plugin: NormalizedPlugin, config: Config): BarrelType | false {\n return plugin.options.output?.barrelType ?? config.output.barrelType ?? DEFAULT_BARREL_TYPE\n}\n\n/**\n * Resolves the effective barrel style for the root `index.ts`: root config option → `'named'` default.\n * Returns `false` when the root barrel is disabled.\n */\nexport function resolveRootBarrelType(config: Config): BarrelType | false {\n return config.output.barrelType ?? DEFAULT_BARREL_TYPE\n}\n","import { defineMiddleware } from '@kubb/core'\nimport type { KubbBuildStartContext } from '@kubb/core'\nimport type { BarrelType } from './types.ts'\nimport { generatePerPluginBarrel } from './utils/generatePerPluginBarrel.ts'\nimport { generateRootBarrel } from './utils/generateRootBarrel.ts'\nimport { getPluginOutputPrefix, isExcludedPath } from './utils/excludedPaths.ts'\nimport { resolvePluginBarrelType, resolveRootBarrelType } from './utils/resolveBarrelType.ts'\n\ndeclare global {\n namespace Kubb {\n interface PluginOptionsRegistry {\n output: {\n /**\n * Re-export style for this plugin's barrel file.\n * Set to `false` to disable barrel generation for this plugin entirely; doing so also\n * excludes the plugin's files from the root barrel.\n *\n * Falls back to `config.output.barrelType` when omitted.\n *\n * @default 'named'\n */\n barrelType?: BarrelType | false\n }\n }\n interface ConfigOptionsRegistry {\n output: {\n /**\n * Re-export style for the root barrel file at `config.output.path/index.ts`.\n * Set to `false` to disable root barrel generation. Individual plugins can override\n * this via their own `output.barrelType`.\n *\n * @default 'named'\n */\n barrelType?: BarrelType | false\n }\n }\n }\n}\n\n/**\n * Generates `index.ts` barrel files for each plugin's output directory and one root barrel\n * at `config.output.path/index.ts`.\n *\n * Plugins inherit `output.barrelType` from `config.output.barrelType` (which itself defaults to `'named'`).\n * Setting `barrelType: false` on a plugin disables its barrel and excludes the plugin's files from the\n * root barrel as well.\n *\n * @example\n * ```ts\n * import { defineConfig } from '@kubb/core'\n * import { middlewareBarrel } from '@kubb/middleware-barrel'\n *\n * export default defineConfig({\n * output: { path: 'src/gen', barrelType: 'named' },\n * plugins: [\n * pluginTs({ output: { path: 'types', barrelType: 'all' } }),\n * pluginZod({ output: { path: 'schemas' } }),\n * ],\n * middleware: [middlewareBarrel],\n * })\n * ```\n */\nexport const middlewareBarrel = defineMiddleware({\n name: 'middleware-barrel',\n install(hooks) {\n let ctx: KubbBuildStartContext | undefined\n const excludedPrefixes = new Set<string>()\n\n hooks.on('kubb:build:start', (buildCtx) => {\n ctx = buildCtx\n })\n\n hooks.on('kubb:plugin:end', ({ plugin }) => {\n if (!ctx) return\n\n const barrelType = resolvePluginBarrelType(plugin, ctx.config)\n\n if (!barrelType) {\n excludedPrefixes.add(getPluginOutputPrefix(plugin, ctx.config))\n return\n }\n\n const barrelFiles = generatePerPluginBarrel({\n barrelType,\n plugin,\n files: ctx.files,\n config: ctx.config,\n })\n\n if (barrelFiles.length > 0) {\n ctx.upsertFile(...barrelFiles)\n }\n })\n\n hooks.on('kubb:plugins:end', ({ files, config, upsertFile }) => {\n const rootBarrelType = resolveRootBarrelType(config)\n if (!rootBarrelType) return\n\n const filteredFiles = excludedPrefixes.size === 0 ? files : files.filter((f) => !isExcludedPath(f.path, excludedPrefixes))\n\n const rootBarrelFiles = generateRootBarrel({\n barrelType: rootBarrelType,\n files: filteredFiles,\n config,\n })\n\n if (rootBarrelFiles.length > 0) {\n upsertFile(...rootBarrelFiles)\n }\n })\n },\n})\n"],"mappings":"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"}
|