feat(cli): generate short numeric redirects for problem pages

This commit is contained in:
Prad Nukala committed 2026-09-24 16:15:49 -04:00
1 parent 717feb7f70
commit ad129b99fd
1 file changed
+25
+25
View File
@@ -29,6 +29,11 @@
* Only the first-solve bucket is read: work/3 and work/7 hold blind re-solves * Only the first-solve bucket is read: work/3 and work/7 hold blind re-solves
* of problems whose page already exists (see work.ts), and a fresh scaffold * of problems whose page already exists (see work.ts), and a fresh scaffold
* there would otherwise wipe the page's `## Solution`. * there would otherwise wipe the page's `## Solution`.
*
* Every page also gets a short link: `/<num>` → `/<topic>/<slug>` (so
* `/leetcode/217` opens Contains Duplicate). The rules live in the generated
* `apps/docs/redirects.ts`, which `blume.config.ts` imports — Blume takes exact
* root-relative paths and prepends the deployment base itself.
*/ */
import { mkdir, readdir, rename, rmdir, unlink } from "node:fs/promises"; import { mkdir, readdir, rename, rmdir, unlink } from "node:fs/promises";
import { basename, dirname, join } from "node:path"; import { basename, dirname, join } from "node:path";
@@ -36,6 +41,7 @@ import { basename, dirname, join } from "node:path";
const ROOT = join(import.meta.dir, "..", ".."); const ROOT = join(import.meta.dir, "..", "..");
const WORK = join(ROOT, "work", "1"); const WORK = join(ROOT, "work", "1");
const DOCS = join(ROOT, "apps", "docs", "content"); const DOCS = join(ROOT, "apps", "docs", "content");
const REDIRECTS = join(ROOT, "apps", "docs", "redirects.ts");
type Lang = "js" | "py"; type Lang = "js" | "py";
@@ -533,6 +539,7 @@ const ordered = [...solutions.values()].sort((a, b) => a.num - b.num);
const groups = new Map<string, Topic>(); // topic folder -> topic, for meta.ts const groups = new Map<string, Topic>(); // topic folder -> topic, for meta.ts
const phases = new Map<string, Phase>(); // phase folder -> phase, for meta.ts const phases = new Map<string, Phase>(); // phase folder -> phase, for meta.ts
const vacated = new Set<string>(); // folders a page moved out of; removed below if empty const vacated = new Set<string>(); // folders a page moved out of; removed below if empty
const redirects: string[] = []; // `{ from: "/<num>", to: "/<topic>/<slug>" }` rows, numeric order
for (const sol of ordered) { for (const sol of ordered) {
const langs = Object.keys(sol.code).sort().join("+"); const langs = Object.keys(sol.code).sort().join("+");
@@ -573,6 +580,24 @@ for (const sol of ordered) {
await Bun.write(join(DOCS, name), renderPage(sol)); await Bun.write(join(DOCS, name), renderPage(sol));
report.push([workRef, name, "created"]); report.push([workRef, name, "created"]);
} }
// The route drops the phase `(group)` and the page's number prefix.
redirects.push(` { from: "/${sol.num}", to: ${JSON.stringify(`/${slugify(topic.name)}/${sol.slug}`)} },`);
}
// Script-owned short links, one per page; imported by blume.config.ts.
{
const module = [
"// Generated by `bun run sync` (apps/cli/sync.ts) — do not edit.",
"// `/leetcode/<num>` → that problem's page; exact paths, base added by Blume.",
"export default [",
...redirects,
"];",
"",
].join("\n");
if (!(await Bun.file(REDIRECTS).exists()) || (await Bun.file(REDIRECTS).text()) !== module) {
await Bun.write(REDIRECTS, module);
report.push([`${redirects.length} redirects`, "apps/docs/redirects.ts", "written"]);
}
} }
// Script-owned folder metas — one per live phase and topic folder — rewritten // Script-owned folder metas — one per live phase and topic folder — rewritten