// Fail before listening if an installation has no valid runtime configuration. import { spawn } from "node:child_process"; import { pathToFileURL } from "node:url"; export function validateRuntime(settings) { const invalid = []; if (!settings.HOTEL_NAME?.trim() || settings.HOTEL_NAME === "Build fixture") invalid.push("HOTEL_NAME"); if ( !settings.AUTH_SECRET || settings.AUTH_SECRET.length < 32 || settings.AUTH_SECRET.startsWith("build-fixture-") ) invalid.push("AUTH_SECRET"); for (const [key, protocols] of [ ["DATABASE_URL", ["mysql:"]], ["APP_URL", ["http:", "https:"]], ]) { try { if (!protocols.includes(new URL(settings[key]).protocol)) invalid.push(key); } catch { invalid.push(key); } } const localEnabled = ["true", "1"].includes( String(settings.CROWDSEC_LOCAL_ENABLED ?? "") .trim() .toLowerCase(), ); if (localEnabled) { if (!settings.CROWDSEC_LAPI_API_KEY?.trim()) invalid.push("CROWDSEC_LAPI_API_KEY"); if (settings.CROWDSEC_LAPI_URL) { try { new URL(settings.CROWDSEC_LAPI_URL); } catch { invalid.push("CROWDSEC_LAPI_URL"); } } } if (invalid.length) throw new Error(`Invalid runtime configuration: ${invalid.join(", ")}`); } if ( process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href ) { try { validateRuntime(process.env); const child = spawn(process.execPath, ["server.js"], { stdio: "inherit" }); for (const signal of ["SIGTERM", "SIGINT"]) process.on(signal, () => child.kill(signal)); child.on("error", () => { console.error("CMS process could not start"); process.exitCode = 1; }); child.on("exit", (code) => { process.exitCode = code ?? 1; }); } catch (error) { console.error(error.message); process.exitCode = 1; } }