2019-06-23 03:35:23 -07:00
|
|
|
import {
|
|
|
|
Db,
|
|
|
|
IExecutionDb,
|
|
|
|
IExecutionFlattedDb,
|
|
|
|
IPushDataExecutionFinished,
|
|
|
|
IWorkflowBase,
|
2019-08-08 11:38:25 -07:00
|
|
|
IWorkflowExecutionDataProcess,
|
2019-12-19 14:07:55 -08:00
|
|
|
NodeTypes,
|
2019-06-23 03:35:23 -07:00
|
|
|
Push,
|
|
|
|
ResponseHelper,
|
|
|
|
WebhookHelpers,
|
2020-01-20 08:22:12 -08:00
|
|
|
WorkflowCredentials,
|
2019-06-23 03:35:23 -07:00
|
|
|
WorkflowHelpers,
|
|
|
|
} from './';
|
|
|
|
|
|
|
|
import {
|
|
|
|
UserSettings,
|
2019-12-19 14:07:55 -08:00
|
|
|
WorkflowExecute,
|
2019-09-19 05:14:37 -07:00
|
|
|
} from 'n8n-core';
|
2019-06-23 03:35:23 -07:00
|
|
|
|
|
|
|
import {
|
2019-08-08 11:38:25 -07:00
|
|
|
IDataObject,
|
2019-12-19 14:07:55 -08:00
|
|
|
IExecuteData,
|
2020-01-02 15:13:53 -08:00
|
|
|
IExecuteWorkflowInfo,
|
2019-12-19 14:07:55 -08:00
|
|
|
INode,
|
2019-10-20 12:42:34 -07:00
|
|
|
INodeParameters,
|
2019-12-19 14:07:55 -08:00
|
|
|
INodeExecutionData,
|
2019-06-23 03:35:23 -07:00
|
|
|
IRun,
|
2019-12-19 14:07:55 -08:00
|
|
|
IRunExecutionData,
|
2019-06-23 03:35:23 -07:00
|
|
|
ITaskData,
|
2019-08-08 11:38:25 -07:00
|
|
|
IWorkflowCredentials,
|
2019-06-23 03:35:23 -07:00
|
|
|
IWorkflowExecuteAdditionalData,
|
2019-08-08 11:38:25 -07:00
|
|
|
IWorkflowExecuteHooks,
|
2019-12-19 14:07:55 -08:00
|
|
|
IWorkflowHooksOptionalParameters,
|
|
|
|
Workflow,
|
2019-06-23 03:35:23 -07:00
|
|
|
WorkflowExecuteMode,
|
2019-12-19 14:07:55 -08:00
|
|
|
WorkflowHooks,
|
2019-06-23 03:35:23 -07:00
|
|
|
} from 'n8n-workflow';
|
|
|
|
|
2019-07-21 10:47:41 -07:00
|
|
|
import * as config from '../config';
|
2019-06-23 03:35:23 -07:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if there was an error and if errorWorkflow is defined. If so it collects
|
|
|
|
* all the data and executes it
|
|
|
|
*
|
|
|
|
* @param {IWorkflowBase} workflowData The workflow which got executed
|
|
|
|
* @param {IRun} fullRunData The run which produced the error
|
2019-12-19 14:07:55 -08:00
|
|
|
* @param {WorkflowExecuteMode} mode The mode in which the workflow got started in
|
2019-06-23 03:35:23 -07:00
|
|
|
* @param {string} [executionId] The id the execution got saved as
|
|
|
|
*/
|
2019-09-11 08:48:14 -07:00
|
|
|
function executeErrorWorkflow(workflowData: IWorkflowBase, fullRunData: IRun, mode: WorkflowExecuteMode, executionId?: string, retryOf?: string): void {
|
2019-06-23 03:35:23 -07:00
|
|
|
// Check if there was an error and if so if an errorWorkflow is set
|
|
|
|
if (fullRunData.data.resultData.error !== undefined && workflowData.settings !== undefined && workflowData.settings.errorWorkflow) {
|
|
|
|
const workflowErrorData = {
|
|
|
|
execution: {
|
|
|
|
id: executionId,
|
|
|
|
error: fullRunData.data.resultData.error,
|
|
|
|
lastNodeExecuted: fullRunData.data.resultData.lastNodeExecuted!,
|
|
|
|
mode,
|
2019-09-11 08:48:14 -07:00
|
|
|
retryOf,
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
|
|
|
workflow: {
|
|
|
|
id: workflowData.id !== undefined ? workflowData.id.toString() as string : undefined,
|
|
|
|
name: workflowData.name,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Run the error workflow
|
|
|
|
WorkflowHelpers.executeErrorWorkflow(workflowData.settings.errorWorkflow as string, workflowErrorData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-07-24 05:25:30 -07:00
|
|
|
/**
|
|
|
|
* Pushes the execution out to all connected clients
|
|
|
|
*
|
2019-12-19 14:07:55 -08:00
|
|
|
* @param {WorkflowExecuteMode} mode The mode in which the workflow got started in
|
2019-07-24 05:25:30 -07:00
|
|
|
* @param {IRun} fullRunData The RunData of the finished execution
|
|
|
|
* @param {string} executionIdActive The id of the finished execution
|
|
|
|
* @param {string} [executionIdDb] The database id of finished execution
|
|
|
|
*/
|
2019-12-19 14:07:55 -08:00
|
|
|
export function pushExecutionFinished(mode: WorkflowExecuteMode, fullRunData: IRun, executionIdActive: string, executionIdDb?: string, retryOf?: string) {
|
2019-07-24 05:25:30 -07:00
|
|
|
// Clone the object except the runData. That one is not supposed
|
|
|
|
// to be send. Because that data got send piece by piece after
|
|
|
|
// each node which finished executing
|
|
|
|
const pushRunData = {
|
|
|
|
...fullRunData,
|
|
|
|
data: {
|
|
|
|
...fullRunData.data,
|
|
|
|
resultData: {
|
|
|
|
...fullRunData.data.resultData,
|
|
|
|
runData: {},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// Push data to editor-ui once workflow finished
|
|
|
|
const sendData: IPushDataExecutionFinished = {
|
|
|
|
executionIdActive,
|
|
|
|
executionIdDb,
|
|
|
|
data: pushRunData,
|
2019-08-08 22:37:10 -07:00
|
|
|
retryOf,
|
2019-07-24 05:25:30 -07:00
|
|
|
};
|
|
|
|
|
2019-08-28 06:28:47 -07:00
|
|
|
const pushInstance = Push.getInstance();
|
2019-07-24 05:25:30 -07:00
|
|
|
pushInstance.send('executionFinished', sendData);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-08-08 11:38:25 -07:00
|
|
|
/**
|
2019-12-19 14:07:55 -08:00
|
|
|
* Returns hook functions to push data to Editor-UI
|
2019-08-08 11:38:25 -07:00
|
|
|
*
|
|
|
|
* @returns {IWorkflowExecuteHooks}
|
|
|
|
*/
|
2019-12-19 14:07:55 -08:00
|
|
|
function hookFunctionsPush(): IWorkflowExecuteHooks {
|
2019-06-23 03:35:23 -07:00
|
|
|
return {
|
|
|
|
nodeExecuteBefore: [
|
2019-12-19 14:07:55 -08:00
|
|
|
async function (this: WorkflowHooks, nodeName: string): Promise<void> {
|
2019-08-08 11:38:25 -07:00
|
|
|
// Push data to session which started workflow before each
|
|
|
|
// node which starts rendering
|
2019-12-19 14:07:55 -08:00
|
|
|
if (this.sessionId === undefined) {
|
2019-06-23 03:35:23 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-28 06:28:47 -07:00
|
|
|
const pushInstance = Push.getInstance();
|
2019-08-08 11:38:25 -07:00
|
|
|
pushInstance.send('nodeExecuteBefore', {
|
2019-12-19 14:07:55 -08:00
|
|
|
executionId: this.executionId,
|
2019-06-23 03:35:23 -07:00
|
|
|
nodeName,
|
2019-12-19 14:07:55 -08:00
|
|
|
}, this.sessionId);
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
|
|
|
],
|
|
|
|
nodeExecuteAfter: [
|
2019-12-19 14:07:55 -08:00
|
|
|
async function (this: WorkflowHooks, nodeName: string, data: ITaskData): Promise<void> {
|
2019-08-08 11:38:25 -07:00
|
|
|
// Push data to session which started workflow after each rendered node
|
2019-12-19 14:07:55 -08:00
|
|
|
if (this.sessionId === undefined) {
|
2019-06-23 03:35:23 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-28 06:28:47 -07:00
|
|
|
const pushInstance = Push.getInstance();
|
2019-08-08 11:38:25 -07:00
|
|
|
pushInstance.send('nodeExecuteAfter', {
|
2019-12-19 14:07:55 -08:00
|
|
|
executionId: this.executionId,
|
2019-06-23 03:35:23 -07:00
|
|
|
nodeName,
|
|
|
|
data,
|
2019-12-19 14:07:55 -08:00
|
|
|
}, this.sessionId);
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
|
|
|
],
|
2019-07-24 05:25:30 -07:00
|
|
|
workflowExecuteBefore: [
|
2019-12-19 14:07:55 -08:00
|
|
|
async function (this: WorkflowHooks): Promise<void> {
|
2019-07-24 05:25:30 -07:00
|
|
|
// Push data to editor-ui once workflow finished
|
2019-08-28 06:28:47 -07:00
|
|
|
const pushInstance = Push.getInstance();
|
2019-08-08 11:38:25 -07:00
|
|
|
pushInstance.send('executionStarted', {
|
2019-12-19 14:07:55 -08:00
|
|
|
executionId: this.executionId,
|
|
|
|
mode: this.mode,
|
2019-07-24 05:25:30 -07:00
|
|
|
startedAt: new Date(),
|
2019-12-19 14:07:55 -08:00
|
|
|
retryOf: this.retryOf,
|
|
|
|
workflowId: this.workflowData.id as string,
|
|
|
|
workflowName: this.workflowData.name,
|
2019-08-08 11:38:25 -07:00
|
|
|
});
|
2019-07-24 05:25:30 -07:00
|
|
|
}
|
|
|
|
],
|
2019-06-23 03:35:23 -07:00
|
|
|
workflowExecuteAfter: [
|
2019-12-19 14:07:55 -08:00
|
|
|
async function (this: WorkflowHooks, fullRunData: IRun, newStaticData: IDataObject): Promise<void> {
|
|
|
|
pushExecutionFinished(this.mode, fullRunData, this.executionId, undefined, this.retryOf);
|
|
|
|
},
|
|
|
|
]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns hook functions to save workflow execution and call error workflow
|
|
|
|
*
|
|
|
|
* @returns {IWorkflowExecuteHooks}
|
|
|
|
*/
|
|
|
|
function hookFunctionsSave(parentProcessMode?: string): IWorkflowExecuteHooks {
|
|
|
|
return {
|
|
|
|
nodeExecuteBefore: [],
|
|
|
|
nodeExecuteAfter: [],
|
|
|
|
workflowExecuteBefore: [],
|
|
|
|
workflowExecuteAfter: [
|
|
|
|
async function (this: WorkflowHooks, fullRunData: IRun, newStaticData: IDataObject): Promise<void> {
|
|
|
|
|
|
|
|
const isManualMode = [this.mode, parentProcessMode].includes('manual');
|
|
|
|
|
2019-06-23 03:35:23 -07:00
|
|
|
try {
|
2019-12-19 14:07:55 -08:00
|
|
|
if (!isManualMode && WorkflowHelpers.isWorkflowIdValid(this.workflowData.id as string) === true && newStaticData) {
|
2019-08-08 11:38:25 -07:00
|
|
|
// Workflow is saved so update in database
|
|
|
|
try {
|
2019-12-19 14:07:55 -08:00
|
|
|
await WorkflowHelpers.saveStaticDataById(this.workflowData.id as string, newStaticData);
|
2019-08-08 11:38:25 -07:00
|
|
|
} catch (e) {
|
|
|
|
// TODO: Add proper logging!
|
2019-12-19 14:07:55 -08:00
|
|
|
console.error(`There was a problem saving the workflow with id "${this.workflowData.id}" to save changed staticData: ${e.message}`);
|
2019-08-08 11:38:25 -07:00
|
|
|
}
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2019-07-21 10:47:41 -07:00
|
|
|
let saveManualExecutions = config.get('executions.saveDataManualExecutions') as boolean;
|
2019-12-19 14:07:55 -08:00
|
|
|
if (this.workflowData.settings !== undefined && this.workflowData.settings.saveManualExecutions !== undefined) {
|
2019-06-23 03:35:23 -07:00
|
|
|
// Apply to workflow override
|
2019-12-19 14:07:55 -08:00
|
|
|
saveManualExecutions = this.workflowData.settings.saveManualExecutions as boolean;
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
if (isManualMode && saveManualExecutions === false) {
|
2019-07-10 11:53:13 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check config to know if execution should be saved or not
|
2019-07-21 10:47:41 -07:00
|
|
|
let saveDataErrorExecution = config.get('executions.saveDataOnError') as string;
|
|
|
|
let saveDataSuccessExecution = config.get('executions.saveDataOnSuccess') as string;
|
2019-12-19 14:07:55 -08:00
|
|
|
if (this.workflowData.settings !== undefined) {
|
|
|
|
saveDataErrorExecution = (this.workflowData.settings.saveDataErrorExecution as string) || saveDataErrorExecution;
|
|
|
|
saveDataSuccessExecution = (this.workflowData.settings.saveDataSuccessExecution as string) || saveDataSuccessExecution;
|
2019-07-10 11:53:13 -07:00
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2019-07-10 11:53:13 -07:00
|
|
|
const workflowDidSucceed = !fullRunData.data.resultData.error;
|
|
|
|
if (workflowDidSucceed === true && saveDataSuccessExecution === 'none' ||
|
|
|
|
workflowDidSucceed === false && saveDataErrorExecution === 'none'
|
|
|
|
) {
|
2019-12-19 14:07:55 -08:00
|
|
|
if (!isManualMode) {
|
|
|
|
executeErrorWorkflow(this.workflowData, fullRunData, this.mode, undefined, this.retryOf);
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const fullExecutionData: IExecutionDb = {
|
|
|
|
data: fullRunData.data,
|
|
|
|
mode: fullRunData.mode,
|
|
|
|
finished: fullRunData.finished ? fullRunData.finished : false,
|
|
|
|
startedAt: fullRunData.startedAt,
|
|
|
|
stoppedAt: fullRunData.stoppedAt,
|
2019-12-19 14:07:55 -08:00
|
|
|
workflowData: this.workflowData,
|
2019-06-23 03:35:23 -07:00
|
|
|
};
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
if (this.retryOf !== undefined) {
|
|
|
|
fullExecutionData.retryOf = this.retryOf.toString();
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
if (this.workflowData.id !== undefined && WorkflowHelpers.isWorkflowIdValid(this.workflowData.id.toString()) === true) {
|
|
|
|
fullExecutionData.workflowId = this.workflowData.id.toString();
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
const executionData = ResponseHelper.flattenExecutionData(fullExecutionData);
|
|
|
|
|
|
|
|
// Save the Execution in DB
|
|
|
|
const executionResult = await Db.collections.Execution!.save(executionData as IExecutionFlattedDb);
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
if (fullRunData.finished === true && this.retryOf !== undefined) {
|
2019-06-23 03:35:23 -07:00
|
|
|
// If the retry was successful save the reference it on the original execution
|
|
|
|
// await Db.collections.Execution!.save(executionData as IExecutionFlattedDb);
|
2019-12-19 14:07:55 -08:00
|
|
|
await Db.collections.Execution!.update(this.retryOf, { retrySuccessId: executionResult.id });
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
if (!isManualMode) {
|
|
|
|
executeErrorWorkflow(this.workflowData, fullRunData, this.mode, executionResult ? executionResult.id as string : undefined, this.retryOf);
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
} catch (error) {
|
2019-12-19 14:07:55 -08:00
|
|
|
if (!isManualMode) {
|
|
|
|
executeErrorWorkflow(this.workflowData, fullRunData, this.mode, undefined, this.retryOf);
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
};
|
2019-12-19 14:07:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Executes the workflow with the given ID
|
|
|
|
*
|
|
|
|
* @export
|
|
|
|
* @param {string} workflowId The id of the workflow to execute
|
|
|
|
* @param {IWorkflowExecuteAdditionalData} additionalData
|
|
|
|
* @param {INodeExecutionData[]} [inputData]
|
|
|
|
* @returns {(Promise<Array<INodeExecutionData[] | null>>)}
|
|
|
|
*/
|
2020-01-02 15:13:53 -08:00
|
|
|
export async function executeWorkflow(workflowInfo: IExecuteWorkflowInfo, additionalData: IWorkflowExecuteAdditionalData, inputData?: INodeExecutionData[]): Promise<Array<INodeExecutionData[] | null>> {
|
2019-12-19 14:07:55 -08:00
|
|
|
const mode = 'integrated';
|
|
|
|
|
2020-01-02 15:13:53 -08:00
|
|
|
if (workflowInfo.id === undefined && workflowInfo.code === undefined) {
|
|
|
|
throw new Error(`No information about the workflow to execute found. Please provide either the "id" or "code"!`);
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
if (Db.collections!.Workflow === null) {
|
|
|
|
// The first time executeWorkflow gets called the Database has
|
|
|
|
// to get initialized first
|
|
|
|
await Db.init();
|
|
|
|
}
|
|
|
|
|
2020-01-02 15:13:53 -08:00
|
|
|
let workflowData: IWorkflowBase | undefined;
|
|
|
|
if (workflowInfo.id !== undefined) {
|
|
|
|
workflowData = await Db.collections!.Workflow!.findOne(workflowInfo.id);
|
|
|
|
if (workflowData === undefined) {
|
|
|
|
throw new Error(`The workflow with the id "${workflowInfo.id}" does not exist.`);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
workflowData = workflowInfo.code;
|
2019-12-19 14:07:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
const nodeTypes = NodeTypes();
|
|
|
|
|
2020-01-02 15:13:53 -08:00
|
|
|
const workflow = new Workflow(workflowInfo.id, workflowData!.nodes, workflowData!.connections, workflowData!.active, nodeTypes, workflowData!.staticData);
|
2019-12-19 14:07:55 -08:00
|
|
|
|
|
|
|
// Does not get used so set it simply to empty string
|
|
|
|
const executionId = '';
|
|
|
|
|
|
|
|
// Create new additionalData to have different workflow loaded and to call
|
|
|
|
// different webooks
|
|
|
|
const additionalDataIntegrated = await getBase(additionalData.credentials);
|
2020-01-02 15:13:53 -08:00
|
|
|
additionalDataIntegrated.hooks = getWorkflowHooksIntegrated(mode, executionId, workflowData!, { parentProcessMode: additionalData.hooks!.mode });
|
2019-12-19 14:07:55 -08:00
|
|
|
|
2020-01-20 08:22:12 -08:00
|
|
|
// Get the needed credentials for the current workflow as they will differ to the ones of the
|
|
|
|
// calling workflow.
|
|
|
|
additionalDataIntegrated.credentials = await WorkflowCredentials(workflowData!.nodes);
|
|
|
|
|
2019-12-19 14:07:55 -08:00
|
|
|
// Find Start-Node
|
|
|
|
const requiredNodeTypes = ['n8n-nodes-base.start'];
|
|
|
|
let startNode: INode | undefined;
|
|
|
|
for (const node of workflowData!.nodes) {
|
|
|
|
if (requiredNodeTypes.includes(node.type)) {
|
|
|
|
startNode = node;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (startNode === undefined) {
|
|
|
|
// If the workflow does not contain a start-node we can not know what
|
|
|
|
// should be executed and with what data to start.
|
|
|
|
throw new Error(`The workflow does not contain a "Start" node and can so not be executed.`);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always start with empty data if no inputData got supplied
|
|
|
|
inputData = inputData || [
|
|
|
|
{
|
|
|
|
json: {}
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
// Initialize the incoming data
|
|
|
|
const nodeExecutionStack: IExecuteData[] = [];
|
|
|
|
nodeExecutionStack.push(
|
|
|
|
{
|
|
|
|
node: startNode,
|
|
|
|
data: {
|
|
|
|
main: [inputData],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
const runExecutionData: IRunExecutionData = {
|
|
|
|
startData: {
|
|
|
|
},
|
|
|
|
resultData: {
|
|
|
|
runData: {},
|
|
|
|
},
|
|
|
|
executionData: {
|
|
|
|
contextData: {},
|
|
|
|
nodeExecutionStack,
|
|
|
|
waitingExecution: {},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// Execute the workflow
|
|
|
|
const workflowExecute = new WorkflowExecute(additionalDataIntegrated, mode, runExecutionData);
|
|
|
|
const data = await workflowExecute.processRunExecutionData(workflow);
|
|
|
|
|
|
|
|
if (data.finished === true) {
|
|
|
|
// Workflow did finish successfully
|
|
|
|
const returnData = WorkflowHelpers.getDataLastExecutedNodeData(data);
|
|
|
|
return returnData!.data!.main;
|
|
|
|
} else {
|
|
|
|
// Workflow did fail
|
|
|
|
const error = new Error(data.data.resultData.error!.message);
|
|
|
|
error.stack = data.data.resultData.error!.stack;
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
|
|
|
|
2019-08-08 11:38:25 -07:00
|
|
|
/**
|
|
|
|
* Returns the base additional data without webhooks
|
|
|
|
*
|
|
|
|
* @export
|
|
|
|
* @param {IWorkflowCredentials} credentials
|
2019-12-19 14:07:55 -08:00
|
|
|
* @param {INodeParameters[]} [currentNodeParameters=[]]
|
2019-08-08 11:38:25 -07:00
|
|
|
* @returns {Promise<IWorkflowExecuteAdditionalData>}
|
|
|
|
*/
|
2019-12-19 14:07:55 -08:00
|
|
|
export async function getBase(credentials: IWorkflowCredentials, currentNodeParameters: INodeParameters[] = []): Promise<IWorkflowExecuteAdditionalData> {
|
2019-06-23 03:35:23 -07:00
|
|
|
const urlBaseWebhook = WebhookHelpers.getWebhookBaseUrl();
|
|
|
|
|
2019-07-21 10:47:41 -07:00
|
|
|
const timezone = config.get('generic.timezone') as string;
|
|
|
|
const webhookBaseUrl = urlBaseWebhook + config.get('endpoints.webhook') as string;
|
|
|
|
const webhookTestBaseUrl = urlBaseWebhook + config.get('endpoints.webhookTest') as string;
|
2019-06-23 03:35:23 -07:00
|
|
|
|
|
|
|
const encryptionKey = await UserSettings.getEncryptionKey();
|
|
|
|
if (encryptionKey === undefined) {
|
|
|
|
throw new Error('No encryption key got found to decrypt the credentials!');
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
2019-08-08 11:38:25 -07:00
|
|
|
credentials,
|
2019-06-23 03:35:23 -07:00
|
|
|
encryptionKey,
|
2019-12-19 14:07:55 -08:00
|
|
|
executeWorkflow,
|
|
|
|
restApiUrl: urlBaseWebhook + config.get('endpoints.rest') as string,
|
2019-06-23 03:35:23 -07:00
|
|
|
timezone,
|
|
|
|
webhookBaseUrl,
|
|
|
|
webhookTestBaseUrl,
|
2019-10-20 12:42:34 -07:00
|
|
|
currentNodeParameters,
|
2019-06-23 03:35:23 -07:00
|
|
|
};
|
|
|
|
}
|
2019-08-08 11:38:25 -07:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2019-12-19 14:07:55 -08:00
|
|
|
* Returns WorkflowHooks instance for running integrated workflows
|
|
|
|
* (Workflows which get started inside of another workflow)
|
|
|
|
*/
|
|
|
|
export function getWorkflowHooksIntegrated(mode: WorkflowExecuteMode, executionId: string, workflowData: IWorkflowBase, optionalParameters?: IWorkflowHooksOptionalParameters): WorkflowHooks {
|
|
|
|
optionalParameters = optionalParameters || {};
|
|
|
|
const hookFunctions = hookFunctionsSave(optionalParameters.parentProcessMode);
|
|
|
|
return new WorkflowHooks(hookFunctions, mode, executionId, workflowData, optionalParameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns WorkflowHooks instance for running the main workflow
|
2019-08-08 11:38:25 -07:00
|
|
|
*
|
|
|
|
* @export
|
|
|
|
* @param {IWorkflowExecutionDataProcess} data
|
|
|
|
* @param {string} executionId
|
2019-12-19 14:07:55 -08:00
|
|
|
* @returns {WorkflowHooks}
|
2019-08-08 11:38:25 -07:00
|
|
|
*/
|
2019-12-19 14:07:55 -08:00
|
|
|
export function getWorkflowHooksMain(data: IWorkflowExecutionDataProcess, executionId: string): WorkflowHooks {
|
|
|
|
const hookFunctions = hookFunctionsSave();
|
|
|
|
const pushFunctions = hookFunctionsPush();
|
|
|
|
for (const key of Object.keys(pushFunctions)) {
|
|
|
|
hookFunctions[key]!.push.apply(hookFunctions[key], pushFunctions[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new WorkflowHooks(hookFunctions, data.executionMode, executionId, data.workflowData, { sessionId: data.sessionId, retryOf: data.retryOf as string});
|
2019-08-08 11:38:25 -07:00
|
|
|
}
|