import path from "node:path"; import fs, { Stats } from "node:fs"; import fsp from "node:fs/promises"; import util from "node:util"; import { withHtmlLiveReload } from "bun-html-live-reload"; import readConfig from "./config"; const base = "../website/"; const publicDir = path.resolve(base, "public") + path.sep; const config = readConfig(base); const defaultHeaders = config.extra.headers; function getFilename(name: string): string { return path.join(publicDir, `${name}`); } type File = { filename: string; headers: Record; size: number; mtime: string; }; let files = new Map(); function registerFile(pathname: string, filename: string, stat: Stats): void { pathname = "/" + (pathname === "." || pathname === "./" ? "" : pathname); if (files.get(pathname) !== undefined) { console.warn("File already registered:", pathname); } files.set(pathname, { filename, headers: pathname === "/404.html" ? Object.assign({}, defaultHeaders, { "cache-control": "no-cache" }) : defaultHeaders, size: stat.size, mtime: stat.mtime.toUTCString(), }); } function walkDirectory(root: string, dir: string) { const absDir = path.join(root, dir); for (let pathname of fs.readdirSync(absDir)) { const relPath = path.join(dir, pathname); const absPath = path.join(absDir, pathname); const stat = fs.statSync(absPath); if (stat.isDirectory()) { walkDirectory(root, relPath + path.sep); } else if (stat.isFile()) { if (pathname === "index.html") { const dir = path.dirname(relPath); registerFile(dir, absPath, stat); if (dir !== ".") { registerFile(dir + path.sep, absPath, stat); } } registerFile(relPath, absPath, stat); } } } walkDirectory(publicDir, ""); async function serveFile( file: File | undefined, statusCode: number = 200, ): Promise { if (file && (await fsp.exists(file.filename))) { return new Response(Bun.file(file.filename), { headers: file.headers, status: statusCode, }); } else { return serveFile(files.get("/404.html"), 404); } } export default withHtmlLiveReload({ fetch: async function (request) { const pathname = new URL(request.url).pathname; const file = files.get(pathname); return serveFile(file); }, });