import { describe, expect, it, vi } from "vitest"; import { IMPORT_SAFETY_TEST_TIMEOUT_MS } from "./support/import-safety.js"; const poolConstructor = vi.hoisted(() => vi.fn()); vi.mock("pg", () => ({ Pool: poolConstructor })); describe("create-initial-owner CLI import safety", () => { const originalEnv = { ...process.env }; it( "does not read DATABASE_URL, connect to PostgreSQL, or create anything merely by importing the module", async () => { delete process.env.DATABASE_URL; // Under Vitest, process.argv[1] is never this file's own path, so isDirectExecution() is false // exactly as it is for `bootstrap-platform-owner.ts` — no argv manipulation is needed to prove // the guard holds. Importing the command must never prompt, connect, or write. await expect(import("../src/cli/create-initial-owner.js")).resolves.toBeDefined(); expect(poolConstructor).not.toHaveBeenCalled(); process.env = originalEnv; }, IMPORT_SAFETY_TEST_TIMEOUT_MS, ); it("reads no environment variable for the password", async () => { // The password is prompted for or read from standard input; it is deliberately never taken from // the environment, so nothing can make it permanent deployment configuration. Asserted against // the source rather than behaviour, because the absence of a lookup is what matters. const source = await import("node:fs/promises").then((fs) => fs.readFile(new URL("../src/cli/create-initial-owner.ts", import.meta.url), "utf8"), ); const environmentReads = [...source.matchAll(/process\.env\.([A-Z_]+)/gu)].map( (match) => match[1], ); expect(environmentReads).toEqual(["DATABASE_URL"]); // No dynamic lookup either, which a named-property scan alone would miss. expect(source).not.toMatch(/process\.env\[/u); // And a password supplied on the command line is refused rather than quietly honoured. expect(source).toContain("--password is not supported"); }); });