Spaces:
Build error
Build error
twenty / packages /twenty-server /src /engine /metadata-modules /logic-function /logic-function.resolver.ts
| import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; | |
| import { Args, Mutation, Query, Subscription } from '@nestjs/graphql'; | |
| import graphqlTypeJson from 'graphql-type-json'; | |
| import { PermissionFlagType } from 'twenty-shared/constants'; | |
| import { isDefined } from 'twenty-shared/utils'; | |
| import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; | |
| import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; | |
| import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; | |
| import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; | |
| import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; | |
| import { FeatureFlagGuard } from 'src/engine/guards/feature-flag.guard'; | |
| import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; | |
| import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; | |
| import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; | |
| import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; | |
| import { CreateLogicFunctionFromSourceInput } from 'src/engine/metadata-modules/logic-function/dtos/create-logic-function-from-source.input'; | |
| import { ExecuteOneLogicFunctionInput } from 'src/engine/metadata-modules/logic-function/dtos/execute-logic-function.input'; | |
| import { LogicFunctionExecutionResultDTO } from 'src/engine/metadata-modules/logic-function/dtos/logic-function-execution-result.dto'; | |
| import { LogicFunctionIdInput } from 'src/engine/metadata-modules/logic-function/dtos/logic-function-id.input'; | |
| import { LogicFunctionLogsDTO } from 'src/engine/metadata-modules/logic-function/dtos/logic-function-logs.dto'; | |
| import { LogicFunctionLogsInput } from 'src/engine/metadata-modules/logic-function/dtos/logic-function-logs.input'; | |
| import { LogicFunctionDTO } from 'src/engine/metadata-modules/logic-function/dtos/logic-function.dto'; | |
| import { UpdateLogicFunctionFromSourceInput } from 'src/engine/metadata-modules/logic-function/dtos/update-logic-function-from-source.input'; | |
| import { LogicFunctionFromSourceService } from 'src/engine/metadata-modules/logic-function/services/logic-function-from-source.service'; | |
| import { type FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/types/flat-logic-function.type'; | |
| import { findFlatLogicFunctionOrThrow } from 'src/engine/metadata-modules/logic-function/utils/find-flat-logic-function-or-throw.util'; | |
| import { fromFlatLogicFunctionToLogicFunctionDto } from 'src/engine/metadata-modules/logic-function/utils/from-flat-logic-function-to-logic-function-dto.util'; | |
| import { logicFunctionGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/logic-function/utils/logic-function-graphql-api-exception-handler.utils'; | |
| import { APPLICATION_KEEPALIVE_INTERVAL_MS } from 'src/engine/subscriptions/constants/application-keepalive-interval-ms.constant'; | |
| import { SubscriptionChannel } from 'src/engine/subscriptions/enums/subscription-channel.enum'; | |
| import { SubscriptionService } from 'src/engine/subscriptions/subscription.service'; | |
| import { wrapAsyncIteratorWithLifecycle } from 'src/engine/subscriptions/utils/wrap-async-iterator-with-lifecycle'; | |
| import { EventLogLiveService } from 'src/engine/core-modules/event-logs/live/event-log-live.service'; | |
| (WorkspaceAuthGuard, FeatureFlagGuard, NoPermissionGuard) | |
| () | |
| (ResolverValidationPipe) | |
| (PreventNestToAutoLogGraphqlErrorsFilter) | |
| export class LogicFunctionResolver { | |
| constructor( | |
| private readonly logicFunctionFromSourceService: LogicFunctionFromSourceService, | |
| private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, | |
| private readonly subscriptionService: SubscriptionService, | |
| private readonly eventLogLiveService: EventLogLiveService, | |
| ) {} | |
| (() => LogicFunctionDTO) | |
| async findOneLogicFunction( | |
| ('input') { id }: LogicFunctionIdInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<LogicFunctionDTO> { | |
| try { | |
| const { flatLogicFunctionMaps } = | |
| await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( | |
| { | |
| workspaceId, | |
| flatMapsKeys: ['flatLogicFunctionMaps'], | |
| }, | |
| ); | |
| const flatLogicFunction = findFlatLogicFunctionOrThrow({ | |
| id, | |
| flatLogicFunctionMaps, | |
| }); | |
| return fromFlatLogicFunctionToLogicFunctionDto({ flatLogicFunction }); | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => [LogicFunctionDTO]) | |
| async findManyLogicFunctions( | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<LogicFunctionDTO[]> { | |
| try { | |
| const { flatLogicFunctionMaps } = | |
| await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( | |
| { | |
| workspaceId, | |
| flatMapsKeys: ['flatLogicFunctionMaps'], | |
| }, | |
| ); | |
| return Object.values(flatLogicFunctionMaps.byUniversalIdentifier) | |
| .filter( | |
| (flatLogicFunction): flatLogicFunction is FlatLogicFunction => | |
| isDefined(flatLogicFunction) && | |
| !isDefined(flatLogicFunction.deletedAt), | |
| ) | |
| .map((flatLogicFunction) => | |
| fromFlatLogicFunctionToLogicFunctionDto({ flatLogicFunction }), | |
| ); | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => graphqlTypeJson) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async getAvailablePackages( | |
| ('input') { id }: LogicFunctionIdInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ) { | |
| try { | |
| const { flatLogicFunctionMaps, flatApplicationMaps } = | |
| await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( | |
| { | |
| workspaceId, | |
| flatMapsKeys: ['flatLogicFunctionMaps', 'flatApplicationMaps'], | |
| }, | |
| ); | |
| const logicFunctionUniversalIdentifier = | |
| flatLogicFunctionMaps.universalIdentifierById[id]; | |
| if (!logicFunctionUniversalIdentifier) { | |
| return {}; | |
| } | |
| const logicFunction = | |
| flatLogicFunctionMaps.byUniversalIdentifier[ | |
| logicFunctionUniversalIdentifier | |
| ]; | |
| if (!logicFunction) { | |
| return {}; | |
| } | |
| const application = flatApplicationMaps.byId[logicFunction.applicationId]; | |
| return application?.availablePackages ?? {}; | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => LogicFunctionDTO) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async deleteOneLogicFunction( | |
| ('input') { id }: LogicFunctionIdInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<LogicFunctionDTO> { | |
| try { | |
| return await this.logicFunctionFromSourceService.deleteOneWithSource({ | |
| id, | |
| workspaceId, | |
| }); | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => LogicFunctionDTO) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async createOneLogicFunction( | |
| ('input') input: CreateLogicFunctionFromSourceInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<LogicFunctionDTO> { | |
| try { | |
| return await this.logicFunctionFromSourceService.createOneFromSource({ | |
| input, | |
| workspaceId, | |
| }); | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => LogicFunctionExecutionResultDTO) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async executeOneLogicFunction( | |
| ('input') { id, payload }: ExecuteOneLogicFunctionInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<LogicFunctionExecutionResultDTO> { | |
| try { | |
| return await this.logicFunctionFromSourceService.executeOneFromSource({ | |
| id, | |
| payload, | |
| workspaceId, | |
| }); | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => String, { nullable: true }) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async getLogicFunctionSourceCode( | |
| ('input') { id }: LogicFunctionIdInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ) { | |
| try { | |
| return await this.logicFunctionFromSourceService.getSourceCode({ | |
| id, | |
| workspaceId, | |
| }); | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => Boolean) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async updateOneLogicFunction( | |
| ('input') | |
| updateLogicFunctionFromSourceInput: UpdateLogicFunctionFromSourceInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<boolean> { | |
| try { | |
| await this.logicFunctionFromSourceService.updateOneFromSource({ | |
| updateLogicFunctionFromSourceInput, | |
| workspaceId, | |
| }); | |
| return true; | |
| } catch (error) { | |
| return logicFunctionGraphQLApiExceptionHandler(error); | |
| } | |
| } | |
| (() => LogicFunctionLogsDTO, { | |
| filter: ( | |
| payload: { logicFunctionLogs: LogicFunctionLogsDTO }, | |
| variables: { input: LogicFunctionLogsInput }, | |
| ) => { | |
| const { logicFunctionLogs } = payload; | |
| const { | |
| id, | |
| universalIdentifier, | |
| applicationId, | |
| applicationUniversalIdentifier, | |
| name, | |
| } = logicFunctionLogs; | |
| const { | |
| id: inputId, | |
| universalIdentifier: inputUniversalIdentifier, | |
| name: inputName, | |
| applicationId: inputApplicationId, | |
| applicationUniversalIdentifier: inputApplicationUniversalIdentifier, | |
| } = variables.input; | |
| return ( | |
| (!isDefined(inputId) || inputId === id) && | |
| (!isDefined(inputUniversalIdentifier) || | |
| inputUniversalIdentifier === universalIdentifier) && | |
| (!isDefined(inputName) || inputName === name) && | |
| (!isDefined(inputApplicationId) || | |
| inputApplicationId === applicationId) && | |
| (!isDefined(inputApplicationUniversalIdentifier) || | |
| inputApplicationUniversalIdentifier === | |
| applicationUniversalIdentifier) | |
| ); | |
| }, | |
| }) | |
| (SettingsPermissionGuard(PermissionFlagType.WORKFLOWS)) | |
| async logicFunctionLogs( | |
| ('input') _: LogicFunctionLogsInput, | |
| () workspace: WorkspaceEntity, | |
| ) { | |
| // Register CLI presence (refreshed by the heartbeat) so the executor only publishes when watched. | |
| await this.eventLogLiveService.markWatched( | |
| workspace.id, | |
| SubscriptionChannel.LOGIC_FUNCTION_LOGS_CHANNEL, | |
| ); | |
| const iterator = await this.subscriptionService.subscribe({ | |
| channel: SubscriptionChannel.LOGIC_FUNCTION_LOGS_CHANNEL, | |
| workspaceId: workspace.id, | |
| }); | |
| return wrapAsyncIteratorWithLifecycle(iterator, { | |
| onHeartbeat: async () => { | |
| await this.eventLogLiveService.markWatched( | |
| workspace.id, | |
| SubscriptionChannel.LOGIC_FUNCTION_LOGS_CHANNEL, | |
| ); | |
| return true; | |
| }, | |
| heartbeatIntervalMs: APPLICATION_KEEPALIVE_INTERVAL_MS, | |
| }); | |
| } | |
| } | |