#!/usr/bin/env bun // Generates src/lib/templates.data.ts with embedded template file contents. // Run: bun run templates import { readdirSync, readFileSync, statSync } from 'fs' import { extname, join, relative } from 'path' const BINARY_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.ico', '.woff', '.woff2', '.ttf', '.eot', '.svg']) const TEMPLATES_DIR = join(import.meta.dir, '..', 'templates') const binary: Record> = {} const shared: Record = {} const templates: Record> = {} const isBinary = (path: string) => BINARY_EXTENSIONS.has(extname(path)) function readDir(dir: string): string[] { const files: string[] = [] for (const entry of readdirSync(dir)) { const path = join(dir, entry) if (statSync(path).isDirectory()) { files.push(...readDir(path)) } else { files.push(path) } } return files.sort() } // First pass: collect shared files (root level) for (const entry of readdirSync(TEMPLATES_DIR).sort()) { const path = join(TEMPLATES_DIR, entry) if (!statSync(path).isDirectory()) { shared[entry] = readFileSync(path, 'utf-8') } } // Second pass: build template maps with shared files folded in for (const entry of readdirSync(TEMPLATES_DIR).sort()) { const path = join(TEMPLATES_DIR, entry) if (statSync(path).isDirectory()) { templates[entry] = { ...shared } binary[entry] = {} for (const filePath of readDir(path)) { const filename = relative(path, filePath) if (isBinary(filePath)) { binary[entry]![filename] = readFileSync(filePath).toString('base64') } else { templates[entry]![filename] = readFileSync(filePath, 'utf-8') } } if (Object.keys(binary[entry]!).length === 0) { delete binary[entry] } } } // Generate TypeScript module const lines: string[] = [ '// Auto-generated by scripts/embed-templates.ts', '// Run `bun run templates` to regenerate', '', `export const TEMPLATES: Record> = ${JSON.stringify(templates, null, 2)}`, '', `export const BINARY: Record> = ${JSON.stringify(binary, null, 2)}`, '', ] const outPath = join(import.meta.dir, '..', 'src', 'lib', 'templates.data.ts') await Bun.write(outPath, lines.join('\n')) console.log(`✓ Embedded templates → ${relative(join(import.meta.dir, '..'), outPath)}`)