refactor(cli): adjust sync for (problems) group and page display meta

This commit is contained in:
Prad Nukala committed 2026-10-05 13:07:52 -04:00
1 parent 0d5c40ac4a
commit 74939c31d7
1 file changed
+17 -13
+17 -13
View File
@@ -45,11 +45,14 @@
* segment — while the topic folder is a real segment * segment — while the topic folder is a real segment
* (`/tree-dfs/invert-binary-tree`), so a hand-written `index.mdx` in it is the * (`/tree-dfs/invert-binary-tree`), so a hand-written `index.mdx` in it is the
* topic's landing page at `/tree-dfs` and Blume links the sidebar group row to * topic's landing page at `/tree-dfs` and Blume links the sidebar group row to
* it. Sync never writes or moves an `index.mdx`, and never removes a folder * it. The topic's problem pages sit one level down in a `(problems)` group,
* that still holds one. A phase folder's `meta.ts` is written once, when * `tree-dfs/(problems)/226_invert-binary-tree.mdx`: no route segment either,
* missing, then hand-owned (its title is yours to rename); a topic's is * and Blume strips the `<num>_` prefix from the route while sorting by it, so
* script-owned. An unplanned category group has no phase and sits at the * the URL is still `/tree-dfs/invert-binary-tree`. Sync never writes or moves
* content root. * an `index.mdx`, and never removes a folder that still holds one. A phase
* folder's `meta.ts` is written once, when missing, then hand-owned (its
* title is yours to rename); a topic's is script-owned. An unplanned category
* group has no phase and sits at the content root.
* *
* 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
@@ -337,8 +340,9 @@ function phaseMeta(phase: Phase): string {
/** /**
* Blume folder meta for a topic: exact label (the folder slug loses `/` and * Blume folder meta for a topic: exact label (the folder slug loses `/` and
* case), curriculum order, the sidebar icon, and `display: "group"` so the * case), curriculum order, the sidebar icon, and `display: "page"` so the
* topic collapses under its phase heading. An unplanned category group * topic is one row under its phase heading that drills into its own panel
* (the landing page, then its `(problems)` list). An unplanned category group
* (warm-ups) has no README number and sorts at 0, ahead of phase 1, so the * (warm-ups) has no README number and sorts at 0, ahead of phase 1, so the
* sidebar opens on the basics. * sidebar opens on the basics.
*/ */
@@ -347,7 +351,7 @@ function groupMeta(topic: Topic): string {
if (!icon) console.warn(`no icon for group ${JSON.stringify(topic.name)}: add it to TOPIC_ICONS`); if (!icon) console.warn(`no icon for group ${JSON.stringify(topic.name)}: add it to TOPIC_ICONS`);
const fields = [`title: ${JSON.stringify(topic.name)}`, `order: ${topic.order ?? 0}`]; const fields = [`title: ${JSON.stringify(topic.name)}`, `order: ${topic.order ?? 0}`];
if (icon) fields.push(`icon: ${JSON.stringify(icon)}`); if (icon) fields.push(`icon: ${JSON.stringify(icon)}`);
fields.push(`display: "group"`); fields.push(`display: "page"`);
return `import { defineMeta } from "blume";\n\nexport default defineMeta({ ${fields.join(", ")} });\n`; return `import { defineMeta } from "blume";\n\nexport default defineMeta({ ${fields.join(", ")} });\n`;
} }
@@ -706,16 +710,16 @@ const tags = new Map<string, TopicTag>(); // every tag slug any problem page car
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("+");
const workRef = `${sol.num}.${sol.slug} (${langs})`; const workRef = `${sol.num}.${sol.slug} (${langs})`;
// (0N-<phase>)/<topic>/ folder (the topic is a real route segment, so its // (0N-<phase>)/<topic>/(problems)/ folder (the topic is a real route segment,
// index.mdx is the landing page) + leetcode-number prefix: numeric sidebar // so its index.mdx is the landing page; `(problems)` adds none) +
// order, prefix stripped from the URL. // leetcode-number prefix: numeric sidebar order, prefix stripped from the URL.
const topic = topics.get(sol.num) ?? topicByName.get(sol.category) ?? { name: sol.category }; const topic = topics.get(sol.num) ?? topicByName.get(sol.category) ?? { name: sol.category };
const dir = topicDir(topic); const dir = topicDir(topic);
groups.set(dir, topic); groups.set(dir, topic);
if (topic.phase) phases.set(phaseDir(topic.phase), topic.phase); if (topic.phase) phases.set(phaseDir(topic.phase), topic.phase);
const name = `${dir}/${sol.num}-${sol.slug}.mdx`; const name = `${dir}/(problems)/${sol.num}_${sol.slug}.mdx`;
const existing = pages.get(sol.num); const existing = pages.get(sol.num);
await mkdir(join(DOCS, dir), { recursive: true }); await mkdir(join(DOCS, dirname(name)), { recursive: true });
let written: string; // the page as it stands after this run, for its topics let written: string; // the page as it stands after this run, for its topics
if (existing) { if (existing) {