MCPcopy Create free account
hub / github.com/ForestHubAI/edge-agents / parseExpression

Function parseExpression

ts/workflow-core/src/expression/parser.ts:22–95  ·  view source on GitHub ↗
(expr: ResolvedExpr)

Source from the content-addressed store, hash-verified

20 * infers types from the AST, and validates against the expected type.
21 */
22export function parseExpression(expr: ResolvedExpr): ParseResult {
23 // Handle early returns
24 if (!expr.expression.trim()) {
25 return { isValid: false, inferredType: null, errors: ["Expression is empty"] };
26 }
27 if (expr.variables.some((v) => v === null)) {
28 return { isValid: false, inferredType: null, errors: ["Expression contains stale variable references"] };
29 }
30
31 const errors: string[] = [];
32
33 // 1. Build type context from variables
34 const typeContext: TypeContext = new Map();
35
36 // Replace ${} placeholders with temp identifiers for jsep
37 let parsableExpr = expr.expression;
38
39 // Count placeholders in expression
40 const placeholderCount = (expr.expression.match(/\$\{\}/g) || []).length;
41
42 if (placeholderCount !== expr.variables.length) {
43 errors.push(`Placeholder count (${placeholderCount}) doesn't match reference count (${expr.variables.length})`);
44 return { isValid: false, inferredType: null, errors };
45 }
46
47 expr.variables.forEach((variable, i) => {
48 const placeholder = `__var${i}__`;
49 parsableExpr = parsableExpr.replace("${}", placeholder);
50
51 if (variable) {
52 typeContext.set(placeholder, variable.dataType);
53 } else {
54 // Stale reference - variable was deleted
55 errors.push(`Referenced variable at position ${i + 1} not found`);
56 }
57 });
58
59 // If we have stale/null variables, don't proceed with parsing
60 if (errors.length > 0) {
61 return { isValid: false, inferredType: null, errors };
62 }
63
64 // 2. For string-type expressions, auto-wrap bare text as string literals
65 // so users don't need to type quotes. E.g. `hello __var0__` → `"hello " + __var0__`
66 if (expr.expectedType === "string") {
67 parsableExpr = wrapStringTemplate(parsableExpr);
68 }
69
70 // 3. Parse with jsep
71 let ast: jsep.Expression;
72 try {
73 ast = jsep(parsableExpr);
74 } catch (e) {
75 const message = e instanceof Error ? e.message : String(e);
76 return { isValid: false, inferredType: null, errors: [`Parse error: ${message}`] };
77 }
78
79 // 4. Infer type by walking AST

Callers 4

BaseNode.tsxFile · 0.90
computeNodeDiagnosticsFunction · 0.90
computeEdgeDiagnosticsFunction · 0.90
validateFunctionOutputsFunction · 0.90

Calls 3

wrapStringTemplateFunction · 0.85
inferTypeFunction · 0.85
isCompatibleFunction · 0.85

Tested by

no test coverage detected