// DraftVision 2027 — serveur statique zéro dépendance // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // Usage : node server.mjs [port] (défaut 8100) · healthcheck : /healthz import { createServer } from "node:http"; import { readFile } from "node:fs/promises"; import { extname, join, normalize } from "node:path"; import { fileURLToPath } from "node:url"; const PORT = Number(process.argv[2]) || 8100; const RACINE = fileURLToPath(new URL(".", import.meta.url)); const TYPES = { ".html":"text/html; charset=utf-8", ".md":"text/markdown; charset=utf-8", ".png":"image/png", ".ico":"image/x-icon", ".txt":"text/plain; charset=utf-8" }; createServer(async (req, res) => { const url = new URL(req.url, "http://x"); if (url.pathname === "/healthz") { res.writeHead(200, {"Content-Type":"application/json"}); return res.end('{"ok":true,"app":"draftvision2027"}'); } let chemin = url.pathname === "/" ? "/index.html" : url.pathname; chemin = normalize(chemin).replace(/^(\.\.[/\\])+/, ""); try { const donnees = await readFile(join(RACINE, chemin)); res.writeHead(200, {"Content-Type": TYPES[extname(chemin)] || "application/octet-stream", "Cache-Control":"no-cache"}); res.end(donnees); } catch { res.writeHead(404, {"Content-Type":"text/plain; charset=utf-8"}); res.end("404 — introuvable"); } }).listen(PORT, "0.0.0.0", () => console.log(`DraftVision 2027 sur http://0.0.0.0:${PORT}`));