|
|
@@ -3344,47 +3344,6 @@ static std::string convertReservedWordAccess(const std::string& expression) {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-// Legacy compatibility shim: rewrites the pre-existing "data.loop.item"
|
|
|
-// convention into the bare "item" identifier before evaluation.
|
|
|
-// e.g., "data.loop.item.hasAttachments" -> "item.hasAttachments"
|
|
|
-//
|
|
|
-// This is purely textual - it does not consult any real object path, and
|
|
|
-// "data.loop" is not a nested field that actually exists anywhere in the
|
|
|
-// data an expression sees. It survives only because live workflows already
|
|
|
-// depend on the "data.loop.item" spelling; new work should address the loop
|
|
|
-// item through the real "loop" object the engine now attaches to every loop
|
|
|
-// body node's input (const loop = input.loop, below), which is a genuine
|
|
|
-// nested JSON value and does not need this rewrite.
|
|
|
-static std::string simplifyLoopVariablePaths(const std::string& expression) {
|
|
|
- // Loop variables that should be simplified
|
|
|
- static const std::vector<std::string> loop_vars = {
|
|
|
- "item", "index", "currentItem", "currentIndex", "totalItems", "isFirst", "isLast"
|
|
|
- };
|
|
|
-
|
|
|
- std::string result = expression;
|
|
|
-
|
|
|
- for (const auto& var : loop_vars) {
|
|
|
- // Pattern: data.loop.var -> var
|
|
|
- std::string full_path = "data.loop." + var;
|
|
|
- size_t pos = 0;
|
|
|
-
|
|
|
- while ((pos = result.find(full_path, pos)) != std::string::npos) {
|
|
|
- // Check if this is at the start or preceded by a non-identifier char
|
|
|
- bool valid_start = (pos == 0) ||
|
|
|
- (!std::isalnum(result[pos - 1]) && result[pos - 1] != '_');
|
|
|
-
|
|
|
- if (valid_start) {
|
|
|
- // Replace data.loop.var with just var
|
|
|
- result.replace(pos, full_path.length(), var);
|
|
|
- pos += var.length();
|
|
|
- } else {
|
|
|
- pos += full_path.length();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
|
|
|
nlohmann::json WorkflowEngine::evaluateJavaScriptExpression(
|
|
|
const std::string& expression,
|
|
|
@@ -3392,11 +3351,8 @@ nlohmann::json WorkflowEngine::evaluateJavaScriptExpression(
|
|
|
const std::unordered_map<std::string, NodeExecutionResult>& results,
|
|
|
const Workflow& workflow) {
|
|
|
|
|
|
- // Simplify loop variable paths (data.loop.item -> item)
|
|
|
- std::string simplified_expression = simplifyLoopVariablePaths(expression);
|
|
|
-
|
|
|
// Convert reserved word property access to bracket notation
|
|
|
- std::string safe_expression = convertReservedWordAccess(simplified_expression);
|
|
|
+ std::string safe_expression = convertReservedWordAccess(expression);
|
|
|
|
|
|
// Debug logging for expression transformation
|
|
|
if (expression != safe_expression) {
|