feat: compute step parameters with prior steps
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
"dependencies": {
|
||||
"@automatisch/web": "0.1.0",
|
||||
"@octokit/oauth-methods": "^1.2.6",
|
||||
"@types/lodash.get": "^4.4.6",
|
||||
"axios": "0.24.0",
|
||||
"bcrypt": "^5.0.1",
|
||||
"cors": "^2.8.5",
|
||||
@@ -32,6 +33,7 @@
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"http-errors": "~1.6.3",
|
||||
"knex": "^0.95.11",
|
||||
"lodash.get": "^4.4.2",
|
||||
"morgan": "^1.10.0",
|
||||
"nodemailer": "6.7.0",
|
||||
"objection": "^3.0.0",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import Step from '../../models/step';
|
||||
import flowType, { flowInputType } from '../types/flow';
|
||||
import RequestWithCurrentUser from '../../types/express/request-with-current-user';
|
||||
import StepEnumType from '../../types/step-enum-type';
|
||||
import { StepType } from '../../types/step';
|
||||
|
||||
type Params = {
|
||||
input: {
|
||||
@@ -21,7 +21,7 @@ const createFlowResolver = async (
|
||||
|
||||
await Step.query().insert({
|
||||
flowId: flow.id,
|
||||
type: StepEnumType.Trigger,
|
||||
type: StepType.Trigger,
|
||||
position: 1,
|
||||
appKey,
|
||||
});
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { GraphQLNonNull } from 'graphql';
|
||||
import stepType, { stepInputType } from '../types/step';
|
||||
import RequestWithCurrentUser from '../../types/express/request-with-current-user';
|
||||
import StepEnumType from '../../types/step-enum-type';
|
||||
import { StepType } from '../../types/step';
|
||||
|
||||
type Params = {
|
||||
input: {
|
||||
@@ -42,7 +42,7 @@ const createStepResolver = async (
|
||||
const step = await flow.$relatedQuery('steps').insertAndFetch({
|
||||
key: input.key,
|
||||
appKey: input.appKey,
|
||||
type: StepEnumType.Action,
|
||||
type: StepType.Action,
|
||||
position: previousStep.position + 1,
|
||||
parameters: {},
|
||||
});
|
||||
|
@@ -2,14 +2,14 @@ import Base from './base';
|
||||
import Flow from './flow';
|
||||
import Connection from './connection';
|
||||
import ExecutionStep from './execution-step';
|
||||
import StepEnumType from '../types/step-enum-type';
|
||||
import { StepType } from '../types/step';
|
||||
|
||||
class Step extends Base {
|
||||
id!: number;
|
||||
flowId!: string;
|
||||
key: string;
|
||||
appKey: string;
|
||||
type!: StepEnumType;
|
||||
type!: StepType;
|
||||
connectionId?: string;
|
||||
status: string;
|
||||
position: number;
|
||||
|
@@ -1,13 +1,19 @@
|
||||
import get from 'lodash.get';
|
||||
import App from '../models/app';
|
||||
import Flow from '../models/flow';
|
||||
import Step from '../models/step';
|
||||
import Execution from '../models/execution';
|
||||
import ExecutionStep from '../models/execution-step';
|
||||
import { StepType } from '../types/step';
|
||||
|
||||
type ExecutionSteps = Record<string, ExecutionStep>;
|
||||
|
||||
class Processor {
|
||||
flow: Flow;
|
||||
untilStep: Step;
|
||||
|
||||
static variableRegExp = /({{step\.\d*\..+?}})/g;
|
||||
|
||||
constructor(flow: Flow, untilStep: Step) {
|
||||
this.flow = flow;
|
||||
this.untilStep = untilStep;
|
||||
@@ -26,48 +32,71 @@ class Processor {
|
||||
|
||||
let previousExecutionStep: ExecutionStep;
|
||||
let fetchedData;
|
||||
const priorExecutionSteps: ExecutionSteps = {};
|
||||
|
||||
for await (const step of steps) {
|
||||
const appData = App.findOneByKey(step.appKey);
|
||||
const {
|
||||
appKey,
|
||||
connection,
|
||||
key,
|
||||
type,
|
||||
parameters: rawParameters = {},
|
||||
id
|
||||
} = step;
|
||||
const isTrigger = type === StepType.Trigger;
|
||||
const AppClass = (await import(`../apps/${appKey}`)).default;
|
||||
const computedParameters = Processor.computeParameters(rawParameters, priorExecutionSteps);
|
||||
const appInstance = new AppClass(appData, connection.data, computedParameters);
|
||||
const commands = isTrigger ? appInstance.triggers : appInstance.actions;
|
||||
const command = commands[key];
|
||||
fetchedData = await command.run();
|
||||
|
||||
if (step.type.toString() === 'trigger') {
|
||||
const appClass = (await import(`../apps/${step.appKey}`)).default;
|
||||
const appInstance = new appClass(appData, step.connection.data);
|
||||
fetchedData = await appInstance.triggers[step.key].run();
|
||||
previousExecutionStep = await execution
|
||||
.$relatedQuery('executionSteps')
|
||||
.insertAndFetch({
|
||||
stepId: id,
|
||||
status: 'success',
|
||||
dataIn: previousExecutionStep?.dataOut,
|
||||
dataOut: fetchedData,
|
||||
});
|
||||
|
||||
previousExecutionStep = await execution
|
||||
.$relatedQuery('executionSteps')
|
||||
.insertAndFetch({
|
||||
stepId: step.id,
|
||||
status: 'success',
|
||||
dataOut: fetchedData,
|
||||
});
|
||||
} else {
|
||||
const appClass = (await import(`../apps/${step.appKey}`)).default;
|
||||
const appInstance = new appClass(
|
||||
appData,
|
||||
step.connection.data,
|
||||
step.parameters
|
||||
);
|
||||
fetchedData = await appInstance.actions[step.key].run();
|
||||
priorExecutionSteps[id] = previousExecutionStep;
|
||||
|
||||
previousExecutionStep = await execution
|
||||
.$relatedQuery('executionSteps')
|
||||
.insertAndFetch({
|
||||
stepId: step.id,
|
||||
status: 'success',
|
||||
dataIn: previousExecutionStep.dataOut,
|
||||
dataOut: fetchedData,
|
||||
});
|
||||
}
|
||||
|
||||
if (step.id === this.untilStep.id) {
|
||||
if (id === this.untilStep.id) {
|
||||
return fetchedData;
|
||||
}
|
||||
}
|
||||
|
||||
return fetchedData;
|
||||
}
|
||||
|
||||
static computeParameters(parameters: Step["parameters"], executionSteps: ExecutionSteps): Step["parameters"] {
|
||||
const entries = Object.entries(parameters);
|
||||
return entries.reduce((result, [key, value]: [string, string]) => {
|
||||
const parts = value.split(Processor.variableRegExp);
|
||||
|
||||
const computedValue = parts.map((part: string) => {
|
||||
const isVariable = part.match(Processor.variableRegExp);
|
||||
if (isVariable) {
|
||||
const stepIdAndKeyPath = part.replace(/{{step.|}}/g, '') as string;
|
||||
const [stepId, ...keyPaths] = stepIdAndKeyPath.split('.');
|
||||
const keyPath = keyPaths.join('.');
|
||||
const executionStep = executionSteps[stepId.toString() as string];
|
||||
const data = executionStep?.dataOut;
|
||||
const dataValue = get(data, keyPath);
|
||||
return dataValue;
|
||||
}
|
||||
|
||||
return part;
|
||||
}).join('');
|
||||
|
||||
return {
|
||||
...result,
|
||||
[key]: computedValue,
|
||||
}
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
export default Processor;
|
||||
|
@@ -1,6 +0,0 @@
|
||||
enum StepEnumType {
|
||||
Trigger = 'trigger',
|
||||
Action = 'action',
|
||||
}
|
||||
|
||||
export default StepEnumType;
|
4
packages/backend/src/types/step.ts
Normal file
4
packages/backend/src/types/step.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum StepType {
|
||||
Trigger = 'trigger',
|
||||
Action = 'action',
|
||||
}
|
@@ -4166,6 +4166,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||
|
||||
"@types/lodash.get@^4.4.6":
|
||||
version "4.4.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.get/-/lodash.get-4.4.6.tgz#0c7ac56243dae0f9f09ab6f75b29471e2e777240"
|
||||
integrity sha512-E6zzjR3GtNig8UJG/yodBeJeIOtgPkMgsLjDU3CbgCAPC++vJ0eCMnJhVpRZb/ENqEFlov1+3K9TKtY4UdWKtQ==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash.template@^4.5.0":
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.template/-/lodash.template-4.5.0.tgz#277654af717ed37ce2687c69f8f221c550276b7a"
|
||||
|
Reference in New Issue
Block a user