import { afterAll, expect, test } from "bun:test"; import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import { get } from "node:http"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { definePlugin } from "@wrnexus/plugin"; import { startServer } from "../src/index.ts"; const root = mkdtempSync(join(tmpdir(), "wrnexus-plugin-config-")); const appDir = join(root, "app"); const routeFile = join(root, "config-probe.ts"); const runtimeKey = `@wrnexus/dev-server:test:plugin-config:${crypto.randomUUID()}`; mkdirSync(appDir, { recursive: true }); writeFileSync(join(root, "package.json"), JSON.stringify({ name: "plugin-config-lifecycle-test" })); writeFileSync( routeFile, ` export function GET() { return Response.json({ value: globalThis[Symbol.for(${JSON.stringify(runtimeKey)})], }); } `, ); afterAll(() => { delete (globalThis as Record)[Symbol.for(runtimeKey)]; rmSync(root, { recursive: true, force: true }); }); function getJson(url: string): Promise<{ status: number | undefined; body: unknown }> { return new Promise((resolve, reject) => { const request = get(url, (response) => { const chunks: Buffer[] = []; response.on("data", (chunk) => chunks.push(Buffer.from(chunk))); response.on("end", () => { try { resolve({ status: response.statusCode, body: JSON.parse(Buffer.concat(chunks).toString("utf8")), }); } catch (error) { reject(error); } }); }); request.on("error", reject); }); } test("startServer configures plugins once with the complete application config", async () => { let configureCalls = 0; const plugin = definePlugin({ name: "plugin-config-lifecycle-test", configure(config) { configureCalls += 1; (globalThis as Record)[Symbol.for(runtimeKey)] = config.lifecycleSentinel; }, routeEntries: [{ kind: "api", path: "/api/config-probe", entry: routeFile }], }); const server = await startServer({ appDir, appConfig: { lifecycleSentinel: "configured" }, plugins: plugin, hostname: "127.0.0.1", port: 0, mode: "development", hmr: false, }); try { const response = await getJson(`${server.url}/api/config-probe`); expect(response.status).toBe(200); expect(response.body).toEqual({ value: "configured" }); expect(configureCalls).toBe(1); } finally { server.stop(); } });