import { existsSync } from "node:fs"; import { spawn, type ChildProcess } from "node:child_process"; import { join, resolve } from "node:path"; export interface PreviewOptions { port?: number; hostname?: string; stdio?: "inherit" | "pipe"; /** Enable the production artifact's reconnecting DOM-morph client. */ developmentRuntime?: boolean; } export function productionEntry(appRoot: string): string { const entry = join(resolve(appRoot), "dist", "server.js"); if (!existsSync(entry)) { throw new Error("WRN-PREVIEW-NO-BUILD: run `wrnexus build` before `wrnexus preview`."); } return entry; } export function runPreview(appRoot: string, options: PreviewOptions = {}): ChildProcess { const entry = productionEntry(appRoot); const port = options.port ?? 3000; const hostname = options.hostname ?? "::"; console.log( `\n ▶ WrNexus production preview — http://${hostname === "::" ? "localhost" : hostname}:${port}`, ); return spawn(process.execPath, [entry], { cwd: resolve(appRoot), stdio: options.stdio ?? "inherit", env: { ...process.env, NODE_ENV: "production", WRNEXUS_PROFILE: process.env.WRNEXUS_PROFILE ?? "production", PORT: String(port), HOST: hostname, ...(options.developmentRuntime ? { WRNEXUS_PRODUCTION_DEV: "1" } : {}), }, }); }