SPB Git

spb/svgarden Public

SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)

HTML 79.2% Astro 10.3% JavaScript 6% CSS 3.7% Shell 0.8%
2.2 KB · 66 lines javascript
Raw Blame History
1/**2 * ============================================================3 * SVGarden — https://www.svgarden.dev4 * Author : Simon-Pierre Boucher5 * Contact: contact@spboucher.ai6 * File   : server.mjs7 * Desc   : Tiny Express static server for dist/ on 127.0.0.1:4321 (+ /healthz)8 * ============================================================9 */10import { readFileSync, existsSync } from 'node:fs';11import path from 'node:path';12import { fileURLToPath } from 'node:url';13import express from 'express';14import compression from 'compression';1516const ROOT = path.dirname(fileURLToPath(import.meta.url));17const DIST = path.join(ROOT, 'dist');18const PORT = Number(process.env.PORT ?? 4321);19const HOST = process.env.HOST ?? '127.0.0.1';2021if (!existsSync(DIST)) {22  console.error('server.mjs: dist/ not found — run `npm run build` first.');23  process.exit(1);24}2526const buildInfoPath = path.join(DIST, 'build-info.json');27const buildInfo = existsSync(buildInfoPath)28  ? JSON.parse(readFileSync(buildInfoPath, 'utf8'))29  : { built: null, snippets: null };3031const app = express();32app.disable('x-powered-by');33app.use(compression());3435app.get('/healthz', (_req, res) => {36  res.set('Cache-Control', 'no-store');37  res.json({ status: 'ok', built: buildInfo.built, snippets: buildInfo.snippets });38});3940app.use(41  express.static(DIST, {42    extensions: ['html'],43    setHeaders(res, filePath) {44      if (/\.(?:js|css|woff2?|svg|png|jpe?g|webp|avif)$/.test(filePath) && /_astro[\\/]/.test(filePath)) {45        // Astro emits content-hashed filenames under _astro/ — safe to cache forever46        res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');47      } else if (filePath.endsWith('.html') || filePath.endsWith('.json')) {48        res.setHeader('Cache-Control', 'no-cache');49      } else {50        res.setHeader('Cache-Control', 'public, max-age=3600');51      }52    },53  })54);5556app.use((_req, res) => {57  res.status(404);58  const notFound = path.join(DIST, '404.html');59  if (existsSync(notFound)) res.sendFile(notFound);60  else res.type('text').send('404 — not found');61});6263app.listen(PORT, HOST, () => {64  console.log(`SVGarden serving ${DIST} on http://${HOST}:${PORT} (${buildInfo.snippets ?? '?'} snippets, built ${buildInfo.built ?? '?'})`);65});66