import yaml from "js-yaml"; export interface DocEntry { tag: string; icon: string; title: string; description: string; syntax: string; props: { name: string; type: string; default?: string; desc: string }[]; /** Markdown body (everything after frontmatter ---) */ body: string; } /** Splits frontmatter and markdown body from a raw .md string. */ function parseFrontmatter(raw: string): Record | null { const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/); if (!match) return null; try { return yaml.load(match[1]) as Record; } catch { return null; } } function getBody(raw: string): string { const match = raw.match(/^---\n[\s\S]*?\n---\n?([\s\S]*)$/); return match ? match[1] : raw; } /** Glob import all .md files in src/doc-entries/ */ const modules = import.meta.webpackContext("./", { recursive: false, regExp: /\.md$/, }); /** Lazy-loaded doc entries, parsed on first access. */ let _entries: DocEntry[] | null = null; export function loadDocEntries(): DocEntry[] { if (_entries) return _entries; const entries: DocEntry[] = []; for (const key of modules.keys()) { const mod = modules(key); const raw = typeof mod === "string" ? mod : ((mod as { default?: string }).default ?? ""); if (!raw) continue; const fm = parseFrontmatter(raw); if (!fm) continue; const body = getBody(raw); entries.push({ tag: fm.tag as string, icon: fm.icon as string, title: fm.title as string, description: fm.description as string, syntax: fm.syntax as string, props: (fm.props as DocEntry["props"]) ?? [], body, }); } // Sort alphabetically by tag entries.sort((a, b) => a.tag.localeCompare(b.tag)); _entries = entries; return entries; } /** * Direct static array for the DocDialog sidebar — uses webpackContext * so all .md files in doc-entries/ are bundled automatically. */ export const docEntries = loadDocEntries();