elearning/Frontend-Learner/node_modules/srvx/dist/static.mjs
2026-01-13 10:48:02 +07:00

78 lines
No EOL
2.6 KiB
JavaScript

import { t as FastURL } from "./_chunks/_url.mjs";
import { extname, join, resolve } from "node:path";
import { createReadStream } from "node:fs";
import { readFile, stat } from "node:fs/promises";
import { FastResponse } from "srvx";
import { createBrotliCompress, createGzip } from "node:zlib";
//#region src/static.ts
const COMMON_MIME_TYPES = {
".html": "text/html",
".htm": "text/html",
".css": "text/css",
".js": "text/javascript",
".mjs": "text/javascript",
".json": "application/json",
".txt": "text/plain",
".xml": "application/xml",
".gif": "image/gif",
".ico": "image/vnd.microsoft.icon",
".jpeg": "image/jpeg",
".jpg": "image/jpeg",
".png": "image/png",
".svg": "image/svg+xml",
".webp": "image/webp",
".woff": "font/woff",
".woff2": "font/woff2",
".mp4": "video/mp4",
".webm": "video/webm",
".zip": "application/zip",
".pdf": "application/pdf"
};
const serveStatic = (options) => {
const dir = resolve(options.dir) + "/";
const methods = new Set((options.methods || ["GET", "HEAD"]).map((m) => m.toUpperCase()));
return async (req, next) => {
if (!methods.has(req.method)) return next();
const path = (req._url ??= new FastURL(req.url)).pathname.slice(1).replace(/\/$/, "");
let paths;
if (path === "") paths = ["index.html"];
else if (extname(path) === "") paths = [`${path}.html`, `${path}/index.html`];
else paths = [path];
for (const path$1 of paths) {
const filePath = join(dir, path$1);
if (!filePath.startsWith(dir)) continue;
const fileStat = await stat(filePath).catch(() => null);
if (fileStat?.isFile()) {
const fileExt = extname(filePath);
const headers = {
"Content-Length": fileStat.size.toString(),
"Content-Type": COMMON_MIME_TYPES[fileExt] || "application/octet-stream"
};
if (options.renderHTML && fileExt === ".html") return options.renderHTML({
html: await readFile(filePath, "utf8"),
filename: filePath,
request: req
});
let stream = createReadStream(filePath);
const acceptEncoding = req.headers.get("accept-encoding") || "";
if (acceptEncoding.includes("br")) {
headers["Content-Encoding"] = "br";
delete headers["Content-Length"];
headers["Vary"] = "Accept-Encoding";
stream = stream.pipe(createBrotliCompress());
} else if (acceptEncoding.includes("gzip")) {
headers["Content-Encoding"] = "gzip";
delete headers["Content-Length"];
headers["Vary"] = "Accept-Encoding";
stream = stream.pipe(createGzip());
}
return new FastResponse(stream, { headers });
}
}
return next();
};
};
//#endregion
export { serveStatic };