@mxpicture/build-api 0.2.50 โ†’ 0.2.51

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.
@@ -17,8 +17,11 @@ export declare class Barrel {
17
17
  * implicitly because the group is rebuilt from readdir on every run.
18
18
  */
19
19
  protected hasGroupChanged(group: BarrelGroup, barrelPath: string): Promise<boolean>;
20
+ protected collectPkgGroups(pkg: Pkg): Promise<BarrelGroup[]>;
21
+ protected collectGroups(packages: Pkg[]): Promise<Map<string, BarrelGroup[]>>;
20
22
  protected updatePackageExports(pkg: Pkg, exports: Record<string, string>): Promise<void>;
21
23
  protected hasExportsChanged(a: Record<string, string> | undefined, b: Record<string, string> | undefined): boolean;
22
24
  protected extractExports(result: BarrelResult): Record<string, string>;
25
+ protected buildAndPersist(groupsByPkg: Map<string, BarrelGroup[]>): Promise<void>;
23
26
  }
24
27
  //# sourceMappingURL=Barrel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Barrel.d.ts","sourceRoot":"","sources":["../../src/barrel/Barrel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACb,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIpC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,eAAO,MAAM,yBAAyB,EAAE,MAAM,EAQ7C,CAAC;AAGF,eAAO,MAAM,cAAc,4DACgC,CAAC;AAE5D,eAAO,MAAM,SAAS,GAAU,QAAQ,YAAY,kBAMnD,CAAC;AAEF,qBAAa,MAAM;IAEf,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;IACrC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM;gBADlB,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,MAAM;IAG1B,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAoGjC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;cAI/B,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GACrC,OAAO,CAAC,WAAW,CAAC;IAwCvB;;;;OAIG;cACa,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;cAwEH,oBAAoB,CAClC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAoBjC,SAAS,CAAC,iBAAiB,CACzB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACrC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACpC,OAAO;IAcV,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CASvE"}
1
+ {"version":3,"file":"Barrel.d.ts","sourceRoot":"","sources":["../../src/barrel/Barrel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACb,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAIpC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,eAAO,MAAM,yBAAyB,EAAE,MAAM,EAQ7C,CAAC;AAGF,eAAO,MAAM,cAAc,4DACgC,CAAC;AAE5D,eAAO,MAAM,SAAS,GAAU,QAAQ,YAAY,kBAMnD,CAAC;AAEF,qBAAa,MAAM;IAEf,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;IACrC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM;gBADlB,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,MAAM;IAG1B,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;cAI/B,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GACrC,OAAO,CAAC,WAAW,CAAC;IAwCvB;;;;OAIG;cACa,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;cAmBH,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;cAsClD,aAAa,CAC3B,QAAQ,EAAE,GAAG,EAAE,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;cAiBtB,oBAAoB,CAClC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAoBjC,SAAS,CAAC,iBAAiB,CACzB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACrC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACpC,OAAO;IAcV,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;cAUtD,eAAe,CAC7B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC;CAwDjB"}
@@ -32,85 +32,22 @@ export class Barrel {
32
32
  const ws = workspace();
33
33
  await ws.read();
34
34
  // Phase 1: collect all barrel groups, keyed by package name
35
- const groupsByPkg = new Map();
36
- for (const pkg of ws.packages) {
37
- try {
38
- const items = (await readdir(pkg.srcPath, { recursive: true })).sort();
39
- let currentGroup;
40
- const pushGroup = (g) => {
41
- const key = g.pkg.content.name;
42
- if (!groupsByPkg.has(key))
43
- groupsByPkg.set(key, []);
44
- groupsByPkg.get(key).push({ ...g });
45
- };
46
- for (const item of items) {
47
- const filename = basename(item);
48
- const dirPath = join(pkg.srcPath, dirname(item));
49
- const filePath = join(dirPath, filename);
50
- if (dirPath !== currentGroup?.dirPath) {
51
- if (currentGroup)
52
- pushGroup(currentGroup);
53
- currentGroup = { dirPath, files: [], pkg };
54
- }
55
- if (this.isExcluded(filePath) ||
56
- (!filename.endsWith(".ts") && !filename.endsWith(".mts")))
57
- continue;
58
- currentGroup.files.push(filename);
59
- }
60
- if (currentGroup)
61
- pushGroup(currentGroup);
62
- }
63
- catch {
64
- continue;
65
- }
66
- }
35
+ const groupsByPkg = await this.collectGroups(ws.packages);
36
+ // todo Phase 1.5: find changed files
67
37
  // Phase 2: build one ts.Program per package, then persist all groups in parallel
68
- const promises = [];
69
- for (const groups of groupsByPkg.values()) {
70
- const allFilePaths = groups.flatMap((g) => g.files.map((f) => join(g.dirPath, f)));
71
- const sourceFileMap = allFilePaths.length > 0
72
- ? createSourceFileMap(allFilePaths)
73
- : new Map();
74
- for (const group of groups) {
75
- promises.push(this.persistBarrel({ ...group }, sourceFileMap));
76
- }
77
- }
78
- const barrelGroups = (await Promise.all(promises)).filter((prom) => prom.files.length > 0);
79
- const results = [];
80
- for (const barrelGroup of barrelGroups) {
81
- let found = results.find((res) => barrelGroup.dirPath === res.pkg.dirPath);
82
- if (!found) {
83
- found = {
84
- barrelDirs: [],
85
- pkg: barrelGroup.pkg,
86
- };
87
- results.push(found);
88
- }
89
- found.barrelDirs.push(barrelGroup.dirPath);
90
- }
91
- const pkgExps = {};
92
- for (const res of results) {
93
- if (!(res.pkg.content.name in pkgExps))
94
- pkgExps[res.pkg.content.name] = { pkg: res.pkg, exps: {} };
95
- pkgExps[res.pkg.content.name].exps = {
96
- ...pkgExps[res.pkg.content.name].exps,
97
- ...this.extractExports(res),
98
- };
99
- }
100
- await Promise.all(Object.values(pkgExps).map(async (pkgExp) => this.updatePackageExports(pkgExp.pkg, pkgExp.exps)));
38
+ await this.buildAndPersist(groupsByPkg);
101
39
  }
102
40
  isExcluded(fileName) {
103
41
  return this.excludes.some((pattern) => pattern.test(fileName));
104
42
  }
105
43
  async persistBarrel(group, sourceFileMap) {
106
- const barrelPath = join(group.dirPath, "index.ts");
107
44
  // no files --> skip/delete index.ts
108
45
  if (group.files.length === 0) {
109
- await rm(barrelPath, { recursive: true, force: true });
46
+ await rm(group.barrelFilePath, { recursive: true, force: true });
110
47
  return group;
111
48
  }
112
49
  // Skip if all source files are older than the existing barrel
113
- if (!(await this.hasGroupChanged(group, barrelPath)))
50
+ if (!(await this.hasGroupChanged(group, group.barrelFilePath)))
114
51
  return group;
115
52
  const exportLines = [];
116
53
  for (const file of group.files.sort()) {
@@ -129,7 +66,7 @@ export class Barrel {
129
66
  }
130
67
  let content = `${this.fileHeader}${exportLines.length > 0 ? exportLines.join("\n") + "\n" : ""}`;
131
68
  content = await formatCode(content);
132
- await writeFile(barrelPath, content);
69
+ await writeFile(group.barrelFilePath, content);
133
70
  return group;
134
71
  }
135
72
  /**
@@ -157,54 +94,51 @@ export class Barrel {
157
94
  }
158
95
  return false;
159
96
  }
160
- // protected async extractExportsFromFile(
161
- // filePath: string,
162
- // ): Promise<{ exports: string[]; hasDefault: boolean }> {
163
- // try {
164
- // const content = await readFile(filePath, "utf-8");
165
- // const exports: Set<string> = new Set();
166
- // let hasDefault = false;
167
- // // Detect any default export
168
- // if (/export\s+default\b/.test(content)) hasDefault = true;
169
- // // Match named exports: export const|function|class Name
170
- // const namedExportPattern =
171
- // /export\s+(?:const|let|var|function|class|interface|type|enum)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/g;
172
- // let match;
173
- // while ((match = namedExportPattern.exec(content)) !== null) {
174
- // const name = match[1];
175
- // if (
176
- // !name.startsWith("_") &&
177
- // !name.startsWith("//") &&
178
- // !name.startsWith("/*")
179
- // )
180
- // exports.add(name);
181
- // }
182
- // // Match export { a, b, c } and export { a, b, c } from '...'
183
- // const exportBracePattern = /export\s*\{\s*([^}]+)\s*\}/g;
184
- // while ((match = exportBracePattern.exec(content)) !== null) {
185
- // const items = match[1].split(",");
186
- // for (const item of items) {
187
- // const trimmed = item.trim();
188
- // if (!trimmed) continue;
189
- // // Handle "export { name as alias }"
190
- // const parts = trimmed.split(/\s+as\s+/);
191
- // const name = parts[0].trim();
192
- // const alias = parts[1]?.trim();
193
- // // Skip default exports (e.g. "export { Foo as default }")
194
- // if (alias === "default") {
195
- // hasDefault = true;
196
- // continue;
197
- // }
198
- // if (name && name !== "default" && !name.startsWith("_")) {
199
- // exports.add(name);
200
- // }
201
- // }
202
- // }
203
- // return { exports: Array.from(exports).sort(), hasDefault };
204
- // } catch {
205
- // return { exports: [], hasDefault: false };
206
- // }
207
- // }
97
+ async collectPkgGroups(pkg) {
98
+ const items = (await readdir(pkg.srcPath, { recursive: true })).sort();
99
+ const groups = [];
100
+ let currentGroup;
101
+ const pushGroup = (g) => groups.push({ ...g });
102
+ for (const item of items) {
103
+ const filename = basename(item);
104
+ const dirPath = join(pkg.srcPath, dirname(item));
105
+ const filePath = join(dirPath, filename);
106
+ if (dirPath !== currentGroup?.dirPath) {
107
+ if (currentGroup)
108
+ pushGroup(currentGroup);
109
+ currentGroup = {
110
+ dirPath,
111
+ files: [],
112
+ pkg,
113
+ barrelFilePath: join(dirPath, "index.ts"),
114
+ barrelExists: false,
115
+ };
116
+ }
117
+ if (filename === "index.ts")
118
+ currentGroup.barrelExists = true;
119
+ if (this.isExcluded(filePath) ||
120
+ (!filename.endsWith(".ts") && !filename.endsWith(".mts")))
121
+ continue;
122
+ currentGroup.files.push(filename);
123
+ }
124
+ if (currentGroup)
125
+ pushGroup(currentGroup);
126
+ return groups;
127
+ }
128
+ async collectGroups(packages) {
129
+ const groupsByPkg = new Map();
130
+ const pushGroup = (g) => {
131
+ const key = g.pkg.content.name;
132
+ if (!groupsByPkg.has(key))
133
+ groupsByPkg.set(key, []);
134
+ groupsByPkg.get(key).push({ ...g });
135
+ };
136
+ const results = await Promise.all(packages.map((pkg) => this.collectPkgGroups(pkg)));
137
+ for (const groups of results)
138
+ for (const group of groups)
139
+ pushGroup(group);
140
+ return groupsByPkg;
141
+ }
208
142
  async updatePackageExports(pkg, exports) {
209
143
  try {
210
144
  // const pkgName = relative(this.paths.workspacesDir, packageDir);
@@ -249,5 +183,40 @@ export class Barrel {
249
183
  record["./package.json"] = "./package.json";
250
184
  return record;
251
185
  }
186
+ async buildAndPersist(groupsByPkg) {
187
+ const promises = [];
188
+ for (const groups of groupsByPkg.values()) {
189
+ const allFilePaths = groups.flatMap((g) => g.files.map((f) => join(g.dirPath, f)));
190
+ const sourceFileMap = allFilePaths.length > 0
191
+ ? createSourceFileMap(allFilePaths)
192
+ : new Map();
193
+ for (const group of groups) {
194
+ promises.push(this.persistBarrel({ ...group }, sourceFileMap));
195
+ }
196
+ }
197
+ const barrelGroups = (await Promise.all(promises)).filter((prom) => prom.files.length > 0);
198
+ const results = [];
199
+ for (const barrelGroup of barrelGroups) {
200
+ let found = results.find((res) => barrelGroup.dirPath === res.pkg.dirPath);
201
+ if (!found) {
202
+ found = {
203
+ barrelDirs: [],
204
+ pkg: barrelGroup.pkg,
205
+ };
206
+ results.push(found);
207
+ }
208
+ found.barrelDirs.push(barrelGroup.dirPath);
209
+ }
210
+ const pkgExps = {};
211
+ for (const res of results) {
212
+ if (!(res.pkg.content.name in pkgExps))
213
+ pkgExps[res.pkg.content.name] = { pkg: res.pkg, exps: {} };
214
+ pkgExps[res.pkg.content.name].exps = {
215
+ ...pkgExps[res.pkg.content.name].exps,
216
+ ...this.extractExports(res),
217
+ };
218
+ }
219
+ await Promise.all(Object.values(pkgExps).map(async (pkgExp) => this.updatePackageExports(pkgExp.pkg, pkgExp.exps)));
220
+ }
252
221
  }
253
222
  //# sourceMappingURL=Barrel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Barrel.js","sourceRoot":"","sources":["../../src/barrel/Barrel.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename, dirname, join, relative } from \"node:path\";\nimport {\n BarrelGroup,\n BarrelParams,\n BarrelResult,\n} from \"../types/types.barrel.js\";\nimport { readdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { logInfo, logSuccess } from \"../logger/Logger.js\";\nimport { initWorkspace, workspace } from \"../workspace/Workspace.js\";\nimport { Pkg } from \"../pkg/Pkg.js\";\nimport { formatCode } from \"../code/code.format.js\";\nimport { fileExports } from \"../code/code.exports.js\";\nimport { createSourceFileMap } from \"../code/code.common.js\";\nimport { SourceFile } from \"../types/types.code.js\";\n\n// /** File patterns to exclude from barrel exports */\nexport const DEFAULT_EXCLUDED_PATTERNS: RegExp[] = [\n /\\.test\\.ts$/,\n /\\.spec\\.ts$/,\n /(^|\\/)__tests__(\\/|$)/,\n /\\.d\\.ts$/,\n /index\\.ts$/,\n /(.+\\/|^)src\\/(.+\\/|)scripts?\\/.+\\.m?ts$/,\n /\\/4testing(\\/|$)/,\n];\n\n// /** Header comment added to every generated barrel file */\nexport const DEFAULT_HEADER =\n \"// This file is auto-generated. Do not edit manually.\\n\";\n\nexport const runBarrel = async (params: BarrelParams) => {\n initWorkspace(params.repoRoot);\n return new Barrel(\n params.excludes ?? DEFAULT_EXCLUDED_PATTERNS,\n params.fileHeader ?? DEFAULT_HEADER,\n ).run();\n};\n\nexport class Barrel {\n public constructor(\n protected readonly excludes: RegExp[],\n protected readonly fileHeader: string,\n ) {}\n\n public async run(): Promise<void> {\n const ws = workspace();\n await ws.read();\n\n // Phase 1: collect all barrel groups, keyed by package name\n const groupsByPkg = new Map<string, BarrelGroup[]>();\n\n for (const pkg of ws.packages) {\n try {\n const items = (await readdir(pkg.srcPath, { recursive: true })).sort();\n let currentGroup: BarrelGroup | undefined;\n\n const pushGroup = (g: BarrelGroup) => {\n const key = g.pkg.content.name;\n if (!groupsByPkg.has(key)) groupsByPkg.set(key, []);\n groupsByPkg.get(key)!.push({ ...g });\n };\n\n for (const item of items) {\n const filename = basename(item);\n const dirPath = join(pkg.srcPath, dirname(item));\n const filePath = join(dirPath, filename);\n\n if (dirPath !== currentGroup?.dirPath) {\n if (currentGroup) pushGroup(currentGroup);\n currentGroup = { dirPath, files: [], pkg };\n }\n\n if (\n this.isExcluded(filePath) ||\n (!filename.endsWith(\".ts\") && !filename.endsWith(\".mts\"))\n )\n continue;\n\n currentGroup.files.push(filename);\n }\n\n if (currentGroup) pushGroup(currentGroup);\n } catch {\n continue;\n }\n }\n\n // Phase 2: build one ts.Program per package, then persist all groups in parallel\n const promises: Promise<BarrelGroup>[] = [];\n\n for (const groups of groupsByPkg.values()) {\n const allFilePaths = groups.flatMap((g) =>\n g.files.map((f) => join(g.dirPath, f)),\n );\n const sourceFileMap: Map<string, SourceFile> =\n allFilePaths.length > 0\n ? createSourceFileMap(allFilePaths)\n : new Map<string, SourceFile>();\n\n for (const group of groups) {\n promises.push(this.persistBarrel({ ...group }, sourceFileMap));\n }\n }\n\n const barrelGroups = (await Promise.all(promises)).filter(\n (prom) => prom.files.length > 0,\n );\n\n const results: BarrelResult[] = [];\n\n for (const barrelGroup of barrelGroups) {\n let found = results.find(\n (res) => barrelGroup.dirPath === res.pkg.dirPath,\n );\n if (!found) {\n found = {\n barrelDirs: [],\n pkg: barrelGroup.pkg,\n };\n results.push(found);\n }\n\n found.barrelDirs.push(barrelGroup.dirPath);\n }\n\n const pkgExps: Record<string, { pkg: Pkg; exps: Record<string, string> }> =\n {};\n for (const res of results) {\n if (!(res.pkg.content.name in pkgExps))\n pkgExps[res.pkg.content.name] = { pkg: res.pkg, exps: {} };\n\n pkgExps[res.pkg.content.name].exps = {\n ...pkgExps[res.pkg.content.name].exps,\n ...this.extractExports(res),\n };\n }\n\n await Promise.all(\n Object.values(pkgExps).map(async (pkgExp) =>\n this.updatePackageExports(pkgExp.pkg, pkgExp.exps),\n ),\n );\n }\n\n protected isExcluded(fileName: string): boolean {\n return this.excludes.some((pattern) => pattern.test(fileName));\n }\n\n protected async persistBarrel(\n group: BarrelGroup,\n sourceFileMap: Map<string, SourceFile>,\n ): Promise<BarrelGroup> {\n const barrelPath = join(group.dirPath, \"index.ts\");\n // no files --> skip/delete index.ts\n if (group.files.length === 0) {\n await rm(barrelPath, { recursive: true, force: true });\n return group;\n }\n\n // Skip if all source files are older than the existing barrel\n if (!(await this.hasGroupChanged(group, barrelPath))) return group;\n\n const exportLines: string[] = [];\n for (const file of group.files.sort()) {\n const filePath = join(group.dirPath, file);\n\n const expResult = fileExports(\n filePath,\n undefined,\n sourceFileMap.get(filePath),\n );\n if (expResult.items.length === 0) continue;\n\n const exports = expResult.items.map((item) => item.name);\n const moduleRef = `./${basename(file, \".ts\")}.js`;\n\n if (expResult.hasDefault) {\n exportLines.push(`export * from \"${moduleRef}\";`);\n } else if (exports.length > 0) {\n exportLines.push(\n `export { ${exports.join(\", \")} } from \"${moduleRef}\";`,\n );\n }\n }\n\n let content = `${this.fileHeader}${exportLines.length > 0 ? exportLines.join(\"\\n\") + \"\\n\" : \"\"}`;\n content = await formatCode(content);\n await writeFile(barrelPath, content);\n return group;\n }\n\n /**\n * Returns true if any source file in the group is newer than the barrel\n * file, or if the barrel file does not yet exist. File deletions are handled\n * implicitly because the group is rebuilt from readdir on every run.\n */\n protected async hasGroupChanged(\n group: BarrelGroup,\n barrelPath: string,\n ): Promise<boolean> {\n let barrelMtime: number;\n try {\n barrelMtime = (await stat(barrelPath)).mtimeMs;\n } catch {\n return true; // barrel doesn't exist yet\n }\n\n for (const file of group.files) {\n try {\n const fileMtime = (await stat(join(group.dirPath, file))).mtimeMs;\n if (fileMtime > barrelMtime) return true;\n } catch {\n return true; // file accessibility changed\n }\n }\n return false;\n }\n\n // protected async extractExportsFromFile(\n // filePath: string,\n // ): Promise<{ exports: string[]; hasDefault: boolean }> {\n // try {\n // const content = await readFile(filePath, \"utf-8\");\n // const exports: Set<string> = new Set();\n // let hasDefault = false;\n\n // // Detect any default export\n // if (/export\\s+default\\b/.test(content)) hasDefault = true;\n\n // // Match named exports: export const|function|class Name\n // const namedExportPattern =\n // /export\\s+(?:const|let|var|function|class|interface|type|enum)\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/g;\n // let match;\n // while ((match = namedExportPattern.exec(content)) !== null) {\n // const name = match[1];\n // if (\n // !name.startsWith(\"_\") &&\n // !name.startsWith(\"//\") &&\n // !name.startsWith(\"/*\")\n // )\n // exports.add(name);\n // }\n\n // // Match export { a, b, c } and export { a, b, c } from '...'\n // const exportBracePattern = /export\\s*\\{\\s*([^}]+)\\s*\\}/g;\n // while ((match = exportBracePattern.exec(content)) !== null) {\n // const items = match[1].split(\",\");\n // for (const item of items) {\n // const trimmed = item.trim();\n // if (!trimmed) continue;\n // // Handle \"export { name as alias }\"\n // const parts = trimmed.split(/\\s+as\\s+/);\n // const name = parts[0].trim();\n // const alias = parts[1]?.trim();\n // // Skip default exports (e.g. \"export { Foo as default }\")\n // if (alias === \"default\") {\n // hasDefault = true;\n // continue;\n // }\n // if (name && name !== \"default\" && !name.startsWith(\"_\")) {\n // exports.add(name);\n // }\n // }\n // }\n\n // return { exports: Array.from(exports).sort(), hasDefault };\n // } catch {\n // return { exports: [], hasDefault: false };\n // }\n // }\n\n protected async updatePackageExports(\n pkg: Pkg,\n exports: Record<string, string>,\n ) {\n try {\n // const pkgName = relative(this.paths.workspacesDir, packageDir);\n // // const pkgs = await workspace().loadPackages();\n\n logInfo(`๐Ÿ“ฆ updating ${pkg.repoDirPath} package.json ...`);\n // const pkg = await readPackageJsonThrow(packageJsonPath);\n if (!this.hasExportsChanged(exports, pkg.content.exports)) {\n logInfo(`๐Ÿงน No changes in ${pkg.repoDirPath}, nothing to do`);\n return;\n }\n pkg.content.exports = { ...exports };\n await pkg.write();\n logSuccess(`โœ… ${pkg.repoDirPath} update successful`);\n } catch (error) {\n logInfo(error);\n }\n }\n\n protected hasExportsChanged(\n a: Record<string, string> | undefined,\n b: Record<string, string> | undefined,\n ): boolean {\n if (!a) a = {};\n if (!b) b = {};\n\n if (Object.keys(a).length !== Object.keys(b).length) return true;\n if (!a && !b) return false;\n if (!a || !b) return true;\n\n for (const entryA of Object.entries(a)) {\n if (b[entryA[0]] !== entryA[1]) return true;\n }\n return false;\n }\n\n protected extractExports(result: BarrelResult): Record<string, string> {\n const record: Record<string, string> = {};\n for (const barrelDir of result.barrelDirs) {\n const ex = relative(result.pkg.srcPath, barrelDir);\n record[`./${ex}`] = `./dist/${ex}/index.js`;\n }\n record[\"./package.json\"] = \"./package.json\";\n return record;\n }\n}\n"]}
1
+ {"version":3,"file":"Barrel.js","sourceRoot":"","sources":["../../src/barrel/Barrel.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename, dirname, join, relative } from \"node:path\";\nimport {\n BarrelGroup,\n BarrelParams,\n BarrelResult,\n} from \"../types/types.barrel.js\";\nimport { readdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { logInfo, logSuccess } from \"../logger/Logger.js\";\nimport { initWorkspace, workspace } from \"../workspace/Workspace.js\";\nimport { Pkg } from \"../pkg/Pkg.js\";\nimport { formatCode } from \"../code/code.format.js\";\nimport { fileExports } from \"../code/code.exports.js\";\nimport { createSourceFileMap } from \"../code/code.common.js\";\nimport { SourceFile } from \"../types/types.code.js\";\n\n// /** File patterns to exclude from barrel exports */\nexport const DEFAULT_EXCLUDED_PATTERNS: RegExp[] = [\n /\\.test\\.ts$/,\n /\\.spec\\.ts$/,\n /(^|\\/)__tests__(\\/|$)/,\n /\\.d\\.ts$/,\n /index\\.ts$/,\n /(.+\\/|^)src\\/(.+\\/|)scripts?\\/.+\\.m?ts$/,\n /\\/4testing(\\/|$)/,\n];\n\n// /** Header comment added to every generated barrel file */\nexport const DEFAULT_HEADER =\n \"// This file is auto-generated. Do not edit manually.\\n\";\n\nexport const runBarrel = async (params: BarrelParams) => {\n initWorkspace(params.repoRoot);\n return new Barrel(\n params.excludes ?? DEFAULT_EXCLUDED_PATTERNS,\n params.fileHeader ?? DEFAULT_HEADER,\n ).run();\n};\n\nexport class Barrel {\n public constructor(\n protected readonly excludes: RegExp[],\n protected readonly fileHeader: string,\n ) {}\n\n public async run(): Promise<void> {\n const ws = workspace();\n await ws.read();\n\n // Phase 1: collect all barrel groups, keyed by package name\n const groupsByPkg = await this.collectGroups(ws.packages);\n\n // todo Phase 1.5: find changed files\n\n // Phase 2: build one ts.Program per package, then persist all groups in parallel\n await this.buildAndPersist(groupsByPkg);\n }\n\n protected isExcluded(fileName: string): boolean {\n return this.excludes.some((pattern) => pattern.test(fileName));\n }\n\n protected async persistBarrel(\n group: BarrelGroup,\n sourceFileMap: Map<string, SourceFile>,\n ): Promise<BarrelGroup> {\n // no files --> skip/delete index.ts\n if (group.files.length === 0) {\n await rm(group.barrelFilePath, { recursive: true, force: true });\n return group;\n }\n\n // Skip if all source files are older than the existing barrel\n if (!(await this.hasGroupChanged(group, group.barrelFilePath)))\n return group;\n\n const exportLines: string[] = [];\n for (const file of group.files.sort()) {\n const filePath = join(group.dirPath, file);\n\n const expResult = fileExports(\n filePath,\n undefined,\n sourceFileMap.get(filePath),\n );\n if (expResult.items.length === 0) continue;\n\n const exports = expResult.items.map((item) => item.name);\n const moduleRef = `./${basename(file, \".ts\")}.js`;\n\n if (expResult.hasDefault) {\n exportLines.push(`export * from \"${moduleRef}\";`);\n } else if (exports.length > 0) {\n exportLines.push(\n `export { ${exports.join(\", \")} } from \"${moduleRef}\";`,\n );\n }\n }\n\n let content = `${this.fileHeader}${exportLines.length > 0 ? exportLines.join(\"\\n\") + \"\\n\" : \"\"}`;\n content = await formatCode(content);\n await writeFile(group.barrelFilePath, content);\n return group;\n }\n\n /**\n * Returns true if any source file in the group is newer than the barrel\n * file, or if the barrel file does not yet exist. File deletions are handled\n * implicitly because the group is rebuilt from readdir on every run.\n */\n protected async hasGroupChanged(\n group: BarrelGroup,\n barrelPath: string,\n ): Promise<boolean> {\n let barrelMtime: number;\n try {\n barrelMtime = (await stat(barrelPath)).mtimeMs;\n } catch {\n return true; // barrel doesn't exist yet\n }\n\n for (const file of group.files) {\n try {\n const fileMtime = (await stat(join(group.dirPath, file))).mtimeMs;\n if (fileMtime > barrelMtime) return true;\n } catch {\n return true; // file accessibility changed\n }\n }\n return false;\n }\n\n protected async collectPkgGroups(pkg: Pkg): Promise<BarrelGroup[]> {\n const items = (await readdir(pkg.srcPath, { recursive: true })).sort();\n const groups: BarrelGroup[] = [];\n let currentGroup: BarrelGroup | undefined;\n\n const pushGroup = (g: BarrelGroup) => groups.push({ ...g });\n\n for (const item of items) {\n const filename = basename(item);\n const dirPath = join(pkg.srcPath, dirname(item));\n const filePath = join(dirPath, filename);\n\n if (dirPath !== currentGroup?.dirPath) {\n if (currentGroup) pushGroup(currentGroup);\n currentGroup = {\n dirPath,\n files: [],\n pkg,\n barrelFilePath: join(dirPath, \"index.ts\"),\n barrelExists: false,\n };\n }\n\n if (filename === \"index.ts\") currentGroup.barrelExists = true;\n\n if (\n this.isExcluded(filePath) ||\n (!filename.endsWith(\".ts\") && !filename.endsWith(\".mts\"))\n )\n continue;\n\n currentGroup.files.push(filename);\n }\n\n if (currentGroup) pushGroup(currentGroup);\n return groups;\n }\n\n protected async collectGroups(\n packages: Pkg[],\n ): Promise<Map<string, BarrelGroup[]>> {\n const groupsByPkg = new Map<string, BarrelGroup[]>();\n\n const pushGroup = (g: BarrelGroup) => {\n const key = g.pkg.content.name;\n if (!groupsByPkg.has(key)) groupsByPkg.set(key, []);\n groupsByPkg.get(key)!.push({ ...g });\n };\n\n const results = await Promise.all(\n packages.map((pkg) => this.collectPkgGroups(pkg)),\n );\n\n for (const groups of results) for (const group of groups) pushGroup(group);\n return groupsByPkg;\n }\n\n protected async updatePackageExports(\n pkg: Pkg,\n exports: Record<string, string>,\n ) {\n try {\n // const pkgName = relative(this.paths.workspacesDir, packageDir);\n // // const pkgs = await workspace().loadPackages();\n\n logInfo(`๐Ÿ“ฆ updating ${pkg.repoDirPath} package.json ...`);\n // const pkg = await readPackageJsonThrow(packageJsonPath);\n if (!this.hasExportsChanged(exports, pkg.content.exports)) {\n logInfo(`๐Ÿงน No changes in ${pkg.repoDirPath}, nothing to do`);\n return;\n }\n pkg.content.exports = { ...exports };\n await pkg.write();\n logSuccess(`โœ… ${pkg.repoDirPath} update successful`);\n } catch (error) {\n logInfo(error);\n }\n }\n\n protected hasExportsChanged(\n a: Record<string, string> | undefined,\n b: Record<string, string> | undefined,\n ): boolean {\n if (!a) a = {};\n if (!b) b = {};\n\n if (Object.keys(a).length !== Object.keys(b).length) return true;\n if (!a && !b) return false;\n if (!a || !b) return true;\n\n for (const entryA of Object.entries(a)) {\n if (b[entryA[0]] !== entryA[1]) return true;\n }\n return false;\n }\n\n protected extractExports(result: BarrelResult): Record<string, string> {\n const record: Record<string, string> = {};\n for (const barrelDir of result.barrelDirs) {\n const ex = relative(result.pkg.srcPath, barrelDir);\n record[`./${ex}`] = `./dist/${ex}/index.js`;\n }\n record[\"./package.json\"] = \"./package.json\";\n return record;\n }\n\n protected async buildAndPersist(\n groupsByPkg: Map<string, BarrelGroup[]>,\n ): Promise<void> {\n const promises: Promise<BarrelGroup>[] = [];\n\n for (const groups of groupsByPkg.values()) {\n const allFilePaths = groups.flatMap((g) =>\n g.files.map((f) => join(g.dirPath, f)),\n );\n const sourceFileMap: Map<string, SourceFile> =\n allFilePaths.length > 0\n ? createSourceFileMap(allFilePaths)\n : new Map<string, SourceFile>();\n\n for (const group of groups) {\n promises.push(this.persistBarrel({ ...group }, sourceFileMap));\n }\n }\n\n const barrelGroups = (await Promise.all(promises)).filter(\n (prom) => prom.files.length > 0,\n );\n\n const results: BarrelResult[] = [];\n\n for (const barrelGroup of barrelGroups) {\n let found = results.find(\n (res) => barrelGroup.dirPath === res.pkg.dirPath,\n );\n if (!found) {\n found = {\n barrelDirs: [],\n pkg: barrelGroup.pkg,\n };\n results.push(found);\n }\n\n found.barrelDirs.push(barrelGroup.dirPath);\n }\n\n const pkgExps: Record<string, { pkg: Pkg; exps: Record<string, string> }> =\n {};\n for (const res of results) {\n if (!(res.pkg.content.name in pkgExps))\n pkgExps[res.pkg.content.name] = { pkg: res.pkg, exps: {} };\n\n pkgExps[res.pkg.content.name].exps = {\n ...pkgExps[res.pkg.content.name].exps,\n ...this.extractExports(res),\n };\n }\n\n await Promise.all(\n Object.values(pkgExps).map(async (pkgExp) =>\n this.updatePackageExports(pkgExp.pkg, pkgExp.exps),\n ),\n );\n }\n}\n"]}
@@ -2,6 +2,8 @@ import type { Pkg } from "../pkg/Pkg.js";
2
2
  import { RunRepoRootParams } from "./types.run.js";
3
3
  export interface BarrelGroup {
4
4
  dirPath: string;
5
+ barrelFilePath: string;
6
+ barrelExists: boolean;
5
7
  files: string[];
6
8
  pkg: Pkg;
7
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.barrel.d.ts","sourceRoot":"","sources":["../../src/types/types.barrel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,GAAG,CAAC;CACV;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,EAAE,GAAG,CAAC;CACV;AAED,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"types.barrel.d.ts","sourceRoot":"","sources":["../../src/types/types.barrel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,GAAG,CAAC;CACV;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,EAAE,GAAG,CAAC;CACV;AAED,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.barrel.js","sourceRoot":"","sources":["../../src/types/types.barrel.ts"],"names":[],"mappings":"","sourcesContent":["import type { Pkg } from \"../pkg/Pkg.js\";\nimport { RunRepoRootParams } from \"./types.run.js\";\n\nexport interface BarrelGroup {\n dirPath: string;\n files: string[];\n pkg: Pkg;\n}\n\nexport interface BarrelResult {\n barrelDirs: string[];\n pkg: Pkg;\n}\n\nexport interface BarrelParams extends RunRepoRootParams {\n excludes?: RegExp[];\n fileHeader?: string;\n}\n"]}
1
+ {"version":3,"file":"types.barrel.js","sourceRoot":"","sources":["../../src/types/types.barrel.ts"],"names":[],"mappings":"","sourcesContent":["import type { Pkg } from \"../pkg/Pkg.js\";\nimport { RunRepoRootParams } from \"./types.run.js\";\n\nexport interface BarrelGroup {\n dirPath: string;\n barrelFilePath: string;\n barrelExists: boolean;\n files: string[];\n pkg: Pkg;\n}\n\nexport interface BarrelResult {\n barrelDirs: string[];\n pkg: Pkg;\n}\n\nexport interface BarrelParams extends RunRepoRootParams {\n excludes?: RegExp[];\n fileHeader?: string;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxpicture/build-api",
3
- "version": "0.2.50",
3
+ "version": "0.2.51",
4
4
  "description": "Build utilities API",
5
5
  "type": "module",
6
6
  "author": "MXPicture",