33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
const port = Number(process.env.WEB_PORT || 3000);
|
|||
|
|
const apiOrigin = process.env.API_ORIGIN || "http://localhost:3001";
|
||
|
|
|
||
|
|
function staticResponse(path: string) {
|
||
|
|
const file = Bun.file(`dist${path}`);
|
||
|
|
return file.exists().then(exists => exists
|
||
|
|
? new Response(file, { headers: { "Cache-Control": path === "/sw.js" || path === "/index.html" ? "no-cache" : "public, max-age=3600" } })
|
||
|
|
: null);
|
||
|
|
}
|
||
|
|
|
||
|
|
Bun.serve({
|
||
|
|
port,
|
||
|
|
hostname: process.env.WEB_HOST || "127.0.0.1",
|
||
|
|
async fetch(request) {
|
||
|
|
const url = new URL(request.url);
|
||
|
|
if (url.pathname.startsWith("/api/") || url.pathname.startsWith("/auth/")) {
|
||
|
|
const upstream = new URL(url.pathname + url.search, apiOrigin);
|
||
|
|
const headers = new Headers(request.headers);
|
||
|
|
headers.delete("host");
|
||
|
|
headers.set("X-Forwarded-Host", url.host);
|
||
|
|
headers.set("X-Forwarded-Proto", url.protocol.slice(0, -1));
|
||
|
|
return fetch(upstream, { method: request.method, headers, body: request.body, redirect: "manual" });
|
||
|
|
}
|
||
|
|
const path = decodeURIComponent(url.pathname);
|
||
|
|
if (path.includes("..") || path.includes("\\")) return new Response("Not found", { status: 404 });
|
||
|
|
const requested = path === "/" ? "/index.html" : path;
|
||
|
|
const response = await staticResponse(requested);
|
||
|
|
if (response) return response;
|
||
|
|
if (!requested.includes(".")) return (await staticResponse("/index.html"))!;
|
||
|
|
return new Response("Not found", { status: 404 });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
console.log(`Timelog web listening on ${port}`);
|