From eb6d093e56ee2c8122ee0b08ca8bdfb41824cd7f Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 21 May 2018 15:10:06 +0100
Subject: [PATCH] Add env-var support to TypedInput
---
editor/images/typedInput/env.png | Bin 0 -> 809 bytes
editor/js/ui/common/typedInput.js | 5 +++
nodes/core/core/20-inject.html | 2 +-
nodes/core/logic/10-switch.html | 8 ++--
nodes/core/logic/15-change.html | 6 +--
nodes/core/logic/15-change.js | 2 +
red/runtime/util.js | 19 ++++++++
test/nodes/core/logic/15-change_spec.js | 56 +++++++++++++++++++++++-
test/red/runtime/util_spec.js | 32 ++++++++++++++
9 files changed, 121 insertions(+), 9 deletions(-)
create mode 100644 editor/images/typedInput/env.png
diff --git a/editor/images/typedInput/env.png b/editor/images/typedInput/env.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ea51da0023ac14d71b8c2c32bc976f01116cc0b
GIT binary patch
literal 809
zcmV+^1J?YBP)rcp@khRiULR=6-%Tr4HYQq=sp
z5tBbH%b${^T&!FeQBEr^q@+D9n&nU1>*lCmZ_oSg`MvKeCFknAr}KNi&pFTU`#tA@
zf88ee9uSd|AP8;+K~Nfo;Zxu9i7Xy+B~TCS&!)nJXLZFuh5ei=BIP1d;PW2^F+j?I
zgTOkVD&irBfhWLmRehclpor`RP6N|o7H|=0Rn?!~mqtVm0Ox?o77Br0;2BT@ddrHr~Z`PB2t?#z;rFWVCqt4E$tJL8^FzM
z1V5J2h)5N1-$0{m6lez?0&i3`nX{IfShoX*9L0&U_f~zUs=mufybX8(umNZ=j!w^T
zyE{zC$Fc@Y0j~${nU-F*DY7Ib?Gmsns?FI9;H0CaZK_%gtO6c6IXi*Id`o=yU"interval" option.
$("#node-input-payload").typedInput({
default: 'str',
typeField: $("#node-input-payloadType"),
- types:['flow','global','str','num','bool','json','bin','date']
+ types:['flow','global','str','num','bool','json','bin','date','env']
});
$("#inject-time-type-select").change(function() {
diff --git a/nodes/core/logic/10-switch.html b/nodes/core/logic/10-switch.html
index ffa5a48e5..f4ffc7dea 100644
--- a/nodes/core/logic/10-switch.html
+++ b/nodes/core/logic/10-switch.html
@@ -230,12 +230,12 @@
selectField.append($("").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
}
}
- var valueField = $('',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata',previousValueType]});
- var numValueField = $('',{class:"node-input-rule-num-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata']});
+ var valueField = $('',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
+ var numValueField = $('',{class:"node-input-rule-num-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']});
var expValueField = $('',{class:"node-input-rule-exp-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']});
- var btwnValueField = $('',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
+ var btwnValueField = $('',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
var btwnAndLabel = $('',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
- var btwnValue2Field = $('',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
+ var btwnValue2Field = $('',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
var typeValueField = $('',{class:"node-input-rule-type-value",type:"text",style:"margin-left: 5px;"}).appendTo(row)
.typedInput({default:'string',types:[
{value:"string",label:"string",hasValue:false},
diff --git a/nodes/core/logic/15-change.html b/nodes/core/logic/15-change.html
index 999c0ed71..83bdecf9e 100644
--- a/nodes/core/logic/15-change.html
+++ b/nodes/core/logic/15-change.html
@@ -146,7 +146,7 @@
.appendTo(row2);
var propertyValue = $('',{class:"node-input-rule-property-value",type:"text"})
.appendTo(row2)
- .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata']});
+ .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
var row3_1 = $('').appendTo(row3);
$('',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
@@ -154,7 +154,7 @@
.appendTo(row3_1);
var fromValue = $('',{class:"node-input-rule-property-search-value",type:"text"})
.appendTo(row3_1)
- .typedInput({default:'str',types:['msg','flow','global','str','re','num','bool']});
+ .typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']});
var row3_2 = $('',{style:"margin-top:8px;"}).appendTo(row3);
$('',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
@@ -162,7 +162,7 @@
.appendTo(row3_2);
var toValue = $('',{class:"node-input-rule-property-replace-value",type:"text"})
.appendTo(row3_2)
- .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin']});
+ .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
$('',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
.text(to)
diff --git a/nodes/core/logic/15-change.js b/nodes/core/logic/15-change.js
index ae50394ed..c7c05118e 100644
--- a/nodes/core/logic/15-change.js
+++ b/nodes/core/logic/15-change.js
@@ -93,6 +93,8 @@ module.exports = function(RED) {
valid = false;
this.error(RED._("change.errors.invalid-expr",{error:e.message}));
}
+ } else if (rule.tot === 'env') {
+ rule.to = RED.util.evaluateNodeProperty(rule.to,'env');
}
}
diff --git a/red/runtime/util.js b/red/runtime/util.js
index 88c06a029..1480a841a 100644
--- a/red/runtime/util.js
+++ b/red/runtime/util.js
@@ -303,6 +303,23 @@ function setMessageProperty(msg,prop,value,createMissing) {
}
}
+function evaluteEnvProperty(value) {
+ if (/^\${[^}]+}$/.test(value)) {
+ // ${ENV_VAR}
+ value = value.substring(2,value.length-1);
+ value = process.env.hasOwnProperty(value)?process.env[value]:""
+ } else if (!/\${\S+}/.test(value)) {
+ // ENV_VAR
+ value = process.env.hasOwnProperty(value)?process.env[value]:""
+ } else {
+ // FOO${ENV_VAR}BAR
+ value = value.replace(/\${([^}]+)}/g, function(match, v) {
+ return process.env.hasOwnProperty(v)?process.env[v]:""
+ });
+ }
+ return value;
+}
+
function evaluateNodeProperty(value, type, node, msg) {
if (type === 'str') {
return ""+value;
@@ -328,6 +345,8 @@ function evaluateNodeProperty(value, type, node, msg) {
} else if (type === 'jsonata') {
var expr = prepareJSONataExpression(value,node);
return evaluateJSONataExpression(expr,msg);
+ } else if (type === 'env') {
+ return evaluteEnvProperty(value);
}
return value;
}
diff --git a/test/nodes/core/logic/15-change_spec.js b/test/nodes/core/logic/15-change_spec.js
index f5ca0f3d2..e444b2663 100644
--- a/test/nodes/core/logic/15-change_spec.js
+++ b/test/nodes/core/logic/15-change_spec.js
@@ -390,7 +390,7 @@ describe('change Node', function() {
changeNode1.receive({payload:""});
});
});
-
+
it('sets the value of the message property to the current timestamp', function(done) {
var flow = [{"id":"changeNode1","type":"change","rules":[{"t":"set","p":"ts","pt":"msg","to":"","tot":"date"}],"name":"changeNode","wires":[["helperNode1"]]},
{id:"helperNode1", type:"helper", wires:[]}];
@@ -409,6 +409,33 @@ describe('change Node', function() {
});
});
+ describe('env var', function() {
+ before(function() {
+ process.env.NR_TEST_A = 'foo';
+ })
+ after(function() {
+ delete process.env.NR_TEST_A;
+ })
+ it('sets the value using env property', function(done) {
+ var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","pt":"msg","to":"NR_TEST_A","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
+ {id:"helperNode1", type:"helper", wires:[]}];
+ helper.load(changeNode, flow, function() {
+ var changeNode1 = helper.getNode("changeNode1");
+ var helperNode1 = helper.getNode("helperNode1");
+ helperNode1.on("input", function(msg) {
+ try {
+ msg.payload.should.equal("foo");
+ done();
+ } catch(err) {
+ done(err);
+ }
+ });
+ changeNode1.receive({payload:"123",topic:"ABC"});
+ });
+ });
+ });
+
+
it('changes the value using jsonata', function(done) {
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$length(payload)","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]]},
{id:"helperNode1", type:"helper", wires:[]}];
@@ -872,6 +899,33 @@ describe('change Node', function() {
changeNode1.receive({payload:""});
});
});
+
+ describe('env var', function() {
+ before(function() {
+ process.env.NR_TEST_A = 'foo';
+ })
+ after(function() {
+ delete process.env.NR_TEST_A;
+ })
+ it('changes the value using env property', function(done) {
+ var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"NR_TEST_A","fromt":"msg","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
+ {id:"helperNode1", type:"helper", wires:[]}];
+ helper.load(changeNode, flow, function() {
+ var changeNode1 = helper.getNode("changeNode1");
+ var helperNode1 = helper.getNode("helperNode1");
+ helperNode1.on("input", function(msg) {
+ try {
+ msg.payload.should.equal("abcfooabc");
+ done();
+ } catch(err) {
+ done(err);
+ }
+ });
+ changeNode1.receive({payload:"abcABCabc",topic:"ABC"});
+ });
+ });
+ });
+
});
describe("#delete", function() {
diff --git a/test/red/runtime/util_spec.js b/test/red/runtime/util_spec.js
index f542228a2..1b7438efd 100644
--- a/test/red/runtime/util_spec.js
+++ b/test/red/runtime/util_spec.js
@@ -307,6 +307,38 @@ describe("red/util", function() {
},{});
result.should.eql("123");
});
+ describe('environment variable', function() {
+ before(function() {
+ process.env.NR_TEST_A = "foo";
+ process.env.NR_TEST_B = "${NR_TEST_A}";
+ })
+ after(function() {
+ delete process.env.NR_TEST_A;
+ delete process.env.NR_TEST_B;
+ })
+
+ it('returns an environment variable - NR_TEST_A', function() {
+ var result = util.evaluateNodeProperty('NR_TEST_A','env');
+ result.should.eql('foo');
+ });
+ it('returns an environment variable - ${NR_TEST_A}', function() {
+ var result = util.evaluateNodeProperty('${NR_TEST_A}','env');
+ result.should.eql('foo');
+ });
+ it('returns an environment variable - ${NR_TEST_A', function() {
+ var result = util.evaluateNodeProperty('${NR_TEST_A','env');
+ result.should.eql('');
+ });
+ it('returns an environment variable - foo${NR_TEST_A}bar', function() {
+ var result = util.evaluateNodeProperty('123${NR_TEST_A}456','env');
+ result.should.eql('123foo456');
+ });
+ it('returns an environment variable - foo${NR_TEST_B}bar', function() {
+ var result = util.evaluateNodeProperty('123${NR_TEST_B}456','env');
+ result.should.eql('123${NR_TEST_A}456');
+ });
+
+ });
});
describe('normalisePropertyExpression', function() {