import { promises as fs } from "node:fs"; import path from "node:path"; import { describe, expect, it } from "@suaveplan/testing/runner"; const PKG_ROOT = path.resolve(__dirname, ".."); const SRC_ROOT = path.join(PKG_ROOT, "src"); async function walk(dir: string): Promise { const out: string[] = []; const entries = await fs.readdir(dir, { withFileTypes: true }); for (const e of entries) { const p = path.join(dir, e.name); if (e.isDirectory()) { out.push(...(await walk(p))); } else { out.push(p); } } return out; } function isExempt(filePath: string): boolean { const base = path.basename(filePath); return ( base.endsWith(".test.ts") || base.endsWith(".types.ts") || base === "index.ts" ); } describe("dep-graph: package shape", () => { it("every implementation .ts has a sibling .md", { timeout: 5000, }, async () => { const files = await walk(SRC_ROOT); const tsFiles = files.filter((f) => f.endsWith(".ts") && !isExempt(f)); const missing: string[] = []; for (const ts of tsFiles) { const md = ts.replace(/\.ts$/, ".md"); try { await fs.stat(md); } catch { missing.push(path.relative(PKG_ROOT, ts)); } } expect( missing, `missing sibling .md for: ${missing.join(", ")}` ).toEqual([]); }); it("no source file uses `export *` (feature-barrel rule)", { timeout: 5000, }, async () => { const files = await walk(SRC_ROOT); const tsFiles = files.filter((f) => f.endsWith(".ts")); const offending: string[] = []; for (const f of tsFiles) { const content = await fs.readFile(f, "utf-8"); if (/^\s*export\s*\*/m.test(content)) { offending.push(path.relative(PKG_ROOT, f)); } } expect(offending).toEqual([]); }); it("no test file imports runner primitives directly from vitest or bun:test", { timeout: 5000, }, async () => { const files = await walk(SRC_ROOT); const tests = files.filter((f) => f.endsWith(".test.ts")); const offending: string[] = []; for (const f of tests) { const content = await fs.readFile(f, "utf-8"); if (/from\s+["'](?:vitest|bun:test)["']/.test(content)) { offending.push(path.relative(PKG_ROOT, f)); } } expect(offending).toEqual([]); }); it("no source file contains banned patterns", { timeout: 5000, }, async () => { const files = await walk(SRC_ROOT); const tsFiles = files.filter( (f) => f.endsWith(".ts") && !f.endsWith(".test.ts") ); const banned = [ "@deprecated", "TODO", "FIXME", "ts-ignore", "ts-expect-error", ".skip", ".only", "console.log", "biome-ignore", ]; const hits: string[] = []; for (const f of tsFiles) { const content = await fs.readFile(f, "utf-8"); for (const b of banned) { if (content.includes(b)) { hits.push(`${path.relative(PKG_ROOT, f)}: ${b}`); } } } expect(hits).toEqual([]); }); it("package.json declares subpath exports for every command + prompt + run-function + otel + error-codes module", { timeout: 5000, }, async () => { const pkg = JSON.parse( await fs.readFile(path.join(PKG_ROOT, "package.json"), "utf-8") ) as { exports: Record }; const required = [ ".", "./error-codes/error-codes", "./otel/instruments", "./run-function", "./prompt/prompt", "./commands/keys/keys", "./commands/files/files", "./commands/files/serve-file", "./commands/license/license", ]; for (const r of required) { expect( pkg.exports[r], `missing subpath export: ${r}` ).toBeDefined(); } }); it("package.json declares all 18 bin entries", { timeout: 5000, }, async () => { const pkg = JSON.parse( await fs.readFile(path.join(PKG_ROOT, "package.json"), "utf-8") ) as { bin: Record }; const required = [ "suaveplan", "license", "create-root-keys", "create-server-keys", "roll-server-keys", "create-root-keys-chain", "create-server-keys-chain", "roll-server-keys-chain", "verify-key-chain", "view-keys", "view-vault", "view-public-key-file", "view-chain-public", "prepare-file", "serve-file", "validate-file", "get-file-stats", "validate-packet", ]; for (const r of required) { expect(pkg.bin[r], `missing bin: ${r}`).toBeDefined(); } expect(Object.keys(pkg.bin)).toHaveLength(18); // Each declared bin must have a matching .ts file in src/bin. for (const r of required) { const expected = path.join( SRC_ROOT, "bin", r === "suaveplan" ? "index.ts" : `${r}.ts` ); await expect(fs.stat(expected)).resolves.toBeDefined(); } }); });