Files
pbakaus_impeccable/server/index.js
T
Paul BakausandClaude Opus 4.6 1671d04dec Revert dynamic HTML serving (broke Bun module bundling)
The serveGenerated() approach for index.html served raw HTML, which
broke bare module specifiers (import "motion") that Bun's HTML import
bundler normally resolves. Restore the static import pattern.

The live mode's auto-reload fallback still works for HMR-capable dev
servers (Vite, Next.js). For Bun's serve() with static HTML imports,
the dev server needs a restart to pick up HTML changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:52:37 -07:00

213 lines
7.9 KiB
JavaScript

import { serve, file } from "bun";
import path from "node:path";
import { fileURLToPath } from "node:url";
import homepage from "../public/index.html";
import privacy from "../public/privacy.html";
import {
getSkills,
getCommands,
getCommandSource,
getPatterns,
handleFileDownload,
handleBundleDownload
} from "./lib/api-handlers.js";
import { generateSubPages } from "../scripts/build-sub-pages.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const ROOT_DIR = path.resolve(__dirname, "..");
// Pre-generate sub-pages so dev + prod share the same output shape.
console.log("📝 Generating sub-pages for dev server...");
const { files: subPageFiles } = await generateSubPages(ROOT_DIR);
console.log(`✓ Generated ${subPageFiles.length} sub-page(s)`);
// Helper: serve a generated HTML file by absolute path, 404 if missing.
async function serveGenerated(pagePath) {
const f = file(pagePath);
if (!(await f.exists())) return new Response("Not Found", { status: 404 });
return new Response(f, {
headers: {
"Content-Type": "text/html;charset=utf-8",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
},
});
}
const server = serve({
port: process.env.PORT || 3000,
routes: {
"/": homepage,
"/privacy": privacy,
// Legacy URL redirects (kept stable for external links and existing users).
"/cheatsheet": Response.redirect("/docs", 301),
"/gallery": Response.redirect("/visual-mode#try-it-live", 301),
"/skills": Response.redirect("/docs", 301),
"/skills/:id": (req) => Response.redirect(`/docs/${req.params.id}`, 301),
// Generated sub-pages — served directly from the pre-generated files
"/docs": () => serveGenerated(path.join(ROOT_DIR, "public/docs/index.html")),
"/docs/:id": (req) => {
const id = req.params.id.replace(/[^a-z0-9-]/gi, "");
return serveGenerated(path.join(ROOT_DIR, `public/docs/${id}.html`));
},
"/anti-patterns": () => serveGenerated(path.join(ROOT_DIR, "public/anti-patterns/index.html")),
"/visual-mode": () => serveGenerated(path.join(ROOT_DIR, "public/visual-mode/index.html")),
"/tutorials": () => serveGenerated(path.join(ROOT_DIR, "public/tutorials/index.html")),
"/tutorials/:slug": (req) => {
const slug = req.params.slug.replace(/[^a-z0-9-]/gi, "");
return serveGenerated(path.join(ROOT_DIR, `public/tutorials/${slug}.html`));
},
// Static assets - all public subdirectories
"/assets/*": async (req) => {
const url = new URL(req.url);
if (url.pathname.includes('..')) return new Response("Bad Request", { status: 400 });
const filePath = `./public${url.pathname}`;
const assetFile = file(filePath);
if (await assetFile.exists()) {
return new Response(assetFile, {
headers: { "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY" }
});
}
return new Response("Not Found", { status: 404 });
},
"/css/*": async (req) => {
const url = new URL(req.url);
if (url.pathname.includes('..')) return new Response("Bad Request", { status: 400 });
const filePath = `./public${url.pathname}`;
const assetFile = file(filePath);
if (await assetFile.exists()) {
return new Response(assetFile, {
headers: { "Content-Type": "text/css", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY" }
});
}
return new Response("Not Found", { status: 404 });
},
"/js/*": async (req) => {
const url = new URL(req.url);
if (url.pathname.includes('..')) return new Response("Bad Request", { status: 400 });
// Check public/js/ first, then fall back to built artifacts
const headers = { "Content-Type": "application/javascript", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY" };
const publicFile = file(`./public${url.pathname}`);
if (await publicFile.exists()) return new Response(publicFile, { headers });
// Browser detector served from impeccable package
if (url.pathname === '/js/detect-antipatterns-browser.js') {
const pkgFile = file('./src/detect-antipatterns-browser.js');
if (await pkgFile.exists()) return new Response(pkgFile, { headers });
}
return new Response("Not Found", { status: 404 });
},
// Test fixtures (for browser visual testing)
"/fixtures/*": async (req) => {
const url = new URL(req.url);
if (url.pathname.includes('..')) return new Response("Bad Request", { status: 400 });
const filePath = `./tests${url.pathname}`;
const assetFile = file(filePath);
if (await assetFile.exists()) {
const ext = url.pathname.split('.').pop();
const types = { html: 'text/html', css: 'text/css', js: 'application/javascript' };
return new Response(assetFile, {
headers: { "Content-Type": types[ext] || "application/octet-stream", "X-Content-Type-Options": "nosniff" }
});
}
return new Response("Not Found", { status: 404 });
},
"/antipattern-images/*": async (req) => {
const url = new URL(req.url);
if (url.pathname.includes('..')) return new Response("Bad Request", { status: 400 });
const filePath = `./public${url.pathname}`;
const assetFile = file(filePath);
if (await assetFile.exists()) {
return new Response(assetFile, {
headers: { "X-Content-Type-Options": "nosniff" }
});
}
return new Response("Not Found", { status: 404 });
},
"/antipattern-examples/*": async (req) => {
const url = new URL(req.url);
if (url.pathname.includes('..')) return new Response("Bad Request", { status: 400 });
const filePath = `./public${url.pathname}`;
const assetFile = file(filePath);
if (await assetFile.exists()) {
return new Response(assetFile, {
headers: { "Content-Type": "text/html", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "SAMEORIGIN" }
});
}
return new Response("Not Found", { status: 404 });
},
// API: Get all skills
"/api/skills": {
async GET() {
const skills = await getSkills();
return Response.json(skills);
},
},
// API: Get all commands
"/api/commands": {
async GET() {
const commands = await getCommands();
return Response.json(commands);
},
},
// API: Get patterns and antipatterns
"/api/patterns": {
async GET() {
const patterns = await getPatterns();
return Response.json(patterns);
},
},
// API: Get command source content
"/api/command-source/:id": async (req) => {
const { id } = req.params;
const result = await getCommandSource(id);
if (result && result.error) {
return Response.json({ error: result.error }, { status: result.status });
}
if (!result) {
return Response.json({ error: "Command not found" }, { status: 404 });
}
return Response.json({ content: result });
},
// API: Download individual file
"/api/download/:type/:provider/:id": async (req) => {
const { type, provider, id } = req.params;
return handleFileDownload(type, provider, id);
},
// API: Download provider bundle ZIP
"/api/download/bundle/:provider": async (req) => {
const { provider } = req.params;
return handleBundleDownload(provider);
},
},
// Serve root-level static files (og-image.png, favicon, robots.txt, etc.)
fetch(req) {
const url = new URL(req.url);
if (url.pathname.includes('..')) {
return new Response("Bad Request", { status: 400 });
}
const filePath = `./public${url.pathname}`;
const staticFile = file(filePath);
if (staticFile.size > 0) {
return new Response(staticFile);
}
return new Response("Not Found", { status: 404 });
},
development: process.env.NODE_ENV !== "production",
});
console.log(`🎨 impeccable.style running at ${server.url}`);