From b2f06b6777acba3de5e70efe969c355450dfcbc1 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 9 Jul 2018 15:12:09 +0100 Subject: [PATCH] Add async mode to evaluateJSONataExpression --- red/runtime/util.js | 33 +++++++++++++++++++++++++++++++-- test/red/runtime/util_spec.js | 24 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/red/runtime/util.js b/red/runtime/util.js index f4c0e1fa7..b6a5a7e7b 100644 --- a/red/runtime/util.js +++ b/red/runtime/util.js @@ -394,15 +394,44 @@ function prepareJSONataExpression(value,node) { }) expr.registerFunction('clone', cloneMessage, '<(oa)-:o>'); expr._legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(value); + expr._node = node; return expr; } -function evaluateJSONataExpression(expr,msg) { +function evaluateJSONataExpression(expr,msg,callback) { var context = msg; if (expr._legacyMode) { context = {msg:msg}; } - return expr.evaluate(context); + var bindings = {}; + + if (callback) { + // If callback provided, need to override the pre-assigned sync + // context functions to be their async variants + bindings.flowContext = function(val) { + return new Promise((resolve,reject) => { + expr._node.context().flow.get(val, function(err,value) { + if (err) { + reject(err); + } else { + resolve(value); + } + }) + }); + } + bindings.globalContext = function(val) { + return new Promise((resolve,reject) => { + expr._node.context().global.get(val, function(err,value) { + if (err) { + reject(err); + } else { + resolve(value); + } + }) + }); + } + } + return expr.evaluate(context, bindings, callback); } diff --git a/test/red/runtime/util_spec.js b/test/red/runtime/util_spec.js index f7bd3e950..1be194f42 100644 --- a/test/red/runtime/util_spec.js +++ b/test/red/runtime/util_spec.js @@ -458,6 +458,30 @@ describe("red/util", function() { var result = util.evaluateJSONataExpression(expr,{payload:"hello"}); should.not.exist(result); }); + it('handles async flow context access', function(done) { + var expr = util.prepareJSONataExpression('$flowContext("foo")',{context:function() { return {flow:{get: function(key,callback) { setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}}); + util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) { + try { + should.not.exist(err); + value.should.eql("bar"); + done(); + } catch(err2) { + done(err2); + } + }); + }) + it('handles async global context access', function(done) { + var expr = util.prepareJSONataExpression('$globalContext("foo")',{context:function() { return {global:{get: function(key,callback) { setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}}); + util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) { + try { + should.not.exist(err); + value.should.eql("bar"); + done(); + } catch(err2) { + done(err2); + } + }); + }) });