toes/src/lib/templates.ts
2026-01-30 15:26:58 -08:00

60 lines
1.6 KiB
TypeScript

import { DEFAULT_EMOJI } from '@types'
import { readdirSync, readFileSync, statSync } from 'fs'
import { join, relative } from 'path'
export type TemplateType = 'ssr' | 'bare' | 'spa'
export type AppTemplates = Record<string, string>
interface TemplateVars {
APP_EMOJI: string
APP_NAME: string
}
const TEMPLATES_DIR = join(import.meta.dir, '../../templates')
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
}
function replaceVars(content: string, vars: TemplateVars): string {
return content
.replace(/\$\$APP_NAME\$\$/g, vars.APP_NAME)
.replace(/\$\$APP_EMOJI\$\$/g, vars.APP_EMOJI)
}
export function generateTemplates(appName: string, template: TemplateType = 'ssr'): AppTemplates {
const vars: TemplateVars = {
APP_EMOJI: DEFAULT_EMOJI,
APP_NAME: appName,
}
const result: AppTemplates = {}
// Read shared files from templates/
for (const filename of ['.npmrc', 'package.json', 'tsconfig.json']) {
const path = join(TEMPLATES_DIR, filename)
const content = readFileSync(path, 'utf-8')
result[filename] = replaceVars(content, vars)
}
// Read template-specific files
const templateDir = join(TEMPLATES_DIR, template)
for (const path of readDir(templateDir)) {
const filename = relative(templateDir, path)
const content = readFileSync(path, 'utf-8')
result[filename] = replaceVars(content, vars)
}
return result
}