mirror of
https://github.com/runyanjake/jakesphotos.git
synced 2026-03-26 05:23:18 -07:00
96 lines
3.2 KiB
JavaScript
96 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Prebuild script: reads content/ files and generates src/generated/content.js
|
|
* Run automatically via npm prestart / prebuild hooks.
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const CONTENT_DIR = path.resolve(__dirname, '../content');
|
|
const OUTPUT_FILE = path.resolve(__dirname, '../src/generated/content.js');
|
|
|
|
// --- Frontmatter parser ---
|
|
function parseFrontmatter(raw) {
|
|
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n)?([\s\S]*)$/);
|
|
if (!match) return { frontmatter: {}, content: raw.trim() };
|
|
|
|
const lines = match[1].split('\n');
|
|
const frontmatter = {};
|
|
for (const line of lines) {
|
|
const m = line.match(/^(\w[\w-]*)\s*:\s*(.*)/);
|
|
if (m) frontmatter[m[1]] = m[2].trim();
|
|
}
|
|
return { frontmatter, content: match[2].trim() };
|
|
}
|
|
|
|
// --- Route derivation ---
|
|
function routeFromDir(dirName) {
|
|
// content/index.md -> /
|
|
// content/about/index.md -> /about
|
|
if (dirName === '') return '/';
|
|
return '/' + dirName;
|
|
}
|
|
|
|
// --- Load site config ---
|
|
const configPath = path.join(CONTENT_DIR, '_config.json');
|
|
if (!fs.existsSync(configPath)) {
|
|
console.error('Missing content/_config.json');
|
|
process.exit(1);
|
|
}
|
|
const siteConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
|
|
// --- Discover page dirs ---
|
|
// Root-level index.md lives directly in content/
|
|
// Subdir index.md lives in content/<slug>/
|
|
const pages = {};
|
|
|
|
function processDir(dirPath, slug) {
|
|
const indexPath = path.join(dirPath, 'index.md');
|
|
if (!fs.existsSync(indexPath)) return;
|
|
|
|
const raw = fs.readFileSync(indexPath, 'utf8');
|
|
const { frontmatter, content } = parseFrontmatter(raw);
|
|
|
|
// Resolve images: check dirPath/images.json first, then dirPath/images/ subfolder
|
|
let images = [];
|
|
const localImagesJsonPath = path.join(dirPath, 'images.json');
|
|
if (fs.existsSync(localImagesJsonPath)) {
|
|
images = JSON.parse(fs.readFileSync(localImagesJsonPath, 'utf8'));
|
|
} else {
|
|
const imagesDirPath = path.join(dirPath, 'images');
|
|
if (fs.existsSync(imagesDirPath)) {
|
|
const files = fs.readdirSync(imagesDirPath);
|
|
images = files.map(f => `/content-images/${slug}/${f}`);
|
|
}
|
|
}
|
|
|
|
const route = routeFromDir(slug);
|
|
pages[route] = { frontmatter, content, images };
|
|
}
|
|
|
|
function walkContent(dirPath, slug) {
|
|
processDir(dirPath, slug);
|
|
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
for (const entry of entries) {
|
|
if (!entry.isDirectory() || entry.name.startsWith('_')) continue;
|
|
const childSlug = slug ? `${slug}/${entry.name}` : entry.name;
|
|
walkContent(path.join(dirPath, entry.name), childSlug);
|
|
}
|
|
}
|
|
|
|
walkContent(CONTENT_DIR, '');
|
|
|
|
// --- Write output ---
|
|
const output = `// AUTO-GENERATED by scripts/build-content.js — do not edit by hand.
|
|
|
|
export const siteConfig = ${JSON.stringify(siteConfig, null, 2)};
|
|
|
|
export const pages = ${JSON.stringify(pages, null, 2)};
|
|
`;
|
|
|
|
fs.mkdirSync(path.dirname(OUTPUT_FILE), { recursive: true });
|
|
fs.writeFileSync(OUTPUT_FILE, output, 'utf8');
|
|
console.log(`[build-content] Generated ${OUTPUT_FILE}`);
|
|
console.log(`[build-content] Pages: ${Object.keys(pages).join(', ')}`);
|