import { createReadStream } from "node:fs"; import { stat } from "node:fs/promises"; import { createServer } from "node:http"; import { extname, join, normalize } from "node:path"; import { fileURLToPath } from "node:url"; import startServer from "./dist/server/server.js"; const root = fileURLToPath(new URL(".", import.meta.url)); const clientDir = join(root, "dist", "client"); const host = process.env.HOST ?? process.env.WEBSITE_LISTEN_ADDRESS ?? "127.0.0.1"; const port = Number(process.env.PORT ?? process.env.WEBSITE_LISTEN_PORT ?? "3002"); const contentTypes = new Map([ [".css", "text/css; charset=utf-8"], [".html", "text/html; charset=utf-8"], [".ico", "image/x-icon"], [".js", "text/javascript; charset=utf-8"], [".json", "application/json; charset=utf-8"], [".png", "image/png"], [".svg", "image/svg+xml"], [".txt", "text/plain; charset=utf-8"], [".woff", "font/woff"], ]); function writeResponse(res, response) { res.writeHead(response.status, Object.fromEntries(response.headers)); if (!response.body) { res.end(); return; } response.body.pipeTo( new WritableStream({ write(chunk) { res.write(chunk); }, close() { res.end(); }, abort(error) { res.destroy(error); }, }), ); } async function tryServeStatic(req, res, pathname) { if (pathname === "/" || !extname(pathname)) return false; const decoded = decodeURIComponent(pathname); const normalized = normalize(decoded).replace(/^\.\.(\/|$)/, ""); const filePath = join(clientDir, normalized); if (!filePath.startsWith(clientDir)) return false; try { const fileStat = await stat(filePath); if (!fileStat.isFile()) return false; } catch { return false; } res.writeHead(200, { "Content-Type": contentTypes.get(extname(filePath)) ?? "application/octet-stream", "Cache-Control": filePath.includes("/assets/") ? "public, max-age=31536000, immutable" : "no-store", }); createReadStream(filePath).pipe(res); return true; } createServer(async (req, res) => { try { const origin = `http://${req.headers.host ?? `${host}:${port}`}`; const url = new URL(req.url ?? "/", origin); if (req.method === "GET" || req.method === "HEAD") { const served = await tryServeStatic(req, res, url.pathname); if (served) return; } const request = new Request(url, { method: req.method, headers: req.headers, body: req.method === "GET" || req.method === "HEAD" ? undefined : req, duplex: "half", }); const response = await startServer.fetch(request); writeResponse(res, response); } catch (error) { console.error(error); res.writeHead(500, { "Content-Type": "text/plain; charset=utf-8" }); res.end("Internal Server Error"); } }).listen(port, host, () => { console.log(`Listening on http://${host}:${port}`); });