import { mkdir, mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; export interface Fixture { root: string; t5: string; betaArchive: string; dbPath: string; cleanup: () => Promise; } /** * Build a servers-root tree in a temp dir and point env at it BEFORE the code * under test is imported. There's no shared/scripts directory anymore — the * upload-only model puts script content in the DB. */ export async function newFixture(servers: string[] = ['t5_zombie_theater_1']): Promise { const root = await mkdtemp(join(tmpdir(), 'cherry-')); const t5 = join(root, 't5'); const betaArchive = join(root, 'beta-archive'); const dbPath = join(root, 'cherry.db'); await mkdir(t5, { recursive: true }); await mkdir(betaArchive, { recursive: true }); for (const s of servers) { await mkdir(join(t5, s, 'runtime/plutonium/storage/t5/raw/scripts/sp'), { recursive: true }); } process.env.SERVERS_ROOT = t5; process.env.REL_DEST = 'runtime/plutonium/storage/t5/raw/scripts/sp'; process.env.BETA_ARCHIVE_DIR = betaArchive; process.env.DB_PATH = dbPath; process.env.DEPLOY_KEEP_DAYS = '7'; process.env.HTTP_TIMEOUT_MS = '2000'; return { root, t5, betaArchive, dbPath, cleanup: async () => { try { const mod = (await import('../../src/lib/server/db/index.js')) as { closeDb: () => void; }; mod.closeDb(); } catch { /* db module was never loaded — nothing to close */ } await rm(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 50 }); } }; } export async function importFresh(mod: string): Promise { return (await import(`${mod}?t=${Date.now()}${Math.random()}`)) as T; }