Add custom routes to migration v2 (#14846)

## Context
Add routes to migration V2
- Resolvers
- Service v2
- Builder
- Validator
- Action runner

Next PR: Add to twenty-cli to sync routes with serverless
This commit is contained in:
Weiko
2025-10-03 00:20:21 +02:00
committed by GitHub
parent dcfae3821c
commit 0b60aa4249
80 changed files with 2242 additions and 151 deletions
@@ -1,5 +1,6 @@
import { Field, InputType } from '@nestjs/graphql';
import { Type } from 'class-transformer';
import {
IsNotEmpty,
IsNumber,
@@ -9,6 +10,7 @@ import {
IsUUID,
Max,
Min,
ValidateNested,
} from 'class-validator';
import graphqlTypeJson from 'graphql-type-json';
@@ -16,14 +18,7 @@ import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/
import { ServerlessFunctionCode } from 'src/engine/metadata-modules/serverless-function/types/serverless-function-code.type';
@InputType()
export class UpdateServerlessFunctionInput {
@Field(() => UUIDScalarType, {
description: 'Id of the serverless function to execute',
})
@IsNotEmpty()
@IsUUID()
id: string;
class UpdateServerlessFunctionInputUpdates {
@IsString()
@Field()
name: string;
@@ -44,3 +39,20 @@ export class UpdateServerlessFunctionInput {
@IsObject()
code: ServerlessFunctionCode;
}
@InputType()
export class UpdateServerlessFunctionInput {
@Field(() => UUIDScalarType, {
description: 'Id of the serverless function to update',
})
@IsNotEmpty()
@IsUUID()
id: string;
@Type(() => UpdateServerlessFunctionInputUpdates)
@ValidateNested()
@Field(() => UpdateServerlessFunctionInputUpdates, {
description: 'The serverless function updates',
})
update: UpdateServerlessFunctionInputUpdates;
}
@@ -17,7 +17,7 @@ import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/inte
import { CronTrigger } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity';
import { DatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity';
import { Route } from 'src/engine/metadata-modules/route/route.entity';
import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
import { ServerlessFunctionEntityRelationProperties } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { InputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/input-schema.type';
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
@@ -33,7 +33,7 @@ export enum ServerlessFunctionRuntime {
export const SERVERLESS_FUNCTION_ENTITY_RELATION_PROPERTIES = [
'cronTriggers',
'databaseEventTriggers',
'routes',
'routeTriggers',
] as const satisfies readonly ServerlessFunctionEntityRelationProperties[];
@Entity('serverlessFunction')
@@ -119,10 +119,14 @@ export class ServerlessFunctionEntity
)
databaseEventTriggers: DatabaseEventTrigger[];
@OneToMany(() => Route, (route) => route.serverlessFunction, {
cascade: true,
})
routes: Route[];
@OneToMany(
() => RouteTrigger,
(routeTrigger) => routeTrigger.serverlessFunction,
{
cascade: true,
},
)
routeTriggers: RouteTrigger[];
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@@ -263,9 +263,9 @@ export class ServerlessFunctionService {
await this.serverlessFunctionRepository.update(
existingServerlessFunction.id,
{
name: serverlessFunctionInput.name,
description: serverlessFunctionInput.description,
timeoutSeconds: serverlessFunctionInput.timeoutSeconds,
name: serverlessFunctionInput.update.name,
description: serverlessFunctionInput.update.description,
timeoutSeconds: serverlessFunctionInput.update.timeoutSeconds,
},
);
@@ -275,7 +275,7 @@ export class ServerlessFunctionService {
});
await this.fileStorageService.writeFolder(
serverlessFunctionInput.code,
serverlessFunctionInput.update.code,
fileFolder,
);
@@ -1,7 +1,7 @@
import { type Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { type CronTrigger } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity';
import { type DatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity';
import { type Route } from 'src/engine/metadata-modules/route/route.entity';
import { type RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { type ExtractRecordTypeOrmRelationProperties } from 'src/engine/workspace-manager/workspace-migration-v2/types/extract-record-typeorm-relation-properties.type';
import { type ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
@@ -13,7 +13,7 @@ export type ServerlessFunctionEntityRelationProperties =
ServerlessFunctionEntity,
| CronTrigger
| DatabaseEventTrigger
| Route
| RouteTrigger
| Workspace
| ApplicationEntity
| ServerlessFunctionLayerEntity
@@ -42,14 +42,14 @@ export const fromUpdateServerlessFunctionInputToFlatServerlessFunctionToUpdateOr
const updatedEditableFieldProperties = {
...extractAndSanitizeObjectStringFields(
{
...rawUpdateServerlessFunctionInput,
...rawUpdateServerlessFunctionInput.update,
checksum: serverlessFunctionCreateHash(
JSON.stringify(rawUpdateServerlessFunctionInput.code),
JSON.stringify(rawUpdateServerlessFunctionInput.update.code),
),
},
FLAT_SERVERLESS_FUNCTION_EDITABLE_PROPERTIES,
),
code: rawUpdateServerlessFunctionInput.code,
code: rawUpdateServerlessFunctionInput.update.code,
};
return mergeUpdateInExistingRecord({