import { readdirSync, readFileSync, statSync } from "node:fs"; import { join } from "node:path"; import { describe, expect, it } from "@suaveplan/testing/runner"; const PKG_ROOT = join(__dirname, ".."); function findFiles( dir: string, predicate: (path: string) => boolean ): string[] { const out: string[] = []; for (const entry of readdirSync(dir)) { const full = join(dir, entry); const stat = statSync(full); if (stat.isDirectory()) { if (entry === "node_modules" || entry === "dist") continue; out.push(...findFiles(full, predicate)); } else if (predicate(full)) { out.push(full); } } return out; } describe("dep-graph invariants", () => { it("src/index.ts has no export * statements", { timeout: 5000 }, () => { const src = readFileSync(join(PKG_ROOT, "src", "index.ts"), "utf8"); expect(/^\s*export\s+(type\s+)?\*\s+from/m.test(src)).toBe(false); }); it("feature barrels have no export * statements", { timeout: 5000 }, () => { const barrels = findFiles(join(PKG_ROOT, "src"), (p) => p.endsWith(`${"/"}index.ts`) ); const offenders: string[] = []; for (const path of barrels) { if (path === join(PKG_ROOT, "src", "index.ts")) continue; const text = readFileSync(path, "utf8"); if (/^\s*export\s+(type\s+)?\*\s+from/m.test(text)) { offenders.push(path); } } expect(offenders).toEqual([]); }); it("package.json declares one subpath per feature module", { timeout: 5000, }, () => { const pkg = JSON.parse( readFileSync(join(PKG_ROOT, "package.json"), "utf8") ) as { exports: Record }; const subpaths = Object.keys(pkg.exports).filter( (k) => k.startsWith("./") && k !== "./package.json" ); const required = ["./error-codes/error-codes", "./provider/provider"]; for (const r of required) { expect(subpaths).toContain(r); } expect(subpaths.length).toBe(required.length); }); });