import jsep from 'jsep'; import { ColumnType } from './Api'; export function substituteColumnIdWithAliasInFormula( formula, columns: ColumnType[], rawFormula? ) { const substituteId = (pt: any, ptRaw?: any) => { if (pt.type === 'CallExpression') { let i = 0; for (const arg of pt.arguments || []) { substituteId(arg, ptRaw?.arguments?.[i++]); } } else if (pt.type === 'Literal') { return; } else if (pt.type === 'Identifier') { const colNameOrId = pt?.name; const column = columns.find( (c) => c.id === colNameOrId || c.column_name === colNameOrId || c.title === colNameOrId ); pt.name = column?.title || ptRaw?.name || pt?.name; if (pt.name[0] != '$' && pt.name[pt.name.length - 1] != '$') { pt.name = '$' + pt.name + '$'; } } else if (pt.type === 'BinaryExpression') { substituteId(pt.left, ptRaw?.left); substituteId(pt.right, ptRaw?.right); } }; const parsedFormula = jsep(formula); const parsedRawFormula = rawFormula && jsep(rawFormula); substituteId(parsedFormula, parsedRawFormula); return jsepTreeToFormula(parsedFormula); } export function jsepTreeToFormula(node) { if (node.type === 'BinaryExpression' || node.type === 'LogicalExpression') { return ( '(' + jsepTreeToFormula(node.left) + ' ' + node.operator + ' ' + jsepTreeToFormula(node.right) + ')' ); } if (node.type === 'UnaryExpression') { return node.operator + jsepTreeToFormula(node.argument); } if (node.type === 'MemberExpression') { return ( jsepTreeToFormula(node.object) + '[' + jsepTreeToFormula(node.property) + ']' ); } if (node.type === 'Identifier') { return node.name; } if (node.type === 'Literal') { if (typeof node.value === 'string') { return '"' + node.value + '"'; } return '' + node.value; } if (node.type === 'CallExpression') { return ( jsepTreeToFormula(node.callee) + '(' + node.arguments.map(jsepTreeToFormula).join(', ') + ')' ); } if (node.type === 'ArrayExpression') { return '[' + node.elements.map(jsepTreeToFormula).join(', ') + ']'; } if (node.type === 'Compound') { return node.body.map((e) => jsepTreeToFormula(e)).join(' '); } if (node.type === 'ConditionalExpression') { return ( jsepTreeToFormula(node.test) + ' ? ' + jsepTreeToFormula(node.consequent) + ' : ' + jsepTreeToFormula(node.alternate) ); } return ''; }