ai_gallery/scripts/generate-md-modules.js
2026-04-17 21:41:16 +08:00

82 lines
3.0 KiB
JavaScript

/**
* Pre-compile all markdown files into JS modules so they can be bundled
* by webpack and work in Cloudflare Workers (no fs access at runtime).
*
* Generates:
* src/generated/markdown-content.js — all src/app/[lang]/.../*.md
* src/generated/posts-content.js — all src/posts/.../*.md
* src/generated/racechart-data.js — public/racechart data files
*/
const fs = require("fs");
const path = require("path");
const ROOT = process.cwd();
const OUT_DIR = path.join(ROOT, "src", "generated");
function ensureDir(dir) {
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
}
// Collect all .md files under a directory, keyed by relative path
function collectMdFiles(baseDir) {
const result = {};
function walk(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
walk(full);
} else if (entry.name.endsWith(".md")) {
const relPath = path.relative(baseDir, full);
result[relPath] = fs.readFileSync(full, "utf8");
}
}
}
walk(baseDir);
return result;
}
ensureDir(OUT_DIR);
// 1. Page markdown files (src/app/[lang]/.../*.md)
const appDir = path.join(ROOT, "src", "app");
const appMd = collectMdFiles(appDir);
fs.writeFileSync(
path.join(OUT_DIR, "markdown-content.js"),
`// Auto-generated by scripts/generate-md-modules.js — do not edit\nexport const markdownFiles = ${JSON.stringify(appMd)};\n`
);
// 2. Blog posts (src/posts/.../*.md)
const postsDir = path.join(ROOT, "src", "posts");
const postsMd = collectMdFiles(postsDir);
// Also generate a list of post slugs (directory names)
const postSlugs = fs
.readdirSync(postsDir, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name);
fs.writeFileSync(
path.join(OUT_DIR, "posts-content.js"),
`// Auto-generated by scripts/generate-md-modules.js — do not edit\nexport const postsFiles = ${JSON.stringify(postsMd)};\nexport const postSlugs = ${JSON.stringify(postSlugs)};\n`
);
console.log(
`Generated markdown modules: ${Object.keys(appMd).length} app files, ${Object.keys(postsMd).length} post files`
);
// 3. Race chart data files. These are consumed by server components and must
// be bundled for Cloudflare Workers, where fs access to public/ is unavailable.
const racechartDir = path.join(ROOT, "public", "racechart");
const racechartFiles = {};
for (const entry of fs.readdirSync(racechartDir, { withFileTypes: true })) {
if (!entry.isFile() || entry.name.startsWith(".")) continue;
if (!entry.name.endsWith(".csv") && !entry.name.endsWith(".json")) continue;
racechartFiles[entry.name] = fs.readFileSync(path.join(racechartDir, entry.name), "utf8");
}
fs.writeFileSync(
path.join(OUT_DIR, "racechart-data.js"),
`// Auto-generated by scripts/generate-md-modules.js — do not edit\nexport const racechartFiles = ${JSON.stringify(racechartFiles)};\n`
);
console.log(`Generated racechart data module: ${Object.keys(racechartFiles).length} files`);