supa-seed
Version:
A constraint-aware, framework-agnostic database seeding framework with deep PostgreSQL business logic discovery and MakerKit integration support
276 lines • 10.2 kB
JavaScript
"use strict";
/**
* Template Engine
* Handles template processing and code generation
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateEngine = void 0;
exports.createTemplateEngine = createTemplateEngine;
exports.processTemplate = processTemplate;
exports.processTemplateFile = processTemplateFile;
const handlebars = __importStar(require("handlebars"));
const logger_1 = require("../../core/utils/logger");
class TemplateEngine {
constructor(options = {}) {
this.handlebars = handlebars.create();
this.options = {
helpers: {},
partials: {},
strictMode: false,
noEscape: false,
...options
};
this.registerBuiltinHelpers();
this.registerHelpers(this.options.helpers);
this.registerPartials(this.options.partials);
}
/**
* Process a template string with given context
*/
processTemplate(templateString, context) {
try {
const template = this.handlebars.compile(templateString, {
strict: this.options.strictMode,
noEscape: this.options.noEscape
});
const output = template(context);
return {
success: true,
output,
warnings: []
};
}
catch (error) {
logger_1.Logger.error(`Template processing failed: ${error.message}`);
return {
success: false,
error: error.message
};
}
}
/**
* Process template from file
*/
async processTemplateFile(filePath, context) {
try {
const fs = await Promise.resolve().then(() => __importStar(require('fs'))).then(m => m.promises);
const templateContent = await fs.readFile(filePath, 'utf-8');
return this.processTemplate(templateContent, context);
}
catch (error) {
logger_1.Logger.error(`Template file processing failed: ${error.message}`);
return {
success: false,
error: error.message
};
}
}
/**
* Register custom helpers
*/
registerHelpers(helpers) {
Object.entries(helpers).forEach(([name, helper]) => {
this.handlebars.registerHelper(name, helper);
});
}
/**
* Register partials
*/
registerPartials(partials) {
Object.entries(partials).forEach(([name, partial]) => {
this.handlebars.registerPartial(name, partial);
});
}
/**
* Register built-in helpers
*/
registerBuiltinHelpers() {
// String helpers
this.handlebars.registerHelper('uppercase', (str) => {
return str ? str.toUpperCase() : '';
});
this.handlebars.registerHelper('lowercase', (str) => {
return str ? str.toLowerCase() : '';
});
this.handlebars.registerHelper('capitalize', (str) => {
return str ? str.charAt(0).toUpperCase() + str.slice(1) : '';
});
this.handlebars.registerHelper('camelCase', (str) => {
return str ? str.replace(/[-_\s]+(.)?/g, (_, char) => char?.toUpperCase() || '') : '';
});
this.handlebars.registerHelper('kebabCase', (str) => {
return str ? str.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '') : '';
});
this.handlebars.registerHelper('snakeCase', (str) => {
return str ? str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '') : '';
});
// Array helpers
this.handlebars.registerHelper('join', (array, separator = ', ') => {
return Array.isArray(array) ? array.join(separator) : '';
});
this.handlebars.registerHelper('length', (array) => {
return Array.isArray(array) ? array.length : 0;
});
this.handlebars.registerHelper('first', (array) => {
return Array.isArray(array) && array.length > 0 ? array[0] : null;
});
this.handlebars.registerHelper('last', (array) => {
return Array.isArray(array) && array.length > 0 ? array[array.length - 1] : null;
});
// Conditional helpers
this.handlebars.registerHelper('eq', (a, b) => a === b);
this.handlebars.registerHelper('ne', (a, b) => a !== b);
this.handlebars.registerHelper('gt', (a, b) => a > b);
this.handlebars.registerHelper('gte', (a, b) => a >= b);
this.handlebars.registerHelper('lt', (a, b) => a < b);
this.handlebars.registerHelper('lte', (a, b) => a <= b);
// Logical helpers
this.handlebars.registerHelper('and', (...args) => {
const options = args.pop();
return args.every(Boolean);
});
this.handlebars.registerHelper('or', (...args) => {
const options = args.pop();
return args.some(Boolean);
});
this.handlebars.registerHelper('not', (value) => !value);
// Object helpers
this.handlebars.registerHelper('keys', (obj) => {
return obj ? Object.keys(obj) : [];
});
this.handlebars.registerHelper('values', (obj) => {
return obj ? Object.values(obj) : [];
});
// Date helpers
this.handlebars.registerHelper('now', () => new Date().toISOString());
this.handlebars.registerHelper('formatDate', (date, format = 'ISO') => {
const d = typeof date === 'string' ? new Date(date) : date;
if (!(d instanceof Date) || isNaN(d.getTime()))
return '';
switch (format) {
case 'ISO':
return d.toISOString();
case 'date':
return d.toDateString();
case 'time':
return d.toTimeString();
default:
return d.toString();
}
});
// Math helpers
this.handlebars.registerHelper('add', (a, b) => (a || 0) + (b || 0));
this.handlebars.registerHelper('subtract', (a, b) => (a || 0) - (b || 0));
this.handlebars.registerHelper('multiply', (a, b) => (a || 0) * (b || 0));
this.handlebars.registerHelper('divide', (a, b) => b !== 0 ? (a || 0) / b : 0);
// Utility helpers
this.handlebars.registerHelper('default', (value, defaultValue) => {
return value != null ? value : defaultValue;
});
this.handlebars.registerHelper('json', (obj) => {
try {
return JSON.stringify(obj, null, 2);
}
catch {
return '{}';
}
});
this.handlebars.registerHelper('debug', (obj) => {
console.log('Template Debug:', obj);
return '';
});
}
/**
* Create a new template engine instance with additional options
*/
extend(additionalOptions) {
const mergedOptions = {
helpers: { ...this.options.helpers, ...additionalOptions.helpers },
partials: { ...this.options.partials, ...additionalOptions.partials },
strictMode: additionalOptions.strictMode ?? this.options.strictMode,
noEscape: additionalOptions.noEscape ?? this.options.noEscape
};
return new TemplateEngine(mergedOptions);
}
/**
* Validate template syntax without processing
*/
validateTemplate(templateString) {
try {
this.handlebars.compile(templateString, {
strict: this.options.strictMode
});
return {
success: true,
warnings: []
};
}
catch (error) {
return {
success: false,
error: error.message
};
}
}
/**
* Get available helpers
*/
getHelpers() {
return Object.keys(this.handlebars.helpers);
}
/**
* Get available partials
*/
getPartials() {
return Object.keys(this.handlebars.partials);
}
}
exports.TemplateEngine = TemplateEngine;
// Export convenience functions
function createTemplateEngine(options) {
return new TemplateEngine(options);
}
function processTemplate(templateString, context, options) {
const engine = new TemplateEngine(options);
return engine.processTemplate(templateString, context);
}
async function processTemplateFile(filePath, context, options) {
const engine = new TemplateEngine(options);
return engine.processTemplateFile(filePath, context);
}
// Default export
exports.default = TemplateEngine;
//# sourceMappingURL=template-engine.js.map