Files
serpkah-linktree/server.ts
2026-01-11 17:19:43 +01:00

67 lines
2.3 KiB
TypeScript

import { serve } from "bun";
const port = Number(process.env.PORT ?? "3000");
function contentType(pathname: string): string | undefined {
if (pathname.endsWith(".html")) return "text/html; charset=utf-8";
if (pathname.endsWith(".css")) return "text/css; charset=utf-8";
if (pathname.endsWith(".js")) return "application/javascript; charset=utf-8";
if (pathname.endsWith(".mjs")) return "application/javascript; charset=utf-8";
if (pathname.endsWith(".json")) return "application/json; charset=utf-8";
if (pathname.endsWith(".svg")) return "image/svg+xml";
if (pathname.endsWith(".png")) return "image/png";
if (pathname.endsWith(".jpg") || pathname.endsWith(".jpeg")) return "image/jpeg";
if (pathname.endsWith(".webp")) return "image/webp";
if (pathname.endsWith(".ico")) return "image/x-icon";
if (pathname.endsWith(".woff")) return "font/woff";
if (pathname.endsWith(".woff2")) return "font/woff2";
if (pathname.endsWith(".txt")) return "text/plain; charset=utf-8";
return undefined;
}
const distDir = `${process.cwd()}/dist`;
serve({
port,
async fetch(req) {
const url = new URL(req.url);
// Normalize paths
let pathname = decodeURIComponent(url.pathname);
// Default document
if (pathname === "/") pathname = "/index.html";
const filePath = `${distDir}${pathname}`;
// Try direct file first
let file = Bun.file(filePath);
if (!(await file.exists())) {
// If request is for a "route", serve index.html (SPA-ish fallback)
// Astro static pages typically exist as real files, but this fallback helps
// if you add client-side routing later.
file = Bun.file(`${distDir}/index.html`);
if (!(await file.exists())) {
return new Response("Not Found", { status: 404 });
}
}
const headers = new Headers();
const ct = contentType(pathname);
if (ct) headers.set("Content-Type", ct);
// Cache policy:
// - HTML: no-cache (so updates show quickly)
// - assets: cache long (Astro fingerprints assets by default)
if (pathname.endsWith(".html")) {
headers.set("Cache-Control", "no-cache");
} else {
headers.set("Cache-Control", "public, max-age=31536000, immutable");
}
return new Response(file, { headers });
}
});
console.log(`Serving dist on http://0.0.0.0:${port}`);