diff --git a/apps/docs/blume.config.ts b/apps/docs/blume.config.ts index bbfbf48..c94f563 100644 --- a/apps/docs/blume.config.ts +++ b/apps/docs/blume.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from "blume"; import type { StandardSchema } from "blume/core/standard-schema.ts"; import { filesystem } from "blume/sources"; +import { APPENDIX } from "./appendix"; import redirects from "./redirects"; // Blume's defaults (`inter`, `ibm-plex-mono`) are fetched from fonts.gstatic.com @@ -36,10 +37,9 @@ const plexMono = { * components/ProblemBadges.astro. Problem pages: `topics:` is LeetCode's topic * tags and `issue:` the problem's GitHub issue URL (both written by * apps/cli/sync.ts), `video:` the NeetCode walkthrough's - * YouTube id (apps/cli/videos.ts). Guide pages (content/appendix/, created by - * sync): `list:` is the tag's LeetCode problem list. Blume rejects undeclared - * keys and takes any Standard Schema; these are hand-rolled so the docs - * workspace needs no zod. All optional — every other page carries none. + * YouTube id (apps/cli/videos.ts). Blume rejects undeclared keys and takes + * any Standard Schema; these are hand-rolled so the docs workspace needs no + * zod. All optional — every other page carries none. */ const optional = ( message: string, @@ -68,12 +68,6 @@ const videoSchema = optional( (value): value is string => typeof value === "string" && /^[\w-]{11}$/.test(value), ); -const listSchema = optional( - "expected a https://leetcode.com/problem-list// URL", - (value): value is string => - typeof value === "string" && - /^https:\/\/leetcode\.com\/problem-list\/[\w-]+\/$/.test(value), -); const issueSchema = optional( "expected a https://github.com///issues/ URL", (value): value is string => @@ -93,12 +87,20 @@ export default defineConfig({ repo: "leetcode", }, lastModified: "git", - redirects, + // Sync's `/` short links, then the Appendix's former per-term pages + // (`/appendix/`, published until the glossary became one page) onto + // their cards, so old links and search results still land. + redirects: [ + ...redirects, + ...Object.keys(APPENDIX).map((slug) => ({ + from: `/appendix/${slug}`, + to: `/appendix#${slug}`, + })), + ], frontmatter: { extend: { topics: topicsSchema, video: videoSchema, - list: listSchema, issue: issueSchema, }, }, @@ -125,9 +127,10 @@ export default defineConfig({ llmsTxt: true, mcp: { enabled: false }, }, - // The only content source. `/changelog` is a custom page (pages/ - // changelog.astro) reading the GitHub releases itself — one timeline, no - // per-release pages, so nothing of it enters the sidebar or prev/next. + // The only content source. `/changelog` and `/appendix` are custom pages + // (pages/*.astro): `/changelog` reads the GitHub releases itself — one + // timeline, no per-release pages — and `/appendix` is one glossary page + // built from appendix.ts, so neither enters the sidebar tree or prev/next. content: { sources: [filesystem({ root: "content" })], }, @@ -139,7 +142,11 @@ export default defineConfig({ sidebar: { display: "flat", // "flat" | "group" | "page" }, - // A plain header link on the right, not a tab. - actions: [{ href: "/changelog", label: "Changelog" }], + // The glossary is no content folder any more, so it is pinned above the + // sidebar tree, on every page and breakpoint. + featured: [ + { label: "Changelog", href: "/changelog", icon: "clock" }, + { label: "Appendix", href: "/appendix", icon: "library" }, + ], }, });