mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge pull request #5000 from node-red/fix-config-node-import
Fix config node sort order when importing
This commit is contained in:
commit
a0952d9a07
@ -2099,6 +2099,8 @@ RED.nodes = (function() {
|
|||||||
activeWorkspace = RED.workspaces.active();
|
activeWorkspace = RED.workspaces.active();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pendingConfigNodes = []
|
||||||
|
const pendingConfigNodeIds = new Set()
|
||||||
// Find all config nodes and add them
|
// Find all config nodes and add them
|
||||||
for (i=0;i<newNodes.length;i++) {
|
for (i=0;i<newNodes.length;i++) {
|
||||||
n = newNodes[i];
|
n = newNodes[i];
|
||||||
@ -2158,7 +2160,8 @@ RED.nodes = (function() {
|
|||||||
type:n.type,
|
type:n.type,
|
||||||
info: n.info,
|
info: n.info,
|
||||||
users:[],
|
users:[],
|
||||||
_config:{}
|
_config:{},
|
||||||
|
_configNodeReferences: new Set()
|
||||||
};
|
};
|
||||||
if (!n.z) {
|
if (!n.z) {
|
||||||
delete configNode.z;
|
delete configNode.z;
|
||||||
@ -2173,6 +2176,9 @@ RED.nodes = (function() {
|
|||||||
if (def.defaults.hasOwnProperty(d)) {
|
if (def.defaults.hasOwnProperty(d)) {
|
||||||
configNode[d] = n[d];
|
configNode[d] = n[d];
|
||||||
configNode._config[d] = JSON.stringify(n[d]);
|
configNode._config[d] = JSON.stringify(n[d]);
|
||||||
|
if (def.defaults[d].type) {
|
||||||
|
configNode._configNodeReferences.add(n[d])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (def.hasOwnProperty('credentials') && n.hasOwnProperty('credentials')) {
|
if (def.hasOwnProperty('credentials') && n.hasOwnProperty('credentials')) {
|
||||||
@ -2189,25 +2195,54 @@ RED.nodes = (function() {
|
|||||||
configNode.id = getID();
|
configNode.id = getID();
|
||||||
}
|
}
|
||||||
node_map[n.id] = configNode;
|
node_map[n.id] = configNode;
|
||||||
new_nodes.push(configNode);
|
pendingConfigNodes.push(configNode);
|
||||||
|
pendingConfigNodeIds.add(configNode.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config node can use another config node, must ensure that this other
|
// We need to sort new_nodes (which only contains config nodes at this point)
|
||||||
// config node is added before to exists when updating the user list
|
// to ensure they get added in the right order. If NodeA depends on NodeB, then
|
||||||
const configNodeFilter = function (node) {
|
// NodeB must be added first.
|
||||||
let count = 0;
|
|
||||||
if (node._def?.defaults) {
|
// Limit us to 5 full iterations of the list - this should be more than
|
||||||
for (const def of Object.values(node._def.defaults)) {
|
// enough to process the list as config->config node relationships are
|
||||||
if (def.type) {
|
// not very common
|
||||||
count++;
|
let iterationLimit = pendingConfigNodes.length * 5
|
||||||
}
|
const handledConfigNodes = new Set()
|
||||||
|
while (pendingConfigNodes.length > 0 && iterationLimit > 0) {
|
||||||
|
const node = pendingConfigNodes.shift()
|
||||||
|
let hasPending = false
|
||||||
|
// Loop through the nodes referenced by this node to see if anything
|
||||||
|
// is pending
|
||||||
|
node._configNodeReferences.forEach(id => {
|
||||||
|
if (pendingConfigNodeIds.has(id) && !handledConfigNodes.has(id)) {
|
||||||
|
// This reference is for a node we know is in this import, but
|
||||||
|
// it isn't added yet - flag as pending
|
||||||
|
hasPending = true
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
if (!hasPending) {
|
||||||
|
// This node has no pending config node references - safe to add
|
||||||
|
delete node._configNodeReferences
|
||||||
|
new_nodes.push(node)
|
||||||
|
handledConfigNodes.add(node.id)
|
||||||
|
} else {
|
||||||
|
// This node has pending config node references
|
||||||
|
// Put to the back of the queue
|
||||||
|
pendingConfigNodes.push(node)
|
||||||
}
|
}
|
||||||
return count;
|
iterationLimit--
|
||||||
};
|
}
|
||||||
new_nodes.sort((a, b) => configNodeFilter(a) - configNodeFilter(b));
|
if (pendingConfigNodes.length > 0) {
|
||||||
|
// We exceeded the iteration count. Could be due to reference loops
|
||||||
|
// between the config nodes. At this point, just add the remaining
|
||||||
|
// nodes as-is
|
||||||
|
pendingConfigNodes.forEach(node => {
|
||||||
|
delete node._configNodeReferences
|
||||||
|
new_nodes.push(node)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Find regular flow nodes and subflow instances
|
// Find regular flow nodes and subflow instances
|
||||||
for (i=0;i<newNodes.length;i++) {
|
for (i=0;i<newNodes.length;i++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user