diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/index.ts | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/src/index.ts b/src/index.ts index d8c9bf1..ec1c296 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,75 @@ 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 serveStatic from "serve-static-bun"; +import containsPath from "contains-path"; import readConfig from "./config"; -const base = Bun.argv.length > 2 ? Bun.argv[Bun.argv.length - 1] : "."; +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}`); +} + +let files: Map<string, any> = new Map(); + +function registerFile(pathname: string, absPath: string, stat: Stats): void { + pathname = "/" + (pathname === "." || pathname === "./" ? "" : pathname); + + if (files.get(pathname) !== undefined) { + console.warn("File already registered:", pathname); + } + files.set(pathname, { + filename: absPath, + 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") { + registerFile(path.dirname(relPath), absPath, stat); + registerFile(path.dirname(relPath) + path.sep, absPath, stat); + } + registerFile(relPath, absPath, stat); + } + } +} + +walkDirectory(publicDir, ""); export default withHtmlLiveReload({ - fetch: serveStatic(path.join(base, "public"), { - headers: config.extra.headers, - dotfiles: "allow", - }), + fetch: async function (request) { + const pathname = new URL(request.url).pathname; + if (files.has(pathname)) { + const file = files.get(pathname); + console.info("filename", file.filename); + return new Response(Bun.file(file.filename), { + headers: defaultHeaders, + status: 200, + }); + } + return new Response(Bun.file(getFilename("404.html")), { + headers: Object.assign({}, defaultHeaders, { + "cache-control": "max-age=5, no-cache", + }), + status: 404, + statusText: "Not Found", + }); + }, }); |