mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Fix config node sort order when importing
This commit is contained in:
parent
30eead76e6
commit
7fa4e60c82
@ -2099,6 +2099,8 @@ RED.nodes = (function() {
|
||||
activeWorkspace = RED.workspaces.active();
|
||||
}
|
||||
|
||||
const pendingConfigNodes = []
|
||||
const pendingConfigNodeIds = new Set()
|
||||
// Find all config nodes and add them
|
||||
for (i=0;i<newNodes.length;i++) {
|
||||
n = newNodes[i];
|
||||
@ -2158,7 +2160,8 @@ RED.nodes = (function() {
|
||||
type:n.type,
|
||||
info: n.info,
|
||||
users:[],
|
||||
_config:{}
|
||||
_config:{},
|
||||
_configNodeReferences: new Set()
|
||||
};
|
||||
if (!n.z) {
|
||||
delete configNode.z;
|
||||
@ -2173,6 +2176,9 @@ RED.nodes = (function() {
|
||||
if (def.defaults.hasOwnProperty(d)) {
|
||||
configNode[d] = 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')) {
|
||||
@ -2189,25 +2195,54 @@ RED.nodes = (function() {
|
||||
configNode.id = getID();
|
||||
}
|
||||
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
|
||||
// config node is added before to exists when updating the user list
|
||||
const configNodeFilter = function (node) {
|
||||
let count = 0;
|
||||
if (node._def?.defaults) {
|
||||
for (const def of Object.values(node._def.defaults)) {
|
||||
if (def.type) {
|
||||
count++;
|
||||
}
|
||||
// We need to sort new_nodes (which only contains config nodes at this point)
|
||||
// to ensure they get added in the right order. If NodeA depends on NodeB, then
|
||||
// NodeB must be added first.
|
||||
|
||||
// Limit us to 5 full iterations of the list - this should be more than
|
||||
// enough to process the list as config->config node relationships are
|
||||
// not very common
|
||||
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;
|
||||
};
|
||||
new_nodes.sort((a, b) => configNodeFilter(a) - configNodeFilter(b));
|
||||
iterationLimit--
|
||||
}
|
||||
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
|
||||
for (i=0;i<newNodes.length;i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user