paperclip/scripts/serve-storybook-static.mjs

70 lines
2.0 KiB
JavaScript

#!/usr/bin/env node
// Tiny dependency-free static file server for the built Storybook
// (ui/storybook-static). Used by the visual snapshot suite's webServer so we
// don't add an http-server dependency.
import { createServer } from "node:http";
import { createReadStream, existsSync, statSync } from "node:fs";
import { extname, join, normalize, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const root = resolve(
fileURLToPath(new URL(".", import.meta.url)),
"..",
"ui",
"storybook-static",
);
const port = Number(process.env.PORT ?? 6106);
if (!existsSync(join(root, "index.html"))) {
console.error(
`No built Storybook at ${root}. Run \`pnpm build-storybook\` first.`,
);
process.exit(1);
}
const MIME = {
".html": "text/html; charset=utf-8",
".js": "text/javascript; charset=utf-8",
".mjs": "text/javascript; charset=utf-8",
".css": "text/css; charset=utf-8",
".json": "application/json; charset=utf-8",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".svg": "image/svg+xml",
".ico": "image/x-icon",
".woff": "font/woff",
".woff2": "font/woff2",
".ttf": "font/ttf",
".map": "application/json; charset=utf-8",
".txt": "text/plain; charset=utf-8",
".webm": "video/webm",
".mp4": "video/mp4",
};
const server = createServer((req, res) => {
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
let filePath = normalize(join(root, decodeURIComponent(url.pathname)));
if (!filePath.startsWith(root)) {
res.writeHead(403).end("forbidden");
return;
}
if (existsSync(filePath) && statSync(filePath).isDirectory()) {
filePath = join(filePath, "index.html");
}
if (!existsSync(filePath)) {
res.writeHead(404).end("not found");
return;
}
res.writeHead(200, {
"content-type": MIME[extname(filePath)] ?? "application/octet-stream",
"cache-control": "no-store",
});
createReadStream(filePath).pipe(res);
});
server.listen(port, () => {
console.log(`storybook-static served at http://localhost:${port}`);
});