diff --git a/public/red/nodes.js b/public/red/nodes.js index 635184031..e0841bc87 100644 --- a/public/red/nodes.js +++ b/public/red/nodes.js @@ -343,14 +343,23 @@ RED.nodes = (function() { } } if(exportCreds && n.credentials) { + var credentialSet = {}; node.credentials = {}; for (var cred in n._def.credentials) { if (n._def.credentials.hasOwnProperty(cred)) { - if (n.credentials[cred] != null) { - node.credentials[cred] = n.credentials[cred]; + if (n._def.credentials[cred].type == 'password') { + if (n.credentials["has_"+cred] != n.credentials._["has_"+cred] || + (n.credentials["has_"+cred] && n.credentials[cred])) { + credentialSet[cred] = n.credentials[cred]; + } + } else if (n.credentials[cred] != null && n.credentials[cred] != n.credentials._[cred]) { + credentialSet[cred] = n.credentials[cred]; } } } + if (Object.keys(credentialSet).length > 0) { + node.credentials = credentialSet; + } } } if (n._def.category != "config") { diff --git a/red/nodes/flows.js b/red/nodes/flows.js index 45923f556..376653f2a 100644 --- a/red/nodes/flows.js +++ b/red/nodes/flows.js @@ -22,12 +22,15 @@ var typeRegistry = require("./registry"); var credentials = require("./credentials"); var log = require("../log"); var events = require("../events"); +var redUtil = require("../util"); var storage = null; var nodes = {}; var subflows = {}; var activeConfig = []; +var activeConfigNodes = {}; + var missingTypes = []; events.on('type-registered',function(type) { @@ -142,6 +145,7 @@ function parseConfig() { var type; var subflow; missingTypes = []; + activeConfigNodes = {}; // Scan the configuration for any unknown node types for (i=0;i 0) { + var newChangedSubflowsObj = {}; + changedSubflows.forEach(function(id) { + changedNodes[id] = newNodes[id]; + }); + + var subflowNameRE = /^subflow:(.*)$/; + config.forEach(function(n) { + var m = subflowNameRE.exec(n.type); + if (m && changedSubflowsObj[m[1]]) { + // This is an instance of a changed subflow + changedNodes[n.id] = n; + if (activeConfigNodes[n.z] && activeConfigNodes[n.z].type == "subflow" && !changedNodes[n.z]) { + // This instance is itself in a subflow that has not yet been dealt with + newChangedSubflowsObj[n.z] = true; + } + } + }); + changedSubflowsObj = newChangedSubflowsObj; + changedSubflows = Object.keys(newChangedSubflowsObj); + } + + // Build the list of what each node is connected to + config.forEach(function(n) { + nodeLinks[n.id] = nodeLinks[n.id] || []; + if (n.wires) { + for (var j=0;j 0) { + var nid = changedNodeStack.pop(); + var n = newNodes[nid]; + if (!visited[nid]) { + visited[nid] = true; + if (nodeLinks[nid]) { + nodeLinks[nid].forEach(function(id) { + var nn = newNodes[id]; + if (!changedNodes[id]) { + linkChangedNodes[id] = nn; + changedNodeStack.push(nn.id); + } + }); + } + } + } + + config.forEach(function(n) { + if (changedNodes[n.id]|| linkChangedNodes[n.id]) { + console.log(changedNodes[n.id]!=null,linkChangedNodes[n.id]!=null,n.id,n.type,n.name); + } + }); + deletedNodes.forEach(function(n) { + console.log("Deleted:",n); + }); + return credentials.save() .then(function() { return storage.saveFlows(config);}) .then(function() { return stopFlows();}) diff --git a/red/util.js b/red/util.js index 7f7d356e3..a50a2405e 100644 --- a/red/util.js +++ b/red/util.js @@ -57,9 +57,51 @@ function cloneMessage(msg) { return m; } +function compareObjects(obj1,obj2) { + if (obj1 === obj2) { + return true; + } + if (obj1 == null || obj2 == null) { + return false; + } + if (!(obj1 instanceof Object) && !(obj2 instanceof Object)) { + return false; + } + var isArray1 = Array.isArray(obj1); + var isArray2 = Array.isArray(obj2); + if (isArray1 != isArray2) { + return false; + } + if (isArray1 && isArray2) { + if (obj1.length != obj2.length) { + return false; + } + for (var i=0;i