// files the host reads at the site root. astro skips pages whose filename starts with "_",
// so _redirects comes through this route instead.
import type { APIRoute } from "astro";
import { loadDocs } from "../lib/docs";
import { markdownPath } from "../lib/llms";
import { SECTIONS } from "../lib/nav";
import { sectionHref } from "../lib/site";
export function getStaticPaths() {
return [{ params: { file: "_redirects" } }];
}
export const GET: APIRoute = async () => {
const docs = await loadDocs();
// an agent asking for markdown (Accept: text/markdown) gets the page's markdown copy at the
// same url, and llms.txt for the home page. one rule per page, so a page without a copy
// can't be rewritten to a missing file
const lines = ["/ /llms.txt 200! Accept=text/markdown"];
for (const doc of docs.values()) lines.push(`${doc.url} ${markdownPath(doc)} 200! Accept=text/markdown`);
lines.push("/docs/w/* /:splat 301", "/~ / 301");
// wisp doesn't add the trailing slash itself, so /configuration would be a 404
for (const doc of docs.values()) lines.push(`${doc.url.slice(0, -1)} ${doc.url} 301`);
// the old verbiage site served each doc at its path with .md on the end, READMEs lowercased
for (const doc of docs.values()) {
const old = `/${doc.id.replace(/README$/, "readme")}.md`;
lines.push(`${old} ${doc.url} 301`, `${old}/ ${doc.url} 301`);
}
// and listed directories; one without a README is now its section's box on the home grid
const dirs = new Set([...docs.keys()].filter((id) => id.includes("/")).map((id) => id.split("/")[0]));
for (const dir of dirs) {
if (docs.has(`${dir}/README`)) continue;
const section = SECTIONS.find((s) => s.pages.some((p) => p.doc.startsWith(`${dir}/`)))!;
lines.push(`/${dir}/ ${sectionHref(section)} 301`);
}
// anything else that isn't a file gets the 404 page
lines.push("/* /404.html 404");
return new Response(lines.join("\n") + "\n", { headers: { "content-type": "text/plain" } });
};