64 lines · 2.0 KB · TypeScript
RawDownload
import type { Context } from "hono"import { WEB_ASSETS, WEB_INDEX } from "./assets" const MIME: Record<string, string> = {  ".html": "text/html; charset=utf-8",  ".js": "application/javascript; charset=utf-8",  ".mjs": "application/javascript; charset=utf-8",  ".css": "text/css; charset=utf-8",  ".json": "application/json; charset=utf-8",  ".map": "application/json; charset=utf-8",  ".svg": "image/svg+xml",  ".png": "image/png",  ".jpg": "image/jpeg",  ".jpeg": "image/jpeg",  ".gif": "image/gif",  ".ico": "image/x-icon",  ".webp": "image/webp",  ".avif": "image/avif",  ".woff": "font/woff",  ".woff2": "font/woff2",  ".ttf": "font/ttf",  ".otf": "font/otf",  ".wasm": "application/wasm",  ".mp4": "video/mp4",  ".webm": "video/webm",  ".txt": "text/plain; charset=utf-8",  ".xml": "application/xml; charset=utf-8",} function contentType(reqPath: string): string {  const dot = reqPath.lastIndexOf(".")  if (dot === -1) return "application/octet-stream"  return MIME[reqPath.slice(dot).toLowerCase()] ?? "application/octet-stream"} export async function serveWebAsset(c: Context): Promise<Response | undefined> {  if (!WEB_INDEX) return undefined   let reqPath = c.req.path  if (reqPath === "/") reqPath = "/index.html"   const direct = WEB_ASSETS[reqPath]  if (direct) {    return new Response(Bun.file(direct), {      headers: { "Content-Type": contentType(reqPath) },    })  }   // Never SPA-fallback for API-shaped paths. If a /api/* route isn't matched  // by an explicit Hono handler upstream, returning index.html would cause  // the SPA's JSON.parse to fail with "Unexpected token '<'" — caller should  // surface a real 404 instead.  if (reqPath.startsWith("/api/")) return undefined   // SPA fallback: anything that looks like a client route → index.html.  // Anything with a file extension that's not a known asset → 404.  if (reqPath.includes(".") && !reqPath.endsWith(".html")) {    return c.notFound()  }   return new Response(Bun.file(WEB_INDEX), {    headers: { "Content-Type": "text/html; charset=utf-8" },  })}