|
import isEmpty from 'lodash/isEmpty.js'; |
|
|
|
import Flow from '../models/flow.js'; |
|
import { processTrigger } from '../services/trigger.js'; |
|
import { processAction } from '../services/action.js'; |
|
import globalVariable from './global-variable.js'; |
|
import QuotaExceededError from '../errors/quote-exceeded.js'; |
|
|
|
export default async (flowId, request, response) => { |
|
const flow = await Flow.query().findById(flowId).throwIfNotFound(); |
|
const user = await flow.$relatedQuery('user'); |
|
|
|
const testRun = !flow.active; |
|
const quotaExceeded = !testRun && !(await user.isAllowedToRunFlows()); |
|
|
|
if (quotaExceeded) { |
|
throw new QuotaExceededError(); |
|
} |
|
|
|
const [triggerStep, ...actionSteps] = await flow |
|
.$relatedQuery('steps') |
|
.withGraphFetched('connection') |
|
.orderBy('position', 'asc'); |
|
const app = await triggerStep.getApp(); |
|
const isWebhookApp = app.key === 'webhook'; |
|
|
|
if (testRun && !isWebhookApp) { |
|
return response.status(404); |
|
} |
|
|
|
const connection = await triggerStep.$relatedQuery('connection'); |
|
|
|
const $ = await globalVariable({ |
|
flow, |
|
connection, |
|
app, |
|
step: triggerStep, |
|
testRun, |
|
request, |
|
}); |
|
|
|
const triggerCommand = await triggerStep.getTriggerCommand(); |
|
await triggerCommand.run($); |
|
|
|
const reversedTriggerItems = $.triggerOutput.data.reverse(); |
|
|
|
|
|
|
|
|
|
if (isEmpty(reversedTriggerItems)) { |
|
return response.status(204); |
|
} |
|
|
|
|
|
response.status(204); |
|
|
|
for (const triggerItem of reversedTriggerItems) { |
|
const { executionId } = await processTrigger({ |
|
flowId, |
|
stepId: triggerStep.id, |
|
triggerItem, |
|
testRun, |
|
}); |
|
|
|
if (testRun) { |
|
|
|
continue; |
|
} |
|
|
|
for (const actionStep of actionSteps) { |
|
const { executionStep: actionExecutionStep } = await processAction({ |
|
flowId: flow.id, |
|
stepId: actionStep.id, |
|
executionId, |
|
}); |
|
|
|
if (actionStep.key === 'respondWith' && !response.headersSent) { |
|
const { headers, statusCode, body } = actionExecutionStep.dataOut; |
|
|
|
|
|
if (headers) { |
|
for (const [key, value] of Object.entries(headers)) { |
|
if (key) { |
|
response.set(key, value); |
|
} |
|
} |
|
} |
|
|
|
|
|
response.status(statusCode); |
|
response.send(body); |
|
} |
|
} |
|
} |
|
|
|
return response; |
|
}; |
|
|