rust-web-server 18.10.0

Single-binary web server and reverse proxy: automatic HTTPS (Let's Encrypt), HTTP/1.1, HTTP/2 and HTTP/3, load balancing, auth and rate limiting, configured in one TOML file. Also a Rust library: routing, middleware, MCP server, ORM, background jobs. No hyper, no Tower; HTTP/2 and HTTP/3 framing via h2 and quinn.
Documentation
// Reads one docs tree (a sidebar.json plus its Markdown pages) and renders
// every page. A version is just another tree under another base, so phase 3's
// per-release builds call this once per release.
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { docsIndex, docsPage } from "./layout.js";
import { renderMarkdown } from "./markdown.js";

// Older versions are noindex, with the canonical on the latest copy of the
// same page when it still exists.
function versionMeta(version, rel) {
  if (version.latest) return {};
  return { noindex: true, canonical: version.latestPages.has(rel) ? `/docs${rel}` : undefined };
}

export async function buildDocs({ contentRoot, sidebar, base = "/docs", version }) {
  const pages = new Map();
  for (const group of sidebar) {
    for (const item of group.items) {
      const rel = item.link.replace(/^\/|\/$/g, "");
      const file = [".md", ".mdx"].map((ext) => rel + ext).find((f) => existsSync(join(contentRoot, f)));
      if (!file) throw new Error(`sidebar entry ${item.link} has no page in ${contentRoot}`);
      const rendered = await renderMarkdown(readFileSync(join(contentRoot, file), "utf8"), { base });
      pages.set(base + item.link, { ...rendered, title: rendered.title || item.label, path: base + item.link, file, label: item.label });
    }
  }

  const order = [...pages.values()];
  const out = order.map((page, i) => ({
    meta: {
      path: page.path,
      title: `${page.title} · rws ${version.latest ? "docs" : `${version.key} docs`}`,
      description: page.description || page.title,
      ...versionMeta(version, page.path.slice(base.length)),
    },
    render: () =>
      docsPage({
        page,
        sidebar,
        base,
        version,
        prev: order[i - 1] && { href: order[i - 1].path, label: order[i - 1].label },
        next: order[i + 1] && { href: order[i + 1].path, label: order[i + 1].label },
      }),
  }));
  out.unshift({
    meta: {
      path: `${base}/`,
      title: version.latest ? "Documentation · rws" : `Documentation for ${version.key} · rws`,
      description: "rust-web-server documentation: configuration, proxy, building apps, MCP, database and deployment.",
      ...versionMeta(version, "/"),
    },
    render: () => docsIndex({ path: `${base}/`, sidebar, base, pages, version }),
  });
  return out;
}