import { createServer } from "node:http"; import { readFile, stat } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; const root = path.resolve( path.dirname(fileURLToPath(import.meta.url)), "..", "dist", ); const nestedPrefix = "/deep/nested/regex/"; const mediaTypes = new Map([ [".css", "text/css; charset=utf-8"], [".html", "text/html; charset=utf-8"], [".js", "text/javascript; charset=utf-8"], [".mjs", "text/javascript; charset=utf-8"], [".json", "application/json; charset=utf-8"], [".svg", "image/svg+xml"], [".wasm", "application/wasm"], ]); const testCatalogue = { schemaVersion: 1, id: "de.add-ideas.regex-tools.browser-test", name: "Regex Tools browser-test Toolbox", home: "./", theme: { mode: "system", brand: "add·ideas" }, apps: [{ manifest: "./toolbox-app.json", enabled: true }], }; const productionSecurityHeaders = { "Content-Security-Policy": "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; connect-src 'self'; worker-src 'self' blob:; manifest-src 'self'", "Cross-Origin-Embedder-Policy": "require-corp", "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Resource-Policy": "same-origin", "X-Content-Type-Options": "nosniff", }; function safeFile(requestPath) { const decoded = decodeURIComponent(requestPath); const relative = decoded.startsWith(nestedPrefix) ? decoded.slice(nestedPrefix.length) : decoded.replace(/^\/+/u, ""); const normalized = path.posix.normalize(relative || "index.html"); if ( normalized === ".." || normalized.startsWith("../") || path.isAbsolute(normalized) ) { return null; } return path.join(root, normalized); } const server = createServer(async (request, response) => { try { const url = new URL(request.url ?? "/", "http://127.0.0.1"); if (url.pathname === "/toolbox.catalog.json") { response.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache", ...productionSecurityHeaders, }); response.end(JSON.stringify(testCatalogue)); return; } let file = safeFile(url.pathname); if (!file) { response.writeHead(400).end("Bad request"); return; } const details = await stat(file).catch(() => null); if (details?.isDirectory()) file = path.join(file, "index.html"); const content = await readFile(file); response.writeHead(200, { "Content-Type": mediaTypes.get(path.extname(file)) ?? "application/octet-stream", "Cache-Control": "no-cache", ...productionSecurityHeaders, }); response.end(content); } catch { response.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" }); response.end("Not found"); } }); server.listen(4173, "127.0.0.1", () => { console.log("Test static server listening on http://127.0.0.1:4173"); });