mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
⚡ Improve selection of start node for manual execution
This commit is contained in:
parent
b38623fa92
commit
f568122e3a
|
@ -46,36 +46,36 @@ export class WorkflowExecute {
|
||||||
* @returns {(Promise<string>)}
|
* @returns {(Promise<string>)}
|
||||||
* @memberof WorkflowExecute
|
* @memberof WorkflowExecute
|
||||||
*/
|
*/
|
||||||
async run(workflow: Workflow, startNodes?: INode[], destinationNode?: string): Promise<string> {
|
async run(workflow: Workflow, startNode?: INode, destinationNode?: string): Promise<string> {
|
||||||
// Get the nodes to start workflow execution from
|
// Get the nodes to start workflow execution from
|
||||||
startNodes = startNodes || workflow.getStartNodes(destinationNode);
|
startNode = startNode || workflow.getStartNode(destinationNode);
|
||||||
|
|
||||||
|
if (startNode === undefined) {
|
||||||
|
throw new Error('No node to start the workflow from could be found!');
|
||||||
|
}
|
||||||
|
|
||||||
// If a destination node is given we only run the direct parent nodes and no others
|
// If a destination node is given we only run the direct parent nodes and no others
|
||||||
let runNodeFilter: string[] | undefined = undefined;
|
let runNodeFilter: string[] | undefined = undefined;
|
||||||
if (destinationNode) {
|
if (destinationNode) {
|
||||||
// TODO: Combine that later with getStartNodes which does more or less the same tree iteration
|
|
||||||
runNodeFilter = workflow.getParentNodes(destinationNode);
|
runNodeFilter = workflow.getParentNodes(destinationNode);
|
||||||
runNodeFilter.push(destinationNode);
|
runNodeFilter.push(destinationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the data of the start nodes
|
// Initialize the data of the start nodes
|
||||||
const nodeExecutionStack: IExecuteData[] = [];
|
const nodeExecutionStack: IExecuteData[] = [
|
||||||
startNodes.forEach((node) => {
|
{
|
||||||
nodeExecutionStack.push(
|
node: startNode,
|
||||||
{
|
data: {
|
||||||
node,
|
main: [
|
||||||
data: {
|
[
|
||||||
main: [
|
{
|
||||||
[
|
json: {},
|
||||||
{
|
},
|
||||||
json: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
);
|
}
|
||||||
});
|
];
|
||||||
|
|
||||||
const runExecutionData: IRunExecutionData = {
|
const runExecutionData: IRunExecutionData = {
|
||||||
startData: {
|
startData: {
|
||||||
|
|
|
@ -707,40 +707,62 @@ export class Workflow {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the start nodes which can be found in the workflow.
|
* Returns the start node to start the worfklow from
|
||||||
*
|
*
|
||||||
* @param {(string | undefined)} [destinationNode]
|
* @param {string} [destinationNode]
|
||||||
* @returns {INode[]}
|
* @returns {(INode | undefined)}
|
||||||
* @memberof Workflow
|
* @memberof Workflow
|
||||||
*/
|
*/
|
||||||
getStartNodes(destinationNode?: string): INode[] {
|
getStartNode(destinationNode?: string): INode | undefined {
|
||||||
const returnData: INode[] = [];
|
const startNodeType = 'n8n-nodes-base.start';
|
||||||
|
|
||||||
if (destinationNode) {
|
if (destinationNode) {
|
||||||
// Find the highest parent nodes of the given one
|
// Find the highest parent nodes of the given one
|
||||||
const nodeNames = this.getHighestNode(destinationNode);
|
const nodeNames = this.getHighestNode(destinationNode);
|
||||||
|
|
||||||
if (nodeNames.length === 0) {
|
if (nodeNames.length === 0) {
|
||||||
// If no parent nodes have been found then only the destination-node
|
// If no parent nodes have been found then only the destination-node
|
||||||
// is in the tree so add that one
|
// is in the tree so add that one
|
||||||
nodeNames.push(destinationNode);
|
nodeNames.push(destinationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeNames.forEach((nodeName) => {
|
// Check which node to return as start node
|
||||||
returnData.push(this.nodes[nodeName]);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// No node given so find all the nodes which do not have any input
|
|
||||||
let nodeType: INodeType | undefined;
|
|
||||||
for (const nodeName of Object.keys(this.nodes)) {
|
|
||||||
nodeType = this.nodeTypes.getByName(this.nodes[nodeName].type);
|
|
||||||
|
|
||||||
if (nodeType !== undefined && nodeType.description.inputs.length === 0 && this.nodes[nodeName].disabled !== true) {
|
// Check if there are any trigger nodes and then return the first one
|
||||||
returnData.push(this.nodes[nodeName]);
|
let node: INode;
|
||||||
|
let nodeType: INodeType;
|
||||||
|
for (const nodeName of nodeNames) {
|
||||||
|
node = this.nodes[nodeName];
|
||||||
|
nodeType = this.nodeTypes.getByName(node.type) as INodeType;
|
||||||
|
|
||||||
|
if (nodeType.trigger !== undefined) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there is the actual "start" node
|
||||||
|
for (const nodeName of nodeNames) {
|
||||||
|
node = this.nodes[nodeName];
|
||||||
|
if (node.type === startNodeType) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If none of the above did find anything simply return the
|
||||||
|
// first parent node in the list
|
||||||
|
return this.nodes[nodeNames[0]];
|
||||||
|
} else {
|
||||||
|
// No node given so start from "start" node
|
||||||
|
let node: INode;
|
||||||
|
for (const nodeName of Object.keys(this.nodes)) {
|
||||||
|
node = this.nodes[nodeName];
|
||||||
|
if (node.type === startNodeType) {
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnData;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue