Template variable extraction ignores functions
This commit is contained in:
@@ -7,50 +7,46 @@ export class TemplateError extends BadRequestError { }
|
||||
|
||||
export function findTemplateVars(html: string): Record<string, any> {
|
||||
const variables = new Set<string>();
|
||||
const arrays = new Set<string>();
|
||||
const excluded = new Set<string>(['true', 'false', 'null', 'undefined']);
|
||||
|
||||
// Extract & exclude loop variables
|
||||
// Extract & exclude loop variables, mark arrays
|
||||
for (const loop of matchAll(html, /\{\{\s*?\*\s*?(.+?)\s+in\s+(.+?)\s*?}}/g)) {
|
||||
const [element, index = 'index'] = loop[1].replaceAll(/[()\s]/g, '').split(',');
|
||||
excluded.add(element);
|
||||
excluded.add(index);
|
||||
// Add the array reference (but exclude if it's a loop variable)
|
||||
const arrayRef = loop[2].trim();
|
||||
const arrayVar = arrayRef.split('.')[0].match(/^[a-zA-Z_$][a-zA-Z0-9_$]*/)?.[0];
|
||||
if (arrayVar && !excluded.has(arrayVar)) variables.add(arrayVar);
|
||||
const arrayVar = loop[2].trim();
|
||||
const root = arrayVar.split('.')[0];
|
||||
if (!excluded.has(root)) {
|
||||
variables.add(arrayVar);
|
||||
arrays.add(arrayVar);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract variables from if/else-if conditions
|
||||
for (const ifStmt of matchAll(html, /\{\{\s*?[!]?\?\s*?([^}]+?)\s*?}}/g)) {
|
||||
const code = ifStmt[1].replace(/["'`][^"'`]*["'`]/g, ''); // Remove string literals
|
||||
const vars = code.match(/[a-zA-Z_$][a-zA-Z0-9_$.]+/g) || [];
|
||||
const code = ifStmt[1].replace(/["'`][^"'`]*["'`]/g, '');
|
||||
const cleaned = code.replace(/([a-zA-Z_$][a-zA-Z0-9_$.]*)\s*\(/g, (_, v) => {
|
||||
const parts = v.split('.');
|
||||
return parts.length > 1 ? parts.slice(0, -1).join('.') + ' ' : '';
|
||||
});
|
||||
const vars = cleaned.match(/[a-zA-Z_$][a-zA-Z0-9_$.]+/g) || [];
|
||||
for (const v of vars) {
|
||||
const root = v.split('.')[0];
|
||||
if (!excluded.has(root)) variables.add(root);
|
||||
if (!excluded.has(root)) variables.add(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract variables from content within if blocks
|
||||
for (const ifBlock of matchAll(html, /\{\{\s*?\?\s*?.+?\s*?}}([\s\S]*?)\{\{\s*?\/\?\s*?}}/g)) {
|
||||
const content = ifBlock[1];
|
||||
const regex = /\{\{\s*([^<>\*\?!/}\s][^}]*?)\s*}}/g;
|
||||
let match;
|
||||
while ((match = regex.exec(content)) !== null) {
|
||||
const code = match[1].trim().replace(/["'`][^"'`]*["'`]/g, '');
|
||||
const vars = code.match(/[a-zA-Z_$][a-zA-Z0-9_$.]+/g) || [];
|
||||
for (const v of vars) {
|
||||
const root = v.split('.')[0];
|
||||
if (!excluded.has(root)) variables.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract variables from regular interpolations
|
||||
// Extract from if block content & regular interpolations
|
||||
const regex = /\{\{\s*([^<>\*\?!/}\s][^}]*?)\s*}}/g;
|
||||
let match;
|
||||
while ((match = regex.exec(html)) !== null) {
|
||||
const code = match[1].trim().replace(/["'`][^"'`]*["'`]/g, '');
|
||||
const vars = code.match(/[a-zA-Z_$][a-zA-Z0-9_$.]+/g) || [];
|
||||
const cleaned = code.replace(/([a-zA-Z_$][a-zA-Z0-9_$.]*)\s*\(/g, (_, v) => {
|
||||
const parts = v.split('.');
|
||||
return parts.length > 1 ? parts.slice(0, -1).join('.') + ' ' : '';
|
||||
});
|
||||
const vars = cleaned.match(/[a-zA-Z_$][a-zA-Z0-9_$.]+/g) || [];
|
||||
for (const v of vars) {
|
||||
const root = v.split('.')[0];
|
||||
if (!excluded.has(root)) variables.add(v);
|
||||
@@ -64,7 +60,8 @@ export function findTemplateVars(html: string): Record<string, any> {
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i];
|
||||
if (i === parts.length - 1) {
|
||||
current[part] = '';
|
||||
const fullPath = parts.slice(0, i + 1).join('.');
|
||||
current[part] = arrays.has(fullPath) ? [] : '';
|
||||
} else {
|
||||
current[part] = current[part] || {};
|
||||
current = current[part];
|
||||
|
||||
Reference in New Issue
Block a user