74 lines
2.0 KiB
TypeScript
74 lines
2.0 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 TemplateOptions {
|
|
tool?: boolean
|
|
}
|
|
|
|
interface TemplateVars {
|
|
APP_EMOJI: string
|
|
APP_NAME: string
|
|
}
|
|
|
|
const SHARED_FILES = ['.gitignore', '.npmrc', 'package.json', 'tsconfig.json']
|
|
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', options: TemplateOptions = {}): AppTemplates {
|
|
const vars: TemplateVars = {
|
|
APP_EMOJI: DEFAULT_EMOJI,
|
|
APP_NAME: appName,
|
|
}
|
|
|
|
const result: AppTemplates = {}
|
|
|
|
// Read shared files from templates/
|
|
for (const filename of SHARED_FILES) {
|
|
const path = join(TEMPLATES_DIR, filename)
|
|
let content = readFileSync(path, 'utf-8')
|
|
content = replaceVars(content, vars)
|
|
|
|
// Add tool option to package.json if specified
|
|
if (filename === 'package.json' && options.tool) {
|
|
const pkg = JSON.parse(content)
|
|
pkg.toes.tool = true
|
|
content = JSON.stringify(pkg, null, 2) + '\n'
|
|
}
|
|
|
|
result[filename] = content
|
|
}
|
|
|
|
// 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
|
|
}
|