Files
leetcode/apps/docs/blume.config.ts
T

110 lines
3.7 KiB
TypeScript

import { defineConfig } from "blume";
import { custom, filesystem } from "blume/sources";
import { githubReleasesSource } from "blume/sources/github-releases.ts";
import redirects from "./redirects";
/**
* GitHub releases → /changelog, dated by the topic's real finish instant.
*
* Blume dates a release entry by `published_at`, which the GitHub API cannot
* backdate — so the topic releases backfilled on one day (apps/cli/
* release-topics.ts) would all read that day. Their tags are timever
* (`YYYYMMDD.HHMMSS.NNNNNNNNN`, UTC) of the moment the topic finished, so this
* fetch rewrites each timever release's `published_at` to that instant before
* Blume maps it; anything else passes through untouched. The config-level
* `githubReleases()` accepts no `fetchImpl`, hence the `custom()` wrap of the
* underlying source (the `blume/sources/*.ts` path the Blume docs use for
* custom sources), with the context the built-in adapter would receive.
*/
const TIMEVER = /^(\d{4})(\d{2})(\d{2})\.(\d{2})(\d{2})(\d{2})\.\d{9}$/;
const releasesDatedByTag: typeof fetch = async (input, init) => {
const res = await fetch(input, init);
if (!res.ok) return res;
const releases: unknown = await res.json();
if (Array.isArray(releases)) {
for (const release of releases) {
const m = typeof release?.tag_name === "string" ? release.tag_name.match(TIMEVER) : null;
if (m) release.published_at = `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}Z`;
}
}
// Blume reads only `ok` and the JSON body, so the original headers (whose
// content-length/encoding describe the upstream bytes) are not carried over.
return Response.json(releases, { status: res.status });
};
// Blume's defaults (`inter`, `ibm-plex-mono`) are fetched from fonts.gstatic.com
// on every build, which has timed out on the Pages runner and, fully offline,
// silently ships no fonts at all. The same two families from Fontsource, as
// local files, keep the build network-free. Blume resolves `src` from this
// directory; the workspace links these packages under ./node_modules.
const inter = {
name: "Inter",
variants: [
{
src: "./node_modules/@fontsource-variable/inter/files/inter-latin-wght-normal.woff2",
weight: "100..900",
},
],
};
const plexMono = {
name: "IBM Plex Mono",
variants: [
{
src: "./node_modules/@fontsource/ibm-plex-mono/files/ibm-plex-mono-latin-400-normal.woff2",
weight: 400,
},
{
src: "./node_modules/@fontsource/ibm-plex-mono/files/ibm-plex-mono-latin-500-normal.woff2",
weight: 500,
},
],
};
export default defineConfig({
title: "prdlk",
description: "Documentation for my LeetCode solutions",
logo: "./public/logo.svg",
deployment: {
site: "https://lc.prd.lk",
},
github: {
owner: "prdlk",
repo: "leetcode",
},
lastModified: "git",
redirects,
content: {
sources: [
filesystem({ root: "content" }),
custom(
githubReleasesSource(
{
name: "changelog",
prefix: "changelog",
owner: "prdlk",
repo: "leetcode",
fetchImpl: releasesDatedByTag,
},
// What resolve.ts hands the built-in adapter: `.blume/cache/<name>/`,
// and a refresh on every load (the source reads nothing else).
{
projectRoot: import.meta.dirname,
cacheDir: `${import.meta.dirname}/.blume/cache/changelog`,
mode: "build",
},
),
),
],
},
theme: {
fonts: { display: inter, body: inter, mono: plexMono },
},
navigation: {
sidebar: {
display: "flat", // "flat" | "group" | "page"
},
tabs: [{ label: "Changelog", path: "/changelog" }],
},
});