/** * Database-postgres import isolation test — locks in the [E00-S03-T02] rule * that `pg`/Kysely imports live only in the `database-postgres` package. * * Acceptance criteria covered (each test fails without the committed state): * - "pg/Kysely imports are isolated to database-postgres" -> the workspace * package `packages/database-postgres` (`@personal-blog/database-postgres`) * exists, declares the driver as its own dependencies (`pg`, `kysely` * exact pins, `@types/pg` for types) and its source really imports the * driver; a static scan of every workspace package's source proves that * every `pg`/`kysely` import specifier (static import/export-from, dynamic * import, require) resolves to a file inside `packages/database-postgres` * — and no other package's manifest declares the driver either. * - "no other package imports the database driver directly" -> the same * scan finds zero driver imports outside the owner package, and the * committed state is non-vacuous: a mutation probe injects a `pg` import * into `apps/server/src/index.ts` in a temp copy of the committed tree * and the scan fails, naming the offending file and the driver; a clean * copy passes (probe sanity). * * Run: `node --test tests/database-postgres-imports.test.mjs` * (node:test — built into Node >= 18; no dependencies, lockfile untouched.) */ import test from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync, readdirSync, writeFileSync, mkdirSync, cpSync, mkdtempSync, rmSync } from 'node:fs'; import { readdir } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const read = (relPath) => readFileSync(path.join(REPO_ROOT, relPath), 'utf8'); /** The workspace package allowed to import the PostgreSQL driver (E00-S03-T02). */ const OWNER_DIR = 'packages/database-postgres'; /** The root test glob (root `scripts.test`, E00-S01-T12) that runs every suite. */ const ROOT_TEST_GLOB = 'tests/**/*.test.mjs'; /** The CI job that gates the isolation criterion on every PR. */ const CI_JOB = 'database-postgres-imports'; /** Directories never scanned as package source. */ const IGNORED_DIRS = new Set(['node_modules', 'dist', 'coverage', '.git', '.pnpm-store']); /** The workspace groups scanned for source files (mirrors pnpm-workspace.yaml). */ const GROUP_DIRS = ['apps', 'packages', 'extensions']; /** Extensions scanned as package source. */ const SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs']); /** * True when a module specifier names the PostgreSQL driver: the `pg` package * or Kysely (including their subpaths, e.g. `pg/connection-string` or * `kysely/plugin/dialect`). `@types/pg` is a types-only package — never * imported at runtime — so it is not a driver import. */ function isDriverSpecifier(specifier) { return ( specifier === 'pg' || specifier.startsWith('pg/') || specifier === 'kysely' || specifier.startsWith('kysely/') ); } // --------------------------------------------------------------------------- // Comment stripping (string/comment aware, preserves line count) // --------------------------------------------------------------------------- /** * Replaces comments with whitespace while preserving line structure, so * specifier extraction never fires on commented-out imports and reported * line numbers still match the original source. Mirrors the stripper in * tests/architecture-import.test.mjs. */ function stripComments(source) { let out = ''; let i = 0; const n = source.length; let state = 'code'; // code | line | block | sq | dq | tpl const tplStack = []; // template states to resume after `${...}` closes let braceDepth = 0; while (i < n) { const c = source[i]; const next = source[i + 1]; if (state === 'code') { if (tplStack.length > 0) { if (c === '{') { braceDepth += 1; out += c; i += 1; continue; } if (c === '}') { braceDepth -= 1; out += c; i += 1; if (braceDepth === 0) state = tplStack.pop(); continue; } } if (c === '/' && next === '/') { out += ' '; i += 2; state = 'line'; continue; } if (c === '/' && next === '*') { out += ' '; i += 2; state = 'block'; continue; } if (c === "'") { out += c; i += 1; state = 'sq'; continue; } if (c === '"') { out += c; i += 1; state = 'dq'; continue; } if (c === '`') { out += c; i += 1; state = 'tpl'; continue; } out += c; i += 1; continue; } if (state === 'line') { if (c === '\n') { out += c; i += 1; state = 'code'; } else { out += ' '; i += 1; } continue; } if (state === 'block') { if (c === '*' && next === '/') { out += ' '; i += 2; state = 'code'; } else { out += c === '\n' ? c : ' '; i += 1; } continue; } if (state === 'sq' || state === 'dq') { const quote = state === 'sq' ? "'" : '"'; out += c; if (c === '\\' && next !== undefined) { out += next; i += 2; } else { if (c === quote) state = 'code'; i += 1; } continue; } // template literal out += c; if (c === '\\' && next !== undefined) { out += next; i += 2; continue; } if (c === '`') { state = 'code'; i += 1; continue; } if (c === '$' && next === '{') { out += next; i += 2; tplStack.push('tpl'); braceDepth = 1; state = 'code'; continue; } i += 1; } return out; } // --------------------------------------------------------------------------- // Driver-import discovery // --------------------------------------------------------------------------- const STATIC_IMPORT = /\b(?:import|export)\s+(?:type\s+)?(?:[\w*{},\s]*?\s+from\s*)?(['"])([^'"]+)\1/g; const REQUIRE_CALL = /\brequire\s*\(\s*(['"])([^'"]+)\1\s*\)/g; const DYNAMIC_IMPORT = /\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g; /** Returns [{ specifier, index }] for every module specifier in the (stripped) source. */ function extractSpecifiers(stripped) { const found = []; for (const re of [STATIC_IMPORT, REQUIRE_CALL, DYNAMIC_IMPORT]) { re.lastIndex = 0; let m; while ((m = re.exec(stripped)) !== null) { found.push({ specifier: m[2], index: m.index }); } } found.sort((a, b) => a.index - b.index); return found; } function lineOf(stripped, index) { return stripped.slice(0, index).split('\n').length; } /** * Returns [{ relPath, line, specifier }] for every pg/Kysely import found in * the given source files. `relPath` is the file path relative to the scan * root (posix), so reports read the same for the real workspace and for temp * copies. */ function findDriverImports(files) { const imports = []; for (const file of files) { const stripped = stripComments(file.content); for (const { specifier, index } of extractSpecifiers(stripped)) { if (isDriverSpecifier(specifier)) { imports.push({ relPath: file.relPath, line: lineOf(stripped, index), specifier, }); } } } return imports; } /** True when a scan-relative posix path sits inside the owner package. */ function isInsideOwner(relPath) { return relPath === OWNER_DIR || relPath.startsWith(`${OWNER_DIR}/`); } /** Walks the workspace groups under a root and returns [{ relPath, content }] for source files. */ async function collectSourceFiles(rootDir) { const files = []; async function walk(dir, relDir) { let entries; try { entries = await readdir(dir, { withFileTypes: true }); } catch { return; } for (const entry of entries) { const abs = path.join(dir, entry.name); const rel = `${relDir}/${entry.name}`; if (entry.isDirectory()) { if (!IGNORED_DIRS.has(entry.name)) await walk(abs, rel); continue; } if (SOURCE_EXTENSIONS.has(path.extname(entry.name))) { files.push({ relPath: rel, content: readFileSync(abs, 'utf8') }); } } } for (const group of GROUP_DIRS) { await walk(path.join(rootDir, group), group); } return files; } // --------------------------------------------------------------------------- // Manifest helpers // --------------------------------------------------------------------------- /** Returns [{ relPath, name, driverDeps }] for every workspace package manifest under a root. */ async function collectManifests(rootDir) { const manifests = []; for (const group of GROUP_DIRS) { let entries; try { entries = await readdir(path.join(rootDir, group), { withFileTypes: true }); } catch { continue; } for (const entry of entries) { if (!entry.isDirectory()) continue; const manifestPath = path.join(rootDir, group, entry.name, 'package.json'); let manifest; try { manifest = JSON.parse(readFileSync(manifestPath, 'utf8')); } catch { continue; } const allDeps = { ...(manifest.dependencies ?? {}), ...(manifest.devDependencies ?? {}), }; manifests.push({ relPath: `${group}/${entry.name}/package.json`, name: manifest.name, driverDeps: Object.keys(allDeps).filter(isDriverSpecifier), }); } } return manifests; } /** A single driver import, formatted for violation reports. */ function formatImport(driverImport) { return ` ${driverImport.relPath}:${driverImport.line} imports "${driverImport.specifier}"`; } // --------------------------------------------------------------------------- // Temp-copy helpers (mutation probes over the committed tree) // --------------------------------------------------------------------------- /** Copies the committed tree (minus ignored dirs) into a fresh temp dir. */ function copyCommittedTree() { const dir = mkdtempSync(path.join(os.tmpdir(), 'eppp-db-imports-')); for (const entry of readdirSync(REPO_ROOT, { withFileTypes: true })) { if (IGNORED_DIRS.has(entry.name) || entry.name === 'tests') continue; cpSync(path.join(REPO_ROOT, entry.name), path.join(dir, entry.name), { recursive: true, }); } // The isolation test file itself is part of the scan surface in a real // checkout; copying it keeps the temp copy's package graph identical. mkdirSync(path.join(dir, 'tests'), { recursive: true }); cpSync(path.join(REPO_ROOT, 'tests'), path.join(dir, 'tests'), { recursive: true }); return dir; } /** Injects a driver import into a package source inside a tree copy. */ function injectDriverImport(rootDir, relPath, line) { const abs = path.join(rootDir, relPath); const original = readFileSync(abs, 'utf8'); const injected = `${line}\n${original}`; writeFileSync(abs, injected); return abs; } /** Runs the isolation scan over a root and returns the misplaced imports. */ async function scanRoot(rootDir) { const files = await collectSourceFiles(rootDir); return findDriverImports(files).filter((d) => !isInsideOwner(d.relPath)); } // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- test('packages/database-postgres exists, is the driver owner, and its source imports the driver', () => { const manifest = JSON.parse(read(path.join(OWNER_DIR, 'package.json'))); assert.equal(manifest.name, '@personal-blog/database-postgres'); // The driver is owned here: exact pins, never ranges (reproducibility, // same policy as typescript@6.0.3 at the root). // Golden tuple (Technology-Stack §5.2 / §7): pg 8.22.0, Kysely 0.29.4. // @types/pg has no 8.22.x release; 8.21.0 is the closest published match // (types for the immediately preceding pg minor). assert.equal(manifest.dependencies?.pg, '8.22.0', 'owner must pin pg exactly'); assert.equal(manifest.dependencies?.kysely, '0.29.4', 'owner must pin kysely exactly'); assert.equal(manifest.devDependencies?.['@types/pg'], '8.21.0', 'owner must pin @types/pg exactly'); // The boundary module really imports the driver — the isolation is // exercised, not just declared. const source = read(path.join(OWNER_DIR, 'src', 'index.ts')); assert.match(source, /from\s+'pg'/, 'packages/database-postgres/src/index.ts must import pg'); assert.match(source, /from\s+'kysely'/, 'packages/database-postgres/src/index.ts must import kysely'); }); test('pg/Kysely imports are isolated to database-postgres in the real workspace', async () => { const files = await collectSourceFiles(REPO_ROOT); const imports = findDriverImports(files); // Non-vacuous: the driver is actually imported somewhere — and that // somewhere is the owner package. assert.ok(imports.length > 0, 'the workspace must contain pg/Kysely imports (in the owner package)'); const ownerImports = imports.filter((d) => isInsideOwner(d.relPath)); assert.ok( ownerImports.some((d) => d.specifier === 'pg'), 'the owner package must import pg', ); assert.ok( ownerImports.some((d) => d.specifier === 'kysely'), 'the owner package must import kysely', ); const misplaced = imports.filter((d) => !isInsideOwner(d.relPath)); assert.deepEqual( misplaced, [], `no package other than database-postgres may import pg/Kysely:\n${misplaced.map(formatImport).join('\n')}`, ); }); test('no other package declares the database driver in its manifest', async () => { const manifests = await collectManifests(REPO_ROOT); assert.ok( manifests.some((m) => m.relPath.startsWith(`${OWNER_DIR}/`)), 'the owner package manifest must be discovered', ); const offenders = manifests.filter((m) => !m.relPath.startsWith(`${OWNER_DIR}/`) && m.driverDeps.length > 0); assert.deepEqual( offenders, [], `only ${OWNER_DIR} may declare pg/kysely as a dependency:\n` + offenders .map((m) => ` ${m.relPath} (${m.name}) declares ${m.driverDeps.join(', ')}`) .join('\n'), ); }); test('the isolation scan catches a driver import injected into another package (mutation probe)', async () => { const dir = copyCommittedTree(); try { injectDriverImport(dir, 'apps/server/src/index.ts', "import { Pool } from 'pg';"); const misplaced = await scanRoot(dir); assert.equal(misplaced.length, 1, `expected exactly one violation, got:\n${misplaced.map(formatImport).join('\n')}`); assert.equal(misplaced[0].relPath, 'apps/server/src/index.ts'); assert.equal(misplaced[0].specifier, 'pg'); assert.equal(misplaced[0].line, 1); } finally { rmSync(dir, { recursive: true, force: true }); } }); test('a copy of the committed tree without misplaced driver imports passes the scan (probe sanity)', async () => { const dir = copyCommittedTree(); try { const misplaced = await scanRoot(dir); assert.deepEqual( misplaced, [], `a clean copy of the committed tree must pass the isolation scan:\n${misplaced.map(formatImport).join('\n')}`, ); } finally { rmSync(dir, { recursive: true, force: true }); } }); test('the specifier matcher flags pg/kysely imports and ignores other packages (unit probe)', () => { for (const spec of ['pg', 'pg/connection-string', 'kysely', 'kysely/plugin/dialect']) { assert.ok(isDriverSpecifier(spec), `"${spec}" must be flagged as a driver import`); } for (const spec of ['fastify', 'node:http', '@types/pg', 'pg-native', 'pg-pool', 'postgres-array', './internal']) { assert.equal(isDriverSpecifier(spec), false, `"${spec}" must not be flagged as a driver import`); } }); test('comment stripping ignores commented-out driver imports (unit probe)', () => { const src = [ '// import { Pool } from \'pg\';', '/* import { Kysely } from "kysely"; */', "import { Pool } from 'pg';", '', ].join('\n'); const imports = findDriverImports([{ relPath: 'apps/server/src/index.ts', content: src }]); assert.equal(imports.length, 1); assert.equal(imports[0].specifier, 'pg'); assert.equal(imports[0].line, 3, 'the stripped line number must match the original source'); }); test('the isolation criterion is enforced in CI', () => { // Picked up by the root test command (root `scripts.test` glob). const scripts = JSON.parse(read('package.json')).scripts ?? {}; assert.equal( scripts.test, `node --test "${ROOT_TEST_GLOB}"`, `root scripts.test must run the "${ROOT_TEST_GLOB}" glob so this suite runs with the rest`, ); // And a dedicated CI job gates it on every PR. const workflow = read('.gitea/workflows/ci.yml'); assert.ok( workflow.includes(`node --test tests/database-postgres-imports.test.mjs`), `CI must run the isolation suite (job "${CI_JOB}") on every PR`, ); });