Add jsonata support to Change/Switch nodes

This commit is contained in:
Nick O'Leary
2016-11-10 23:58:34 +00:00
parent 89a05c580f
commit bf90509526
12 changed files with 2884 additions and 8 deletions

View File

@@ -502,6 +502,9 @@
"null":"is null",
"nnull":"is not null",
"else":"otherwise"
},
"errors": {
"invalid-expr": "Invalid expression: __error__"
}
},
"change": {

View File

@@ -64,7 +64,7 @@
var node = this;
var previousValueType = {value:"prev",label:this._("inject.previous"),hasValue:false};
$("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global']});
$("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global','jsonata']});
var operators = [
{v:"eq",t:"=="},
{v:"neq",t:"!="},
@@ -129,10 +129,10 @@
for (var d in operators) {
selectField.append($("<option></option>").val(operators[d].v).text(operators[d].t));
}
var valueField = $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num',previousValueType]});
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num',previousValueType]});
var valueField = $('<input/>',{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 btwnValueField = $('<input/>',{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 btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num',previousValueType]});
var btwnValue2Field = $('<input/>',{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 finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row);
finalspan.append(' &#8594; <span class="node-input-rule-index">'+(i+1)+'</span> ');
var caseSensitive = $('<input/>',{id:"node-input-rule-case-"+i,class:"node-input-rule-case",type:"checkbox",style:"width:auto;vertical-align:top"}).appendTo(row2);

View File

@@ -16,6 +16,9 @@
module.exports = function(RED) {
"use strict";
var jsonata = require('jsonata');
var operators = {
'eq': function(a, b) { return a == b; },
'neq': function(a, b) { return a != b; },
@@ -38,9 +41,20 @@ module.exports = function(RED) {
this.rules = n.rules || [];
this.property = n.property;
this.propertyType = n.propertyType || "msg";
if (this.propertyType === 'jsonata') {
try {
this.property = jsonata(this.property);
} catch(err) {
this.error(RED._("switch.errors.invalid-expr",{error:err.message}));
return;
}
}
this.checkall = n.checkall || "true";
this.previousValue = null;
var node = this;
var valid = true;
for (var i=0; i<this.rules.length; i+=1) {
var rule = this.rules[i];
if (!rule.vt) {
@@ -54,6 +68,13 @@ module.exports = function(RED) {
if (!isNaN(Number(rule.v))) {
rule.v = Number(rule.v);
}
} else if (rule.vt === "jsonata") {
try {
rule.v = jsonata(rule.v);
} catch(err) {
this.error(RED._("switch.errors.invalid-expr",{error:err.message}));
valid = false;
}
}
if (typeof rule.v2 !== 'undefined') {
if (!rule.v2t) {
@@ -65,14 +86,30 @@ module.exports = function(RED) {
}
if (rule.v2t === 'num') {
rule.v2 = Number(rule.v2);
} else if (rule.v2t === 'jsonata') {
try {
rule.v2 = jsonata(rule.v2);
} catch(err) {
this.error(RED._("switch.errors.invalid-expr",{error:err.message}));
valid = false;
}
}
}
}
if (!valid) {
return;
}
this.on('input', function (msg) {
var onward = [];
try {
var prop = RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
var prop;
if (node.propertyType === 'jsonata') {
prop = node.property.evaluate({msg:msg});
} else {
prop = RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
}
var elseflag = true;
for (var i=0; i<node.rules.length; i+=1) {
var rule = node.rules[i];
@@ -80,12 +117,26 @@ module.exports = function(RED) {
var v1,v2;
if (rule.vt === 'prev') {
v1 = node.previousValue;
} else if (rule.vt === 'jsonata') {
try {
v1 = rule.v.evaluate({msg:msg});
} catch(err) {
node.error(RED._("switch.errors.invalid-expr",{error:err.message}));
return;
}
} else {
v1 = RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);
}
v2 = rule.v2;
if (rule.v2t === 'prev') {
v2 = node.previousValue;
} else if (rule.v2t === 'jsonata') {
try {
v2 = rule.v2.evaluate({msg:msg});
} catch(err) {
node.error(RED._("switch.errors.invalid-expr",{error:err.message}));
return;
}
} else if (typeof v2 !== 'undefined') {
v2 = RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg);
}

View File

@@ -150,7 +150,7 @@
.appendTo(row2);
var propertyValue = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
.appendTo(row2)
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','date']});
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','date','jsonata']});
var row3_1 = $('<div/>').appendTo(row3);
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})

View File

@@ -16,6 +16,7 @@
module.exports = function(RED) {
"use strict";
var jsonata = require("jsonata");
function ChangeNode(n) {
RED.nodes.createNode(this, n);
@@ -85,6 +86,13 @@ module.exports = function(RED) {
}
} else if (rule.tot === 'bool') {
rule.to = /^true$/i.test(rule.to);
} else if (rule.tot === 'jsonata') {
try {
rule.to = jsonata(rule.to);
} catch(e) {
valid = false;
this.error(RED._("change.errors.invalid-from",{error:e.message}));
}
}
}
@@ -107,6 +115,8 @@ module.exports = function(RED) {
value = node.context().global.get(rule.to);
} else if (rule.tot === 'date') {
value = Date.now();
} else if (rule.tot === 'jsonata') {
value = rule.to.evaluate({msg:msg});
}
if (rule.t === 'change') {
if (rule.fromt === 'msg' || rule.fromt === 'flow' || rule.fromt === 'global') {