Create record action (#8460)

- Add create record action
- Migrate all step name => action in a common folder
- Separate types
This commit is contained in:
Thomas Trompette
2024-11-13 15:21:40 +01:00
committed by GitHub
parent ba79a1d324
commit faeea2b887
27 changed files with 268 additions and 128 deletions

View File

@ -21,7 +21,7 @@ import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/f
import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity';
import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
import { WorkflowStep } from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import { WorkflowTrigger } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
export enum WorkflowVersionStatus {
@ -98,7 +98,7 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity {
icon: 'IconSettingsAutomation',
})
@WorkspaceIsNullable()
steps: WorkflowStep[] | null;
steps: WorkflowAction[] | null;
@WorkspaceField({
standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.status,

View File

@ -5,24 +5,24 @@ import { join } from 'path';
import { Repository } from 'typeorm';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
import { INDEX_FILE_NAME } from 'src/engine/core-modules/serverless/drivers/constants/index-file-name';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
import { CodeIntrospectionService } from 'src/modules/code-introspection/code-introspection.service';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record';
import { generateFakeObjectRecordEvent } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record-event';
import { WorkflowSendEmailStepOutputSchema } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/send-email.workflow-action';
import {
WorkflowAction,
WorkflowActionType,
WorkflowStep,
} from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import { WorkflowSendEmailStepOutputSchema } from 'src/modules/workflow/workflow-executor/types/workflow-step-settings.type';
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import {
WorkflowTrigger,
WorkflowTriggerType,
} from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
import { isDefined } from 'src/utils/is-defined';
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
import { generateFakeObjectRecordEvent } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record-event';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
@Injectable()
export class WorkflowBuilderWorkspaceService {
@ -37,7 +37,7 @@ export class WorkflowBuilderWorkspaceService {
step,
workspaceId,
}: {
step: WorkflowTrigger | WorkflowStep;
step: WorkflowTrigger | WorkflowAction;
workspaceId: string;
}): Promise<object> {
const stepType = step.type;
@ -57,7 +57,7 @@ export class WorkflowBuilderWorkspaceService {
return {};
}
return await this.computeManualTriggerOutputSchema({
return await this.computeRecordOutputSchema({
objectType,
workspaceId,
objectMetadataRepository: this.objectMetadataRepository,
@ -78,6 +78,12 @@ export class WorkflowBuilderWorkspaceService {
codeIntrospectionService: this.codeIntrospectionService,
});
}
case WorkflowActionType.RECORD_CRUD:
return await this.computeRecordOutputSchema({
objectType: step.settings.input.objectName,
workspaceId,
objectMetadataRepository: this.objectMetadataRepository,
});
default:
return {};
}
@ -116,7 +122,7 @@ export class WorkflowBuilderWorkspaceService {
);
}
private async computeManualTriggerOutputSchema<Entity>({
private async computeRecordOutputSchema<Entity>({
objectType,
workspaceId,
objectMetadataRepository,

View File

@ -2,19 +2,21 @@ import { Injectable } from '@nestjs/common';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
} from 'src/modules/workflow/workflow-executor/exceptions/workflow-step-executor.exception';
import { CodeWorkflowAction } from 'src/modules/serverless/workflow-actions/code.workflow-action';
import { SendEmailWorkflowAction } from 'src/modules/mail-sender/workflow-actions/send-email.workflow-action';
import { CodeWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/code/code.workflow-action';
import { SendEmailWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/send-email.workflow-action';
import { RecordCRUDWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/record-crud.workflow-action';
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
@Injectable()
export class WorkflowActionFactory {
constructor(
private readonly codeWorkflowAction: CodeWorkflowAction,
private readonly sendEmailWorkflowAction: SendEmailWorkflowAction,
private readonly recordCRUDWorkflowAction: RecordCRUDWorkflowAction,
) {}
get(stepType: WorkflowActionType): WorkflowAction {
@ -23,6 +25,8 @@ export class WorkflowActionFactory {
return this.codeWorkflowAction;
case WorkflowActionType.SEND_EMAIL:
return this.sendEmailWorkflowAction;
case WorkflowActionType.RECORD_CRUD:
return this.recordCRUDWorkflowAction;
default:
throw new WorkflowStepExecutorException(
`Workflow step executor not found for step type '${stepType}'`,

View File

@ -1,4 +1,4 @@
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/types/workflow-action-result.type';
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-result.type';
export interface WorkflowAction {
execute(workflowStepInput: unknown): Promise<WorkflowActionResult>;

View File

@ -1,30 +0,0 @@
import {
WorkflowCodeStepSettings,
WorkflowSendEmailStepSettings,
WorkflowStepSettings,
} from 'src/modules/workflow/workflow-executor/types/workflow-step-settings.type';
export enum WorkflowActionType {
CODE = 'CODE',
SEND_EMAIL = 'SEND_EMAIL',
}
type BaseWorkflowStep = {
id: string;
name: string;
type: WorkflowActionType;
settings: WorkflowStepSettings;
valid: boolean;
};
export type WorkflowCodeStep = BaseWorkflowStep & {
type: WorkflowActionType.CODE;
settings: WorkflowCodeStepSettings;
};
export type WorkflowSendEmailStep = BaseWorkflowStep & {
type: WorkflowActionType.SEND_EMAIL;
settings: WorkflowSendEmailStepSettings;
};
export type WorkflowStep = WorkflowCodeStep | WorkflowSendEmailStep;

View File

@ -1,45 +0,0 @@
export type OutputSchema = object;
type BaseWorkflowStepSettings = {
input: object;
outputSchema: OutputSchema;
errorHandlingOptions: {
retryOnFailure: {
value: boolean;
};
continueOnFailure: {
value: boolean;
};
};
};
export type WorkflowCodeStepInput = {
serverlessFunctionId: string;
serverlessFunctionVersion: string;
serverlessFunctionInput: {
[key: string]: any;
};
};
export type WorkflowCodeStepSettings = BaseWorkflowStepSettings & {
input: WorkflowCodeStepInput;
};
export type WorkflowSendEmailStepInput = {
connectedAccountId: string;
email: string;
subject?: string;
body?: string;
};
export type WorkflowSendEmailStepOutputSchema = {
success: boolean;
};
export type WorkflowSendEmailStepSettings = BaseWorkflowStepSettings & {
input: WorkflowSendEmailStepInput;
};
export type WorkflowStepSettings =
| WorkflowSendEmailStepSettings
| WorkflowCodeStepSettings;

View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { CodeWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/code/code.workflow-action';
@Module({
imports: [ServerlessFunctionModule],
providers: [ScopedWorkspaceContextFactory, CodeWorkflowAction],
exports: [CodeWorkflowAction],
})
export class CodeActionModule {}

View File

@ -0,0 +1,50 @@
import { Injectable } from '@nestjs/common';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
} from 'src/modules/workflow/workflow-executor/exceptions/workflow-step-executor.exception';
import { WorkflowCodeActionInput } from 'src/modules/workflow/workflow-executor/workflow-actions/code/types/workflow-code-action-input.type';
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-result.type';
@Injectable()
export class CodeWorkflowAction implements WorkflowAction {
constructor(
private readonly serverlessFunctionService: ServerlessFunctionService,
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
) {}
async execute(
workflowActionInput: WorkflowCodeActionInput,
): Promise<WorkflowActionResult> {
try {
const { workspaceId } = this.scopedWorkspaceContextFactory.create();
if (!workspaceId) {
throw new WorkflowStepExecutorException(
'Scoped workspace not found',
WorkflowStepExecutorExceptionCode.SCOPED_WORKSPACE_NOT_FOUND,
);
}
const result =
await this.serverlessFunctionService.executeOneServerlessFunction(
workflowActionInput.serverlessFunctionId,
workspaceId,
workflowActionInput.serverlessFunctionInput,
);
if (result.error) {
return { error: result.error };
}
return { result: result.data || {} };
} catch (error) {
return { error: error.message };
}
}
}

View File

@ -0,0 +1,7 @@
export type WorkflowCodeActionInput = {
serverlessFunctionId: string;
serverlessFunctionVersion: string;
serverlessFunctionInput: {
[key: string]: any;
};
};

View File

@ -0,0 +1,6 @@
import { WorkflowCodeActionInput } from 'src/modules/workflow/workflow-executor/workflow-actions/code/types/workflow-code-action-input.type';
import { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
export type WorkflowCodeActionSettings = BaseWorkflowActionSettings & {
input: WorkflowCodeActionInput;
};

View File

@ -0,0 +1,13 @@
import { CustomException } from 'src/utils/custom-exception';
export class SendEmailActionException extends CustomException {
code: SendEmailActionExceptionCode;
constructor(message: string, code: SendEmailActionExceptionCode) {
super(message, code);
}
}
export enum SendEmailActionExceptionCode {
PROVIDER_NOT_SUPPORTED = 'PROVIDER_NOT_SUPPORTED',
CONNECTED_ACCOUNT_NOT_FOUND = 'CONNECTED_ACCOUNT_NOT_FOUND',
}

View File

@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { OAuth2ClientManagerModule } from 'src/modules/connected-account/oauth2-client-manager/oauth2-client-manager.module';
import { GmailClientProvider } from 'src/modules/messaging/message-import-manager/drivers/gmail/providers/gmail-client.provider';
import { SendEmailWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/send-email.workflow-action';
@Module({
imports: [OAuth2ClientManagerModule],
providers: [
GmailClientProvider,
ScopedWorkspaceContextFactory,
SendEmailWorkflowAction,
],
exports: [SendEmailWorkflowAction],
})
export class SendEmailActionModule {}

View File

@ -0,0 +1,126 @@
import { Injectable, Logger } from '@nestjs/common';
import DOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
import { z } from 'zod';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import { GmailClientProvider } from 'src/modules/messaging/message-import-manager/drivers/gmail/providers/gmail-client.provider';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
} from 'src/modules/workflow/workflow-executor/exceptions/workflow-step-executor.exception';
import {
SendEmailActionException,
SendEmailActionExceptionCode,
} from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/exceptions/send-email-action.exception';
import { WorkflowSendEmailActionInput } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/types/workflow-send-email-action-input.type';
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-result.type';
import { isDefined } from 'src/utils/is-defined';
export type WorkflowSendEmailStepOutputSchema = {
success: boolean;
};
@Injectable()
export class SendEmailWorkflowAction implements WorkflowAction {
private readonly logger = new Logger(SendEmailWorkflowAction.name);
constructor(
private readonly gmailClientProvider: GmailClientProvider,
private readonly scopedWorkspaceContextFactory: ScopedWorkspaceContextFactory,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {}
private async getEmailClient(connectedAccountId: string) {
const { workspaceId } = this.scopedWorkspaceContextFactory.create();
if (!workspaceId) {
throw new WorkflowStepExecutorException(
'Scoped workspace not found',
WorkflowStepExecutorExceptionCode.SCOPED_WORKSPACE_NOT_FOUND,
);
}
const connectedAccountRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace<ConnectedAccountWorkspaceEntity>(
workspaceId,
'connectedAccount',
);
const connectedAccount = await connectedAccountRepository.findOneBy({
id: connectedAccountId,
});
if (!isDefined(connectedAccount)) {
throw new SendEmailActionException(
`Connected Account '${connectedAccountId}' not found`,
SendEmailActionExceptionCode.CONNECTED_ACCOUNT_NOT_FOUND,
);
}
switch (connectedAccount.provider) {
case 'google':
return await this.gmailClientProvider.getGmailClient(connectedAccount);
default:
throw new SendEmailActionException(
`Provider ${connectedAccount.provider} is not supported`,
SendEmailActionExceptionCode.PROVIDER_NOT_SUPPORTED,
);
}
}
async execute(
workflowActionInput: WorkflowSendEmailActionInput,
): Promise<WorkflowActionResult> {
const emailProvider = await this.getEmailClient(
workflowActionInput.connectedAccountId,
);
const { email, body, subject } = workflowActionInput;
try {
const emailSchema = z.string().trim().email('Invalid email');
const result = emailSchema.safeParse(email);
if (!result.success) {
this.logger.warn(`Email '${email}' invalid`);
return { result: { success: false } };
}
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const safeBody = purify.sanitize(body || '');
const safeSubject = purify.sanitize(subject || '');
const message = [
`To: ${email}`,
`Subject: ${safeSubject || ''}`,
'MIME-Version: 1.0',
'Content-Type: text/plain; charset="UTF-8"',
'',
safeBody,
].join('\n');
const encodedMessage = Buffer.from(message).toString('base64');
await emailProvider.users.messages.send({
userId: 'me',
requestBody: {
raw: encodedMessage,
},
});
this.logger.log(`Email sent successfully`);
return {
result: { success: true } satisfies WorkflowSendEmailStepOutputSchema,
};
} catch (error) {
return { error };
}
}
}

View File

@ -0,0 +1,6 @@
export type WorkflowSendEmailActionInput = {
connectedAccountId: string;
email: string;
subject?: string;
body?: string;
};

View File

@ -0,0 +1,6 @@
import { WorkflowSendEmailActionInput } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/types/workflow-send-email-action-input.type';
import { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
export type WorkflowSendEmailActionSettings = BaseWorkflowActionSettings & {
input: WorkflowSendEmailActionInput;
};

View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { RecordCRUDWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/record-crud.workflow-action';
@Module({
providers: [RecordCRUDWorkflowAction],
exports: [RecordCRUDWorkflowAction],
})
export class RecordCRUDActionModule {}

View File

@ -0,0 +1,45 @@
import { Injectable } from '@nestjs/common';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import {
WorkflowCreateRecordActionInput,
WorkflowRecordCRUDActionInput,
WorkflowRecordCRUDType,
} from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/types/workflow-record-crud-action-input.type';
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-result.type';
@Injectable()
export class RecordCRUDWorkflowAction implements WorkflowAction {
constructor(private readonly twentyORMManager: TwentyORMManager) {}
async execute(
workflowActionInput: WorkflowRecordCRUDActionInput,
): Promise<WorkflowActionResult> {
switch (workflowActionInput.type) {
case WorkflowRecordCRUDType.CREATE:
return this.createRecord(workflowActionInput);
default:
throw new Error(
`Unknown record operation type: ${workflowActionInput.type}`,
);
}
}
private async createRecord(
workflowActionInput: WorkflowCreateRecordActionInput,
): Promise<WorkflowActionResult> {
const repository = await this.twentyORMManager.getRepository(
workflowActionInput.objectName,
);
const objectRecord = await repository.create(
workflowActionInput.objectRecord,
);
const createdObjectRecord = await repository.save(objectRecord);
return { result: createdObjectRecord };
}
}

View File

@ -0,0 +1,31 @@
type ObjectRecord = Record<string, any>;
export enum WorkflowRecordCRUDType {
CREATE = 'create',
UPDATE = 'update',
DELETE = 'delete',
}
export type WorkflowCreateRecordActionInput = {
type: WorkflowRecordCRUDType.CREATE;
objectName: string;
objectRecord: ObjectRecord;
};
export type WorkflowUpdateRecordActionInput = {
type: WorkflowRecordCRUDType.UPDATE;
objectName: string;
objectRecord: ObjectRecord;
objectRecordId: string;
};
export type WorkflowDeleteRecordActionInput = {
type: WorkflowRecordCRUDType.DELETE;
objectName: string;
objectRecordId: string;
};
export type WorkflowRecordCRUDActionInput =
| WorkflowCreateRecordActionInput
| WorkflowUpdateRecordActionInput
| WorkflowDeleteRecordActionInput;

View File

@ -0,0 +1,6 @@
import { WorkflowRecordCRUDActionInput } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/types/workflow-record-crud-action-input.type';
import { BaseWorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
export type WorkflowRecordCRUDActionSettings = BaseWorkflowActionSettings & {
input: WorkflowRecordCRUDActionInput;
};

View File

@ -0,0 +1,23 @@
import { WorkflowCodeActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/code/types/workflow-code-action-settings.type';
import { WorkflowSendEmailActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/types/workflow-send-email-action-settings.type';
import { WorkflowRecordCRUDActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/types/workflow-record-crud-action-settings.type';
export type OutputSchema = object;
export type BaseWorkflowActionSettings = {
input: object;
outputSchema: OutputSchema;
errorHandlingOptions: {
retryOnFailure: {
value: boolean;
};
continueOnFailure: {
value: boolean;
};
};
};
export type WorkflowActionSettings =
| WorkflowSendEmailActionSettings
| WorkflowCodeActionSettings
| WorkflowRecordCRUDActionSettings;

View File

@ -0,0 +1,38 @@
import { WorkflowCodeActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/code/types/workflow-code-action-settings.type';
import { WorkflowSendEmailActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/types/workflow-send-email-action-settings.type';
import { WorkflowRecordCRUDActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/types/workflow-record-crud-action-settings.type';
import { WorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
export enum WorkflowActionType {
CODE = 'CODE',
SEND_EMAIL = 'SEND_EMAIL',
RECORD_CRUD = 'RECORD_CRUD',
}
type BaseWorkflowAction = {
id: string;
name: string;
type: WorkflowActionType;
settings: WorkflowActionSettings;
valid: boolean;
};
export type WorkflowCodeAction = BaseWorkflowAction & {
type: WorkflowActionType.CODE;
settings: WorkflowCodeActionSettings;
};
export type WorkflowSendEmailAction = BaseWorkflowAction & {
type: WorkflowActionType.SEND_EMAIL;
settings: WorkflowSendEmailActionSettings;
};
export type WorkflowRecordCRUDAction = BaseWorkflowAction & {
type: WorkflowActionType.RECORD_CRUD;
settings: WorkflowRecordCRUDActionSettings;
};
export type WorkflowAction =
| WorkflowCodeAction
| WorkflowSendEmailAction
| WorkflowRecordCRUDAction;

View File

@ -1,26 +1,24 @@
import { Module } from '@nestjs/common';
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
import { SendEmailWorkflowAction } from 'src/modules/mail-sender/workflow-actions/send-email.workflow-action';
import { MessagingGmailDriverModule } from 'src/modules/messaging/message-import-manager/drivers/gmail/messaging-gmail-driver.module';
import { CodeWorkflowAction } from 'src/modules/serverless/workflow-actions/code.workflow-action';
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
import { WorkflowActionFactory } from 'src/modules/workflow/workflow-executor/factories/workflow-action.factory';
import { CodeActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/code/code-action.module';
import { SendEmailActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/send-email-action.module';
import { RecordCRUDActionModule } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/record-crud-action.module';
import { WorkflowExecutorWorkspaceService } from 'src/modules/workflow/workflow-executor/workspace-services/workflow-executor.workspace-service';
@Module({
imports: [
WorkflowCommonModule,
ServerlessFunctionModule,
MessagingGmailDriverModule,
CodeActionModule,
SendEmailActionModule,
RecordCRUDActionModule,
],
providers: [
WorkflowExecutorWorkspaceService,
ScopedWorkspaceContextFactory,
WorkflowActionFactory,
CodeWorkflowAction,
SendEmailWorkflowAction,
],
exports: [WorkflowExecutorWorkspaceService],
})

View File

@ -5,8 +5,8 @@ import {
WorkflowRunStatus,
} from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
import { WorkflowActionFactory } from 'src/modules/workflow/workflow-executor/factories/workflow-action.factory';
import { WorkflowStep } from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import { resolveInput } from 'src/modules/workflow/workflow-executor/utils/variable-resolver.util';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
const MAX_RETRIES_ON_FAILURE = 3;
@ -27,7 +27,7 @@ export class WorkflowExecutorWorkspaceService {
attemptCount = 1,
}: {
currentStepIndex: number;
steps: WorkflowStep[];
steps: WorkflowAction[];
output: WorkflowExecutorOutput;
context: Record<string, unknown>;
attemptCount?: number;

View File

@ -1,4 +1,4 @@
import { OutputSchema } from 'src/modules/workflow/workflow-executor/types/workflow-step-settings.type';
import { OutputSchema } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
export enum WorkflowTriggerType {
DATABASE_EVENT = 'DATABASE_EVENT',