mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
add support of environtment variable for tab & group
This commit is contained in:
parent
f1e7ec0c6b
commit
6aecc3915c
@ -53,7 +53,8 @@ RED.nodes = (function() {
|
|||||||
defaults: {
|
defaults: {
|
||||||
label: {value:""},
|
label: {value:""},
|
||||||
disabled: {value: false},
|
disabled: {value: false},
|
||||||
info: {value: ""}
|
info: {value: ""},
|
||||||
|
env: {value: []}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1387,7 +1388,8 @@ RED.nodes = (function() {
|
|||||||
type: "tab",
|
type: "tab",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
label: RED._("clipboard.recoveredNodes"),
|
label: RED._("clipboard.recoveredNodes"),
|
||||||
info: RED._("clipboard.recoveredNodesInfo")
|
info: RED._("clipboard.recoveredNodesInfo"),
|
||||||
|
env: []
|
||||||
}
|
}
|
||||||
addWorkspace(recoveryWorkspace);
|
addWorkspace(recoveryWorkspace);
|
||||||
RED.workspaces.add(recoveryWorkspace);
|
RED.workspaces.add(recoveryWorkspace);
|
||||||
@ -1518,7 +1520,7 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
// Add a tab if there isn't one there already
|
// Add a tab if there isn't one there already
|
||||||
if (defaultWorkspace == null) {
|
if (defaultWorkspace == null) {
|
||||||
defaultWorkspace = { type:"tab", id:getID(), disabled: false, info:"", label:RED._('workspace.defaultName',{number:1})};
|
defaultWorkspace = { type:"tab", id:getID(), disabled: false, info:"", label:RED._('workspace.defaultName',{number:1}), env:[]};
|
||||||
addWorkspace(defaultWorkspace);
|
addWorkspace(defaultWorkspace);
|
||||||
RED.workspaces.add(defaultWorkspace);
|
RED.workspaces.add(defaultWorkspace);
|
||||||
new_workspaces.push(defaultWorkspace);
|
new_workspaces.push(defaultWorkspace);
|
||||||
|
@ -2637,6 +2637,28 @@ var buildingEditDialog = false;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
var old_env = editing_node.env;
|
||||||
|
var new_env = RED.subflow.exportSubflowInstanceEnv(editing_node);
|
||||||
|
if (new_env && new_env.length > 0) {
|
||||||
|
new_env.forEach(function(prop) {
|
||||||
|
if (prop.type === "cred") {
|
||||||
|
editing_node.credentials = editing_node.credentials || {_:{}};
|
||||||
|
editing_node.credentials[prop.name] = prop.value;
|
||||||
|
editing_node.credentials['has_'+prop.name] = (prop.value !== "");
|
||||||
|
if (prop.value !== '__PWRD__') {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
delete prop.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!isSameObj(old_env, new_env)) {
|
||||||
|
editing_node.env = new_env;
|
||||||
|
changes.env = editing_node.env;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
var wasChanged = editing_node.changed;
|
var wasChanged = editing_node.changed;
|
||||||
editing_node.changed = true;
|
editing_node.changed = true;
|
||||||
@ -2668,6 +2690,16 @@ var buildingEditDialog = false;
|
|||||||
// console.log("oneditresize",editing_node.id,editing_node.type,err.toString());
|
// console.log("oneditresize",editing_node.id,editing_node.type,err.toString());
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
var envContainer = $("#red-ui-editor-group-env-list");
|
||||||
|
if (envContainer.length) {
|
||||||
|
var rows = $("#dialog-form>div:not(#group-env-tabs-content)");
|
||||||
|
var height = size.height;
|
||||||
|
for (var i=0; i<rows.size(); i++) {
|
||||||
|
height -= $(rows[i]).outerHeight(true);
|
||||||
|
}
|
||||||
|
$("#red-ui-editor-group-env-list").editableList('height',height-30);
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
open: function(tray, done) {
|
open: function(tray, done) {
|
||||||
var trayFooter = tray.find(".red-ui-tray-footer");
|
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||||
@ -2707,6 +2739,18 @@ var buildingEditDialog = false;
|
|||||||
|
|
||||||
editorTabs.addTab(nodePropertiesTab);
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
|
var groupPropertiesTab = {
|
||||||
|
id: "editor-group-envProperties",
|
||||||
|
label: RED._("editor-tab.envProperties"),
|
||||||
|
name: RED._("editor-tab.envProperties"),
|
||||||
|
content: $('<div>', {
|
||||||
|
id: "editor-group-envProperties-content",
|
||||||
|
class: "red-ui-tray-content"
|
||||||
|
}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-list",
|
||||||
|
};
|
||||||
|
editorTabs.addTab(groupPropertiesTab);
|
||||||
|
|
||||||
var descriptionTab = {
|
var descriptionTab = {
|
||||||
id: "editor-tab-description",
|
id: "editor-tab-description",
|
||||||
label: RED._("editor-tab.description"),
|
label: RED._("editor-tab.description"),
|
||||||
@ -2725,6 +2769,7 @@ var buildingEditDialog = false;
|
|||||||
buildingEditDialog = false;
|
buildingEditDialog = false;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
|
@ -87,14 +87,18 @@ RED.group = (function() {
|
|||||||
"label-position": "nw"
|
"label-position": "nw"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var groupDef = {
|
var groupDef = {
|
||||||
defaults:{
|
defaults:{
|
||||||
name:{value:""},
|
name:{value:""},
|
||||||
style:{value:{label:true}},
|
style:{value:{label:true}},
|
||||||
nodes:{value:[]}
|
nodes:{value:[]},
|
||||||
|
env: {value:[]},
|
||||||
},
|
},
|
||||||
category: "config",
|
category: "config",
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
|
RED.subflow.buildPropertiesForm(this);
|
||||||
|
|
||||||
var style = this.style || {};
|
var style = this.style || {};
|
||||||
RED.colorPicker.create({
|
RED.colorPicker.create({
|
||||||
id:"node-input-style-stroke",
|
id:"node-input-style-stroke",
|
||||||
@ -144,7 +148,6 @@ RED.group = (function() {
|
|||||||
})
|
})
|
||||||
$("#node-input-style-label").prop("checked", this.style.label)
|
$("#node-input-style-label").prop("checked", this.style.label)
|
||||||
$("#node-input-style-label").trigger("change");
|
$("#node-input-style-label").trigger("change");
|
||||||
|
|
||||||
},
|
},
|
||||||
oneditresize: function(size) {
|
oneditresize: function(size) {
|
||||||
},
|
},
|
||||||
|
@ -980,6 +980,9 @@ RED.subflow = (function() {
|
|||||||
function buildPropertiesList(envContainer, node) {
|
function buildPropertiesList(envContainer, node) {
|
||||||
|
|
||||||
var isTemplateNode = (node.type === "subflow");
|
var isTemplateNode = (node.type === "subflow");
|
||||||
|
var isGroup = (node.type === "group");
|
||||||
|
var isTab = (node.type === "tab");
|
||||||
|
var kind = isGroup ? "group" : (isTab ? "tab" : "subflow");
|
||||||
|
|
||||||
if (isTemplateNode) {
|
if (isTemplateNode) {
|
||||||
buildEnvControl(envContainer, node);
|
buildEnvControl(envContainer, node);
|
||||||
@ -1841,7 +1844,10 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
function exportSubflowInstanceEnv(node) {
|
function exportSubflowInstanceEnv(node) {
|
||||||
var env = [];
|
var env = [];
|
||||||
|
var isGroup = (node.type === "group");
|
||||||
|
var isTab = (node.type === "tab");
|
||||||
|
|
||||||
|
if (!isGroup && !isTab) {
|
||||||
// First, get the values for the SubflowTemplate defined properties
|
// First, get the values for the SubflowTemplate defined properties
|
||||||
// - these are the ones with custom UI elements
|
// - these are the ones with custom UI elements
|
||||||
var parentEnv = getSubflowInstanceParentEnv(node);
|
var parentEnv = getSubflowInstanceParentEnv(node);
|
||||||
@ -1893,8 +1899,10 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
// Second, get the values from the Properties table tab
|
// Second, get the values from the Properties table tab
|
||||||
var items = $('#red-ui-editor-subflow-env-list').editableList('items');
|
var kind = isGroup ? "group" : (isTab ? "tab" : "subflow");
|
||||||
|
var items = $("#red-ui-editor-"+kind+"-env-list").editableList('items');
|
||||||
items.each(function (i,el) {
|
items.each(function (i,el) {
|
||||||
var data = el.data('data');
|
var data = el.data('data');
|
||||||
var item;
|
var item;
|
||||||
@ -1947,11 +1955,13 @@ RED.subflow = (function() {
|
|||||||
buildEnvUI($("#subflow-input-ui"), getSubflowInstanceParentEnv(node), node);
|
buildEnvUI($("#subflow-input-ui"), getSubflowInstanceParentEnv(node), node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildPropertiesForm(node) {
|
function buildPropertiesForm(node) {
|
||||||
var container = $('#editor-subflow-envProperties-content');
|
var kind = (node.type === "group") ? "group" : ((node.type === "tab") ? "tab": "subflow");
|
||||||
|
var container = $("#editor-"+kind+"-envProperties-content");
|
||||||
var form = $('<form class="dialog-form form-horizontal"></form>').appendTo(container);
|
var form = $('<form class="dialog-form form-horizontal"></form>').appendTo(container);
|
||||||
var listContainer = $('<div class="form-row node-input-env-container-row"></div>').appendTo(form);
|
var listContainer = $('<div class="form-row node-input-env-container-row"></div>').appendTo(form);
|
||||||
var list = $('<ol id="red-ui-editor-subflow-env-list" class="red-ui-editor-subflow-env-list"></ol>').appendTo(listContainer);
|
var list = $('<ol id="red-ui-editor-'+kind+'-env-list" class="red-ui-editor-subflow-env-list"></ol>').appendTo(listContainer);
|
||||||
buildPropertiesList(list, node);
|
buildPropertiesList(list, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@ RED.workspaces = (function() {
|
|||||||
var viewStack = [];
|
var viewStack = [];
|
||||||
var viewStackPos = 0;
|
var viewStackPos = 0;
|
||||||
|
|
||||||
|
function isSameObj(env0, env1) {
|
||||||
|
return (JSON.stringify(env0) === JSON.stringify(env1));
|
||||||
|
}
|
||||||
|
|
||||||
function addToViewStack(id) {
|
function addToViewStack(id) {
|
||||||
if (viewStackPos !== viewStack.length) {
|
if (viewStackPos !== viewStack.length) {
|
||||||
@ -43,7 +46,7 @@ RED.workspaces = (function() {
|
|||||||
workspaceIndex += 1;
|
workspaceIndex += 1;
|
||||||
} while ($("#red-ui-workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
|
} while ($("#red-ui-workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
|
||||||
|
|
||||||
ws = {type:"tab",id:tabId,disabled: false,info:"",label:RED._('workspace.defaultName',{number:workspaceIndex})};
|
ws = {type:"tab",id:tabId,disabled: false,info:"",label:RED._('workspace.defaultName',{number:workspaceIndex}),env:[]};
|
||||||
RED.nodes.addWorkspace(ws,targetIndex);
|
RED.nodes.addWorkspace(ws,targetIndex);
|
||||||
workspace_tabs.addTab(ws,targetIndex);
|
workspace_tabs.addTab(ws,targetIndex);
|
||||||
workspace_tabs.activateTab(tabId);
|
workspace_tabs.activateTab(tabId);
|
||||||
@ -55,6 +58,7 @@ RED.workspaces = (function() {
|
|||||||
RED.view.focus();
|
RED.view.focus();
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteWorkspace(ws) {
|
function deleteWorkspace(ws) {
|
||||||
if (workspaceTabCount === 1) {
|
if (workspaceTabCount === 1) {
|
||||||
return;
|
return;
|
||||||
@ -71,6 +75,51 @@ RED.workspaces = (function() {
|
|||||||
RED.sidebar.config.refresh();
|
RED.sidebar.config.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tabflowEditor;
|
||||||
|
|
||||||
|
function buildProperties(container, workspace) {
|
||||||
|
var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(container);
|
||||||
|
$('<div class="form-row">'+
|
||||||
|
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
||||||
|
'<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+
|
||||||
|
'</div>').appendTo(dialogForm);
|
||||||
|
|
||||||
|
var row = $('<div class="form-row node-text-editor-row">'+
|
||||||
|
'<label for="node-input-info" data-i18n="editor:workspace.info" style="width:300px;"></label>'+
|
||||||
|
'<div style="min-height:250px;" class="node-text-editor" id="node-input-info"></div>'+
|
||||||
|
'</div>').appendTo(dialogForm);
|
||||||
|
tabflowEditor = RED.editor.createEditor({
|
||||||
|
id: 'node-input-info',
|
||||||
|
mode: 'ace/mode/markdown',
|
||||||
|
value: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#node-info-input-info-expand').on("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var value = tabflowEditor.getValue();
|
||||||
|
RED.editor.editMarkdown({
|
||||||
|
value: value,
|
||||||
|
width: "Infinity",
|
||||||
|
cursor: tabflowEditor.getCursorPosition(),
|
||||||
|
complete: function(v,cursor) {
|
||||||
|
tabflowEditor.setValue(v, -1);
|
||||||
|
tabflowEditor.gotoLine(cursor.row+1,cursor.column,false);
|
||||||
|
setTimeout(function() {
|
||||||
|
tabflowEditor.focus();
|
||||||
|
},300);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
||||||
|
dialogForm.on("submit", function(e) { e.preventDefault();});
|
||||||
|
|
||||||
|
$("#node-input-name").val(workspace.label);
|
||||||
|
RED.text.bidi.prepareInput($("#node-input-name"));
|
||||||
|
tabflowEditor.getSession().setValue(workspace.info || "", -1);
|
||||||
|
dialogForm.i18n();
|
||||||
|
}
|
||||||
|
|
||||||
function showEditWorkspaceDialog(id) {
|
function showEditWorkspaceDialog(id) {
|
||||||
var workspace = RED.nodes.workspace(id);
|
var workspace = RED.nodes.workspace(id);
|
||||||
if (!workspace) {
|
if (!workspace) {
|
||||||
@ -81,7 +130,6 @@ RED.workspaces = (function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RED.view.state(RED.state.EDITING);
|
RED.view.state(RED.state.EDITING);
|
||||||
var tabflowEditor;
|
|
||||||
var trayOptions = {
|
var trayOptions = {
|
||||||
title: RED._("workspace.editFlow",{name:RED.utils.sanitize(workspace.label)}),
|
title: RED._("workspace.editFlow",{name:RED.utils.sanitize(workspace.label)}),
|
||||||
buttons: [
|
buttons: [
|
||||||
@ -130,6 +178,28 @@ RED.workspaces = (function() {
|
|||||||
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
$("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
|
||||||
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
|
||||||
|
|
||||||
|
var old_env = workspace.env;
|
||||||
|
var new_env = RED.subflow.exportSubflowInstanceEnv(workspace);
|
||||||
|
console.log("; NE", new_env);
|
||||||
|
if (new_env && (new_env.length > 0)) {
|
||||||
|
new_env.forEach(function(prop) {
|
||||||
|
if (prop.type === "cred") {
|
||||||
|
workspace.credentials = workspace.credentials || {_:{}};
|
||||||
|
workspace.credentials[prop.name] = prop.value;
|
||||||
|
workspace.credentials['has_'+prop.name] = (prop.value !== "");
|
||||||
|
if (prop.value !== '__PWRD__') {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
delete prop.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!isSameObj(old_env, new_env)) {
|
||||||
|
workspace.env = new_env;
|
||||||
|
changes.env = old_env;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
var historyEvent = {
|
var historyEvent = {
|
||||||
t: "edit",
|
t: "edit",
|
||||||
@ -156,27 +226,67 @@ RED.workspaces = (function() {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
resize: function(dimensions) {
|
resize: function(dimensions) {
|
||||||
|
var height = dimensions.height;
|
||||||
|
|
||||||
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
||||||
var editorRow = $("#dialog-form>div.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++) {
|
for (var i=0; i<rows.size(); i++) {
|
||||||
height -= $(rows[i]).outerHeight(true);
|
height -= $(rows[i]).outerHeight(true);
|
||||||
}
|
}
|
||||||
height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom")));
|
var editorHeight = height -(parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))) -100;
|
||||||
$(".node-text-editor").css("height",height+"px");
|
$(".node-text-editor").css("height", editorHeight+"px");
|
||||||
tabflowEditor.resize();
|
tabflowEditor.resize();
|
||||||
|
|
||||||
|
$("#red-ui-editor-tab-env-list").editableList("height", height -70);
|
||||||
},
|
},
|
||||||
open: function(tray) {
|
open: function(tray) {
|
||||||
var trayFooter = tray.find(".red-ui-tray-footer");
|
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||||
var trayBody = tray.find('.red-ui-tray-body');
|
var trayBody = tray.find('.red-ui-tray-body');
|
||||||
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
|
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
|
||||||
|
|
||||||
var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(trayBody);
|
var editorTabEl = $('<ul></ul>').appendTo(trayBody);
|
||||||
$('<div class="form-row">'+
|
var editorContent = $('<div></div>').appendTo(trayBody);
|
||||||
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
|
||||||
'<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+
|
|
||||||
'</div>').appendTo(dialogForm);
|
|
||||||
|
|
||||||
|
var finishedBuilding = false;
|
||||||
|
|
||||||
|
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,
|
||||||
|
menu: false
|
||||||
|
});
|
||||||
|
|
||||||
|
var nodePropertiesTab = {
|
||||||
|
id: "editor-tab-properties",
|
||||||
|
label: RED._("editor-tab.properties"),
|
||||||
|
name: RED._("editor-tab.properties"),
|
||||||
|
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-cog"
|
||||||
|
};
|
||||||
|
buildProperties(nodePropertiesTab.content, workspace);
|
||||||
|
editorTabs.addTab(nodePropertiesTab);
|
||||||
|
|
||||||
|
var tabPropertiesTab = {
|
||||||
|
id: "editor-tab-envProperties",
|
||||||
|
label: RED._("editor-tab.envProperties"),
|
||||||
|
name: RED._("editor-tab.envProperties"),
|
||||||
|
content: $('<div>', {
|
||||||
|
id: "editor-tab-envProperties-content",
|
||||||
|
class: "red-ui-tray-content"
|
||||||
|
}).appendTo(editorContent).hide(),
|
||||||
|
iconClass: "fa fa-list",
|
||||||
|
};
|
||||||
|
RED.subflow.buildPropertiesForm(workspace);
|
||||||
|
editorTabs.addTab(tabPropertiesTab);
|
||||||
|
|
||||||
if (!workspace.hasOwnProperty("disabled")) {
|
if (!workspace.hasOwnProperty("disabled")) {
|
||||||
workspace.disabled = false;
|
workspace.disabled = false;
|
||||||
@ -187,43 +297,8 @@ RED.workspaces = (function() {
|
|||||||
disabledIcon: "fa-ban",
|
disabledIcon: "fa-ban",
|
||||||
invertState: true
|
invertState: true
|
||||||
})
|
})
|
||||||
|
finishedBuilding = true;
|
||||||
|
RED.tray.resize();
|
||||||
var row = $('<div class="form-row node-text-editor-row">'+
|
|
||||||
'<label for="node-input-info" data-i18n="editor:workspace.info" style="width:300px;"></label>'+
|
|
||||||
'<div style="min-height:250px;" class="node-text-editor" id="node-input-info"></div>'+
|
|
||||||
'</div>').appendTo(dialogForm);
|
|
||||||
tabflowEditor = RED.editor.createEditor({
|
|
||||||
id: 'node-input-info',
|
|
||||||
mode: 'ace/mode/markdown',
|
|
||||||
value: ""
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#node-info-input-info-expand').on("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var value = tabflowEditor.getValue();
|
|
||||||
RED.editor.editMarkdown({
|
|
||||||
value: value,
|
|
||||||
width: "Infinity",
|
|
||||||
cursor: tabflowEditor.getCursorPosition(),
|
|
||||||
complete: function(v,cursor) {
|
|
||||||
tabflowEditor.setValue(v, -1);
|
|
||||||
tabflowEditor.gotoLine(cursor.row+1,cursor.column,false);
|
|
||||||
setTimeout(function() {
|
|
||||||
tabflowEditor.focus();
|
|
||||||
},300);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
|
||||||
dialogForm.on("submit", function(e) { e.preventDefault();});
|
|
||||||
$("#node-input-name").val(workspace.label);
|
|
||||||
RED.text.bidi.prepareInput($("#node-input-name"));
|
|
||||||
tabflowEditor.getSession().setValue(workspace.info || "", -1);
|
|
||||||
dialogForm.i18n();
|
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
|
||||||
|
@ -396,6 +396,17 @@ class Flow {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a group node instance
|
||||||
|
* @param {String} id
|
||||||
|
* @return {Node} group node
|
||||||
|
*/
|
||||||
|
getGroupNode(id) {
|
||||||
|
const groups = this.global.groups;
|
||||||
|
return groups[id];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all of the nodes instantiated within this flow
|
* Get all of the nodes instantiated within this flow
|
||||||
* @return {[type]} [description]
|
* @return {[type]} [description]
|
||||||
@ -404,6 +415,57 @@ class Flow {
|
|||||||
return this.activeNodes;
|
return this.activeNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a flow setting value deined in this flow.
|
||||||
|
* @param {String} key
|
||||||
|
* @return {Object} result containinig val property or null
|
||||||
|
*/
|
||||||
|
getFlowSetting(name) {
|
||||||
|
const flow = this.flow;
|
||||||
|
if (flow.env) {
|
||||||
|
if (!name.startsWith("$parent.")) {
|
||||||
|
if (!flow._env) {
|
||||||
|
const envs = flow.env;
|
||||||
|
const entries = envs.map((env) => [env.name, env]);
|
||||||
|
flow._env = Object.fromEntries(entries);
|
||||||
|
}
|
||||||
|
const env = flow._env[name];
|
||||||
|
if (env) {
|
||||||
|
let value = env.value;
|
||||||
|
const type = env.type;
|
||||||
|
if ((type !== "env") || (value !== name)) {
|
||||||
|
if (type === "env") {
|
||||||
|
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (type === "bool") {
|
||||||
|
const val = ((value === "true") ||
|
||||||
|
(value === true));
|
||||||
|
return {
|
||||||
|
val: val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === "cred") {
|
||||||
|
return {
|
||||||
|
val: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var val = redUtil.evaluateNodeProperty(value, type, null, null, null);
|
||||||
|
return {
|
||||||
|
val: val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a flow setting value. This currently automatically defers to the parent
|
* Get a flow setting value. This currently automatically defers to the parent
|
||||||
* flow which, as defined in ./index.js returns `process.env[key]`.
|
* flow which, as defined in ./index.js returns `process.env[key]`.
|
||||||
@ -412,6 +474,10 @@ class Flow {
|
|||||||
* @return {[type]} [description]
|
* @return {[type]} [description]
|
||||||
*/
|
*/
|
||||||
getSetting(key) {
|
getSetting(key) {
|
||||||
|
const result = this.getFlowSetting(key);
|
||||||
|
if (result) {
|
||||||
|
return result.val;
|
||||||
|
}
|
||||||
return this.parent.getSetting(key);
|
return this.parent.getSetting(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,54 @@ function evaluateInputValue(value, type, node) {
|
|||||||
return redUtil.evaluateNodeProperty(value, type, node, null, null);
|
return redUtil.evaluateNodeProperty(value, type, node, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get value of environment variable defined in group node.
|
||||||
|
* @param {String} group - group node
|
||||||
|
* @param {String} name - name of variable
|
||||||
|
* @return {Object} object containing the value in val property or null if not defined
|
||||||
|
*/
|
||||||
|
function getGroupSetting(node, group, flow, name) {
|
||||||
|
if (group) {
|
||||||
|
if (!name.startsWith("$parent.")) {
|
||||||
|
if (group.env) {
|
||||||
|
if (!group._env) {
|
||||||
|
const envs = group.env;
|
||||||
|
const entries = envs.map((env) => [env.name, env]);
|
||||||
|
group._env = Object.fromEntries(entries);
|
||||||
|
}
|
||||||
|
const env = group._env[name];
|
||||||
|
if (env) {
|
||||||
|
let value = env.value;
|
||||||
|
const type = env.type;
|
||||||
|
if ((type !== "env") || (value !== name)) {
|
||||||
|
if (type === "env") {
|
||||||
|
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const val = evaluateInputValue(value, type, node);
|
||||||
|
return {
|
||||||
|
val: val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = name.substring(8);
|
||||||
|
}
|
||||||
|
if (group.g && flow) {
|
||||||
|
const parent = flow.getGroupNode(group.g);
|
||||||
|
return getGroupSetting(node, parent, flow, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a subflow - which is handled as a special type of Flow
|
* This class represents a subflow - which is handled as a special type of Flow
|
||||||
*/
|
*/
|
||||||
@ -370,6 +418,16 @@ class Subflow extends Flow {
|
|||||||
// name starts $parent. ... so delegate to parent automatically
|
// name starts $parent. ... so delegate to parent automatically
|
||||||
name = name.substring(8);
|
name = name.substring(8);
|
||||||
}
|
}
|
||||||
|
const node = this.subflowInstance;
|
||||||
|
if (node.g) {
|
||||||
|
const group = this.getGroupNode(node.g);
|
||||||
|
const result = getGroupSetting(node, group, this, name);
|
||||||
|
if (result) {
|
||||||
|
return result.val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var parent = this.parent;
|
var parent = this.parent;
|
||||||
if (parent) {
|
if (parent) {
|
||||||
var val = parent.getSetting(name);
|
var val = parent.getSetting(name);
|
||||||
|
@ -539,6 +539,9 @@ async function addFlow(flow, user) {
|
|||||||
if (flow.hasOwnProperty('disabled')) {
|
if (flow.hasOwnProperty('disabled')) {
|
||||||
tabNode.disabled = flow.disabled;
|
tabNode.disabled = flow.disabled;
|
||||||
}
|
}
|
||||||
|
if (flow.hasOwnProperty('env')) {
|
||||||
|
tabNode.env = flow.env;
|
||||||
|
}
|
||||||
|
|
||||||
var nodes = [tabNode];
|
var nodes = [tabNode];
|
||||||
|
|
||||||
@ -599,6 +602,9 @@ function getFlow(id) {
|
|||||||
if (flow.hasOwnProperty('info')) {
|
if (flow.hasOwnProperty('info')) {
|
||||||
result.info = flow.info;
|
result.info = flow.info;
|
||||||
}
|
}
|
||||||
|
if (flow.hasOwnProperty('env')) {
|
||||||
|
result.env = flow.env;
|
||||||
|
}
|
||||||
if (id !== 'global') {
|
if (id !== 'global') {
|
||||||
result.nodes = [];
|
result.nodes = [];
|
||||||
}
|
}
|
||||||
@ -694,6 +700,9 @@ async function updateFlow(id,newFlow, user) {
|
|||||||
if (newFlow.hasOwnProperty('disabled')) {
|
if (newFlow.hasOwnProperty('disabled')) {
|
||||||
tabNode.disabled = newFlow.disabled;
|
tabNode.disabled = newFlow.disabled;
|
||||||
}
|
}
|
||||||
|
if (newFlow.hasOwnProperty('env')) {
|
||||||
|
tabNode.env = newFlow.env;
|
||||||
|
}
|
||||||
|
|
||||||
nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]);
|
nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]);
|
||||||
nodes.forEach(function(n) {
|
nodes.forEach(function(n) {
|
||||||
|
@ -44,24 +44,25 @@ function diffNodes(oldNode,newNode) {
|
|||||||
var EnvVarPropertyRE_old = /^\$\((\S+)\)$/;
|
var EnvVarPropertyRE_old = /^\$\((\S+)\)$/;
|
||||||
var EnvVarPropertyRE = /^\${(\S+)}$/;
|
var EnvVarPropertyRE = /^\${(\S+)}$/;
|
||||||
|
|
||||||
function mapEnvVarProperties(obj,prop,flow) {
|
|
||||||
|
function mapEnvVarProperties(obj,prop,flow,config) {
|
||||||
var v = obj[prop];
|
var v = obj[prop];
|
||||||
if (Buffer.isBuffer(v)) {
|
if (Buffer.isBuffer(v)) {
|
||||||
return;
|
return;
|
||||||
} else if (Array.isArray(v)) {
|
} else if (Array.isArray(v)) {
|
||||||
for (var i=0;i<v.length;i++) {
|
for (var i=0;i<v.length;i++) {
|
||||||
mapEnvVarProperties(v,i,flow);
|
mapEnvVarProperties(v,i,flow,config);
|
||||||
}
|
}
|
||||||
} else if (typeof obj[prop] === 'string') {
|
} else if (typeof obj[prop] === 'string') {
|
||||||
if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) {
|
if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) {
|
||||||
var envVar = v.substring(2,v.length-1);
|
var envVar = v.substring(2,v.length-1);
|
||||||
var r = flow.getSetting(envVar);
|
var r = redUtil.getSetting(config, envVar, flow);
|
||||||
obj[prop] = r!==undefined?r:obj[prop];
|
obj[prop] = r ? r : obj[prop];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (var p in v) {
|
for (var p in v) {
|
||||||
if (v.hasOwnProperty(p)) {
|
if (v.hasOwnProperty(p)) {
|
||||||
mapEnvVarProperties(v,p,flow);
|
mapEnvVarProperties(v,p,flow,config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ function createNode(flow,config) {
|
|||||||
delete conf.credentials;
|
delete conf.credentials;
|
||||||
for (var p in conf) {
|
for (var p in conf) {
|
||||||
if (conf.hasOwnProperty(p)) {
|
if (conf.hasOwnProperty(p)) {
|
||||||
mapEnvVarProperties(conf,p,flow);
|
mapEnvVarProperties(conf,p,flow,conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -38,6 +38,7 @@ function Node(n) {
|
|||||||
this.id = n.id;
|
this.id = n.id;
|
||||||
this.type = n.type;
|
this.type = n.type;
|
||||||
this.z = n.z;
|
this.z = n.z;
|
||||||
|
this.g = n.g;
|
||||||
this._closeCallbacks = [];
|
this._closeCallbacks = [];
|
||||||
this._inputCallback = null;
|
this._inputCallback = null;
|
||||||
this._inputCallbacks = null;
|
this._inputCallbacks = null;
|
||||||
|
@ -103,7 +103,7 @@ function createNode(node,def) {
|
|||||||
// allow $(foo) syntax to substitute env variables for credentials also...
|
// allow $(foo) syntax to substitute env variables for credentials also...
|
||||||
for (var p in creds) {
|
for (var p in creds) {
|
||||||
if (creds.hasOwnProperty(p)) {
|
if (creds.hasOwnProperty(p)) {
|
||||||
flowUtil.mapEnvVarProperties(creds,p,node._flow);
|
flowUtil.mapEnvVarProperties(creds,p,node._flow,node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.credentials = creds;
|
node.credentials = creds;
|
||||||
|
85
packages/node_modules/@node-red/util/lib/util.js
vendored
85
packages/node_modules/@node-red/util/lib/util.js
vendored
@ -515,19 +515,84 @@ function setObjectProperty(msg,prop,value,createMissing) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get value of environment variable defined in group node.
|
||||||
|
* @param {String} group - group node
|
||||||
|
* @param {String} name - name of variable
|
||||||
|
* @return {Object} object containing the value in val property or null if not defined
|
||||||
|
*/
|
||||||
|
function getGroupSetting(node, group, flow, name) {
|
||||||
|
if (group) {
|
||||||
|
if (!name.startsWith("$parent.")) {
|
||||||
|
if (group.env) {
|
||||||
|
if (!group._env) {
|
||||||
|
const envs = group.env;
|
||||||
|
const entries = envs.map((env) => [env.name, env]);
|
||||||
|
group._env = Object.fromEntries(entries);
|
||||||
|
}
|
||||||
|
const env = group._env[name];
|
||||||
|
if (env) {
|
||||||
|
let value = env.value;
|
||||||
|
const type = env.type;
|
||||||
|
if ((type !== "env") || (value !== name)) {
|
||||||
|
if (type === "env") {
|
||||||
|
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (type === "bool") {
|
||||||
|
const val = ((value === "true") ||
|
||||||
|
(value === true));
|
||||||
|
return {
|
||||||
|
val: val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === "cred") {
|
||||||
|
return {
|
||||||
|
val: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var val = evaluateNodeProperty(value, type, node, null, null);
|
||||||
|
return {
|
||||||
|
val: val
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = name.substring(8);
|
||||||
|
}
|
||||||
|
if (group.g && flow) {
|
||||||
|
const parent = flow.getGroupNode(group.g);
|
||||||
|
return getGroupSetting(node, parent, flow, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Get value of environment variable.
|
* Get value of environment variable.
|
||||||
* @param {Node} node - accessing node
|
* @param {Node} node - accessing node
|
||||||
* @param {String} name - name of variable
|
* @param {String} name - name of variable
|
||||||
* @return {String} value of env var
|
* @return {String} value of env var
|
||||||
*/
|
*/
|
||||||
function getSetting(node, name) {
|
function getSetting(node, name, flow_) {
|
||||||
if (node && node._flow) {
|
var flow = (flow_ ? flow_ : (node ? node._flow : null));
|
||||||
var flow = node._flow;
|
|
||||||
if (flow) {
|
if (flow) {
|
||||||
return flow.getSetting(name);
|
if (node && node.g) {
|
||||||
|
const group = flow.getGroupNode(node.g);
|
||||||
|
const result = getGroupSetting(node, group, flow, name);
|
||||||
|
if (result) {
|
||||||
|
return result.val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return flow.getSetting(name);
|
||||||
|
}
|
||||||
return process.env[name];
|
return process.env[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,18 +609,19 @@ function getSetting(node, name) {
|
|||||||
* @memberof @node-red/util_util
|
* @memberof @node-red/util_util
|
||||||
*/
|
*/
|
||||||
function evaluateEnvProperty(value, node) {
|
function evaluateEnvProperty(value, node) {
|
||||||
|
var flow = (node && node.hasOwnProperty("_flow")) ? node._flow : null;
|
||||||
var result;
|
var result;
|
||||||
if (/^\${[^}]+}$/.test(value)) {
|
if (/^\${[^}]+}$/.test(value)) {
|
||||||
// ${ENV_VAR}
|
// ${ENV_VAR}
|
||||||
var name = value.substring(2,value.length-1);
|
var name = value.substring(2,value.length-1);
|
||||||
result = getSetting(node, name);
|
result = getSetting(node, name, flow);
|
||||||
} else if (!/\${\S+}/.test(value)) {
|
} else if (!/\${\S+}/.test(value)) {
|
||||||
// ENV_VAR
|
// ENV_VAR
|
||||||
result = getSetting(node, value);
|
result = getSetting(node, value, flow);
|
||||||
} else {
|
} else {
|
||||||
// FOO${ENV_VAR}BAR
|
// FOO${ENV_VAR}BAR
|
||||||
return value.replace(/\${([^}]+)}/g, function(match, name) {
|
return value.replace(/\${([^}]+)}/g, function(match, name) {
|
||||||
var val = getSetting(node, name);
|
var val = getSetting(node, name, flow);
|
||||||
return (val === undefined)?"":val;
|
return (val === undefined)?"":val;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -668,7 +734,7 @@ function prepareJSONataExpression(value,node) {
|
|||||||
return node.context().global.get(val, store);
|
return node.context().global.get(val, store);
|
||||||
});
|
});
|
||||||
expr.assign('env', function(name) {
|
expr.assign('env', function(name) {
|
||||||
var val = getSetting(node, name);
|
var val = getSetting(node, name, node._flow);
|
||||||
if (typeof val !== 'undefined') {
|
if (typeof val !== 'undefined') {
|
||||||
return val;
|
return val;
|
||||||
} else {
|
} else {
|
||||||
@ -976,5 +1042,6 @@ module.exports = {
|
|||||||
normaliseNodeTypeName: normaliseNodeTypeName,
|
normaliseNodeTypeName: normaliseNodeTypeName,
|
||||||
prepareJSONataExpression: prepareJSONataExpression,
|
prepareJSONataExpression: prepareJSONataExpression,
|
||||||
evaluateJSONataExpression: evaluateJSONataExpression,
|
evaluateJSONataExpression: evaluateJSONataExpression,
|
||||||
parseContextStore: parseContextStore
|
parseContextStore: parseContextStore,
|
||||||
|
getSetting: getSetting
|
||||||
};
|
};
|
||||||
|
@ -542,6 +542,77 @@ describe('change Node', function() {
|
|||||||
changeNode1.receive({payload:"123",topic:"ABC"});
|
changeNode1.receive({payload:"123",topic:"ABC"});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('sets the value using env property from tab', function(done) {
|
||||||
|
var flow = [
|
||||||
|
{"id":"tab1","type":"tab","env":[
|
||||||
|
{"name":"NR_TEST_A", "value":"bar", "type": "str"}
|
||||||
|
]},
|
||||||
|
{"id":"changeNode1","type":"change","z":"tab1",rules:[{"t":"set","p":"payload","pt":"msg","to":"NR_TEST_A","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||||
|
{id:"helperNode1", type:"helper", wires:[]}
|
||||||
|
];
|
||||||
|
helper.load(changeNode, flow, function() {
|
||||||
|
var changeNode1 = helper.getNode("changeNode1");
|
||||||
|
var helperNode1 = helper.getNode("helperNode1");
|
||||||
|
helperNode1.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.payload.should.equal("bar");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changeNode1.receive({payload:"123",topic:"ABC"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets the value using env property from group', function(done) {
|
||||||
|
var flow = [
|
||||||
|
{"id":"group1","type":"group","env":[
|
||||||
|
{"name":"NR_TEST_A", "value":"bar", "type": "str"}
|
||||||
|
]},
|
||||||
|
{"id":"changeNode1","type":"change","g":"group1",rules:[{"t":"set","p":"payload","pt":"msg","to":"NR_TEST_A","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||||
|
{id:"helperNode1", type:"helper", wires:[]}
|
||||||
|
];
|
||||||
|
helper.load(changeNode, flow, function() {
|
||||||
|
var changeNode1 = helper.getNode("changeNode1");
|
||||||
|
var helperNode1 = helper.getNode("helperNode1");
|
||||||
|
helperNode1.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.payload.should.equal("bar");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changeNode1.receive({payload:"123",topic:"ABC"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets the value using env property from nested group', function(done) {
|
||||||
|
var flow = [
|
||||||
|
{"id":"group1","type":"group","env":[
|
||||||
|
{"name":"NR_TEST_A", "value":"bar", "type": "str"}
|
||||||
|
]},
|
||||||
|
{"id":"group2","type":"group","g":"group1","env":[]},
|
||||||
|
{"id":"changeNode1","type":"change","g":"group2",rules:[{"t":"set","p":"payload","pt":"msg","to":"NR_TEST_A","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||||
|
{id:"helperNode1", type:"helper", wires:[]}
|
||||||
|
];
|
||||||
|
helper.load(changeNode, flow, function() {
|
||||||
|
var changeNode1 = helper.getNode("changeNode1");
|
||||||
|
var helperNode1 = helper.getNode("helperNode1");
|
||||||
|
helperNode1.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.payload.should.equal("bar");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changeNode1.receive({payload:"123",topic:"ABC"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -447,4 +447,124 @@ describe('subflow', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should access env var of tab', function(done) {
|
||||||
|
var flow = [
|
||||||
|
{id:"t0", type:"tab", label:"", disabled:false, info:"", env: [
|
||||||
|
{name: "K", type: "str", value: "V"}
|
||||||
|
]},
|
||||||
|
{id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", wires:[["n2"]]},
|
||||||
|
{id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]},
|
||||||
|
// Subflow
|
||||||
|
{id:"s1", type:"subflow", name:"Subflow", info:"", env: [],
|
||||||
|
in:[{
|
||||||
|
x:10, y:10,
|
||||||
|
wires:[ {id:"s1-n1"} ]
|
||||||
|
}],
|
||||||
|
out:[{
|
||||||
|
x:10, y:10,
|
||||||
|
wires:[ {id:"s1-n1", port:0} ]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{id:"s1-n1", x:10, y:10, z:"s1", type:"function",
|
||||||
|
func:"msg.V = env.get('K'); return msg;",
|
||||||
|
wires:[]}
|
||||||
|
];
|
||||||
|
helper.load(functionNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.should.have.property("V", "V");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.receive({payload:"foo"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should access env var of group', function(done) {
|
||||||
|
var flow = [
|
||||||
|
{id:"t0", type:"tab", label:"", disabled:false, info:""},
|
||||||
|
{id:"g1", z:"t0", type:"group", env:[
|
||||||
|
{name: "K", type: "str", value: "V"}
|
||||||
|
]},
|
||||||
|
{id:"n1", x:10, y:10, z:"t0", g:"g1", type:"subflow:s1", wires:[["n2"]]},
|
||||||
|
{id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]},
|
||||||
|
// Subflow
|
||||||
|
{id:"s1", type:"subflow", name:"Subflow", info:"", env: [],
|
||||||
|
in:[{
|
||||||
|
x:10, y:10,
|
||||||
|
wires:[ {id:"s1-n1"} ]
|
||||||
|
}],
|
||||||
|
out:[{
|
||||||
|
x:10, y:10,
|
||||||
|
wires:[ {id:"s1-n1", port:0} ]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{id:"s1-n1", x:10, y:10, z:"s1", type:"function",
|
||||||
|
func:"msg.V = env.get('K'); return msg;",
|
||||||
|
wires:[]}
|
||||||
|
];
|
||||||
|
helper.load(functionNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.should.have.property("V", "V");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.receive({payload:"foo"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should access env var of nested group', function(done) {
|
||||||
|
var flow = [
|
||||||
|
{id:"t0", type:"tab", label:"", disabled:false, info:""},
|
||||||
|
{id:"g1", z:"t0", type:"group", env:[
|
||||||
|
{name: "K", type: "str", value: "V"}
|
||||||
|
]},
|
||||||
|
{id:"g2", z:"t0", g:"g1", type:"group", env:[]},
|
||||||
|
{id:"n1", x:10, y:10, z:"t0", g:"g2", type:"subflow:s1", wires:[["n2"]]},
|
||||||
|
{id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]},
|
||||||
|
// Subflow
|
||||||
|
{id:"s1", type:"subflow", name:"Subflow", info:"", env: [],
|
||||||
|
in:[{
|
||||||
|
x:10, y:10,
|
||||||
|
wires:[ {id:"s1-n1"} ]
|
||||||
|
}],
|
||||||
|
out:[{
|
||||||
|
x:10, y:10,
|
||||||
|
wires:[ {id:"s1-n1", port:0} ]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{id:"s1-n1", x:10, y:10, z:"s1", type:"function",
|
||||||
|
func:"msg.V = env.get('K'); return msg;",
|
||||||
|
wires:[]}
|
||||||
|
];
|
||||||
|
helper.load(functionNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.should.have.property("V", "V");
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
n1.receive({payload:"foo"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1228,4 +1228,54 @@ describe('Flow', function() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("#env", function () {
|
||||||
|
it("can instantiate a node with environment variable property values of group and tab", function (done) {
|
||||||
|
try {
|
||||||
|
after(function() {
|
||||||
|
delete process.env.V0;
|
||||||
|
delete process.env.V1;
|
||||||
|
})
|
||||||
|
process.env.V0 = "gv0";
|
||||||
|
process.env.V1 = "gv1";
|
||||||
|
var config = flowUtils.parseConfig([
|
||||||
|
{id:"t1",type:"tab",env:[
|
||||||
|
{"name": "V0", value: "v0", type: "str"}
|
||||||
|
]},
|
||||||
|
{id:"g1",type:"group",z:"t1",env:[
|
||||||
|
{"name": "V0", value: "v1", type: "str"},
|
||||||
|
{"name": "V1", value: "v2", type: "str"}
|
||||||
|
]},
|
||||||
|
{id:"g2",type:"group",z:"t1",g:"g1",env:[
|
||||||
|
{"name": "V1", value: "v3", type: "str"}
|
||||||
|
]},
|
||||||
|
{id:"1",x:10,y:10,z:"t1",type:"test",foo:"$(V0)",wires:[]},
|
||||||
|
{id:"2",x:10,y:10,z:"t1",g:"g1",type:"test",foo:"$(V0)",wires:[]},
|
||||||
|
{id:"3",x:10,y:10,z:"t1",g:"g1",type:"test",foo:"$(V1)",wires:[]},
|
||||||
|
{id:"4",x:10,y:10,z:"t1",g:"g2",type:"test",foo:"$(V1)",wires:[]},
|
||||||
|
{id:"5",x:10,y:10,z:"t1",type:"test",foo:"$(V1)",wires:[]},
|
||||||
|
]);
|
||||||
|
var flow = Flow.create({getSetting:v=>process.env[v]},config,config.flows["t1"]);
|
||||||
|
flow.start();
|
||||||
|
|
||||||
|
var activeNodes = flow.getActiveNodes();
|
||||||
|
|
||||||
|
activeNodes["1"].foo.should.equal("v0");
|
||||||
|
activeNodes["2"].foo.should.equal("v1");
|
||||||
|
activeNodes["3"].foo.should.equal("v2");
|
||||||
|
activeNodes["4"].foo.should.equal("v3");
|
||||||
|
activeNodes["5"].foo.should.equal("gv1");
|
||||||
|
|
||||||
|
flow.stop().then(function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e.stack);
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user