import { afterEach, describe, it } from "node:test"; import assert from "node:assert/strict"; import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { loadWorkspaceEnv, resolveWorkspaceEnvPaths } from "./load-workspace-env.js"; const envKeys = [ "DATABASE_URL", "SHARED_VALUE", "LOCAL_ONLY", "MODE_ONLY", "MODE_LOCAL_ONLY", ]; function clearEnv() { for (const key of envKeys) { delete process.env[key]; } } function withTempWorkspace(run: (workspaceRoot: string) => void) { const workspaceRoot = mkdtempSync(join(tmpdir(), "capakraken-env-")); try { run(workspaceRoot); } finally { rmSync(workspaceRoot, { recursive: true, force: true }); } } afterEach(() => { clearEnv(); delete process.env.NODE_ENV; }); describe("loadWorkspaceEnv", () => { it("loads standard workspace env files in precedence order", () => { withTempWorkspace((workspaceRoot) => { writeFileSync(join(workspaceRoot, ".env"), "DATABASE_URL=postgres://from-env\nSHARED_VALUE=base\n"); writeFileSync(join(workspaceRoot, ".env.development"), "SHARED_VALUE=mode\nMODE_ONLY=development\n"); writeFileSync(join(workspaceRoot, ".env.local"), "SHARED_VALUE=local\nLOCAL_ONLY=1\n"); writeFileSync(join(workspaceRoot, ".env.development.local"), "SHARED_VALUE=mode-local\nMODE_LOCAL_ONLY=1\n"); process.env.NODE_ENV = "development"; const loadedPaths = loadWorkspaceEnv({ workspaceRoot }); assert.deepEqual( loadedPaths.map((entry) => entry.slice(workspaceRoot.length + 1)), [".env", ".env.development", ".env.local", ".env.development.local"], ); assert.equal(process.env.DATABASE_URL, "postgres://from-env"); assert.equal(process.env.SHARED_VALUE, "mode-local"); assert.equal(process.env.LOCAL_ONLY, "1"); assert.equal(process.env.MODE_ONLY, "development"); assert.equal(process.env.MODE_LOCAL_ONLY, "1"); }); }); it("does not override variables that already exist in the shell environment", () => { withTempWorkspace((workspaceRoot) => { writeFileSync(join(workspaceRoot, ".env"), "DATABASE_URL=postgres://from-env\n"); writeFileSync(join(workspaceRoot, ".env.local"), "DATABASE_URL=postgres://from-local\n"); process.env.DATABASE_URL = "postgres://from-shell"; loadWorkspaceEnv({ workspaceRoot }); assert.equal(process.env.DATABASE_URL, "postgres://from-shell"); }); }); it("returns the candidate env paths even when files are missing", () => { withTempWorkspace((workspaceRoot) => { process.env.NODE_ENV = "test"; const envPaths = resolveWorkspaceEnvPaths({ workspaceRoot }); assert.deepEqual( envPaths.map((entry) => entry.slice(workspaceRoot.length + 1)), [".env", ".env.test", ".env.local", ".env.test.local"], ); assert.deepEqual(loadWorkspaceEnv({ workspaceRoot }), []); }); }); });