import { readdirSync, readFileSync, statSync } from "node:fs"; import { join } from "node:path"; import { describe, expect, it } from "@suaveplan/testing/runner"; const PKG_ROOT = new URL("..", import.meta.url).pathname; const PKG_JSON = JSON.parse( readFileSync(join(PKG_ROOT, "package.json"), "utf8") ) as { dependencies: Record; exports: Record; }; const RUNTIME_ALLOWLIST = new Set([ "@suaveplan/error", "@suaveplan/events", "@suaveplan/types", "tslib", "zod", "@opentelemetry/api", ]); const SRC_ROOT = join(PKG_ROOT, "src"); function walk(dir: string): string[] { const out: string[] = []; for (const entry of readdirSync(dir)) { const p = join(dir, entry); const st = statSync(p); if (st.isDirectory()) out.push(...walk(p)); else out.push(p); } return out; } const FEATURE_MODULES = [ "error-codes", "types", "topo-sort", "service-registry", "context", "hook-executor", "define", "registry", ]; describe("dep-graph", () => { it("dependencies match the universal allowlist", { timeout: 5000 }, () => { for (const dep of Object.keys(PKG_JSON.dependencies)) { expect(RUNTIME_ALLOWLIST.has(dep)).toBe(true); } }); it("subpath exports cover every feature module", { timeout: 5000 }, () => { const exports = PKG_JSON.exports; for (const m of FEATURE_MODULES) { expect(exports[`./${m}`]).toBeDefined(); } expect(exports["."]).toBeDefined(); }); it("every implementation .ts has a sibling .md", { timeout: 5000 }, () => { const files = walk(SRC_ROOT).filter( (f) => f.endsWith(".ts") && !f.endsWith(".test.ts") && !f.endsWith(".types.ts") && !f.endsWith(".bench.ts") && !f.endsWith(".spec-conformance.test.ts") && !/[/\\]index\.ts$/.test(f) && !/[/\\]src[/\\]index\.ts$/.test(f) ); for (const f of files) { const md = f.replace(/\.ts$/, ".md"); const has = (() => { try { statSync(md); return true; } catch { return false; } })(); expect({ file: f, hasMd: has }).toEqual({ file: f, hasMd: true, }); } }); it("no biome-ignore suppressions in src", { timeout: 5000 }, () => { const files = walk(SRC_ROOT).filter((f) => f.endsWith(".ts")); for (const f of files) { const text = readFileSync(f, "utf8"); expect(text.includes("biome-ignore")).toBe(false); } }); it("no direct vitest/bun:test imports", { timeout: 5000 }, () => { const files = walk(SRC_ROOT) .concat(walk(join(PKG_ROOT, "tests"))) .filter((f) => f.endsWith(".ts")); const banned = /from\s+['"](vitest|bun:test)['"]|require\(\s*['"](vitest|bun:test)['"]\s*\)/; for (const f of files) { const text = readFileSync(f, "utf8"); if (banned.test(text)) { throw new Error(`${f} imports vitest or bun:test directly`); } } expect(true).toBe(true); }); it("no `export *` in feature barrels", { timeout: 5000 }, () => { for (const m of FEATURE_MODULES) { const idx = join(SRC_ROOT, m, "index.ts"); const text = readFileSync(idx, "utf8"); expect(text.includes("export *")).toBe(false); } }); });