learning_ai_common_plat/packages/create-app/src/lib/template-engine.ts
saravanakumardb1 6354711f97 feat(create-app): add CLI Scaffolder (3.1) — interactive product repo generator
Scaffolder (scaffolder.ts):
- Interactive prompts: product name/ID/tagline/domain, port, platforms, features
- --from product.json flag to skip prompts (non-interactive)
- --dry-run preview mode
- Generates backend (always) + web (Next.js) + mobile (Expo) based on selection
- Template engine with {{VARIABLE}} and {{#IF FEATURE}} conditional blocks
- Backend scaffold: Fastify 5, Zod config, JWT auth, datastore, server.ts
- Web scaffold: Next.js 16 App Router, layout, page, product-config
- Mobile scaffold: Expo with app.json, index screen
- Root files: product.json, .gitignore, .env.example, README.md

Tests: 26 passing (11 template-engine + 15 scaffolder)
Tested with ActionTrail product.json dry-run — correct output
2026-03-19 20:31:35 -07:00

35 lines
1.1 KiB
TypeScript

/**
* Simple template engine for scaffolding.
* Supports {{VARIABLE}} replacement and {{#IF FEATURE}}...{{/IF FEATURE}} conditional blocks.
*/
export type TemplateVars = Record<string, string | boolean | number>;
/**
* Replace {{VARIABLE}} placeholders and process {{#IF FEATURE}}...{{/IF FEATURE}} blocks.
*/
export function renderTemplate(template: string, vars: TemplateVars): string {
let result = template;
// Process conditional blocks: {{#IF KEY}}...{{/IF KEY}}
const ifRegex = /\{\{#IF (\w+)\}\}([\s\S]*?)\{\{\/IF \1\}\}/g;
result = result.replace(ifRegex, (_, key: string, content: string) => {
return vars[key] ? content : '';
});
// Process negative conditional blocks: {{#UNLESS KEY}}...{{/UNLESS KEY}}
const unlessRegex = /\{\{#UNLESS (\w+)\}\}([\s\S]*?)\{\{\/UNLESS \1\}\}/g;
result = result.replace(unlessRegex, (_, key: string, content: string) => {
return !vars[key] ? content : '';
});
// Replace {{VARIABLE}} placeholders
result = result.replace(/\{\{(\w+)\}\}/g, (match, key: string) => {
const val = vars[key];
if (val === undefined) return match;
return String(val);
});
return result;
}