UNPKG

@bernierllc/email-template-engine

Version:

Email template processing engine with compilation, rendering, and text generation

81 lines (79 loc) 2.61 kB
"use strict"; /* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.checkBalancedBraces = checkBalancedBraces; exports.checkUnclosedBlocks = checkUnclosedBlocks; exports.isBuiltInHelper = isBuiltInHelper; exports.inferVariableType = inferVariableType; /** * Check if template has balanced braces */ function checkBalancedBraces(template) { let count = 0; for (let i = 0; i < template.length; i++) { if (template[i] === '{' && template[i + 1] === '{') { count++; i++; // Skip next brace } else if (template[i] === '}' && template[i + 1] === '}') { count--; i++; // Skip next brace if (count < 0) { return { balanced: false, position: i }; } } } return { balanced: count === 0, position: count !== 0 ? template.length : undefined }; } /** * Check for unclosed block helpers */ function checkUnclosedBlocks(template) { const unclosed = []; const blockStack = []; const blockRegex = /\{\{#(\w+).*?\}\}|\{\{\/(\w+)\}\}/g; let match; while ((match = blockRegex.exec(template)) !== null) { if (match[1]) { // Opening block blockStack.push(match[1]); } else if (match[2]) { // Closing block const last = blockStack.pop(); if (last !== match[2]) { unclosed.push(match[2]); } } } // Any remaining blocks are unclosed return [...unclosed, ...blockStack]; } /** * Check if a variable name is a built-in Handlebars helper */ function isBuiltInHelper(variable) { const builtIns = ['if', 'unless', 'each', 'with', 'log', 'lookup', 'else']; const firstWord = variable.split(/[\s.]/)[0]; return builtIns.includes(firstWord); } /** * Infer variable type from path */ function inferVariableType(path) { // Simple heuristic based on variable name if (path.includes('.length') || path.includes('.count')) return 'number'; if (path.includes('.is') || path.includes('.has')) return 'boolean'; if (path.includes('.items') || path.includes('.list')) return 'array'; if (path.includes('.')) return 'object'; return 'string'; }