Clone the first message passed to node.send in Function

Also introduces an optional second arg to node.send in the Function
node that can disable that cloning
This commit is contained in:
Nick O'Leary 2019-09-12 22:08:52 +01:00
parent 89d0d6ec93
commit f0839571d0
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
2 changed files with 59 additions and 5 deletions

View File

@ -19,7 +19,7 @@ module.exports = function(RED) {
var util = require("util");
var vm = require("vm");
function sendResults(node,send,_msgid,msgs) {
function sendResults(node,send,_msgid,msgs,cloneFirstMessage) {
if (msgs == null) {
return;
} else if (!util.isArray(msgs)) {
@ -35,6 +35,10 @@ module.exports = function(RED) {
var msg = msgs[m][n];
if (msg !== null && msg !== undefined) {
if (typeof msg === 'object' && !Buffer.isBuffer(msg) && !util.isArray(msg)) {
if (msgCount === 0 && cloneFirstMessage !== false) {
msgs[m][n] = RED.util.cloneMessage(msgs[m][n]);
msg = msgs[m][n];
}
msg._msgid = _msgid;
msgCount++;
} else {
@ -80,7 +84,7 @@ module.exports = function(RED) {
"trace:__node__.trace,"+
"on:__node__.on,"+
"status:__node__.status,"+
"send:function(msgs){ __node__.send(__send__,__msgid__,msgs);},"+
"send:function(msgs,cloneMsg){ __node__.send(__send__,__msgid__,msgs,cloneMsg);},"+
"done:__done__"+
"};\n"+
this.func+"\n"+
@ -114,8 +118,8 @@ module.exports = function(RED) {
trace: function() {
node.trace.apply(node, arguments);
},
send: function(send, id, msgs) {
sendResults(node, send, id, msgs);
send: function(send, id, msgs, cloneMsg) {
sendResults(node, send, id, msgs, cloneMsg);
},
on: function() {
if (arguments[0] === "input") {
@ -241,7 +245,7 @@ module.exports = function(RED) {
context.done = done;
this.script.runInContext(context);
sendResults(this,send,msg._msgid,context.results);
sendResults(this,send,msg._msgid,context.results,false);
if (handleNodeDoneCall) {
done();
}

View File

@ -93,6 +93,56 @@ describe('function node', function() {
});
});
function testSendCloning(args,done) {
var flow = [{id:"n1",type:"function",wires:[["n2"],["n2"]],func:"node.send("+args+"); msg.payload = 'changed';"},
{id:"n2", type:"helper"}];
helper.load(functionNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
try {
msg.should.have.property('topic', 'bar');
msg.should.have.property('payload', 'foo');
done();
} catch(err) {
done(err);
}
});
var origMessage = {payload:"foo",topic: "bar"};
n1.receive(origMessage);
});
}
it('should clone single message sent using send()', function(done) {
testSendCloning("msg",done);
});
it('should not clone single message sent using send(,false)', function(done) {
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.send(msg,false); msg.payload = 'changed';"},
{id:"n2", type:"helper"}];
helper.load(functionNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('topic', 'bar');
msg.should.have.property('payload', 'changed');
done();
});
var origMessage = {payload:"foo",topic: "bar"};
n1.receive(origMessage);
});
});
it('should clone first message sent using send() - array 1', function(done) {
testSendCloning("[msg]",done);
});
it('should clone first message sent using send() - array 2', function(done) {
testSendCloning("[[msg],[null]]",done);
});
it('should clone first message sent using send() - array 3', function(done) {
testSendCloning("[null,msg]",done);
});
it('should clone first message sent using send() - array 3', function(done) {
testSendCloning("[null,[msg]]",done);
});
it('should pass through _topic', function(done) {
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"},
{id:"n2", type:"helper"}];