import { readFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const workspaceRoot = path.resolve(packageRoot, "..", ".."); async function text(relative: string): Promise { return readFile(path.resolve(workspaceRoot, relative), "utf8"); } describe("the module-side database architecture", () => { it("keeps the Drizzle adapter free of Core, pg, and Core-owned Drizzle types", async () => { const source = await text("packages/module-database/src/drizzle.ts"); expect(source).not.toMatch(/@ekklesia\/core|from ["']pg["']|node-postgres/u); expect(source).not.toMatch(/NodePgDatabase|NodePgTransaction/u); expect(source).toContain("@ekklesia/contracts"); expect(source).toContain("drizzle-orm/pg-proxy"); }); it("keeps ABI v1 contracts free of ORM imports", async () => { for (const file of ["module-database-abi.ts", "module-schema-metadata.ts"]) { const source = await text(`packages/contracts/src/${file}`); expect(source).not.toMatch(/(?:import|export).*drizzle-orm/u); expect(source).not.toMatch(/(?:import|export).*kysely/u); expect(source).not.toMatch(/(?:import|export).*\bpg\b/u); } }); it("makes Drizzle an optional ranged peer and keeps raw SQL independent from it", async () => { const manifest = JSON.parse(await text("packages/module-database/package.json")) as Record< string, Record >; expect(manifest.dependencies).not.toHaveProperty("drizzle-orm"); expect(manifest.peerDependencies?.["drizzle-orm"]).toBe(">=0.45.2 <0.46.0"); expect(manifest.peerDependenciesMeta?.["drizzle-orm"]).toEqual({ optional: true }); const rawSource = await text("packages/module-database/src/index.ts"); expect(rawSource).not.toContain("drizzle-orm"); }); it("does not introduce an adapter dependency into Core", async () => { const manifest = await text("core/package.json"); expect(manifest).not.toContain("@ekklesia/module-database"); }); });