Files
automatisch/packages/backend/src/models/step.ts
2022-10-14 22:33:26 +02:00

135 lines
3.3 KiB
TypeScript

import { QueryContext, ModelOptions } from 'objection';
import Base from './base';
import App from './app';
import Flow from './flow';
import Connection from './connection';
import ExecutionStep from './execution-step';
import type { IJSONObject, IStep } from '@automatisch/types';
import Telemetry from '../helpers/telemetry';
import appConfig from '../config/app';
class Step extends Base {
id!: string;
flowId!: string;
key?: string;
appKey?: string;
type!: IStep['type'];
connectionId?: string;
status = 'incomplete';
position!: number;
parameters: IJSONObject;
connection?: Connection;
flow: Flow;
executionSteps: ExecutionStep[];
static tableName = 'steps';
static jsonSchema = {
type: 'object',
required: ['type'],
properties: {
id: { type: 'string', format: 'uuid' },
flowId: { type: 'string', format: 'uuid' },
key: { type: ['string', 'null'] },
appKey: { type: ['string', 'null'], minLength: 1, maxLength: 255 },
type: { type: 'string', enum: ['action', 'trigger'] },
connectionId: { type: ['string', 'null'], format: 'uuid' },
status: { type: 'string', enum: ['incomplete', 'completed'] },
position: { type: 'integer' },
parameters: { type: 'object' },
},
};
static get virtualAttributes() {
return ['iconUrl'];
}
static relationMappings = () => ({
flow: {
relation: Base.BelongsToOneRelation,
modelClass: Flow,
join: {
from: 'steps.flow_id',
to: 'flows.id',
},
},
connection: {
relation: Base.HasOneRelation,
modelClass: Connection,
join: {
from: 'steps.connection_id',
to: 'connections.id',
},
},
executionSteps: {
relation: Base.HasManyRelation,
modelClass: ExecutionStep,
join: {
from: 'steps.id',
to: 'execution_steps.step_id',
},
},
});
get iconUrl() {
if (!this.appKey) return null;
return `${appConfig.baseUrl}/apps/${this.appKey}/assets/favicon.svg`;
}
async $afterInsert(queryContext: QueryContext) {
await super.$afterInsert(queryContext);
Telemetry.stepCreated(this);
}
async $afterUpdate(opt: ModelOptions, queryContext: QueryContext) {
await super.$afterUpdate(opt, queryContext);
Telemetry.stepUpdated(this);
}
get isTrigger(): boolean {
return this.type === 'trigger';
}
get isAction(): boolean {
return this.type === 'action';
}
async getApp() {
if (!this.appKey) return null;
return await App.findOneByKey(this.appKey);
}
async getNextStep() {
const flow = await this.$relatedQuery('flow');
return await flow
.$relatedQuery('steps')
.findOne({ position: this.position + 1 });
}
async getTriggerCommand() {
const { appKey, key, isTrigger } = this;
if (!isTrigger || !appKey || !key) return null;
const app = await App.findOneByKey(appKey);
const command = app.triggers.find((trigger) => trigger.key === key);
return command;
}
async getActionCommand() {
const { appKey, key, isAction } = this;
if (!isAction || !appKey || !key) return null;
const app = await App.findOneByKey(appKey);
const command = app.actions.find((action) => action.key === key);
return command;
}
}
export default Step;