b3755bd6b1
/privacy says what the launcher may send when a player allows it (performance summaries, crash and bug reports, benchmark uploads), why, on what basis, where it is kept and for how long, and how to delete it. The footer links it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
28 lines
1.4 KiB
JavaScript
28 lines
1.4 KiB
JavaScript
// A dependency-free static server for dist/, for local checks (`npm run dev`).
|
|
// Railway uses Caddy instead (see Dockerfile).
|
|
import { createServer } from "node:http";
|
|
import { readFile, stat } from "node:fs/promises";
|
|
import { join, extname, normalize } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = join(fileURLToPath(new URL(".", import.meta.url)), "dist");
|
|
const types = { ".html": "text/html; charset=utf-8", ".css": "text/css", ".js": "text/javascript", ".webp": "image/webp", ".png": "image/png", ".svg": "image/svg+xml", ".woff2": "font/woff2", ".txt": "text/plain; charset=utf-8", ".md": "text/plain; charset=utf-8", ".json": "application/json" };
|
|
const port = Number(process.env.PORT) || 4173;
|
|
|
|
createServer(async (req, res) => {
|
|
let path = normalize(decodeURIComponent(new URL(req.url, "http://x").pathname)).replace(/^(\.\.[/\\])+/, "");
|
|
if (path.endsWith("/")) path += "index.html";
|
|
// /privacy is privacy.html, as the Caddyfile rewrites it.
|
|
if (!extname(path)) path += ".html";
|
|
let file = join(root, path);
|
|
let status = 200;
|
|
try {
|
|
if (!(await stat(file)).isFile()) throw 0;
|
|
} catch {
|
|
file = join(root, "404.html");
|
|
status = 404;
|
|
}
|
|
res.writeHead(status, { "Content-Type": types[extname(file)] || "application/octet-stream" });
|
|
res.end(await readFile(file));
|
|
}).listen(port, () => console.log(`http://localhost:${port}`));
|