mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge branch 'dev' into repackage
This commit is contained in:
commit
2aae76c9bc
15
CHANGELOG.md
15
CHANGELOG.md
@ -1,3 +1,18 @@
|
|||||||
|
#### 0.19.4: Maintenance Release
|
||||||
|
|
||||||
|
- Fix race condition in non-cache lfs context Fixes #1888
|
||||||
|
- LocalFileSystem Context: Remove extra flush code
|
||||||
|
- Prevent race condition in caching mode of lfs context (#1889)
|
||||||
|
- Allow context store name to be provided in the key
|
||||||
|
- Switch node: only use promises when absolutely necessary
|
||||||
|
- Fix dbl-click handling on webkit-based browsers
|
||||||
|
- Ensure context.flow/global cannot be deleted or enumerated
|
||||||
|
- Handle context.get with multiple levels of unknown key Fixes #1883
|
||||||
|
- Fix global.get("foo.bar") for functionGlobalContext set values
|
||||||
|
- Fix node color bug (#1877)
|
||||||
|
- Merge pull request #1857 from cclauss/patch-1
|
||||||
|
- Define raw_input() in Python 3 & fix time.sleep()
|
||||||
|
|
||||||
#### 0.19.3: Maintenance Release
|
#### 0.19.3: Maintenance Release
|
||||||
|
|
||||||
- Split node - fix complete to send msg for k/v object
|
- Split node - fix complete to send msg for k/v object
|
||||||
|
1
packages/node_modules/@node-red/editor-api/lib/editor/locales/en-US/editor.json
generated
vendored
1
packages/node_modules/@node-red/editor-api/lib/editor/locales/en-US/editor.json
generated
vendored
@ -270,6 +270,7 @@
|
|||||||
"defaultLabel": "use default label",
|
"defaultLabel": "use default label",
|
||||||
"searchIcons": "Search icons",
|
"searchIcons": "Search icons",
|
||||||
"useDefault": "use default",
|
"useDefault": "use default",
|
||||||
|
"description": "Description",
|
||||||
"errors": {
|
"errors": {
|
||||||
"scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it"
|
"scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it"
|
||||||
}
|
}
|
||||||
|
1
packages/node_modules/@node-red/editor-api/lib/editor/locales/ja/editor.json
generated
vendored
1
packages/node_modules/@node-red/editor-api/lib/editor/locales/ja/editor.json
generated
vendored
@ -266,6 +266,7 @@
|
|||||||
"defaultLabel": "既定の名前を使用",
|
"defaultLabel": "既定の名前を使用",
|
||||||
"searchIcons": "アイコンを検索",
|
"searchIcons": "アイコンを検索",
|
||||||
"useDefault": "デフォルトを使用",
|
"useDefault": "デフォルトを使用",
|
||||||
|
"description": "詳細",
|
||||||
"errors": {
|
"errors": {
|
||||||
"scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします"
|
"scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします"
|
||||||
}
|
}
|
||||||
|
13
packages/node_modules/@node-red/editor-client/src/js/nodes.js
generated
vendored
13
packages/node_modules/@node-red/editor-client/src/js/nodes.js
generated
vendored
@ -510,6 +510,9 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (n.info) {
|
||||||
|
node.info = n.info;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -904,7 +907,14 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
|
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
|
||||||
configNode = {id:n.id, z:n.z, type:n.type, users:[], _config:{}};
|
configNode = {
|
||||||
|
id:n.id,
|
||||||
|
z:n.z,
|
||||||
|
type:n.type,
|
||||||
|
info: n.info,
|
||||||
|
users:[],
|
||||||
|
_config:{}
|
||||||
|
};
|
||||||
for (d in def.defaults) {
|
for (d in def.defaults) {
|
||||||
if (def.defaults.hasOwnProperty(d)) {
|
if (def.defaults.hasOwnProperty(d)) {
|
||||||
configNode[d] = n[d];
|
configNode[d] = n[d];
|
||||||
@ -947,6 +957,7 @@ RED.nodes = (function() {
|
|||||||
inputLabels: n.inputLabels,
|
inputLabels: n.inputLabels,
|
||||||
outputLabels: n.outputLabels,
|
outputLabels: n.outputLabels,
|
||||||
icon: n.icon,
|
icon: n.icon,
|
||||||
|
info: n.info,
|
||||||
changed:false,
|
changed:false,
|
||||||
_config:{}
|
_config:{}
|
||||||
};
|
};
|
||||||
|
305
packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
generated
vendored
305
packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
generated
vendored
@ -772,7 +772,7 @@ RED.editor = (function() {
|
|||||||
searchInput.focus();
|
searchInput.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildLabelForm(container,node) {
|
function buildAppearanceForm(container,node) {
|
||||||
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||||
|
|
||||||
var inputCount = node.inputs || node._def.inputs || 0;
|
var inputCount = node.inputs || node._def.inputs || 0;
|
||||||
@ -882,10 +882,27 @@ RED.editor = (function() {
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildDescriptionForm(container,node) {
|
||||||
|
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||||
|
$('<div style="height: 100%;" class="node-text-editor" id="node-info-input-info-editor" ></div>').appendTo(dialogForm);
|
||||||
|
var nodeInfoEditor = RED.editor.createEditor({
|
||||||
|
id: "node-info-input-info-editor",
|
||||||
|
mode: 'ace/mode/markdown',
|
||||||
|
value: ""
|
||||||
|
});
|
||||||
|
if (node.info) {
|
||||||
|
nodeInfoEditor.getSession().setValue(node.info, -1);
|
||||||
|
}
|
||||||
|
return nodeInfoEditor;
|
||||||
|
}
|
||||||
|
|
||||||
function showEditDialog(node) {
|
function showEditDialog(node) {
|
||||||
var editing_node = node;
|
var editing_node = node;
|
||||||
var isDefaultIcon;
|
var isDefaultIcon;
|
||||||
var defaultIcon;
|
var defaultIcon;
|
||||||
|
var nodeInfoEditor;
|
||||||
|
var finishedBuilding = false;
|
||||||
|
|
||||||
editStack.push(node);
|
editStack.push(node);
|
||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
var type = node.type;
|
var type = node.type;
|
||||||
@ -1126,6 +1143,33 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var oldInfo = node.info;
|
||||||
|
if (nodeInfoEditor) {
|
||||||
|
var newInfo = nodeInfoEditor.getValue();
|
||||||
|
if (!!oldInfo) {
|
||||||
|
// Has existing info property
|
||||||
|
if (newInfo.trim() === "") {
|
||||||
|
// New value is blank - remove the property
|
||||||
|
changed = true;
|
||||||
|
changes.info = oldInfo;
|
||||||
|
delete node.info;
|
||||||
|
} else if (newInfo !== oldInfo) {
|
||||||
|
// New value is different
|
||||||
|
changed = true;
|
||||||
|
changes.info = oldInfo;
|
||||||
|
node.info = newInfo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No existing info
|
||||||
|
if (newInfo.trim() !== "") {
|
||||||
|
// New value is not blank
|
||||||
|
changed = true;
|
||||||
|
changes.info = undefined;
|
||||||
|
node.info = newInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
var wasChanged = editing_node.changed;
|
var wasChanged = editing_node.changed;
|
||||||
editing_node.changed = true;
|
editing_node.changed = true;
|
||||||
@ -1174,8 +1218,8 @@ RED.editor = (function() {
|
|||||||
],
|
],
|
||||||
resize: function(dimensions) {
|
resize: function(dimensions) {
|
||||||
editTrayWidthCache[type] = dimensions.width;
|
editTrayWidthCache[type] = dimensions.width;
|
||||||
$(".editor-tray-content").height(dimensions.height - 78);
|
$(".editor-tray-content").height(dimensions.height - 50);
|
||||||
var form = $(".editor-tray-content form").height(dimensions.height - 78 - 40);
|
var form = $(".editor-tray-content form").height(dimensions.height - 50 - 40);
|
||||||
if (editing_node && editing_node._def.oneditresize) {
|
if (editing_node && editing_node._def.oneditresize) {
|
||||||
try {
|
try {
|
||||||
editing_node._def.oneditresize.call(editing_node,{width:form.width(),height:form.height()});
|
editing_node._def.oneditresize.call(editing_node,{width:form.width(),height:form.height()});
|
||||||
@ -1189,25 +1233,23 @@ RED.editor = (function() {
|
|||||||
var trayBody = tray.find('.editor-tray-body');
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
trayBody.parent().css('overflow','hidden');
|
trayBody.parent().css('overflow','hidden');
|
||||||
|
|
||||||
var stack = RED.stack.create({
|
var editorTabEl = $('<ul></ul>').appendTo(trayBody);
|
||||||
container: trayBody,
|
var editorContent = $('<div></div>').appendTo(trayBody);
|
||||||
singleExpanded: true
|
|
||||||
});
|
|
||||||
var nodeProperties = stack.add({
|
|
||||||
title: RED._("editor.nodeProperties"),
|
|
||||||
expanded: true
|
|
||||||
});
|
|
||||||
nodeProperties.content.addClass("editor-tray-content");
|
|
||||||
|
|
||||||
var portLabels = stack.add({
|
var editorTabs = RED.tabs.create({
|
||||||
title: RED._("editor.portLabels"),
|
element:editorTabEl,
|
||||||
onexpand: function() {
|
onchange:function(tab) {
|
||||||
refreshLabelForm(this.content,node);
|
editorContent.children().hide();
|
||||||
|
if (tab.onchange) {
|
||||||
|
tab.onchange.call(tab);
|
||||||
}
|
}
|
||||||
|
tab.content.show();
|
||||||
|
if (finishedBuilding) {
|
||||||
|
RED.tray.resize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapsible: true
|
||||||
});
|
});
|
||||||
portLabels.content.addClass("editor-tray-content");
|
|
||||||
|
|
||||||
|
|
||||||
if (editing_node) {
|
if (editing_node) {
|
||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
@ -1224,11 +1266,48 @@ RED.editor = (function() {
|
|||||||
} else {
|
} else {
|
||||||
isDefaultIcon = true;
|
isDefaultIcon = true;
|
||||||
}
|
}
|
||||||
buildEditForm(nodeProperties.content,"dialog-form",type,ns);
|
|
||||||
buildLabelForm(portLabels.content,node);
|
var nodePropertiesTab = {
|
||||||
|
id: "editor-tab-properties",
|
||||||
|
label: "Properties",
|
||||||
|
name: "Properties",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-cog"
|
||||||
|
};
|
||||||
|
buildEditForm(nodePropertiesTab.content,"dialog-form",type,ns);
|
||||||
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
|
if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) {
|
||||||
|
var descriptionTab = {
|
||||||
|
id: "editor-tab-description",
|
||||||
|
label: "Description",
|
||||||
|
name: "Description",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-file-text-o",
|
||||||
|
onchange: function() {
|
||||||
|
nodeInfoEditor.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
editorTabs.addTab(descriptionTab);
|
||||||
|
nodeInfoEditor = buildDescriptionForm(descriptionTab.content,node);
|
||||||
|
}
|
||||||
|
|
||||||
|
var appearanceTab = {
|
||||||
|
id: "editor-tab-appearance",
|
||||||
|
label: "Appearance",
|
||||||
|
name: "Appearance",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-object-group",
|
||||||
|
onchange: function() {
|
||||||
|
refreshLabelForm(this.content,node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
buildAppearanceForm(appearanceTab.content,node);
|
||||||
|
editorTabs.addTab(appearanceTab);
|
||||||
|
|
||||||
prepareEditDialog(node,node._def,"node-input", function() {
|
prepareEditDialog(node,node._def,"node-input", function() {
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
|
finishedBuilding = true;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1240,6 +1319,10 @@ RED.editor = (function() {
|
|||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
|
if (nodeInfoEditor) {
|
||||||
|
nodeInfoEditor.destroy();
|
||||||
|
nodeInfoEditor = null;
|
||||||
|
}
|
||||||
RED.view.redraw(true);
|
RED.view.redraw(true);
|
||||||
editStack.pop();
|
editStack.pop();
|
||||||
},
|
},
|
||||||
@ -1277,6 +1360,8 @@ RED.editor = (function() {
|
|||||||
var adding = (id == "_ADD_");
|
var adding = (id == "_ADD_");
|
||||||
var node_def = RED.nodes.getType(type);
|
var node_def = RED.nodes.getType(type);
|
||||||
var editing_config_node = RED.nodes.node(id);
|
var editing_config_node = RED.nodes.node(id);
|
||||||
|
var nodeInfoEditor;
|
||||||
|
var finishedBuilding = false;
|
||||||
|
|
||||||
var ns;
|
var ns;
|
||||||
if (node_def.set.module === "node-red") {
|
if (node_def.set.module === "node-red") {
|
||||||
@ -1309,7 +1394,8 @@ RED.editor = (function() {
|
|||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
var trayOptions = {
|
var trayOptions = {
|
||||||
title: getEditStackTitle(), //(adding?RED._("editor.addNewConfig", {type:type}):RED._("editor.editConfig", {type:type})),
|
title: getEditStackTitle(), //(adding?RED._("editor.addNewConfig", {type:type}):RED._("editor.editConfig", {type:type})),
|
||||||
resize: function() {
|
resize: function(dimensions) {
|
||||||
|
$(".editor-tray-content").height(dimensions.height - 50);
|
||||||
if (editing_config_node && editing_config_node._def.oneditresize) {
|
if (editing_config_node && editing_config_node._def.oneditresize) {
|
||||||
var form = $("#node-config-dialog-edit-form");
|
var form = $("#node-config-dialog-edit-form");
|
||||||
try {
|
try {
|
||||||
@ -1321,6 +1407,7 @@ RED.editor = (function() {
|
|||||||
},
|
},
|
||||||
open: function(tray, done) {
|
open: function(tray, done) {
|
||||||
var trayHeader = tray.find(".editor-tray-header");
|
var trayHeader = tray.find(".editor-tray-header");
|
||||||
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
var trayFooter = tray.find(".editor-tray-footer");
|
var trayFooter = tray.find(".editor-tray-footer");
|
||||||
|
|
||||||
if (node_def.hasUsers !== false) {
|
if (node_def.hasUsers !== false) {
|
||||||
@ -1328,7 +1415,49 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
trayFooter.append('<span id="node-config-dialog-scope-container"><span id="node-config-dialog-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="node-config-dialog-scope"></select></span>');
|
trayFooter.append('<span id="node-config-dialog-scope-container"><span id="node-config-dialog-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="node-config-dialog-scope"></select></span>');
|
||||||
|
|
||||||
var dialogForm = buildEditForm(tray.find('.editor-tray-body'),"node-config-dialog-edit-form",type,ns);
|
var editorTabEl = $('<ul></ul>').appendTo(trayBody);
|
||||||
|
var editorContent = $('<div></div>').appendTo(trayBody);
|
||||||
|
|
||||||
|
var editorTabs = RED.tabs.create({
|
||||||
|
element:editorTabEl,
|
||||||
|
onchange:function(tab) {
|
||||||
|
editorContent.children().hide();
|
||||||
|
if (tab.onchange) {
|
||||||
|
tab.onchange.call(tab);
|
||||||
|
}
|
||||||
|
tab.content.show();
|
||||||
|
if (finishedBuilding) {
|
||||||
|
RED.tray.resize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapsible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var nodePropertiesTab = {
|
||||||
|
id: "editor-tab-cproperties",
|
||||||
|
label: "Properties",
|
||||||
|
name: "Properties",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-cog"
|
||||||
|
};
|
||||||
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
buildEditForm(nodePropertiesTab.content,"node-config-dialog-edit-form",type,ns);
|
||||||
|
|
||||||
|
if (!node_def.defaults || !node_def.defaults.hasOwnProperty('info')) {
|
||||||
|
var descriptionTab = {
|
||||||
|
id: "editor-tab-description",
|
||||||
|
label: "Description",
|
||||||
|
name: "Description",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-file-text-o",
|
||||||
|
onchange: function() {
|
||||||
|
nodeInfoEditor.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
editorTabs.addTab(descriptionTab);
|
||||||
|
nodeInfoEditor = buildDescriptionForm(descriptionTab.content,editing_config_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
prepareEditDialog(editing_config_node,node_def,"node-config-input", function() {
|
prepareEditDialog(editing_config_node,node_def,"node-config-input", function() {
|
||||||
if (editing_config_node._def.exclusive) {
|
if (editing_config_node._def.exclusive) {
|
||||||
@ -1376,17 +1505,20 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
tabSelect.i18n();
|
|
||||||
|
|
||||||
dialogForm.i18n();
|
|
||||||
if (node_def.hasUsers !== false) {
|
if (node_def.hasUsers !== false) {
|
||||||
$("#node-config-dialog-user-count").find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
|
$("#node-config-dialog-user-count").find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
|
||||||
}
|
}
|
||||||
|
trayBody.i18n();
|
||||||
|
finishedBuilding = true;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
|
if (nodeInfoEditor) {
|
||||||
|
nodeInfoEditor.destroy();
|
||||||
|
nodeInfoEditor = null;
|
||||||
|
}
|
||||||
editStack.pop();
|
editStack.pop();
|
||||||
},
|
},
|
||||||
show: function() {
|
show: function() {
|
||||||
@ -1480,6 +1612,31 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nodeInfoEditor) {
|
||||||
|
editing_config_node.info = nodeInfoEditor.getValue();
|
||||||
|
|
||||||
|
var oldInfo = editing_config_node.info;
|
||||||
|
if (nodeInfoEditor) {
|
||||||
|
var newInfo = nodeInfoEditor.getValue();
|
||||||
|
if (!!oldInfo) {
|
||||||
|
// Has existing info property
|
||||||
|
if (newInfo.trim() === "") {
|
||||||
|
// New value is blank - remove the property
|
||||||
|
delete editing_config_node.info;
|
||||||
|
} else if (newInfo !== oldInfo) {
|
||||||
|
// New value is different
|
||||||
|
editing_config_node.info = newInfo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No existing info
|
||||||
|
if (newInfo.trim() !== "") {
|
||||||
|
// New value is not blank
|
||||||
|
editing_config_node.info = newInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
editing_config_node.label = configTypeDef.label;
|
editing_config_node.label = configTypeDef.label;
|
||||||
editing_config_node.z = scope;
|
editing_config_node.z = scope;
|
||||||
|
|
||||||
@ -1667,7 +1824,7 @@ RED.editor = (function() {
|
|||||||
editStack.push(subflow);
|
editStack.push(subflow);
|
||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
var subflowEditor;
|
var subflowEditor;
|
||||||
|
var finishedBuilding = false;
|
||||||
var trayOptions = {
|
var trayOptions = {
|
||||||
title: getEditStackTitle(),
|
title: getEditStackTitle(),
|
||||||
buttons: [
|
buttons: [
|
||||||
@ -1768,48 +1925,76 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
resize: function(dimensions) {
|
resize: function(dimensions) {
|
||||||
$(".editor-tray-content").height(dimensions.height - 78);
|
$(".editor-tray-content").height(dimensions.height - 50);
|
||||||
var form = $(".editor-tray-content form").height(dimensions.height - 78 - 40);
|
var form = $(".editor-tray-content form").height(dimensions.height - 50 - 40);
|
||||||
|
|
||||||
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
|
||||||
var editorRow = $("#dialog-form>div.node-text-editor-row");
|
|
||||||
var height = $("#dialog-form").height();
|
|
||||||
for (var i=0;i<rows.size();i++) {
|
|
||||||
height -= $(rows[i]).outerHeight(true);
|
|
||||||
}
|
|
||||||
height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom")));
|
|
||||||
$(".node-text-editor").css("height",height+"px");
|
|
||||||
subflowEditor.resize();
|
|
||||||
},
|
},
|
||||||
open: function(tray) {
|
open: function(tray) {
|
||||||
var trayFooter = tray.find(".editor-tray-footer");
|
var trayFooter = tray.find(".editor-tray-footer");
|
||||||
var trayBody = tray.find('.editor-tray-body');
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
trayBody.parent().css('overflow','hidden');
|
trayBody.parent().css('overflow','hidden');
|
||||||
|
|
||||||
var stack = RED.stack.create({
|
|
||||||
container: trayBody,
|
|
||||||
singleExpanded: true
|
|
||||||
});
|
|
||||||
var nodeProperties = stack.add({
|
|
||||||
title: RED._("editor.nodeProperties"),
|
|
||||||
expanded: true
|
|
||||||
});
|
|
||||||
nodeProperties.content.addClass("editor-tray-content");
|
|
||||||
var portLabels = stack.add({
|
|
||||||
title: RED._("editor.portLabels")
|
|
||||||
});
|
|
||||||
portLabels.content.addClass("editor-tray-content");
|
|
||||||
|
|
||||||
if (editing_node) {
|
if (editing_node) {
|
||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
var dialogForm = buildEditForm(nodeProperties.content,"dialog-form","subflow-template");
|
|
||||||
subflowEditor = RED.editor.createEditor({
|
var editorTabEl = $('<ul></ul>').appendTo(trayBody);
|
||||||
id: 'subflow-input-info-editor',
|
var editorContent = $('<div></div>').appendTo(trayBody);
|
||||||
mode: 'ace/mode/markdown',
|
|
||||||
value: ""
|
var editorTabs = RED.tabs.create({
|
||||||
|
element:editorTabEl,
|
||||||
|
onchange:function(tab) {
|
||||||
|
editorContent.children().hide();
|
||||||
|
if (tab.onchange) {
|
||||||
|
tab.onchange.call(tab);
|
||||||
|
}
|
||||||
|
tab.content.show();
|
||||||
|
if (finishedBuilding) {
|
||||||
|
RED.tray.resize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapsible: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var nodePropertiesTab = {
|
||||||
|
id: "editor-tab-properties",
|
||||||
|
label: "Properties",
|
||||||
|
name: "Properties",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-cog"
|
||||||
|
};
|
||||||
|
buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template");
|
||||||
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
|
var descriptionTab = {
|
||||||
|
id: "editor-tab-description",
|
||||||
|
label: "Description",
|
||||||
|
name: "Description",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-file-text-o",
|
||||||
|
onchange: function() {
|
||||||
|
subflowEditor.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
editorTabs.addTab(descriptionTab);
|
||||||
|
subflowEditor = buildDescriptionForm(descriptionTab.content,editing_node);
|
||||||
|
|
||||||
|
var appearanceTab = {
|
||||||
|
id: "editor-tab-appearance",
|
||||||
|
label: "Appearance",
|
||||||
|
name: "Appearance",
|
||||||
|
content: $('<div>', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-object-group",
|
||||||
|
onchange: function() {
|
||||||
|
refreshLabelForm(this.content,editing_node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
buildAppearanceForm(appearanceTab.content,editing_node);
|
||||||
|
editorTabs.addTab(appearanceTab);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$("#subflow-input-name").val(subflow.name);
|
$("#subflow-input-name").val(subflow.name);
|
||||||
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
||||||
|
|
||||||
@ -1836,10 +2021,7 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
$("#subflow-input-category").val(subflow.category||"subflows");
|
$("#subflow-input-category").val(subflow.category||"subflows");
|
||||||
|
|
||||||
subflowEditor.getSession().setValue(subflow.info||"",-1);
|
|
||||||
var userCount = 0;
|
var userCount = 0;
|
||||||
var subflowType = "subflow:"+editing_node.id;
|
var subflowType = "subflow:"+editing_node.id;
|
||||||
|
|
||||||
@ -1850,8 +2032,8 @@ RED.editor = (function() {
|
|||||||
});
|
});
|
||||||
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||||
|
|
||||||
buildLabelForm(portLabels.content,subflow);
|
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
|
finishedBuilding = true;
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
@ -1860,6 +2042,7 @@ RED.editor = (function() {
|
|||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
RED.workspaces.refresh();
|
RED.workspaces.refresh();
|
||||||
subflowEditor.destroy();
|
subflowEditor.destroy();
|
||||||
|
subflowEditor = null;
|
||||||
editStack.pop();
|
editStack.pop();
|
||||||
editing_node = null;
|
editing_node = null;
|
||||||
},
|
},
|
||||||
|
7
packages/node_modules/@node-red/editor-client/src/js/ui/search.js
generated
vendored
7
packages/node_modules/@node-red/editor-client/src/js/ui/search.js
generated
vendored
@ -118,6 +118,7 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureSelectedIsVisible() {
|
function ensureSelectedIsVisible() {
|
||||||
var selectedEntry = searchResults.find("li.selected");
|
var selectedEntry = searchResults.find("li.selected");
|
||||||
if (selectedEntry.length === 1) {
|
if (selectedEntry.length === 1) {
|
||||||
@ -143,6 +144,7 @@ RED.search = (function() {
|
|||||||
search($(this).val());
|
search($(this).val());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
searchInput.on('keydown',function(evt) {
|
searchInput.on('keydown',function(evt) {
|
||||||
var children;
|
var children;
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
@ -229,12 +231,13 @@ RED.search = (function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function reveal(node) {
|
function reveal(node) {
|
||||||
hide();
|
hide();
|
||||||
RED.view.reveal(node.id);
|
RED.view.reveal(node.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function show(v) {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -250,11 +253,13 @@ RED.search = (function() {
|
|||||||
createDialog();
|
createDialog();
|
||||||
}
|
}
|
||||||
dialog.slideDown(300);
|
dialog.slideDown(300);
|
||||||
|
searchInput.searchBox('value',v)
|
||||||
RED.events.emit("search:open");
|
RED.events.emit("search:open");
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
searchInput.focus();
|
searchInput.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
RED.keyboard.remove("escape");
|
RED.keyboard.remove("escape");
|
||||||
|
2
packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js
generated
vendored
2
packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js
generated
vendored
@ -21,8 +21,6 @@ RED.subflow = (function() {
|
|||||||
var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template">'+
|
var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template">'+
|
||||||
'<div class="form-row"><i class="fa fa-tag"></i> <label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name"></div>'+
|
'<div class="form-row"><i class="fa fa-tag"></i> <label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name"></div>'+
|
||||||
'<div class="form-row"><i class="fa fa-folder-o"></i> <label for="subflow-input-category" data-i18n="editor:subflow.category"></label><select style="width: 250px;" id="subflow-input-category"></select><input style="display:none; margin-left: 10px; width:calc(100% - 250px)" type="text" id="subflow-input-custom-category"></div>'+
|
'<div class="form-row"><i class="fa fa-folder-o"></i> <label for="subflow-input-category" data-i18n="editor:subflow.category"></label><select style="width: 250px;" id="subflow-input-category"></select><input style="display:none; margin-left: 10px; width:calc(100% - 250px)" type="text" id="subflow-input-custom-category"></div>'+
|
||||||
'<div class="form-row" style="margin-bottom: 0px;"><label for="subflow-input-info" data-i18n="editor:subflow.info"></label><a href="https://help.github.com/articles/markdown-basics/" style="font-size: 0.8em; float: right;" data-i18n="[html]subflow.format"></a></div>'+
|
|
||||||
'<div class="form-row node-text-editor-row"><div style="height: 250px;" class="node-text-editor" id="subflow-input-info-editor"></div></div>'+
|
|
||||||
'<div class="form-row form-tips" id="subflow-dialog-user-count"></div>'+
|
'<div class="form-row form-tips" id="subflow-dialog-user-count"></div>'+
|
||||||
'</script>';
|
'</script>';
|
||||||
|
|
||||||
|
4
packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
generated
vendored
4
packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
generated
vendored
@ -140,7 +140,8 @@ RED.sidebar.config = (function() {
|
|||||||
var entry = $('<li class="palette_node config_node palette_node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list);
|
var entry = $('<li class="palette_node config_node palette_node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list);
|
||||||
$('<div class="palette_label"></div>').text(label).appendTo(entry);
|
$('<div class="palette_label"></div>').text(label).appendTo(entry);
|
||||||
if (node._def.hasUsers !== false) {
|
if (node._def.hasUsers !== false) {
|
||||||
var iconContainer = $('<div/>',{class:"palette_icon_container palette_icon_container_right"}).text(node.users.length).appendTo(entry);
|
var iconContainer = $('<div/>',{class:"palette_icon_container palette_icon_container_right"}).appendTo(entry);
|
||||||
|
var butt = $('<a href="#"/>').click(function(e) { e.preventDefault(); RED.search.show(node.id); }).text(node.users.length).appendTo(iconContainer);
|
||||||
if (node.users.length === 0) {
|
if (node.users.length === 0) {
|
||||||
entry.addClass("config_node_unused");
|
entry.addClass("config_node_unused");
|
||||||
}
|
}
|
||||||
@ -161,7 +162,6 @@ RED.sidebar.config = (function() {
|
|||||||
});
|
});
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
});
|
});
|
||||||
|
|
||||||
entry.on('mouseout',function(e) {
|
entry.on('mouseout',function(e) {
|
||||||
RED.nodes.eachNode(function(node) {
|
RED.nodes.eachNode(function(node) {
|
||||||
if(node.highlighted) {
|
if(node.highlighted) {
|
||||||
|
4
packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
generated
vendored
4
packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
generated
vendored
@ -277,6 +277,10 @@ RED.sidebar.info = (function() {
|
|||||||
// TODO: help
|
// TODO: help
|
||||||
infoText = infoText + marked(textInfo);
|
infoText = infoText + marked(textInfo);
|
||||||
}
|
}
|
||||||
|
if (node.info) {
|
||||||
|
infoSection.title.text(RED._("sidebar.info.nodeHelp"));
|
||||||
|
infoText = marked(node.info || "") || ('<span class="node-info-none">' + RED._("sidebar.info.none") + '</span>');
|
||||||
|
}
|
||||||
if (infoText) {
|
if (infoText) {
|
||||||
setInfoText(infoText);
|
setInfoText(infoText);
|
||||||
}
|
}
|
||||||
|
1
packages/node_modules/@node-red/editor-client/src/js/ui/tray.js
generated
vendored
1
packages/node_modules/@node-red/editor-client/src/js/ui/tray.js
generated
vendored
@ -232,6 +232,7 @@ RED.tray = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
resize: handleWindowResize,
|
||||||
close: function close(done) {
|
close: function close(done) {
|
||||||
if (stack.length > 0) {
|
if (stack.length > 0) {
|
||||||
var tray = stack.pop();
|
var tray = stack.pop();
|
||||||
|
4
packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
generated
vendored
4
packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
generated
vendored
@ -826,7 +826,11 @@ RED.utils = (function() {
|
|||||||
}
|
}
|
||||||
result = nodeColorCache[type];
|
result = nodeColorCache[type];
|
||||||
}
|
}
|
||||||
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
|
} else {
|
||||||
|
return "#ddd";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSpinnerOverlay(container,contain) {
|
function addSpinnerOverlay(container,contain) {
|
||||||
|
2
packages/node_modules/@node-red/editor-client/src/js/ui/view.js
generated
vendored
2
packages/node_modules/@node-red/editor-client/src/js/ui/view.js
generated
vendored
@ -1766,7 +1766,7 @@ RED.view = (function() {
|
|||||||
clickTime = now;
|
clickTime = now;
|
||||||
|
|
||||||
dblClickPrimed = (lastClickNode == mousedown_node &&
|
dblClickPrimed = (lastClickNode == mousedown_node &&
|
||||||
d3.event.buttons === 1 &&
|
d3.event.button === 0 &&
|
||||||
!d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey);
|
!d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey);
|
||||||
lastClickNode = mousedown_node;
|
lastClickNode = mousedown_node;
|
||||||
|
|
||||||
|
1
packages/node_modules/@node-red/nodes/99-sample.html.demo
generated
vendored
1
packages/node_modules/@node-red/nodes/99-sample.html.demo
generated
vendored
@ -67,6 +67,7 @@
|
|||||||
},
|
},
|
||||||
inputs:1, // set the number of inputs - only 0 or 1
|
inputs:1, // set the number of inputs - only 0 or 1
|
||||||
outputs:1, // set the number of outputs - 0 to n
|
outputs:1, // set the number of outputs - 0 to n
|
||||||
|
color: "#ddd", // set icon color
|
||||||
// set the icon (held in icons dir below where you save the node)
|
// set the icon (held in icons dir below where you save the node)
|
||||||
icon: "myicon.png", // saved in icons/myicon.png
|
icon: "myicon.png", // saved in icons/myicon.png
|
||||||
label: function() { // sets the default label contents
|
label: function() { // sets the default label contents
|
||||||
|
9
packages/node_modules/@node-red/nodes/core/hardware/nrgpio.py
generated
vendored
9
packages/node_modules/@node-red/nodes/core/hardware/nrgpio.py
generated
vendored
@ -21,7 +21,12 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
bounce = 25;
|
try:
|
||||||
|
raw_input # Python 2
|
||||||
|
except NameError:
|
||||||
|
raw_input = input # Python 3
|
||||||
|
|
||||||
|
bounce = 25
|
||||||
|
|
||||||
if len(sys.argv) > 2:
|
if len(sys.argv) > 2:
|
||||||
cmd = sys.argv[1].lower()
|
cmd = sys.argv[1].lower()
|
||||||
@ -198,7 +203,7 @@ if len(sys.argv) > 2:
|
|||||||
elif cmd == "kbd": # catch keyboard button events
|
elif cmd == "kbd": # catch keyboard button events
|
||||||
try:
|
try:
|
||||||
while not os.path.isdir("/dev/input/by-path"):
|
while not os.path.isdir("/dev/input/by-path"):
|
||||||
time.sleep(10)
|
sleep(10)
|
||||||
infile = subprocess.check_output("ls /dev/input/by-path/ | grep -m 1 'kbd'", shell=True).strip()
|
infile = subprocess.check_output("ls /dev/input/by-path/ | grep -m 1 'kbd'", shell=True).strip()
|
||||||
infile_path = "/dev/input/by-path/" + infile
|
infile_path = "/dev/input/by-path/" + infile
|
||||||
EVENT_SIZE = struct.calcsize('llHHI')
|
EVENT_SIZE = struct.calcsize('llHHI')
|
||||||
|
35
packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
generated
vendored
35
packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
generated
vendored
@ -83,6 +83,7 @@ module.exports = function(RED) {
|
|||||||
opts.headers = {};
|
opts.headers = {};
|
||||||
opts.encoding = null; // Force NodeJs to return a Buffer (instead of a string)
|
opts.encoding = null; // Force NodeJs to return a Buffer (instead of a string)
|
||||||
opts.maxRedirects = 21;
|
opts.maxRedirects = 21;
|
||||||
|
opts.jar = request.jar();
|
||||||
var ctSet = "Content-Type"; // set default camel case
|
var ctSet = "Content-Type"; // set default camel case
|
||||||
var clSet = "Content-Length";
|
var clSet = "Content-Length";
|
||||||
if (msg.headers) {
|
if (msg.headers) {
|
||||||
@ -113,27 +114,41 @@ module.exports = function(RED) {
|
|||||||
if (msg.hasOwnProperty('followRedirects')) {
|
if (msg.hasOwnProperty('followRedirects')) {
|
||||||
opts.followRedirect = msg.followRedirects;
|
opts.followRedirect = msg.followRedirects;
|
||||||
}
|
}
|
||||||
if (msg.cookies) {
|
if (!opts.hasOwnProperty('followRedirect') || opts.followRedirect) {
|
||||||
var cookies = [];
|
opts.followRedirect = function(res) {
|
||||||
if (opts.headers.hasOwnProperty('cookie')) {
|
if (this.headers.cookie) {
|
||||||
cookies.push(opts.headers.cookie);
|
delete this.headers.cookie;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (opts.headers.hasOwnProperty('cookie')) {
|
||||||
|
var cookies = cookie.parse(opts.headers.cookie);
|
||||||
|
for (var name in cookies) {
|
||||||
|
if (cookies.hasOwnProperty(name)) {
|
||||||
|
if (cookies[name] === null) {
|
||||||
|
// This case clears a cookie for HTTP In/Response nodes.
|
||||||
|
// Ignore for this node.
|
||||||
|
} else {
|
||||||
|
opts.jar.setCookie(name + '=' + cookies[name], url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete opts.headers.cookie;
|
||||||
|
}
|
||||||
|
if (msg.cookies) {
|
||||||
for (var name in msg.cookies) {
|
for (var name in msg.cookies) {
|
||||||
if (msg.cookies.hasOwnProperty(name)) {
|
if (msg.cookies.hasOwnProperty(name)) {
|
||||||
if (msg.cookies[name] === null || msg.cookies[name].value === null) {
|
if (msg.cookies[name] === null || msg.cookies[name].value === null) {
|
||||||
// This case clears a cookie for HTTP In/Response nodes.
|
// This case clears a cookie for HTTP In/Response nodes.
|
||||||
// Ignore for this node.
|
// Ignore for this node.
|
||||||
} else if (typeof msg.cookies[name] === 'object') {
|
} else if (typeof msg.cookies[name] === 'object') {
|
||||||
cookies.push(cookie.serialize(name,msg.cookies[name].value));
|
opts.jar.setCookie(name + '=' + msg.cookies[name].value, url);
|
||||||
} else {
|
} else {
|
||||||
cookies.push(cookie.serialize(name,msg.cookies[name]));
|
opts.jar.setCookie(name + '=' + msg.cookies[name], url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cookies.length > 0) {
|
|
||||||
opts.headers.cookie = cookies.join("; ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (this.credentials && this.credentials.user) {
|
if (this.credentials && this.credentials.user) {
|
||||||
opts.auth = {
|
opts.auth = {
|
||||||
|
143
packages/node_modules/@node-red/nodes/core/logic/10-switch.js
generated
vendored
143
packages/node_modules/@node-red/nodes/core/logic/10-switch.js
generated
vendored
@ -92,6 +92,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getProperty(node,msg) {
|
function getProperty(node,msg) {
|
||||||
|
if (node.useAsyncRules) {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
if (node.propertyType === 'jsonata') {
|
if (node.propertyType === 'jsonata') {
|
||||||
RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => {
|
RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => {
|
||||||
@ -111,9 +112,25 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (node.propertyType === 'jsonata') {
|
||||||
|
try {
|
||||||
|
return RED.util.evaluateJSONataExpression(node.property,msg);
|
||||||
|
} catch(err) {
|
||||||
|
throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
|
||||||
|
} catch(err) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getV1(node,msg,rule,hasParts) {
|
function getV1(node,msg,rule,hasParts) {
|
||||||
|
if (node.useAsyncRules) {
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
if (rule.vt === 'prev') {
|
if (rule.vt === 'prev') {
|
||||||
resolve(node.previousValue);
|
resolve(node.previousValue);
|
||||||
@ -133,7 +150,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (rule.vt === 'json') {
|
} else if (rule.vt === 'json') {
|
||||||
resolve("json");
|
resolve("json"); // TODO: ?! invalid case
|
||||||
} else if (rule.vt === 'null') {
|
} else if (rule.vt === 'null') {
|
||||||
resolve("null");
|
resolve("null");
|
||||||
} else {
|
} else {
|
||||||
@ -146,9 +163,38 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (rule.vt === 'prev') {
|
||||||
|
return node.previousValue;
|
||||||
|
} else if (rule.vt === 'jsonata') {
|
||||||
|
var exp = rule.v;
|
||||||
|
if (rule.t === 'jsonata_exp') {
|
||||||
|
if (hasParts) {
|
||||||
|
exp.assign("I", msg.parts.index);
|
||||||
|
exp.assign("N", msg.parts.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return RED.util.evaluateJSONataExpression(exp,msg);
|
||||||
|
} catch(err) {
|
||||||
|
throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
|
||||||
|
}
|
||||||
|
} else if (rule.vt === 'json') {
|
||||||
|
return "json"; // TODO: ?! invalid case
|
||||||
|
} else if (rule.vt === 'null') {
|
||||||
|
return "null";
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);
|
||||||
|
} catch(err) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getV2(node,msg,rule) {
|
function getV2(node,msg,rule) {
|
||||||
|
if (node.useAsyncRules) {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
var v2 = rule.v2;
|
var v2 = rule.v2;
|
||||||
if (rule.v2t === 'prev') {
|
if (rule.v2t === 'prev') {
|
||||||
@ -173,9 +219,30 @@ module.exports = function(RED) {
|
|||||||
resolve(v2);
|
resolve(v2);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
var v2 = rule.v2;
|
||||||
|
if (rule.v2t === 'prev') {
|
||||||
|
return node.previousValue;
|
||||||
|
} else if (rule.v2t === 'jsonata') {
|
||||||
|
try {
|
||||||
|
return RED.util.evaluateJSONataExpression(rule.v2,msg);
|
||||||
|
} catch(err) {
|
||||||
|
throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
|
||||||
|
}
|
||||||
|
} else if (typeof v2 !== 'undefined') {
|
||||||
|
try {
|
||||||
|
return RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg);
|
||||||
|
} catch(err) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return v2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyRule(node, msg, property, state) {
|
function applyRule(node, msg, property, state) {
|
||||||
|
if (node.useAsyncRules) {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
|
|
||||||
var rule = node.rules[state.currentRule];
|
var rule = node.rules[state.currentRule];
|
||||||
@ -202,6 +269,25 @@ module.exports = function(RED) {
|
|||||||
resolve(state.currentRule < node.rules.length - 1);
|
resolve(state.currentRule < node.rules.length - 1);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
var rule = node.rules[state.currentRule];
|
||||||
|
var v1 = getV1(node,msg,rule,state.hasParts);
|
||||||
|
var v2 = getV2(node,msg,rule);
|
||||||
|
if (rule.t == "else") {
|
||||||
|
property = state.elseflag;
|
||||||
|
state.elseflag = true;
|
||||||
|
}
|
||||||
|
if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
|
||||||
|
state.onward.push(msg);
|
||||||
|
state.elseflag = false;
|
||||||
|
if (node.checkall == "false") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.onward.push(null);
|
||||||
|
}
|
||||||
|
return state.currentRule < node.rules.length - 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyRules(node, msg, property,state) {
|
function applyRules(node, msg, property,state) {
|
||||||
@ -215,6 +301,7 @@ module.exports = function(RED) {
|
|||||||
msg.parts.hasOwnProperty("index")
|
msg.parts.hasOwnProperty("index")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (node.useAsyncRules) {
|
||||||
return applyRule(node,msg,property,state).then(hasMore => {
|
return applyRule(node,msg,property,state).then(hasMore => {
|
||||||
if (hasMore) {
|
if (hasMore) {
|
||||||
state.currentRule++;
|
state.currentRule++;
|
||||||
@ -224,6 +311,16 @@ module.exports = function(RED) {
|
|||||||
return state.onward;
|
return state.onward;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
var hasMore = applyRule(node,msg,property,state);
|
||||||
|
if (hasMore) {
|
||||||
|
state.currentRule++;
|
||||||
|
return applyRules(node,msg,property,state);
|
||||||
|
} else {
|
||||||
|
node.previousValue = property;
|
||||||
|
return state.onward;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,6 +345,14 @@ module.exports = function(RED) {
|
|||||||
var valid = true;
|
var valid = true;
|
||||||
var repair = n.repair;
|
var repair = n.repair;
|
||||||
var needsCount = repair;
|
var needsCount = repair;
|
||||||
|
this.useAsyncRules = (
|
||||||
|
this.propertyType === 'flow' ||
|
||||||
|
this.propertyType === 'global' || (
|
||||||
|
this.propertyType === 'jsonata' &&
|
||||||
|
/\$(flow|global)Context/.test(this.property)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
for (var i=0; i<this.rules.length; i+=1) {
|
for (var i=0; i<this.rules.length; i+=1) {
|
||||||
var rule = this.rules[i];
|
var rule = this.rules[i];
|
||||||
needsCount = needsCount || ((rule.t === "tail") || (rule.t === "jsonata_exp"));
|
needsCount = needsCount || ((rule.t === "tail") || (rule.t === "jsonata_exp"));
|
||||||
@ -258,6 +363,13 @@ module.exports = function(RED) {
|
|||||||
rule.vt = 'str';
|
rule.vt = 'str';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.useAsyncRules = this.useAsyncRules || (
|
||||||
|
rule.vt === 'flow' ||
|
||||||
|
rule.vt === 'global' || (
|
||||||
|
rule.vt === 'jsonata' &&
|
||||||
|
/\$(flow|global)Context/.test(rule.v)
|
||||||
|
)
|
||||||
|
);
|
||||||
if (rule.vt === 'num') {
|
if (rule.vt === 'num') {
|
||||||
if (!isNaN(Number(rule.v))) {
|
if (!isNaN(Number(rule.v))) {
|
||||||
rule.v = Number(rule.v);
|
rule.v = Number(rule.v);
|
||||||
@ -270,6 +382,9 @@ module.exports = function(RED) {
|
|||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rule.vt === 'flow' || rule.vt === 'global' || rule.vt === 'jsonata') {
|
||||||
|
this.useAsyncRules = true;
|
||||||
|
}
|
||||||
if (typeof rule.v2 !== 'undefined') {
|
if (typeof rule.v2 !== 'undefined') {
|
||||||
if (!rule.v2t) {
|
if (!rule.v2t) {
|
||||||
if (!isNaN(Number(rule.v2))) {
|
if (!isNaN(Number(rule.v2))) {
|
||||||
@ -278,6 +393,13 @@ module.exports = function(RED) {
|
|||||||
rule.v2t = 'str';
|
rule.v2t = 'str';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.useAsyncRules = this.useAsyncRules || (
|
||||||
|
rule.v2t === 'flow' ||
|
||||||
|
rule.v2t === 'global' || (
|
||||||
|
rule.v2t === 'jsonata' &&
|
||||||
|
/\$(flow|global)Context/.test(rule.v2)
|
||||||
|
)
|
||||||
|
);
|
||||||
if (rule.v2t === 'num') {
|
if (rule.v2t === 'num') {
|
||||||
rule.v2 = Number(rule.v2);
|
rule.v2 = Number(rule.v2);
|
||||||
} else if (rule.v2t === 'jsonata') {
|
} else if (rule.v2t === 'jsonata') {
|
||||||
@ -290,7 +412,6 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -420,6 +541,7 @@ module.exports = function(RED) {
|
|||||||
if (needsCount && checkParts && hasParts) {
|
if (needsCount && checkParts && hasParts) {
|
||||||
return addMessageToPending(msg);
|
return addMessageToPending(msg);
|
||||||
}
|
}
|
||||||
|
if (node.useAsyncRules) {
|
||||||
return getProperty(node,msg)
|
return getProperty(node,msg)
|
||||||
.then(property => applyRules(node,msg,property))
|
.then(property => applyRules(node,msg,property))
|
||||||
.then(onward => {
|
.then(onward => {
|
||||||
@ -432,6 +554,19 @@ module.exports = function(RED) {
|
|||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
node.warn(err);
|
node.warn(err);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var property = getProperty(node,msg);
|
||||||
|
var onward = applyRules(node,msg,property);
|
||||||
|
if (!repair || !hasParts) {
|
||||||
|
node.send(onward);
|
||||||
|
} else {
|
||||||
|
sendGroupMessages(onward, msg);
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
node.warn(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearPending() {
|
function clearPending() {
|
||||||
@ -473,7 +608,11 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.on('input', function(msg) {
|
this.on('input', function(msg) {
|
||||||
|
if (node.useAsyncRules) {
|
||||||
processMessageQueue(msg);
|
processMessageQueue(msg);
|
||||||
|
} else {
|
||||||
|
processMessage(msg,true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('close', function() {
|
this.on('close', function() {
|
||||||
|
82
packages/node_modules/@node-red/runtime/lib/nodes/context/index.js
generated
vendored
82
packages/node_modules/@node-red/runtime/lib/nodes/context/index.js
generated
vendored
@ -15,7 +15,8 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var clone = require("clone");
|
var clone = require("clone");
|
||||||
var log = require("@node-red/util").log; // TODO: separate module
|
var log = require("@node-red/util").log;
|
||||||
|
var util = require("@node-red/util").util;
|
||||||
var memory = require("./memory");
|
var memory = require("./memory");
|
||||||
|
|
||||||
var settings;
|
var settings;
|
||||||
@ -209,32 +210,43 @@ function createContext(id,seed) {
|
|||||||
insertSeedValues = function(keys,values) {
|
insertSeedValues = function(keys,values) {
|
||||||
if (!Array.isArray(keys)) {
|
if (!Array.isArray(keys)) {
|
||||||
if (values[0] === undefined) {
|
if (values[0] === undefined) {
|
||||||
values[0] = seed[keys];
|
values[0] = util.getObjectProperty(seed,keys);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (var i=0;i<keys.length;i++) {
|
for (var i=0;i<keys.length;i++) {
|
||||||
if (values[i] === undefined) {
|
if (values[i] === undefined) {
|
||||||
values[i] = seed[keys[i]];
|
values[i] = util.getObjectProperty(seed,keys[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Object.defineProperties(obj, {
|
||||||
obj.get = function(key, storage, callback) {
|
get: {
|
||||||
|
value: function(key, storage, callback) {
|
||||||
var context;
|
var context;
|
||||||
if (!storage && !callback) {
|
|
||||||
context = stores["_"];
|
if (!callback && typeof storage === 'function') {
|
||||||
} else {
|
|
||||||
if (typeof storage === 'function') {
|
|
||||||
callback = storage;
|
callback = storage;
|
||||||
storage = "_";
|
storage = undefined;
|
||||||
}
|
}
|
||||||
if (callback && typeof callback !== 'function'){
|
if (callback && typeof callback !== 'function'){
|
||||||
throw new Error("Callback must be a function");
|
throw new Error("Callback must be a function");
|
||||||
}
|
}
|
||||||
context = getContextStorage(storage);
|
|
||||||
|
if (!Array.isArray(key)) {
|
||||||
|
var keyParts = util.parseContextStore(key);
|
||||||
|
key = keyParts.key;
|
||||||
|
if (!storage) {
|
||||||
|
storage = keyParts.store || "_";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!storage) {
|
||||||
|
storage = "_";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context = getContextStorage(storage);
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
if (!seed) {
|
if (!seed) {
|
||||||
context.get(scope,key,callback);
|
context.get(scope,key,callback);
|
||||||
@ -258,29 +270,43 @@ function createContext(id,seed) {
|
|||||||
if (Array.isArray(key)) {
|
if (Array.isArray(key)) {
|
||||||
insertSeedValues(key,results);
|
insertSeedValues(key,results);
|
||||||
} else if (results === undefined){
|
} else if (results === undefined){
|
||||||
results = seed[key];
|
results = util.getObjectProperty(seed,key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
obj.set = function(key, value, storage, callback) {
|
},
|
||||||
|
set: {
|
||||||
|
value: function(key, value, storage, callback) {
|
||||||
var context;
|
var context;
|
||||||
if (!storage && !callback) {
|
|
||||||
context = stores["_"];
|
if (!callback && typeof storage === 'function') {
|
||||||
} else {
|
|
||||||
if (typeof storage === 'function') {
|
|
||||||
callback = storage;
|
callback = storage;
|
||||||
storage = "_";
|
storage = undefined;
|
||||||
}
|
}
|
||||||
if (callback && typeof callback !== 'function'){
|
if (callback && typeof callback !== 'function'){
|
||||||
throw new Error("Callback must be a function");
|
throw new Error("Callback must be a function");
|
||||||
}
|
}
|
||||||
context = getContextStorage(storage);
|
|
||||||
|
if (!Array.isArray(key)) {
|
||||||
|
var keyParts = util.parseContextStore(key);
|
||||||
|
key = keyParts.key;
|
||||||
|
if (!storage) {
|
||||||
|
storage = keyParts.store || "_";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!storage) {
|
||||||
|
storage = "_";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context = getContextStorage(storage);
|
||||||
|
|
||||||
context.set(scope, key, value, callback);
|
context.set(scope, key, value, callback);
|
||||||
};
|
}
|
||||||
obj.keys = function(storage, callback) {
|
},
|
||||||
|
keys: {
|
||||||
|
value: function(storage, callback) {
|
||||||
var context;
|
var context;
|
||||||
if (!storage && !callback) {
|
if (!storage && !callback) {
|
||||||
context = stores["_"];
|
context = stores["_"];
|
||||||
@ -306,7 +332,9 @@ function createContext(id,seed) {
|
|||||||
} else {
|
} else {
|
||||||
return context.keys(scope, callback);
|
return context.keys(scope, callback);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,9 +348,13 @@ function getContext(localId,flowId) {
|
|||||||
}
|
}
|
||||||
var newContext = createContext(contextId);
|
var newContext = createContext(contextId);
|
||||||
if (flowId) {
|
if (flowId) {
|
||||||
newContext.flow = getContext(flowId);
|
Object.defineProperty(newContext, 'flow', {
|
||||||
|
value: getContext(flowId)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
newContext.global = contexts['global'];
|
Object.defineProperty(newContext, 'global', {
|
||||||
|
value: contexts['global']
|
||||||
|
})
|
||||||
contexts[contextId] = newContext;
|
contexts[contextId] = newContext;
|
||||||
return newContext;
|
return newContext;
|
||||||
}
|
}
|
||||||
|
37
packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js
generated
vendored
37
packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js
generated
vendored
@ -140,6 +140,7 @@ function stringify(value) {
|
|||||||
function LocalFileSystem(config){
|
function LocalFileSystem(config){
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.storageBaseDir = getBasePath(this.config);
|
this.storageBaseDir = getBasePath(this.config);
|
||||||
|
this.writePromise = Promise.resolve();
|
||||||
if (config.hasOwnProperty('cache')?config.cache:true) {
|
if (config.hasOwnProperty('cache')?config.cache:true) {
|
||||||
this.cache = MemoryStore({});
|
this.cache = MemoryStore({});
|
||||||
}
|
}
|
||||||
@ -213,12 +214,13 @@ LocalFileSystem.prototype.open = function(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalFileSystem.prototype.close = function(){
|
LocalFileSystem.prototype.close = function(){
|
||||||
if (this.cache && this._flushPendingWrites) {
|
var self = this;
|
||||||
|
if (this.cache && this._pendingWriteTimeout) {
|
||||||
clearTimeout(this._pendingWriteTimeout);
|
clearTimeout(this._pendingWriteTimeout);
|
||||||
delete this._pendingWriteTimeout;
|
delete this._pendingWriteTimeout;
|
||||||
return this._flushPendingWrites();
|
this.flushInterval = 0;
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return this.writePromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFileSystem.prototype.get = function(scope, key, callback) {
|
LocalFileSystem.prototype.get = function(scope, key, callback) {
|
||||||
@ -230,14 +232,31 @@ LocalFileSystem.prototype.get = function(scope, key, callback) {
|
|||||||
}
|
}
|
||||||
var storagePath = getStoragePath(this.storageBaseDir ,scope);
|
var storagePath = getStoragePath(this.storageBaseDir ,scope);
|
||||||
loadFile(storagePath + ".json").then(function(data){
|
loadFile(storagePath + ".json").then(function(data){
|
||||||
|
var value;
|
||||||
if(data){
|
if(data){
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
if (!Array.isArray(key)) {
|
if (!Array.isArray(key)) {
|
||||||
callback(null, util.getObjectProperty(data,key));
|
try {
|
||||||
|
value = util.getObjectProperty(data,key);
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code === "INVALID_EXPR") {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
value = undefined;
|
||||||
|
}
|
||||||
|
callback(null, value);
|
||||||
} else {
|
} else {
|
||||||
var results = [undefined];
|
var results = [undefined];
|
||||||
for (var i=0;i<key.length;i++) {
|
for (var i=0;i<key.length;i++) {
|
||||||
results.push(util.getObjectProperty(data,key[i]))
|
try {
|
||||||
|
value = util.getObjectProperty(data,key[i]);
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code === "INVALID_EXPR") {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
value = undefined;
|
||||||
|
}
|
||||||
|
results.push(value)
|
||||||
}
|
}
|
||||||
callback.apply(null,results);
|
callback.apply(null,results);
|
||||||
}
|
}
|
||||||
@ -260,15 +279,17 @@ LocalFileSystem.prototype.set = function(scope, key, value, callback) {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this._pendingWriteTimeout = setTimeout(function() {
|
this._pendingWriteTimeout = setTimeout(function() {
|
||||||
self._flushPendingWrites.call(self).catch(function(err) {
|
self.writePromise = self.writePromise.then(function(){
|
||||||
log.error(log._("context.localfilesystem.error-write",{message:err.toString()}))
|
return self._flushPendingWrites.call(self).catch(function(err) {
|
||||||
|
log.error(log._("context.localfilesystem.error-write",{message:err.toString()}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, this.flushInterval);
|
}, this.flushInterval);
|
||||||
}
|
}
|
||||||
} else if (callback && typeof callback !== 'function') {
|
} else if (callback && typeof callback !== 'function') {
|
||||||
throw new Error("Callback must be a function");
|
throw new Error("Callback must be a function");
|
||||||
} else {
|
} else {
|
||||||
loadFile(storagePath + ".json").then(function(data){
|
self.writePromise = self.writePromise.then(function() { return loadFile(storagePath + ".json") }).then(function(data){
|
||||||
var obj = data ? JSON.parse(data) : {}
|
var obj = data ? JSON.parse(data) : {}
|
||||||
if (!Array.isArray(key)) {
|
if (!Array.isArray(key)) {
|
||||||
key = [key];
|
key = [key];
|
||||||
|
7
packages/node_modules/@node-red/runtime/lib/nodes/context/memory.js
generated
vendored
7
packages/node_modules/@node-red/runtime/lib/nodes/context/memory.js
generated
vendored
@ -32,7 +32,14 @@ Memory.prototype._getOne = function(scope, key) {
|
|||||||
var value;
|
var value;
|
||||||
var error;
|
var error;
|
||||||
if(this.data[scope]){
|
if(this.data[scope]){
|
||||||
|
try {
|
||||||
value = util.getObjectProperty(this.data[scope], key);
|
value = util.getObjectProperty(this.data[scope], key);
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code === "INVALID_EXPR") {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
value = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
36
packages/node_modules/@node-red/util/lib/util.js
generated
vendored
36
packages/node_modules/@node-red/util/lib/util.js
generated
vendored
@ -174,6 +174,12 @@ function compareObjects(obj1,obj2) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createError(code, message) {
|
||||||
|
var e = new Error(message);
|
||||||
|
e.code = code;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a property expression, such as `msg.foo.bar[3]` to validate it
|
* Parses a property expression, such as `msg.foo.bar[3]` to validate it
|
||||||
* and convert it to a canonical version expressed as an Array of property
|
* and convert it to a canonical version expressed as an Array of property
|
||||||
@ -191,7 +197,7 @@ function normalisePropertyExpression(str) {
|
|||||||
|
|
||||||
var length = str.length;
|
var length = str.length;
|
||||||
if (length === 0) {
|
if (length === 0) {
|
||||||
throw new Error("Invalid property expression: zero-length");
|
throw createError("INVALID_EXPR","Invalid property expression: zero-length");
|
||||||
}
|
}
|
||||||
var parts = [];
|
var parts = [];
|
||||||
var start = 0;
|
var start = 0;
|
||||||
@ -204,14 +210,14 @@ function normalisePropertyExpression(str) {
|
|||||||
if (!inString) {
|
if (!inString) {
|
||||||
if (c === "'" || c === '"') {
|
if (c === "'" || c === '"') {
|
||||||
if (i != start) {
|
if (i != start) {
|
||||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||||
}
|
}
|
||||||
inString = true;
|
inString = true;
|
||||||
quoteChar = c;
|
quoteChar = c;
|
||||||
start = i+1;
|
start = i+1;
|
||||||
} else if (c === '.') {
|
} else if (c === '.') {
|
||||||
if (i===0) {
|
if (i===0) {
|
||||||
throw new Error("Invalid property expression: unexpected . at position 0");
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected . at position 0");
|
||||||
}
|
}
|
||||||
if (start != i) {
|
if (start != i) {
|
||||||
v = str.substring(start,i);
|
v = str.substring(start,i);
|
||||||
@ -222,57 +228,57 @@ function normalisePropertyExpression(str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i===length-1) {
|
if (i===length-1) {
|
||||||
throw new Error("Invalid property expression: unterminated expression");
|
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||||
}
|
}
|
||||||
// Next char is first char of an identifier: a-z 0-9 $ _
|
// Next char is first char of an identifier: a-z 0-9 $ _
|
||||||
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
} else if (c === '[') {
|
} else if (c === '[') {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||||
}
|
}
|
||||||
if (start != i) {
|
if (start != i) {
|
||||||
parts.push(str.substring(start,i));
|
parts.push(str.substring(start,i));
|
||||||
}
|
}
|
||||||
if (i===length-1) {
|
if (i===length-1) {
|
||||||
throw new Error("Invalid property expression: unterminated expression");
|
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||||
}
|
}
|
||||||
// Next char is either a quote or a number
|
// Next char is either a quote or a number
|
||||||
if (!/["'\d]/.test(str[i+1])) {
|
if (!/["'\d]/.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
inBox = true;
|
inBox = true;
|
||||||
} else if (c === ']') {
|
} else if (c === ']') {
|
||||||
if (!inBox) {
|
if (!inBox) {
|
||||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||||
}
|
}
|
||||||
if (start != i) {
|
if (start != i) {
|
||||||
v = str.substring(start,i);
|
v = str.substring(start,i);
|
||||||
if (/^\d+$/.test(v)) {
|
if (/^\d+$/.test(v)) {
|
||||||
parts.push(parseInt(v));
|
parts.push(parseInt(v));
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
inBox = false;
|
inBox = false;
|
||||||
} else if (c === ' ') {
|
} else if (c === ' ') {
|
||||||
throw new Error("Invalid property expression: unexpected ' ' at position "+i);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected ' ' at position "+i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (c === quoteChar) {
|
if (c === quoteChar) {
|
||||||
if (i-start === 0) {
|
if (i-start === 0) {
|
||||||
throw new Error("Invalid property expression: zero-length string at position "+start);
|
throw createError("INVALID_EXPR","Invalid property expression: zero-length string at position "+start);
|
||||||
}
|
}
|
||||||
parts.push(str.substring(start,i));
|
parts.push(str.substring(start,i));
|
||||||
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
||||||
if (inBox && !/\]/.test(str[i+1])) {
|
if (inBox && !/\]/.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||||
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
||||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||||
}
|
}
|
||||||
start = i+1;
|
start = i+1;
|
||||||
inString = false;
|
inString = false;
|
||||||
@ -281,7 +287,7 @@ function normalisePropertyExpression(str) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (inBox || inString) {
|
if (inBox || inString) {
|
||||||
throw new Error("Invalid property expression: unterminated expression");
|
throw new createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||||
}
|
}
|
||||||
if (start < length) {
|
if (start < length) {
|
||||||
parts.push(str.substring(start));
|
parts.push(str.substring(start));
|
||||||
|
@ -46,6 +46,9 @@ describe('HTTP Request Node', function() {
|
|||||||
var preEnvNoProxyLowerCase;
|
var preEnvNoProxyLowerCase;
|
||||||
var preEnvNoProxyUpperCase;
|
var preEnvNoProxyUpperCase;
|
||||||
|
|
||||||
|
//rediect cookie variables
|
||||||
|
var receivedCookies = {};
|
||||||
|
|
||||||
function startServer(done) {
|
function startServer(done) {
|
||||||
testPort += 1;
|
testPort += 1;
|
||||||
testServer = stoppable(http.createServer(testApp));
|
testServer = stoppable(http.createServer(testApp));
|
||||||
@ -98,6 +101,10 @@ describe('HTTP Request Node', function() {
|
|||||||
return "https://localhost:"+testSslPort+url;
|
return "https://localhost:"+testSslPort+url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDifferentTestURL(url) {
|
||||||
|
return "http://127.0.0.1:"+testPort+url;
|
||||||
|
}
|
||||||
|
|
||||||
function getSslTestURLWithoutProtocol(url) {
|
function getSslTestURLWithoutProtocol(url) {
|
||||||
return "localhost:"+testSslPort+url;
|
return "localhost:"+testSslPort+url;
|
||||||
}
|
}
|
||||||
@ -182,6 +189,24 @@ describe('HTTP Request Node', function() {
|
|||||||
testApp.options('/*', function(req,res) {
|
testApp.options('/*', function(req,res) {
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
});
|
});
|
||||||
|
testApp.get('/redirectToSameDomain', function(req, res) {
|
||||||
|
var key = req.headers.host + req.url;
|
||||||
|
receivedCookies[key] = req.cookies;
|
||||||
|
res.cookie('redirectToSameDomainCookie','same1');
|
||||||
|
res.redirect(getTestURL('/redirectReturn'));
|
||||||
|
});
|
||||||
|
testApp.get('/redirectToDifferentDomain', function(req, res) {
|
||||||
|
var key = req.headers.host + req.url;
|
||||||
|
receivedCookies[key] = req.cookies;
|
||||||
|
res.cookie('redirectToDifferentDomain','different1');
|
||||||
|
res.redirect(getDifferentTestURL('/redirectReturn'));
|
||||||
|
});
|
||||||
|
testApp.get('/redirectReturn', function(req, res) {
|
||||||
|
var key = req.headers.host + req.url;
|
||||||
|
receivedCookies[key] = req.cookies;
|
||||||
|
res.cookie('redirectReturn','return1');
|
||||||
|
res.status(200).end();
|
||||||
|
});
|
||||||
startServer(function(err) {
|
startServer(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
done(err);
|
done(err);
|
||||||
@ -1240,4 +1265,162 @@ describe('HTTP Request Node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('redirect-cookie', function() {
|
||||||
|
it('should send cookies to the same domain when redirected(no cookies)', function(done) {
|
||||||
|
var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToSameDomain')},
|
||||||
|
{id:"n2", type:"helper"}];
|
||||||
|
receivedCookies = {};
|
||||||
|
helper.load(httpRequestNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain'];
|
||||||
|
var cookies2 = receivedCookies['localhost:'+testPort+'/redirectReturn'];
|
||||||
|
if (cookies1 && Object.keys(cookies1).length != 0) {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectToSame)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((cookies2 && Object.keys(cookies2).length != 1) ||
|
||||||
|
cookies2['redirectToSameDomainCookie'] !== 'same1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectReurn)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not send cookies to the different domain when redirected(no cookies)', function(done) {
|
||||||
|
var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToDifferentDomain')},
|
||||||
|
{id:"n2", type:"helper"}];
|
||||||
|
receivedCookies = {};
|
||||||
|
helper.load(httpRequestNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain'];
|
||||||
|
var cookies2 = receivedCookies['127.0.0.1:'+testPort+'/redirectReturn'];
|
||||||
|
if (cookies1 && Object.keys(cookies1).length != 0) {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectToDiffer)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cookies2 && Object.keys(cookies2).length != 0) {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectReurn)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should send cookies to the same domain when redirected(msg.cookies)', function(done) {
|
||||||
|
var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToSameDomain')},
|
||||||
|
{id:"n2", type:"helper"}];
|
||||||
|
receivedCookies = {};
|
||||||
|
helper.load(httpRequestNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain'];
|
||||||
|
var cookies2 = receivedCookies['localhost:'+testPort+'/redirectReturn'];
|
||||||
|
if ((cookies1 && Object.keys(cookies1).length != 1) ||
|
||||||
|
cookies1['requestCookie'] !== 'request1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectToSame)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((cookies2 && Object.keys(cookies2).length != 2) ||
|
||||||
|
cookies1['requestCookie'] !== 'request1' ||
|
||||||
|
cookies2['redirectToSameDomainCookie'] !== 'same1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectReurn)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({
|
||||||
|
cookies: { requestCookie: 'request1' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not send cookies to the different domain when redirected(msg.cookies)', function(done) {
|
||||||
|
var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToDifferentDomain')},
|
||||||
|
{id:"n2", type:"helper"}];
|
||||||
|
receivedCookies = {};
|
||||||
|
helper.load(httpRequestNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToDifferentDomain'];
|
||||||
|
var cookies2 = receivedCookies['127.0.0.1:'+testPort+'/redirectReturn'];
|
||||||
|
if ((cookies1 && Object.keys(cookies1).length != 1) ||
|
||||||
|
cookies1['requestCookie'] !== 'request1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectToDiffer)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cookies2 && Object.keys(cookies2).length != 0) {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectReurn)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({
|
||||||
|
cookies: { requestCookie: 'request1' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should send cookies to the same domain when redirected(msg.headers.cookie)', function(done) {
|
||||||
|
var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToSameDomain')},
|
||||||
|
{id:"n2", type:"helper"}];
|
||||||
|
receivedCookies = {};
|
||||||
|
helper.load(httpRequestNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain'];
|
||||||
|
var cookies2 = receivedCookies['localhost:'+testPort+'/redirectReturn'];
|
||||||
|
if ((cookies1 && Object.keys(cookies1).length != 1) ||
|
||||||
|
cookies1['requestCookie'] !== 'request1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectToSame)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((cookies2 && Object.keys(cookies2).length != 2) ||
|
||||||
|
cookies1['requestCookie'] !== 'request1' ||
|
||||||
|
cookies2['redirectToSameDomainCookie'] !== 'same1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectReurn)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({
|
||||||
|
headers: { cookie: 'requestCookie=request1' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not send cookies to the different domain when redirected(msg.headers.cookie)', function(done) {
|
||||||
|
var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToDifferentDomain')},
|
||||||
|
{id:"n2", type:"helper"}];
|
||||||
|
receivedCookies = {};
|
||||||
|
helper.load(httpRequestNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToDifferentDomain'];
|
||||||
|
var cookies2 = receivedCookies['127.0.0.1:'+testPort+'/redirectReturn'];
|
||||||
|
if ((cookies1 && Object.keys(cookies1).length != 1) ||
|
||||||
|
cookies1['requestCookie'] !== 'request1') {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectToDiffer)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cookies2 && Object.keys(cookies2).length != 0) {
|
||||||
|
done(new Error('Invalid cookie(path:/rediectReurn)'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({
|
||||||
|
headers: { cookie: 'requestCookie=request1' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -114,6 +114,21 @@ describe('context', function() {
|
|||||||
context2.global.get("foo").should.equal("test");
|
context2.global.get("foo").should.equal("test");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('context.flow/global are not enumerable', function() {
|
||||||
|
var context1 = Context.get("1","flowA");
|
||||||
|
Object.keys(context1).length.should.equal(0);
|
||||||
|
Object.keys(context1.flow).length.should.equal(0);
|
||||||
|
Object.keys(context1.global).length.should.equal(0);
|
||||||
|
})
|
||||||
|
|
||||||
|
it('context.flow/global cannot be deleted', function() {
|
||||||
|
var context1 = Context.get("1","flowA");
|
||||||
|
delete context1.flow;
|
||||||
|
should.exist(context1.flow);
|
||||||
|
delete context1.global;
|
||||||
|
should.exist(context1.global);
|
||||||
|
})
|
||||||
|
|
||||||
it('deletes context',function() {
|
it('deletes context',function() {
|
||||||
var context = Context.get("1","flowA");
|
var context = Context.get("1","flowA");
|
||||||
should.not.exist(context.get("foo"));
|
should.not.exist(context.get("foo"));
|
||||||
@ -192,15 +207,26 @@ describe('context', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('returns functionGlobalContext value if store value undefined', function() {
|
it('returns functionGlobalContext value if store value undefined', function() {
|
||||||
Context.init({functionGlobalContext: {foo:"bar"}});
|
Context.init({functionGlobalContext: {foo:"bar"}});
|
||||||
Context.load().then(function(){
|
return Context.load().then(function(){
|
||||||
var context = Context.get("1","flowA");
|
var context = Context.get("1","flowA");
|
||||||
var v = context.global.get('foo');
|
var v = context.global.get('foo');
|
||||||
v.should.equal('bar');
|
v.should.equal('bar');
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('returns functionGlobalContext sub-value if store value undefined', function() {
|
||||||
|
Context.init({functionGlobalContext: {foo:{bar:123}}});
|
||||||
|
return Context.load().then(function(){
|
||||||
|
var context = Context.get("1","flowA");
|
||||||
|
var v = context.global.get('foo.bar');
|
||||||
|
should.equal(v,123);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('external context storage',function() {
|
describe('external context storage',function() {
|
||||||
@ -474,6 +500,23 @@ describe('context', function() {
|
|||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow the store name to be provide in the key', function(done) {
|
||||||
|
Context.init({contextStorage:contextDefaultStorage});
|
||||||
|
Context.load().then(function(){
|
||||||
|
var context = Context.get("1","flow");
|
||||||
|
var cb = function(){done("An error occurred")}
|
||||||
|
context.set("#:(test)::foo","bar");
|
||||||
|
context.get("#:(test)::foo");
|
||||||
|
stubGet2.called.should.be.false();
|
||||||
|
stubSet2.called.should.be.false();
|
||||||
|
stubSet.calledWithExactly("1:flow","foo","bar",undefined).should.be.true();
|
||||||
|
stubGet.calledWith("1:flow","foo").should.be.true();
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should use default as the alias of other context', function(done) {
|
it('should use default as the alias of other context', function(done) {
|
||||||
Context.init({contextStorage:contextAlias});
|
Context.init({contextStorage:contextAlias});
|
||||||
Context.load().then(function(){
|
Context.load().then(function(){
|
||||||
@ -580,16 +623,16 @@ describe('context', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return multiple functionGlobalContext values if key is an array', function(done) {
|
it('should return multiple functionGlobalContext values if key is an array', function(done) {
|
||||||
var fGC = { "foo1": 456, "foo2": 789 };
|
var fGC = { "foo1": 456, "foo2": {"bar":789} };
|
||||||
Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC });
|
Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC });
|
||||||
Context.load().then(function(){
|
Context.load().then(function(){
|
||||||
var context = Context.get("1","flow");
|
var context = Context.get("1","flow");
|
||||||
context.global.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
context.global.get(["foo1","foo2.bar","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||||
if (err) {
|
if (err) {
|
||||||
done(err);
|
done(err);
|
||||||
} else {
|
} else {
|
||||||
foo1.should.be.equal(456);
|
should.equal(foo1, 456);
|
||||||
foo2.should.be.equal(789);
|
should.equal(foo2, 789);
|
||||||
should.not.exist(foo3);
|
should.not.exist(foo3);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ describe('memory',function() {
|
|||||||
context.set("nodeX","three","test3");
|
context.set("nodeX","three","test3");
|
||||||
context.set("nodeX","four","test4");
|
context.set("nodeX","four","test4");
|
||||||
|
|
||||||
var values = context.get("nodeX",["one","unknown"]);
|
var values = context.get("nodeX",["one","unknown.with.multiple.levels"]);
|
||||||
values.should.eql(["test1",undefined])
|
values.should.eql(["test1",undefined])
|
||||||
})
|
})
|
||||||
it('should throw error if bad key included in multiple keys', function() {
|
it('should throw error if bad key included in multiple keys', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user