diff --git a/Gruntfile.js b/Gruntfile.js index 2a1506186..b9c962c87 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -168,8 +168,8 @@ module.exports = function(grunt) { // TODO: resolve relative resource paths in // bootstrap/FA/jquery ], - "public/vendor/jsonata/jsonata.js": [ - "node_modules/jsonata/jsonata.js", + "public/vendor/jsonata/jsonata.min.js": [ + "node_modules/jsonata/jsonata.min.js", "editor/vendor/jsonata/formatter.js" ] } @@ -180,7 +180,6 @@ module.exports = function(grunt) { files: { 'public/red/red.min.js': 'public/red/red.js', 'public/red/main.min.js': 'public/red/main.js', - 'public/vendor/jsonata/jsonata.min.js': 'public/vendor/jsonata/jsonata.js', 'public/vendor/ace/mode-jsonata.js': 'editor/vendor/jsonata/mode-jsonata.js', 'public/vendor/ace/worker-jsonata.js': 'editor/vendor/jsonata/worker-jsonata.js', 'public/vendor/ace/snippets/jsonata.js': 'editor/vendor/jsonata/snippets-jsonata.js' diff --git a/editor/vendor/jsonata/formatter.js b/editor/vendor/jsonata/formatter.js index 80c83b4bb..2ef4ecfb0 100644 --- a/editor/vendor/jsonata/formatter.js +++ b/editor/vendor/jsonata/formatter.js @@ -111,8 +111,11 @@ '$average':{ args:['value'] }, '$boolean':{ args:['value'] }, '$contains':{ args:['str','pattern']}, + '$context': {args:['string']}, '$count':{ args:['array'] }, '$exists':{ args:['value'] }, + '$flow': {args:['string']}, + '$global': {args:['string']}, '$join':{ args:['array','separator'] }, '$keys':{ args:['object'] }, '$length':{ args:['string'] }, diff --git a/nodes/core/logic/10-switch.js b/nodes/core/logic/10-switch.js index 1eeffdd47..4cd1b6151 100644 --- a/nodes/core/logic/10-switch.js +++ b/nodes/core/logic/10-switch.js @@ -17,8 +17,6 @@ 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; }, @@ -44,7 +42,7 @@ module.exports = function(RED) { if (this.propertyType === 'jsonata') { try { - this.property = jsonata(this.property); + this.property = RED.util.prepareJSONataExpression(this.property,this); } catch(err) { this.error(RED._("switch.errors.invalid-expr",{error:err.message})); return; @@ -70,7 +68,7 @@ module.exports = function(RED) { } } else if (rule.vt === "jsonata") { try { - rule.v = jsonata(rule.v); + rule.v = RED.util.prepareJSONataExpression(rule.v,node); } catch(err) { this.error(RED._("switch.errors.invalid-expr",{error:err.message})); valid = false; @@ -88,7 +86,7 @@ module.exports = function(RED) { rule.v2 = Number(rule.v2); } else if (rule.v2t === 'jsonata') { try { - rule.v2 = jsonata(rule.v2); + rule.v2 = RED.util.prepareJSONataExpression(rule.v2,node); } catch(err) { this.error(RED._("switch.errors.invalid-expr",{error:err.message})); valid = false; diff --git a/nodes/core/logic/15-change.js b/nodes/core/logic/15-change.js index 822124b8e..fc28337b2 100644 --- a/nodes/core/logic/15-change.js +++ b/nodes/core/logic/15-change.js @@ -16,7 +16,6 @@ module.exports = function(RED) { "use strict"; - var jsonata = require("jsonata"); function ChangeNode(n) { RED.nodes.createNode(this, n); @@ -88,7 +87,7 @@ module.exports = function(RED) { rule.to = /^true$/i.test(rule.to); } else if (rule.tot === 'jsonata') { try { - rule.to = jsonata(rule.to); + rule.to = RED.util.prepareJSONataExpression(rule.to,this); } catch(e) { valid = false; this.error(RED._("change.errors.invalid-from",{error:e.message})); diff --git a/red/api/locales/en-US/jsonata.json b/red/api/locales/en-US/jsonata.json index 4b018e63e..d7ce59c91 100644 --- a/red/api/locales/en-US/jsonata.json +++ b/red/api/locales/en-US/jsonata.json @@ -109,7 +109,18 @@ "$spread": { "args": "object", "desc": "Splits an object containing key/value pairs into an array of objects, each of which has a single key/value pair from the input object. If the parameter is an array of objects, then the resultant array contains an object for every key/value pair in every object in the supplied array." + }, + + "$context": { + "args": "string", + "desc": "Retrieves a node context property." + }, + "$flow": { + "args": "string", + "desc": "Retrieves a flow context property." + }, + "$global": { + "args": "string", + "desc": "Retrieves a global context property." } - - } diff --git a/red/runtime/util.js b/red/runtime/util.js index 55c3d8a57..921f7e521 100644 --- a/red/runtime/util.js +++ b/red/runtime/util.js @@ -323,11 +323,25 @@ function evaluateNodeProperty(value, type, node, msg) { } else if (type === 'bool') { return /^true$/i.test(value); } else if (type === 'jsonata') { - return jsonata(value).evaluate({msg:msg}); + return prepareJSONataExpression(value,node).evaluate({msg:msg}); } return value; } +function prepareJSONataExpression(value,node) { + var expr = jsonata(value); + expr.assign('context',function(val) { + return node.context().get(val); + }); + expr.assign('flow',function(val) { + return node.context().flow.get(val); + }); + expr.assign('global',function(val) { + return node.context().global(val); + }); + return expr; +} + function normaliseNodeTypeName(name) { var result = name.replace(/[^a-zA-Z0-9]/g, " "); result = result.trim(); @@ -351,5 +365,6 @@ module.exports = { setMessageProperty: setMessageProperty, evaluateNodeProperty: evaluateNodeProperty, normalisePropertyExpression: normalisePropertyExpression, - normaliseNodeTypeName: normaliseNodeTypeName + normaliseNodeTypeName: normaliseNodeTypeName, + prepareJSONataExpression: prepareJSONataExpression };