// Serveur de prévisualisation QA (zéro dépendance) : sert un build Vite // (dist-next par défaut) et relaie /api vers le backend local — permet de // valider une fiche avec Playwright SANS toucher au dist/ servi en production. // Usage : node frontend/scripts/preview.mjs [dir=dist-next] [port=18096] [api=http://127.0.0.1:8096] import http from "node:http"; import { createReadStream, existsSync, statSync } from "node:fs"; import { extname, join, resolve } from "node:path"; const DIR = resolve(process.argv[2] || "dist-next"); const PORT = Number(process.argv[3] || 18096); const API = new URL(process.argv[4] || "http://127.0.0.1:8096"); const MIME = { ".html": "text/html; charset=utf-8", ".js": "text/javascript", ".css": "text/css", ".svg": "image/svg+xml", ".png": "image/png", ".json": "application/json", ".geojson": "application/geo+json", ".woff2": "font/woff2", ".ico": "image/x-icon" }; http.createServer((req, res) => { const url = new URL(req.url, "http://x"); if (url.pathname.startsWith("/api/")) { const p = http.request({ host: API.hostname, port: API.port, path: req.url, method: req.method, headers: { ...req.headers, host: API.host } }, (r) => { res.writeHead(r.statusCode, r.headers); r.pipe(res); }); p.on("error", () => { res.writeHead(502); res.end("api down"); }); req.pipe(p); return; } let f = join(DIR, decodeURIComponent(url.pathname)); if (!existsSync(f) || statSync(f).isDirectory()) f = join(DIR, "index.html"); res.writeHead(200, { "content-type": MIME[extname(f)] || "application/octet-stream" }); createReadStream(f).pipe(res); }).listen(PORT, "127.0.0.1", () => console.log(`preview ${DIR} → http://127.0.0.1:${PORT} (api → ${API.origin})`));