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:
+67
@@ -0,0 +1,67 @@
|
||||
import { type MigrationInterface, type QueryRunner } from 'typeorm';
|
||||
|
||||
export class SetServerlessFunctionIdInTriggersNonNullable1759417994272
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'SetServerlessFunctionIdInTriggersNonNullable1759417994272';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."cronTrigger" DROP CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."cronTrigger" ALTER COLUMN "serverlessFunctionId" SET NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."databaseEventTrigger" DROP CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."databaseEventTrigger" ALTER COLUMN "serverlessFunctionId" SET NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" DROP CONSTRAINT "FK_c63b1110bbf09051be2f495d0be"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" ALTER COLUMN "serverlessFunctionId" SET NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."cronTrigger" ADD CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."databaseEventTrigger" ADD CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" ADD CONSTRAINT "FK_c63b1110bbf09051be2f495d0be" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" DROP CONSTRAINT "FK_c63b1110bbf09051be2f495d0be"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."databaseEventTrigger" DROP CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."cronTrigger" DROP CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" ALTER COLUMN "serverlessFunctionId" DROP NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" ADD CONSTRAINT "FK_c63b1110bbf09051be2f495d0be" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."databaseEventTrigger" ALTER COLUMN "serverlessFunctionId" DROP NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."databaseEventTrigger" ADD CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."cronTrigger" ALTER COLUMN "serverlessFunctionId" DROP NOT NULL`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."cronTrigger" ADD CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
import { type MigrationInterface, type QueryRunner } from 'typeorm';
|
||||
|
||||
export class RenameRouteToRouteTrigger1759418198310
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'RenameRouteToRouteTrigger1759418198310';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."route" RENAME TO "routeTrigger"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TYPE "core"."route_httpmethod_enum" RENAME TO "routeTrigger_httpmethod_enum"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER INDEX "core"."IDX_1c39502392dd9cbb186deba158" RENAME TO "IDX_e9c53b9ac5035d3202a8737020"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "FK_c63b1110bbf09051be2f495d0be"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "IDX_ROUTE_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE" UNIQUE ("path", "httpMethod", "workspaceId")`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "FK_c89ed9d929873119478fc0d9cc5" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "FK_c89ed9d929873119478fc0d9cc5"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "IDX_ROUTE_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE" UNIQUE ("path", "httpMethod", "workspaceId")`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "FK_c63b1110bbf09051be2f495d0be" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER INDEX "core"."IDX_e9c53b9ac5035d3202a8737020" RENAME TO "IDX_1c39502392dd9cbb186deba158"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TYPE "core"."routeTrigger_httpmethod_enum" RENAME TO "route_httpmethod_enum"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."routeTrigger" RENAME TO "route"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -369,9 +369,11 @@ export class ApplicationSyncService {
|
||||
|
||||
const updateServerlessFunctionInput = {
|
||||
id: serverlessFunctionToUpdate.id,
|
||||
name: serverlessFunctionToSync.name,
|
||||
timeoutSeconds: serverlessFunctionToSync.timeoutSeconds,
|
||||
code: serverlessFunctionToSync.code,
|
||||
update: {
|
||||
name: serverlessFunctionToSync.name,
|
||||
timeoutSeconds: serverlessFunctionToSync.timeoutSeconds,
|
||||
code: serverlessFunctionToSync.code,
|
||||
},
|
||||
};
|
||||
|
||||
await this.serverlessFunctionV2Service.updateOne(
|
||||
@@ -505,8 +507,10 @@ export class ApplicationSyncService {
|
||||
|
||||
const updateDatabaseEventTriggerInput = {
|
||||
id: triggerToUpdate.id,
|
||||
settings: {
|
||||
eventName: triggerToSync.eventName,
|
||||
update: {
|
||||
settings: {
|
||||
eventName: triggerToSync.eventName,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -616,8 +620,10 @@ export class ApplicationSyncService {
|
||||
|
||||
const updateCronTriggerInput = {
|
||||
id: triggerToUpdate.id,
|
||||
settings: {
|
||||
pattern: triggerToSync.schedule,
|
||||
update: {
|
||||
settings: {
|
||||
pattern: triggerToSync.schedule,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+1
@@ -8,5 +8,6 @@ export const ALL_FLAT_ENTITY_MAPS_PROPERTIES = [
|
||||
'flatServerlessFunctionMaps',
|
||||
'flatDatabaseEventTriggerMaps',
|
||||
'flatCronTriggerMaps',
|
||||
'flatRouteTriggerMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
] as const satisfies (keyof AllFlatEntityMaps)[];
|
||||
|
||||
+1
@@ -10,4 +10,5 @@ export const EMPTY_ALL_FLAT_ENTITY_MAPS = {
|
||||
flatServerlessFunctionMaps: EMPTY_FLAT_ENTITY_MAPS,
|
||||
flatCronTriggerMaps: EMPTY_FLAT_ENTITY_MAPS,
|
||||
flatDatabaseEventTriggerMaps: EMPTY_FLAT_ENTITY_MAPS,
|
||||
flatRouteTriggerMaps: EMPTY_FLAT_ENTITY_MAPS,
|
||||
} as const satisfies AllFlatEntityMaps;
|
||||
|
||||
+2
@@ -5,6 +5,7 @@ import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/datab
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
|
||||
|
||||
export type AllFlatEntitiesByMetadataEngineName = {
|
||||
@@ -16,4 +17,5 @@ export type AllFlatEntitiesByMetadataEngineName = {
|
||||
serverlessFunction: FlatServerlessFunction;
|
||||
cronTrigger: FlatCronTrigger;
|
||||
databaseEventTrigger: FlatDatabaseEventTrigger;
|
||||
routeTrigger: FlatRouteTrigger;
|
||||
};
|
||||
|
||||
+20
-7
@@ -1,19 +1,32 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { IsNotEmpty, IsObject, IsUUID } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsNotEmpty, IsObject, IsUUID, ValidateNested } from 'class-validator';
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
|
||||
import { CronTriggerSettings } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity';
|
||||
|
||||
@InputType()
|
||||
export class UpdateCronTriggerInput {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field(() => String)
|
||||
id: string;
|
||||
|
||||
class UpdateCronTriggerInputUpdates {
|
||||
@IsObject()
|
||||
@IsNotEmpty()
|
||||
@Field(() => GraphQLJSON)
|
||||
settings: CronTriggerSettings;
|
||||
}
|
||||
|
||||
@InputType()
|
||||
export class UpdateCronTriggerInput {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field(() => String, {
|
||||
description: 'The id of the cron trigger to update',
|
||||
})
|
||||
id: string;
|
||||
|
||||
@Type(() => UpdateCronTriggerInputUpdates)
|
||||
@ValidateNested()
|
||||
@Field(() => UpdateCronTriggerInputUpdates, {
|
||||
description: 'The cron trigger updates',
|
||||
})
|
||||
update: UpdateCronTriggerInputUpdates;
|
||||
}
|
||||
|
||||
+2
-2
@@ -40,8 +40,8 @@ export class CronTrigger extends SyncableEntity {
|
||||
@JoinColumn({ name: 'serverlessFunctionId' })
|
||||
serverlessFunction: Relation<ServerlessFunctionEntity>;
|
||||
|
||||
@Column({ nullable: true, type: 'uuid' })
|
||||
serverlessFunctionId: string | null;
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
serverlessFunctionId: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
workspaceId: string;
|
||||
|
||||
+1
@@ -9,4 +9,5 @@ export class CronTriggerException extends CustomException {
|
||||
export enum CronTriggerExceptionCode {
|
||||
CRON_TRIGGER_NOT_FOUND = 'CRON_TRIGGER_NOT_FOUND',
|
||||
CRON_TRIGGER_ALREADY_EXIST = 'CRON_TRIGGER_ALREADY_EXIST',
|
||||
SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND',
|
||||
}
|
||||
|
||||
+19
-5
@@ -36,7 +36,7 @@ export class CronTriggerV2Service {
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatCronTriggerMaps'],
|
||||
flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -64,6 +64,10 @@ export class CronTriggerV2Service {
|
||||
to: toFlatCronTriggerMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
flatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
@@ -82,7 +86,7 @@ export class CronTriggerV2Service {
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatCronTriggerMaps'],
|
||||
flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -100,7 +104,7 @@ export class CronTriggerV2Service {
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatCronTriggerMaps'],
|
||||
flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -131,6 +135,10 @@ export class CronTriggerV2Service {
|
||||
to: toFlatCronTriggerMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
flatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
@@ -166,11 +174,14 @@ export class CronTriggerV2Service {
|
||||
destroyCronTriggerInput: CronTriggerIdInput;
|
||||
workspaceId: string;
|
||||
}): Promise<FlatCronTrigger> {
|
||||
const { flatCronTriggerMaps: existingFlatCronTriggerMaps } =
|
||||
const {
|
||||
flatCronTriggerMaps: existingFlatCronTriggerMaps,
|
||||
flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatCronTriggerMaps'],
|
||||
flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -202,6 +213,9 @@ export class CronTriggerV2Service {
|
||||
to: toFlatCronTriggerMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: true,
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ export const fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow = ({
|
||||
|
||||
return {
|
||||
...existingFlatCronTrigger,
|
||||
settings: updateCronTriggerInput.settings,
|
||||
settings: updateCronTriggerInput.update.settings,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
};
|
||||
|
||||
+20
-7
@@ -1,19 +1,32 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { IsNotEmpty, IsObject, IsUUID } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsNotEmpty, IsObject, IsUUID, ValidateNested } from 'class-validator';
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
|
||||
import { DatabaseEventTriggerSettings } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity';
|
||||
|
||||
@InputType()
|
||||
export class UpdateDatabaseEventTriggerInput {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
id: string;
|
||||
|
||||
class UpdateDatabaseEventTriggerInputUpdates {
|
||||
@IsObject()
|
||||
@IsNotEmpty()
|
||||
@Field(() => GraphQLJSON)
|
||||
settings: DatabaseEventTriggerSettings;
|
||||
}
|
||||
|
||||
@InputType()
|
||||
export class UpdateDatabaseEventTriggerInput {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field({
|
||||
description: 'The id of the database event trigger to update',
|
||||
})
|
||||
id: string;
|
||||
|
||||
@Type(() => UpdateDatabaseEventTriggerInputUpdates)
|
||||
@ValidateNested()
|
||||
@Field(() => UpdateDatabaseEventTriggerInputUpdates, {
|
||||
description: 'The database event trigger updates',
|
||||
})
|
||||
update: UpdateDatabaseEventTriggerInputUpdates;
|
||||
}
|
||||
|
||||
+2
-2
@@ -43,8 +43,8 @@ export class DatabaseEventTrigger
|
||||
@JoinColumn({ name: 'serverlessFunctionId' })
|
||||
serverlessFunction: Relation<ServerlessFunctionEntity>;
|
||||
|
||||
@Column({ nullable: true, type: 'uuid' })
|
||||
serverlessFunctionId: string | null;
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
serverlessFunctionId: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
workspaceId: string;
|
||||
|
||||
+2
@@ -9,4 +9,6 @@ export class DatabaseEventTriggerException extends CustomException {
|
||||
export enum DatabaseEventTriggerExceptionCode {
|
||||
DATABASE_EVENT_TRIGGER_NOT_FOUND = 'DATABASE_EVENT_TRIGGER_NOT_FOUND',
|
||||
DATABASE_EVENT_TRIGGER_ALREADY_EXIST = 'DATABASE_EVENT_TRIGGER_ALREADY_EXIST',
|
||||
DATABASE_EVENT_TRIGGER_INVALID = 'DATABASE_EVENT_TRIGGER_INVALID',
|
||||
SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND',
|
||||
}
|
||||
|
||||
+24
-3
@@ -36,7 +36,10 @@ export class DatabaseEventTriggerV2Service {
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatDatabaseEventTriggerMaps'],
|
||||
flatEntities: [
|
||||
'flatDatabaseEventTriggerMaps',
|
||||
'flatServerlessFunctionMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -66,6 +69,10 @@ export class DatabaseEventTriggerV2Service {
|
||||
to: toFlatDatabaseEventTriggerMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
flatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
@@ -105,7 +112,10 @@ export class DatabaseEventTriggerV2Service {
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatDatabaseEventTriggerMaps'],
|
||||
flatEntities: [
|
||||
'flatDatabaseEventTriggerMaps',
|
||||
'flatServerlessFunctionMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -140,6 +150,10 @@ export class DatabaseEventTriggerV2Service {
|
||||
to: toFlatDatabaseEventTriggerMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
flatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
@@ -180,11 +194,15 @@ export class DatabaseEventTriggerV2Service {
|
||||
}): Promise<FlatDatabaseEventTrigger> {
|
||||
const {
|
||||
flatDatabaseEventTriggerMaps: existingFlatDatabaseEventTriggerMaps,
|
||||
flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatDatabaseEventTriggerMaps'],
|
||||
flatEntities: [
|
||||
'flatDatabaseEventTriggerMaps',
|
||||
'flatServerlessFunctionMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -219,6 +237,9 @@ export class DatabaseEventTriggerV2Service {
|
||||
to: toFlatDatabaseEventTriggerMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: true,
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ export const fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpda
|
||||
|
||||
return {
|
||||
...existingFlatDatabaseEventTrigger,
|
||||
settings: updateDatabaseEventTriggerInput.settings,
|
||||
settings: updateDatabaseEventTriggerInput.update.settings,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
};
|
||||
|
||||
+1
@@ -38,6 +38,7 @@ export const throwOnFieldInputTranspilationsError: ThrowOnFieldInputTranspilatio
|
||||
serverlessFunction: [],
|
||||
databaseEventTrigger: [],
|
||||
cronTrigger: [],
|
||||
routeTrigger: [],
|
||||
},
|
||||
status: 'fail',
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SearchFieldMetadataModule } from 'src/engine/metadata-modules/search-fi
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { RouteModule } from 'src/engine/metadata-modules/route/route.module';
|
||||
import { RouteTriggerModule } from 'src/engine/metadata-modules/route-trigger/route-trigger.module';
|
||||
import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.module';
|
||||
|
||||
@Module({
|
||||
@@ -30,7 +30,7 @@ import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serve
|
||||
RemoteServerModule,
|
||||
RoleModule,
|
||||
PermissionsModule,
|
||||
RouteModule,
|
||||
RouteTriggerModule,
|
||||
CronTriggerModule,
|
||||
DatabaseEventTriggerModule,
|
||||
],
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
|
||||
export const FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES = [
|
||||
'path',
|
||||
'isAuthRequired',
|
||||
'httpMethod',
|
||||
] as const satisfies (keyof FlatRouteTrigger)[];
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant';
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
|
||||
export const FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE = [
|
||||
...FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES,
|
||||
] as const satisfies (keyof FlatRouteTrigger)[];
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { Field, HideField, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsString,
|
||||
IsUUID,
|
||||
} from 'class-validator';
|
||||
|
||||
import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
|
||||
@InputType()
|
||||
export class CreateRouteTriggerInput {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
path: string;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field({ defaultValue: true })
|
||||
isAuthRequired: boolean;
|
||||
|
||||
@IsEnum(HTTPMethod)
|
||||
@IsNotEmpty()
|
||||
@Field(() => HTTPMethod, { defaultValue: HTTPMethod.GET })
|
||||
httpMethod: HTTPMethod;
|
||||
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
serverlessFunctionId: string;
|
||||
|
||||
@HideField()
|
||||
universalIdentifier?: string;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { IsNotEmpty, IsUUID } from 'class-validator';
|
||||
|
||||
@InputType()
|
||||
export class RouteTriggerIdInput {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
id: string;
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
|
||||
registerEnumType(HTTPMethod, { name: 'HTTPMethod' });
|
||||
|
||||
@ObjectType('RouteTrigger')
|
||||
export class RouteTriggerDTO {
|
||||
@Field(() => ID)
|
||||
id: string;
|
||||
|
||||
@Field()
|
||||
path: string;
|
||||
|
||||
@Field()
|
||||
isAuthRequired: boolean;
|
||||
|
||||
@Field(() => HTTPMethod)
|
||||
httpMethod: HTTPMethod;
|
||||
|
||||
@Field()
|
||||
serverlessFunctionId: string;
|
||||
|
||||
@Field()
|
||||
workspaceId: string;
|
||||
|
||||
@Field()
|
||||
createdAt: Date;
|
||||
|
||||
@Field()
|
||||
updatedAt: Date;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsString,
|
||||
IsUUID,
|
||||
ValidateNested,
|
||||
} from 'class-validator';
|
||||
|
||||
import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
|
||||
@InputType()
|
||||
class UpdateRouteTriggerInputUpdates {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
path: string;
|
||||
|
||||
@IsBoolean()
|
||||
@IsNotEmpty()
|
||||
@Field()
|
||||
isAuthRequired: boolean;
|
||||
|
||||
@IsEnum(HTTPMethod)
|
||||
@IsNotEmpty()
|
||||
@Field(() => HTTPMethod)
|
||||
httpMethod: HTTPMethod;
|
||||
}
|
||||
|
||||
@InputType()
|
||||
export class UpdateRouteTriggerInput {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@Field({
|
||||
description: 'The id of the route to update',
|
||||
})
|
||||
id: string;
|
||||
|
||||
@Type(() => UpdateRouteTriggerInputUpdates)
|
||||
@ValidateNested()
|
||||
@Field(() => UpdateRouteTriggerInputUpdates, {
|
||||
description: 'The route updates',
|
||||
})
|
||||
update: UpdateRouteTriggerInputUpdates;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { CustomException } from 'src/utils/custom-exception';
|
||||
|
||||
export class RouteTriggerException extends CustomException {
|
||||
code: RouteTriggerExceptionCode;
|
||||
constructor(message: string, code: RouteTriggerExceptionCode) {
|
||||
super(message, code);
|
||||
}
|
||||
}
|
||||
|
||||
export enum RouteTriggerExceptionCode {
|
||||
ROUTE_NOT_FOUND = 'ROUTE_NOT_FOUND',
|
||||
ROUTE_ALREADY_EXIST = 'ROUTE_ALREADY_EXIST',
|
||||
ROUTE_INVALID = 'ROUTE_INVALID',
|
||||
ROUTE_PATH_ALREADY_EXIST = 'ROUTE_PATH_ALREADY_EXIST',
|
||||
SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND',
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
|
||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
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 { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input';
|
||||
import { RouteTriggerIdInput } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input';
|
||||
import { RouteTriggerDTO } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto';
|
||||
import { UpdateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input';
|
||||
import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service';
|
||||
import { routeTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils';
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@Resolver()
|
||||
@UsePipes(ResolverValidationPipe)
|
||||
@UseFilters(PreventNestToAutoLogGraphqlErrorsFilter)
|
||||
export class RouteTriggerResolver {
|
||||
constructor(
|
||||
private readonly routeV2Service: RouteTriggerV2Service,
|
||||
@InjectRepository(RouteTrigger)
|
||||
private readonly routeTriggerRepository: Repository<RouteTrigger>,
|
||||
) {}
|
||||
|
||||
@Query(() => RouteTriggerDTO)
|
||||
async findOneRouteTrigger(
|
||||
@Args('input') { id }: RouteTriggerIdInput,
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
try {
|
||||
return await this.routeTriggerRepository.findOneOrFail({
|
||||
where: {
|
||||
id,
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
routeTriggerGraphQLApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@Query(() => [RouteTriggerDTO])
|
||||
async findManyRouteTriggers(@AuthWorkspace() { id: workspaceId }: Workspace) {
|
||||
try {
|
||||
return await this.routeTriggerRepository.find({
|
||||
where: { workspaceId },
|
||||
});
|
||||
} catch (error) {
|
||||
routeTriggerGraphQLApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@Mutation(() => RouteTriggerDTO)
|
||||
async deleteOneRouteTrigger(
|
||||
@Args('input') input: RouteTriggerIdInput,
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
try {
|
||||
return await this.routeV2Service.destroyOne({
|
||||
destroyRouteInput: input,
|
||||
workspaceId,
|
||||
});
|
||||
} catch (error) {
|
||||
routeTriggerGraphQLApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@Mutation(() => RouteTriggerDTO)
|
||||
async updateOneRouteTrigger(
|
||||
@Args('input')
|
||||
input: UpdateRouteTriggerInput,
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
try {
|
||||
return await this.routeV2Service.updateOne(input, workspaceId);
|
||||
} catch (error) {
|
||||
routeTriggerGraphQLApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@Mutation(() => RouteTriggerDTO)
|
||||
async createOneRouteTrigger(
|
||||
@Args('input')
|
||||
input: CreateRouteTriggerInput,
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
try {
|
||||
return await this.routeV2Service.createOne(input, workspaceId);
|
||||
} catch (error) {
|
||||
routeTriggerGraphQLApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -12,20 +12,20 @@ import {
|
||||
|
||||
import { Request } from 'express';
|
||||
|
||||
import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard';
|
||||
import { RouteService } from 'src/engine/metadata-modules/route/route.service';
|
||||
import { HTTPMethod } from 'src/engine/metadata-modules/route/route.entity';
|
||||
import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter';
|
||||
import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard';
|
||||
import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { RouteTriggerService } from 'src/engine/metadata-modules/route-trigger/route-trigger.service';
|
||||
|
||||
@Controller('s')
|
||||
@UseGuards(PublicEndpointGuard)
|
||||
@UseFilters(RestApiExceptionFilter)
|
||||
export class RouteController {
|
||||
constructor(private readonly routeService: RouteService) {}
|
||||
export class RouteTriggerController {
|
||||
constructor(private readonly routeTriggerService: RouteTriggerService) {}
|
||||
|
||||
@Get('*')
|
||||
async get(@Req() request: Request) {
|
||||
return await this.routeService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.GET,
|
||||
});
|
||||
@@ -33,7 +33,7 @@ export class RouteController {
|
||||
|
||||
@Post('*')
|
||||
async post(@Req() request: Request) {
|
||||
return await this.routeService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.POST,
|
||||
});
|
||||
@@ -41,7 +41,7 @@ export class RouteController {
|
||||
|
||||
@Put('*')
|
||||
async put(@Req() request: Request) {
|
||||
return await this.routeService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.PUT,
|
||||
});
|
||||
@@ -49,7 +49,7 @@ export class RouteController {
|
||||
|
||||
@Patch('*')
|
||||
async patch(@Req() request: Request) {
|
||||
return await this.routeService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.PATCH,
|
||||
});
|
||||
@@ -57,7 +57,7 @@ export class RouteController {
|
||||
|
||||
@Delete('*')
|
||||
async delete(@Req() request: Request) {
|
||||
return await this.routeService.handle({
|
||||
return await this.routeTriggerService.handle({
|
||||
request,
|
||||
httpMethod: HTTPMethod.DELETE,
|
||||
});
|
||||
+16
-5
@@ -6,12 +6,13 @@ import {
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
Relation,
|
||||
UpdateDateColumn,
|
||||
Unique,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/interfaces/syncable-entity.interface';
|
||||
|
||||
import { RouteTriggerEntityRelationProperties } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
|
||||
export enum HTTPMethod {
|
||||
@@ -22,13 +23,20 @@ export enum HTTPMethod {
|
||||
DELETE = 'DELETE',
|
||||
}
|
||||
|
||||
@Entity({ name: 'route', schema: 'core' })
|
||||
@Unique('IDX_ROUTE_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE', [
|
||||
export const ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES = [
|
||||
'serverlessFunction',
|
||||
] as const satisfies readonly RouteTriggerEntityRelationProperties[];
|
||||
|
||||
@Entity({ name: 'routeTrigger', schema: 'core' })
|
||||
@Unique('IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE', [
|
||||
'path',
|
||||
'httpMethod',
|
||||
'workspaceId',
|
||||
])
|
||||
export class Route extends SyncableEntity {
|
||||
export class RouteTrigger
|
||||
extends SyncableEntity
|
||||
implements Required<RouteTrigger>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@@ -48,12 +56,15 @@ export class Route extends SyncableEntity {
|
||||
|
||||
@ManyToOne(
|
||||
() => ServerlessFunctionEntity,
|
||||
(serverlessFunction) => serverlessFunction.routes,
|
||||
(serverlessFunction) => serverlessFunction.routeTriggers,
|
||||
{ onDelete: 'CASCADE' },
|
||||
)
|
||||
@JoinColumn({ name: 'serverlessFunctionId' })
|
||||
serverlessFunction: Relation<ServerlessFunctionEntity>;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
serverlessFunctionId: string;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
workspaceId: string;
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { AuthModule } from 'src/engine/core-modules/auth/auth.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { DomainManagerModule } from 'src/engine/core-modules/domain-manager/domain-manager.module';
|
||||
import { RouteTriggerResolver } from 'src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver';
|
||||
import { RouteTriggerController } from 'src/engine/metadata-modules/route-trigger/route-trigger.controller';
|
||||
import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { RouteTriggerService } from 'src/engine/metadata-modules/route-trigger/route-trigger.service';
|
||||
import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service';
|
||||
import { WorkspaceFlatRouteTriggerMapCacheService } from 'src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([RouteTrigger]),
|
||||
AuthModule,
|
||||
DomainManagerModule,
|
||||
ServerlessFunctionModule,
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
WorkspaceMigrationV2Module,
|
||||
],
|
||||
controllers: [RouteTriggerController],
|
||||
providers: [
|
||||
RouteTriggerService,
|
||||
RouteTriggerV2Service,
|
||||
WorkspaceFlatRouteTriggerMapCacheService,
|
||||
RouteTriggerResolver,
|
||||
],
|
||||
exports: [RouteTriggerV2Service, WorkspaceFlatRouteTriggerMapCacheService],
|
||||
})
|
||||
export class RouteTriggerModule {}
|
||||
+27
-24
@@ -12,8 +12,8 @@ import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
HTTPMethod,
|
||||
Route,
|
||||
} from 'src/engine/metadata-modules/route/route.entity';
|
||||
RouteTrigger,
|
||||
} from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import {
|
||||
@@ -23,23 +23,23 @@ import {
|
||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||
|
||||
@Injectable()
|
||||
export class RouteService {
|
||||
export class RouteTriggerService {
|
||||
constructor(
|
||||
private readonly accessTokenService: AccessTokenService,
|
||||
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||
private readonly domainManagerService: DomainManagerService,
|
||||
@InjectRepository(Route)
|
||||
private readonly routeRepository: Repository<Route>,
|
||||
@InjectRepository(RouteTrigger)
|
||||
private readonly routeTriggerRepository: Repository<RouteTrigger>,
|
||||
) {}
|
||||
|
||||
private async getOneRouteWithPathParamsOrFail({
|
||||
private async getOneRouteTriggerWithPathParamsOrFail({
|
||||
request,
|
||||
httpMethod,
|
||||
}: {
|
||||
request: Request;
|
||||
httpMethod: HTTPMethod;
|
||||
}): Promise<{
|
||||
route: Route;
|
||||
routeTrigger: RouteTrigger;
|
||||
pathParams: Partial<Record<string, string | string[]>>;
|
||||
}> {
|
||||
const host = `${request.protocol}://${request.get('host')}`;
|
||||
@@ -57,7 +57,7 @@ export class RouteService {
|
||||
),
|
||||
);
|
||||
|
||||
const routes = await this.routeRepository.find({
|
||||
const routeTriggers = await this.routeTriggerRepository.find({
|
||||
where: {
|
||||
httpMethod,
|
||||
workspaceId: workspace.id,
|
||||
@@ -67,19 +67,21 @@ export class RouteService {
|
||||
|
||||
const requestPath = request.path.replace(/^\/s\//, '/');
|
||||
|
||||
for (const route of routes) {
|
||||
const routeMatcher = match(route.path, { decode: decodeURIComponent });
|
||||
const routeMatched = routeMatcher(requestPath);
|
||||
for (const routeTrigger of routeTriggers) {
|
||||
const routeTriggerMatcher = match(routeTrigger.path, {
|
||||
decode: decodeURIComponent,
|
||||
});
|
||||
const routeTriggerMatched = routeTriggerMatcher(requestPath);
|
||||
|
||||
if (routeMatched) {
|
||||
if (routeTriggerMatched) {
|
||||
return {
|
||||
route,
|
||||
pathParams: routeMatched.params,
|
||||
routeTrigger,
|
||||
pathParams: routeTriggerMatched.params,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundException('No Route found');
|
||||
throw new NotFoundException('No Route trigger found');
|
||||
}
|
||||
|
||||
private async validateWorkspaceFromRequest({
|
||||
@@ -108,15 +110,16 @@ export class RouteService {
|
||||
request: Request;
|
||||
httpMethod: HTTPMethod;
|
||||
}) {
|
||||
const routeWithPathParams = await this.getOneRouteWithPathParamsOrFail({
|
||||
request,
|
||||
httpMethod,
|
||||
});
|
||||
const routeTriggerWithPathParams =
|
||||
await this.getOneRouteTriggerWithPathParamsOrFail({
|
||||
request,
|
||||
httpMethod,
|
||||
});
|
||||
|
||||
if (routeWithPathParams.route.isAuthRequired) {
|
||||
if (routeTriggerWithPathParams.routeTrigger.isAuthRequired) {
|
||||
await this.validateWorkspaceFromRequest({
|
||||
request,
|
||||
workspaceId: routeWithPathParams.route.workspaceId,
|
||||
workspaceId: routeTriggerWithPathParams.routeTrigger.workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,12 +130,12 @@ export class RouteService {
|
||||
const executionParams = {
|
||||
...queryParams,
|
||||
...bodyParams,
|
||||
...routeWithPathParams.pathParams,
|
||||
...routeTriggerWithPathParams.pathParams,
|
||||
};
|
||||
|
||||
return await this.serverlessFunctionService.executeOneServerlessFunction(
|
||||
routeWithPathParams.route.serverlessFunction.id,
|
||||
routeWithPathParams.route.workspaceId,
|
||||
routeTriggerWithPathParams.routeTrigger.serverlessFunction.id,
|
||||
routeTriggerWithPathParams.routeTrigger.workspaceId,
|
||||
executionParams,
|
||||
'draft',
|
||||
);
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { getSubFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/get-sub-flat-entity-maps-or-throw.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
||||
import { CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input';
|
||||
import { RouteTriggerIdInput } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input';
|
||||
import { UpdateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input';
|
||||
import {
|
||||
RouteTriggerException,
|
||||
RouteTriggerExceptionCode,
|
||||
} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
|
||||
import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { fromCreateRouteTriggerInputToFlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util';
|
||||
import { fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow } from 'src/engine/metadata-modules/route-trigger/utils/from-update-route-trigger-input-to-flat-route-trigger-to-update-or-throw.util';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class RouteTriggerV2Service {
|
||||
constructor(
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
) {}
|
||||
|
||||
async createOne(routeInput: CreateRouteTriggerInput, workspaceId: string) {
|
||||
const flatEntityMaps =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const existingFlatRouteMaps = flatEntityMaps.flatRouteTriggerMaps;
|
||||
|
||||
const flatRouteTriggerToCreate =
|
||||
fromCreateRouteTriggerInputToFlatRouteTrigger({
|
||||
createRouteTriggerInput: routeInput,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const toFlatRouteMaps = addFlatEntityToFlatEntityMapsOrThrow({
|
||||
flatEntity: flatRouteTriggerToCreate,
|
||||
flatEntityMaps: existingFlatRouteMaps,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
workspaceId,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatRouteTriggerMaps: {
|
||||
from: existingFlatRouteMaps,
|
||||
to: toFlatRouteMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
flatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while creating route',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatRouteTriggerMaps: recomputedExistingFlatRouteMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatRouteTriggerMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: flatRouteTriggerToCreate.id,
|
||||
flatEntityMaps: recomputedExistingFlatRouteMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async updateOne(routeInput: UpdateRouteTriggerInput, workspaceId: string) {
|
||||
const flatEntityMaps =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const existingFlatRouteMaps = flatEntityMaps.flatRouteTriggerMaps;
|
||||
|
||||
const optimisticallyUpdatedFlatRouteTrigger =
|
||||
fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow({
|
||||
flatRouteTriggerMaps: existingFlatRouteMaps,
|
||||
updateRouteTriggerInput: routeInput,
|
||||
});
|
||||
|
||||
const fromFlatRouteMaps = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: [optimisticallyUpdatedFlatRouteTrigger.id],
|
||||
flatEntityMaps: existingFlatRouteMaps,
|
||||
});
|
||||
const toFlatRouteMaps = replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: optimisticallyUpdatedFlatRouteTrigger,
|
||||
flatEntityMaps: fromFlatRouteMaps,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
workspaceId,
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatRouteTriggerMaps: {
|
||||
from: existingFlatRouteMaps,
|
||||
to: toFlatRouteMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
flatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: false,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while updating route',
|
||||
);
|
||||
}
|
||||
|
||||
const { flatRouteTriggerMaps: recomputedExistingFlatRouteMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatRouteTriggerMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: optimisticallyUpdatedFlatRouteTrigger.id,
|
||||
flatEntityMaps: recomputedExistingFlatRouteMaps,
|
||||
});
|
||||
}
|
||||
|
||||
async destroyOne({
|
||||
destroyRouteInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
destroyRouteInput: RouteTriggerIdInput;
|
||||
workspaceId: string;
|
||||
}): Promise<FlatRouteTrigger> {
|
||||
const {
|
||||
flatRouteTriggerMaps: existingFlatRouteMaps,
|
||||
flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatEntities: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
const existingFlatRoute = existingFlatRouteMaps.byId[destroyRouteInput.id];
|
||||
|
||||
if (!isDefined(existingFlatRoute)) {
|
||||
throw new RouteTriggerException(
|
||||
'Route to destroy not found',
|
||||
RouteTriggerExceptionCode.ROUTE_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const fromFlatRouteMaps = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: [existingFlatRoute.id],
|
||||
flatEntityMaps: existingFlatRouteMaps,
|
||||
});
|
||||
const toFlatRouteMaps = deleteFlatEntityFromFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: fromFlatRouteMaps,
|
||||
entityToDeleteId: existingFlatRoute.id,
|
||||
});
|
||||
|
||||
const validateAndBuildResult =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
fromToAllFlatEntityMaps: {
|
||||
flatRouteTriggerMaps: {
|
||||
from: fromFlatRouteMaps,
|
||||
to: toFlatRouteMaps,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
inferDeletionFromMissingEntities: true,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while destroying route',
|
||||
);
|
||||
}
|
||||
|
||||
return existingFlatRoute;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { removePropertiesFromRecord } from 'twenty-shared/utils';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
|
||||
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
|
||||
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
|
||||
import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/core-modules/common/constant/empty-flat-entity-maps.constant';
|
||||
import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import {
|
||||
ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES,
|
||||
RouteTrigger,
|
||||
} from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator';
|
||||
import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceFlatMapCache('flatRouteTriggerMaps')
|
||||
export class WorkspaceFlatRouteTriggerMapCacheService extends WorkspaceFlatMapCacheService<
|
||||
FlatEntityMaps<FlatRouteTrigger>
|
||||
> {
|
||||
constructor(
|
||||
@InjectCacheStorage(CacheStorageNamespace.EngineWorkspace)
|
||||
cacheStorageService: CacheStorageService,
|
||||
@InjectRepository(RouteTrigger)
|
||||
private readonly routeTriggerRepository: Repository<RouteTrigger>,
|
||||
) {
|
||||
super(cacheStorageService);
|
||||
}
|
||||
|
||||
protected async computeFlatMap({
|
||||
workspaceId,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
}): Promise<FlatEntityMaps<FlatRouteTrigger>> {
|
||||
const routeTriggers = await this.routeTriggerRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
const flatRouteTriggerMaps = routeTriggers.reduce<
|
||||
FlatEntityMaps<FlatRouteTrigger>
|
||||
>((flatEntityMaps, routeTrigger) => {
|
||||
const flatRouteTrigger = {
|
||||
...removePropertiesFromRecord(routeTrigger, [
|
||||
...ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES,
|
||||
]),
|
||||
universalIdentifier: routeTrigger.universalIdentifier ?? '',
|
||||
} satisfies FlatRouteTrigger;
|
||||
|
||||
return {
|
||||
byId: {
|
||||
...flatEntityMaps.byId,
|
||||
[flatRouteTrigger.id]: flatRouteTrigger,
|
||||
},
|
||||
idByUniversalIdentifier: {
|
||||
...flatEntityMaps.idByUniversalIdentifier,
|
||||
[flatRouteTrigger.universalIdentifier]: flatRouteTrigger.id,
|
||||
},
|
||||
};
|
||||
}, EMPTY_FLAT_ENTITY_MAPS);
|
||||
|
||||
return flatRouteTriggerMaps;
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant';
|
||||
|
||||
export type FlatRouteTriggerPropertiesToCompare =
|
||||
(typeof FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE)[number];
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { type Workspace } from 'src/engine/core-modules/workspace/workspace.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';
|
||||
|
||||
export type RouteTriggerEntityRelationProperties =
|
||||
ExtractRecordTypeOrmRelationProperties<
|
||||
RouteTrigger,
|
||||
ServerlessFunctionEntity | Workspace
|
||||
>;
|
||||
|
||||
export type FlatRouteTrigger = Omit<
|
||||
RouteTrigger,
|
||||
RouteTriggerEntityRelationProperties
|
||||
> & {
|
||||
universalIdentifier: string;
|
||||
};
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import diff from 'microdiff';
|
||||
import { type FromTo } from 'twenty-shared/types';
|
||||
|
||||
import { FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant';
|
||||
import { type FlatRouteTriggerPropertiesToCompare } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type';
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { type UpdateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type';
|
||||
import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util';
|
||||
|
||||
type GetWorkspaceMigrationUpdateRouteTriggerActionArgs = FromTo<
|
||||
FlatRouteTrigger,
|
||||
'FlatRouteTrigger'
|
||||
>;
|
||||
|
||||
export const compareTwoFlatRouteTrigger = ({
|
||||
fromFlatRouteTrigger,
|
||||
toFlatRouteTrigger,
|
||||
}: GetWorkspaceMigrationUpdateRouteTriggerActionArgs) => {
|
||||
const transformMetadataForComparisonParameters = {
|
||||
shouldIgnoreProperty: (property: string) =>
|
||||
!FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE.includes(
|
||||
property as FlatRouteTriggerPropertiesToCompare,
|
||||
),
|
||||
propertiesToStringify: [] as const,
|
||||
};
|
||||
const fromCompare = transformMetadataForComparison(
|
||||
fromFlatRouteTrigger,
|
||||
transformMetadataForComparisonParameters,
|
||||
);
|
||||
const toCompare = transformMetadataForComparison(
|
||||
toFlatRouteTrigger,
|
||||
transformMetadataForComparisonParameters,
|
||||
);
|
||||
|
||||
const flatRouteTriggerDifferences = diff(fromCompare, toCompare);
|
||||
|
||||
return flatRouteTriggerDifferences.flatMap<
|
||||
UpdateRouteTriggerAction['updates'][number]
|
||||
>((difference) => {
|
||||
switch (difference.type) {
|
||||
case 'CHANGE': {
|
||||
const { oldValue, path, value } = difference;
|
||||
const property = path[0] as FlatRouteTriggerPropertiesToCompare;
|
||||
|
||||
return {
|
||||
from: oldValue,
|
||||
to: value,
|
||||
property,
|
||||
};
|
||||
}
|
||||
case 'CREATE':
|
||||
case 'REMOVE':
|
||||
default: {
|
||||
// Should never occurs, we should only provide null never undefined and so on
|
||||
return [];
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
|
||||
import { type CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input';
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
|
||||
export const fromCreateRouteTriggerInputToFlatRouteTrigger = ({
|
||||
createRouteTriggerInput,
|
||||
workspaceId,
|
||||
}: {
|
||||
createRouteTriggerInput: CreateRouteTriggerInput;
|
||||
workspaceId: string;
|
||||
}): FlatRouteTrigger => {
|
||||
const now = new Date();
|
||||
|
||||
return {
|
||||
id: uuidV4(),
|
||||
universalIdentifier:
|
||||
createRouteTriggerInput.universalIdentifier ?? uuidV4(),
|
||||
path: createRouteTriggerInput.path,
|
||||
isAuthRequired: createRouteTriggerInput.isAuthRequired,
|
||||
httpMethod: createRouteTriggerInput.httpMethod,
|
||||
serverlessFunctionId: createRouteTriggerInput.serverlessFunctionId,
|
||||
workspaceId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
};
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type UpdateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input';
|
||||
import {
|
||||
RouteTriggerException,
|
||||
RouteTriggerExceptionCode,
|
||||
} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
|
||||
export const fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow = ({
|
||||
flatRouteTriggerMaps,
|
||||
updateRouteTriggerInput,
|
||||
}: {
|
||||
flatRouteTriggerMaps: FlatEntityMaps<FlatRouteTrigger>;
|
||||
updateRouteTriggerInput: UpdateRouteTriggerInput;
|
||||
}): FlatRouteTrigger => {
|
||||
const existingFlatRouteTrigger =
|
||||
flatRouteTriggerMaps.byId[updateRouteTriggerInput.id];
|
||||
|
||||
if (!existingFlatRouteTrigger) {
|
||||
throw new RouteTriggerException(
|
||||
'Route not found',
|
||||
RouteTriggerExceptionCode.ROUTE_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...existingFlatRouteTrigger,
|
||||
path: updateRouteTriggerInput.update.path,
|
||||
isAuthRequired: updateRouteTriggerInput.update.isAuthRequired,
|
||||
httpMethod: updateRouteTriggerInput.update.httpMethod,
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import {
|
||||
ConflictError,
|
||||
NotFoundError,
|
||||
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import {
|
||||
RouteTriggerException,
|
||||
RouteTriggerExceptionCode,
|
||||
} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
|
||||
|
||||
export const routeTriggerGraphQLApiExceptionHandler = (error: Error): void => {
|
||||
if (error instanceof RouteTriggerException) {
|
||||
switch (error.code) {
|
||||
case RouteTriggerExceptionCode.ROUTE_NOT_FOUND:
|
||||
throw new NotFoundError('Route not found');
|
||||
case RouteTriggerExceptionCode.ROUTE_ALREADY_EXIST:
|
||||
throw new ConflictError('Route already exists');
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
throw error;
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { RouteService } from 'src/engine/metadata-modules/route/route.service';
|
||||
import { Route } from 'src/engine/metadata-modules/route/route.entity';
|
||||
import { RouteController } from 'src/engine/metadata-modules/route/route.controller';
|
||||
import { AuthModule } from 'src/engine/core-modules/auth/auth.module';
|
||||
import { DomainManagerModule } from 'src/engine/core-modules/domain-manager/domain-manager.module';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Route]),
|
||||
AuthModule,
|
||||
DomainManagerModule,
|
||||
ServerlessFunctionModule,
|
||||
],
|
||||
controllers: [RouteController],
|
||||
providers: [RouteService],
|
||||
})
|
||||
export class RouteModule {}
|
||||
+20
-8
@@ -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;
|
||||
}
|
||||
|
||||
+10
-6
@@ -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;
|
||||
|
||||
+4
-4
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+3
-3
@@ -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({
|
||||
|
||||
+1
@@ -18,4 +18,5 @@ export const EMPTY_ORCHESTRATOR_ACTIONS_REPORT = {
|
||||
serverlessFunction: emptyCreatedDeletedUpdated,
|
||||
databaseEventTrigger: emptyCreatedDeletedUpdated,
|
||||
cronTrigger: emptyCreatedDeletedUpdated,
|
||||
routeTrigger: emptyCreatedDeletedUpdated,
|
||||
} as const satisfies OrchestratorActionsReport;
|
||||
|
||||
+2
@@ -13,6 +13,7 @@ export const fromWorkspaceMigrationBuilderExceptionToValidationResponseError = (
|
||||
invalidServerlessFunction: 0,
|
||||
invalidDatabaseEventTrigger: 0,
|
||||
invalidCronTrigger: 0,
|
||||
invalidRouteTrigger: 0,
|
||||
invalidFieldMetadata: 0,
|
||||
totalErrors: 0,
|
||||
},
|
||||
@@ -25,6 +26,7 @@ export const fromWorkspaceMigrationBuilderExceptionToValidationResponseError = (
|
||||
serverlessFunction: [],
|
||||
databaseEventTrigger: [],
|
||||
cronTrigger: [],
|
||||
routeTrigger: [],
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+48
-2
@@ -17,6 +17,7 @@ import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 's
|
||||
import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/services/workspace-migration-v2-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/services/workspace-migration-v2-object-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service';
|
||||
@@ -30,6 +31,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
private readonly workspaceMigrationV2ServerlessFunctionActionsBuilderService: WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
|
||||
private readonly workspaceMigrationV2DatabaseEventTriggerActionsBuilderService: WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationV2CronTriggerActionsBuilderService: WorkspaceMigrationV2CronTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationV2RouteTriggerActionsBuilderService: WorkspaceMigrationV2RouteTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationV2FieldActionsBuilderService: WorkspaceMigrationV2FieldActionsBuilderService,
|
||||
) {}
|
||||
|
||||
@@ -84,6 +86,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
serverlessFunction: [],
|
||||
databaseEventTrigger: [],
|
||||
cronTrigger: [],
|
||||
routeTrigger: [],
|
||||
fieldMetadata: [],
|
||||
};
|
||||
|
||||
@@ -99,6 +102,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatServerlessFunctionMaps,
|
||||
flatDatabaseEventTriggerMaps,
|
||||
flatCronTriggerMaps,
|
||||
flatRouteTriggerMaps,
|
||||
flatFieldMetadataMaps,
|
||||
} = fromToAllFlatEntityMaps;
|
||||
|
||||
@@ -289,8 +293,11 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
from: fromFlatDatabaseEventTriggerMaps,
|
||||
to: toFlatDatabaseEventTriggerMaps,
|
||||
buildOptions,
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
optimisticAllFlatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
workspaceId,
|
||||
dependencyOptimisticFlatEntityMaps: undefined,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -317,8 +324,11 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
from: fromFlatCronTriggerMaps,
|
||||
to: toFlatCronTriggerMaps,
|
||||
buildOptions,
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
optimisticAllFlatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
workspaceId,
|
||||
dependencyOptimisticFlatEntityMaps: undefined,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -332,6 +342,36 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(flatRouteTriggerMaps)) {
|
||||
const { from: fromFlatRouteTriggerMaps, to: toFlatRouteTriggerMaps } =
|
||||
flatRouteTriggerMaps;
|
||||
|
||||
const routeTriggerResult =
|
||||
await this.workspaceMigrationV2RouteTriggerActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
from: fromFlatRouteTriggerMaps,
|
||||
to: toFlatRouteTriggerMaps,
|
||||
buildOptions,
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatServerlessFunctionMaps:
|
||||
optimisticAllFlatEntityMaps.flatServerlessFunctionMaps,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
optimisticAllFlatEntityMaps.flatRouteTriggerMaps =
|
||||
routeTriggerResult.optimisticFlatEntityMaps;
|
||||
|
||||
if (routeTriggerResult.status === 'fail') {
|
||||
orchestratorFailureReport.routeTrigger.push(
|
||||
...routeTriggerResult.errors,
|
||||
);
|
||||
} else {
|
||||
orchestratorActionsReport.routeTrigger = routeTriggerResult.actions;
|
||||
}
|
||||
}
|
||||
|
||||
const allErrors = Object.values(orchestratorFailureReport);
|
||||
|
||||
if (allErrors.some((report) => report.length > 0)) {
|
||||
@@ -396,6 +436,12 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
...aggregatedOrchestratorActionsReport.cronTrigger.created,
|
||||
...aggregatedOrchestratorActionsReport.cronTrigger.updated,
|
||||
///
|
||||
|
||||
// Route triggers
|
||||
...orchestratorActionsReport.routeTrigger.deleted,
|
||||
...orchestratorActionsReport.routeTrigger.created,
|
||||
...orchestratorActionsReport.routeTrigger.updated,
|
||||
///
|
||||
],
|
||||
workspaceId,
|
||||
},
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
|
||||
export type CronTriggerRelatedFlatEntityMaps = Pick<
|
||||
AllFlatEntityMaps,
|
||||
'flatServerlessFunctionMaps'
|
||||
>;
|
||||
+23
-7
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type';
|
||||
import { compareTwoFlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/utils/compare-two-flat-cron-trigger.util';
|
||||
import { CronTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type';
|
||||
import {
|
||||
FlatEntityUpdateValidationArgs,
|
||||
FlatEntityValidationArgs,
|
||||
@@ -19,7 +20,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
|
||||
'cronTrigger',
|
||||
FlatCronTrigger,
|
||||
WorkspaceMigrationCronTriggerActionV2,
|
||||
undefined
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
> {
|
||||
constructor(
|
||||
private readonly flatCronTriggerValidatorService: FlatCronTriggerValidatorService,
|
||||
@@ -31,10 +32,14 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
|
||||
flatEntityToValidate: flatCronTriggerToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<FlatCronTrigger>): Promise<
|
||||
}: FlatEntityValidationArgs<
|
||||
FlatCronTrigger,
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationCronTriggerActionV2,
|
||||
FlatCronTrigger
|
||||
FlatCronTrigger,
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
> {
|
||||
const validationResult =
|
||||
@@ -42,6 +47,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
|
||||
{
|
||||
flatCronTriggerToValidate,
|
||||
optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -66,16 +72,21 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
|
||||
flatEntityToValidate: flatCronTriggerToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<FlatCronTrigger>): Promise<
|
||||
}: FlatEntityValidationArgs<
|
||||
FlatCronTrigger,
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationCronTriggerActionV2,
|
||||
FlatCronTrigger
|
||||
FlatCronTrigger,
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
> {
|
||||
const validationResult =
|
||||
this.flatCronTriggerValidatorService.validateFlatCronTriggerDeletion({
|
||||
flatCronTriggerToValidate,
|
||||
optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
});
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
@@ -99,10 +110,14 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
|
||||
flatEntityUpdate: { from: fromFlatCronTrigger, to: toFlatCronTrigger },
|
||||
optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityUpdateValidationArgs<FlatCronTrigger>): Promise<
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
FlatCronTrigger,
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
| FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationCronTriggerActionV2,
|
||||
FlatCronTrigger
|
||||
FlatCronTrigger,
|
||||
CronTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
| undefined
|
||||
> {
|
||||
@@ -119,6 +134,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp
|
||||
this.flatCronTriggerValidatorService.validateFlatCronTriggerUpdate({
|
||||
flatCronTriggerToValidate: toFlatCronTrigger,
|
||||
optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
});
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
|
||||
export type DatabaseEventTriggerRelatedFlatEntityMaps = Pick<
|
||||
AllFlatEntityMaps,
|
||||
'flatServerlessFunctionMaps'
|
||||
>;
|
||||
+23
-7
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type';
|
||||
import { compareTwoFlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/utils/compare-two-flat-database-event-trigger.util';
|
||||
import { DatabaseEventTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type';
|
||||
import {
|
||||
FlatEntityUpdateValidationArgs,
|
||||
FlatEntityValidationArgs,
|
||||
@@ -19,7 +20,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
'databaseEventTrigger',
|
||||
FlatDatabaseEventTrigger,
|
||||
WorkspaceMigrationDatabaseEventTriggerActionV2,
|
||||
undefined
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
> {
|
||||
constructor(
|
||||
private readonly flatDatabaseEventTriggerValidatorService: FlatDatabaseEventTriggerValidatorService,
|
||||
@@ -31,10 +32,14 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
flatEntityToValidate: flatDatabaseEventTriggerToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<FlatDatabaseEventTrigger>): Promise<
|
||||
}: FlatEntityValidationArgs<
|
||||
FlatDatabaseEventTrigger,
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationDatabaseEventTriggerActionV2,
|
||||
FlatDatabaseEventTrigger
|
||||
FlatDatabaseEventTrigger,
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
> {
|
||||
const validationResult =
|
||||
@@ -42,6 +47,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
{
|
||||
flatDatabaseEventTriggerToValidate,
|
||||
optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -66,10 +72,14 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
flatEntityToValidate: flatDatabaseEventTriggerToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<FlatDatabaseEventTrigger>): Promise<
|
||||
}: FlatEntityValidationArgs<
|
||||
FlatDatabaseEventTrigger,
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationDatabaseEventTriggerActionV2,
|
||||
FlatDatabaseEventTrigger
|
||||
FlatDatabaseEventTrigger,
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
> {
|
||||
const validationResult =
|
||||
@@ -77,6 +87,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
{
|
||||
flatDatabaseEventTriggerToValidate,
|
||||
optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -104,10 +115,14 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
},
|
||||
optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityUpdateValidationArgs<FlatDatabaseEventTrigger>): Promise<
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
FlatDatabaseEventTrigger,
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
| FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationDatabaseEventTriggerActionV2,
|
||||
FlatDatabaseEventTrigger
|
||||
FlatDatabaseEventTrigger,
|
||||
DatabaseEventTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
| undefined
|
||||
> {
|
||||
@@ -126,6 +141,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten
|
||||
{
|
||||
flatDatabaseEventTriggerToValidate: toFlatDatabaseEventTrigger,
|
||||
optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
|
||||
export type RouteTriggerRelatedFlatEntityMaps = Pick<
|
||||
AllFlatEntityMaps,
|
||||
'flatServerlessFunctionMaps'
|
||||
>;
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { compareTwoFlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/utils/compare-two-flat-route-trigger.util';
|
||||
import { RouteTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type';
|
||||
import {
|
||||
FlatEntityUpdateValidationArgs,
|
||||
FlatEntityValidationArgs,
|
||||
FlatEntityValidationReturnType,
|
||||
WorkspaceEntityMigrationBuilderV2Service,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
|
||||
import {
|
||||
UpdateRouteTriggerAction,
|
||||
WorkspaceMigrationRouteTriggerActionV2,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type';
|
||||
import { FlatRouteTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends WorkspaceEntityMigrationBuilderV2Service<
|
||||
'routeTrigger',
|
||||
FlatRouteTrigger,
|
||||
WorkspaceMigrationRouteTriggerActionV2,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
> {
|
||||
constructor(
|
||||
private readonly flatRouteTriggerValidatorService: FlatRouteTriggerValidatorService,
|
||||
) {
|
||||
super('routeTrigger');
|
||||
}
|
||||
|
||||
protected async validateFlatEntityCreation({
|
||||
flatEntityToValidate: flatRouteTriggerToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<
|
||||
FlatRouteTrigger,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationRouteTriggerActionV2,
|
||||
FlatRouteTrigger,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
> {
|
||||
const validationResult =
|
||||
await this.flatRouteTriggerValidatorService.validateFlatRouteTriggerCreation(
|
||||
{
|
||||
flatRouteTriggerToValidate,
|
||||
optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
},
|
||||
);
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
return {
|
||||
status: 'fail',
|
||||
...validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'create_route_trigger',
|
||||
routeTrigger: flatRouteTriggerToValidate,
|
||||
},
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
};
|
||||
}
|
||||
|
||||
protected async validateFlatEntityDeletion({
|
||||
flatEntityToValidate: flatRouteTriggerToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<
|
||||
FlatRouteTrigger,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationRouteTriggerActionV2,
|
||||
FlatRouteTrigger,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
> {
|
||||
const validationResult =
|
||||
this.flatRouteTriggerValidatorService.validateFlatRouteTriggerDeletion({
|
||||
flatRouteTriggerToValidate,
|
||||
optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
});
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
return {
|
||||
status: 'fail',
|
||||
...validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'delete_route_trigger',
|
||||
routeTriggerId: flatRouteTriggerToValidate.id,
|
||||
},
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
};
|
||||
}
|
||||
|
||||
protected async validateFlatEntityUpdate({
|
||||
flatEntityUpdate: { from: fromFlatRouteTrigger, to: toFlatRouteTrigger },
|
||||
optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
FlatRouteTrigger,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
>): Promise<
|
||||
| FlatEntityValidationReturnType<
|
||||
WorkspaceMigrationRouteTriggerActionV2,
|
||||
FlatRouteTrigger,
|
||||
RouteTriggerRelatedFlatEntityMaps
|
||||
>
|
||||
| undefined
|
||||
> {
|
||||
const routeTriggerUpdatedProperties = compareTwoFlatRouteTrigger({
|
||||
fromFlatRouteTrigger,
|
||||
toFlatRouteTrigger,
|
||||
});
|
||||
|
||||
if (routeTriggerUpdatedProperties.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const validationResult =
|
||||
this.flatRouteTriggerValidatorService.validateFlatRouteTriggerUpdate({
|
||||
flatRouteTriggerToValidate: toFlatRouteTrigger,
|
||||
optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
});
|
||||
|
||||
if (validationResult.errors.length > 0) {
|
||||
return {
|
||||
status: 'fail',
|
||||
...validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
const updateRouteTriggerAction: UpdateRouteTriggerAction = {
|
||||
type: 'update_route_trigger',
|
||||
routeTriggerId: toFlatRouteTrigger.id,
|
||||
updates: routeTriggerUpdatedProperties,
|
||||
};
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: updateRouteTriggerAction,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/comm
|
||||
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
|
||||
import { FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
import { compareTwoFlatViewField } from 'src/engine/core-modules/view/flat-view/utils/compare-two-flat-view-field.util';
|
||||
import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/view-field-related-flat-entity-maps.type';
|
||||
import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/view-field-related-flat-entity-maps.type';
|
||||
import {
|
||||
FlatEntityUpdateValidationArgs,
|
||||
FlatEntityValidationArgs,
|
||||
|
||||
+3
-1
@@ -3,6 +3,7 @@ import { type WorkspaceMigrationDatabaseEventTriggerActionV2 } from 'src/engine/
|
||||
import { type WorkspaceMigrationFieldActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-field-action-v2';
|
||||
import { type WorkspaceMigrationIndexActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-index-action-v2';
|
||||
import { type WorkspaceMigrationObjectActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-object-action-v2';
|
||||
import { type WorkspaceMigrationRouteTriggerActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type';
|
||||
import { type WorkspaceMigrationServerlessFunctionActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-serverless-function-action-v2.type';
|
||||
import { type WorkspaceMigrationViewActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-action-v2.type';
|
||||
import { type WorkspaceMigrationViewFieldActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-field-action-v2.type';
|
||||
@@ -15,7 +16,8 @@ export type WorkspaceMigrationActionV2 =
|
||||
| WorkspaceMigrationViewFieldActionV2
|
||||
| WorkspaceMigrationServerlessFunctionActionV2
|
||||
| WorkspaceMigrationDatabaseEventTriggerActionV2
|
||||
| WorkspaceMigrationCronTriggerActionV2;
|
||||
| WorkspaceMigrationCronTriggerActionV2
|
||||
| WorkspaceMigrationRouteTriggerActionV2;
|
||||
export type WorkspaceMigrationActionTypeV2 = WorkspaceMigrationActionV2['type'];
|
||||
|
||||
export type ExtractAction<T extends WorkspaceMigrationActionTypeV2> = Extract<
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { type FlatRouteTriggerPropertiesToCompare } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type';
|
||||
import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/property-update.type';
|
||||
|
||||
export type CreateRouteTriggerAction = {
|
||||
type: 'create_route_trigger';
|
||||
routeTrigger: FlatRouteTrigger;
|
||||
};
|
||||
|
||||
export type UpdateRouteTriggerAction = {
|
||||
type: 'update_route_trigger';
|
||||
routeTriggerId: string;
|
||||
updates: Array<
|
||||
{
|
||||
[P in FlatRouteTriggerPropertiesToCompare]: PropertyUpdate<
|
||||
FlatRouteTrigger,
|
||||
P
|
||||
>;
|
||||
}[FlatRouteTriggerPropertiesToCompare]
|
||||
>;
|
||||
};
|
||||
|
||||
export type DeleteRouteTriggerAction = {
|
||||
type: 'delete_route_trigger';
|
||||
routeTriggerId: string;
|
||||
};
|
||||
|
||||
export type WorkspaceMigrationRouteTriggerActionV2 =
|
||||
| CreateRouteTriggerAction
|
||||
| UpdateRouteTriggerAction
|
||||
| DeleteRouteTriggerAction;
|
||||
+30
@@ -6,11 +6,13 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { CronTriggerExceptionCode } from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception';
|
||||
import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type';
|
||||
import { CronTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
|
||||
type CronTriggerValidationArgs = {
|
||||
flatCronTriggerToValidate: FlatCronTrigger;
|
||||
optimisticFlatCronTriggerMaps: FlatEntityMaps<FlatCronTrigger>;
|
||||
dependencyOptimisticFlatEntityMaps: CronTriggerRelatedFlatEntityMaps;
|
||||
};
|
||||
// TODO: validate settings integrity
|
||||
@Injectable()
|
||||
@@ -20,6 +22,7 @@ export class FlatCronTriggerValidatorService {
|
||||
public validateFlatCronTriggerUpdate({
|
||||
flatCronTriggerToValidate: updatedFlatCronTrigger,
|
||||
optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: CronTriggerValidationArgs): FailedFlatEntityValidation<FlatCronTrigger> {
|
||||
const errors = [];
|
||||
|
||||
@@ -34,6 +37,19 @@ export class FlatCronTriggerValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const serverlessFunction =
|
||||
dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
|
||||
updatedFlatCronTrigger.serverlessFunctionId
|
||||
];
|
||||
|
||||
if (!isDefined(serverlessFunction)) {
|
||||
errors.push({
|
||||
code: CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
||||
message: t`Serverless function not found`,
|
||||
userFriendlyMessage: t`Serverless function not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'update_cron_trigger',
|
||||
errors,
|
||||
@@ -72,6 +88,7 @@ export class FlatCronTriggerValidatorService {
|
||||
public async validateFlatCronTriggerCreation({
|
||||
flatCronTriggerToValidate,
|
||||
optimisticFlatCronTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: CronTriggerValidationArgs): Promise<
|
||||
FailedFlatEntityValidation<FlatCronTrigger>
|
||||
> {
|
||||
@@ -89,6 +106,19 @@ export class FlatCronTriggerValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const serverlessFunction =
|
||||
dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
|
||||
flatCronTriggerToValidate.serverlessFunctionId
|
||||
];
|
||||
|
||||
if (!isDefined(serverlessFunction)) {
|
||||
errors.push({
|
||||
code: CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
||||
message: t`Serverless function not found`,
|
||||
userFriendlyMessage: t`Serverless function not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'create_cron_trigger',
|
||||
errors,
|
||||
|
||||
+30
@@ -6,11 +6,13 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { DatabaseEventTriggerExceptionCode } from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception';
|
||||
import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type';
|
||||
import { DatabaseEventTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
|
||||
type DatabaseEventTriggerValidationArgs = {
|
||||
flatDatabaseEventTriggerToValidate: FlatDatabaseEventTrigger;
|
||||
optimisticFlatDatabaseEventTriggerMaps: FlatEntityMaps<FlatDatabaseEventTrigger>;
|
||||
dependencyOptimisticFlatEntityMaps: DatabaseEventTriggerRelatedFlatEntityMaps;
|
||||
};
|
||||
// TODO: validate settings integrity
|
||||
@Injectable()
|
||||
@@ -20,6 +22,7 @@ export class FlatDatabaseEventTriggerValidatorService {
|
||||
public validateFlatDatabaseEventTriggerUpdate({
|
||||
flatDatabaseEventTriggerToValidate: updatedFlatDatabaseEventTrigger,
|
||||
optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: DatabaseEventTriggerValidationArgs): FailedFlatEntityValidation<FlatDatabaseEventTrigger> {
|
||||
const errors = [];
|
||||
|
||||
@@ -36,6 +39,19 @@ export class FlatDatabaseEventTriggerValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const serverlessFunction =
|
||||
dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
|
||||
updatedFlatDatabaseEventTrigger.serverlessFunctionId
|
||||
];
|
||||
|
||||
if (!isDefined(serverlessFunction)) {
|
||||
errors.push({
|
||||
code: DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
||||
message: t`Serverless function not found`,
|
||||
userFriendlyMessage: t`Serverless function not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'update_database_event_trigger',
|
||||
errors,
|
||||
@@ -76,6 +92,7 @@ export class FlatDatabaseEventTriggerValidatorService {
|
||||
public async validateFlatDatabaseEventTriggerCreation({
|
||||
flatDatabaseEventTriggerToValidate,
|
||||
optimisticFlatDatabaseEventTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: DatabaseEventTriggerValidationArgs): Promise<
|
||||
FailedFlatEntityValidation<FlatDatabaseEventTrigger>
|
||||
> {
|
||||
@@ -95,6 +112,19 @@ export class FlatDatabaseEventTriggerValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const serverlessFunction =
|
||||
dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[
|
||||
flatDatabaseEventTriggerToValidate.serverlessFunctionId
|
||||
];
|
||||
|
||||
if (!isDefined(serverlessFunction)) {
|
||||
errors.push({
|
||||
code: DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
||||
message: t`Serverless function not found`,
|
||||
userFriendlyMessage: t`Serverless function not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'create_database_event_trigger',
|
||||
errors,
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { RouteTriggerExceptionCode } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception';
|
||||
import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type';
|
||||
import { RouteTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
|
||||
type RouteTriggerValidationArgs = {
|
||||
flatRouteTriggerToValidate: FlatRouteTrigger;
|
||||
optimisticFlatRouteTriggerMaps: FlatEntityMaps<FlatRouteTrigger>;
|
||||
dependencyOptimisticFlatEntityMaps: RouteTriggerRelatedFlatEntityMaps;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class FlatRouteTriggerValidatorService {
|
||||
constructor() {}
|
||||
|
||||
public validateFlatRouteTriggerUpdate({
|
||||
flatRouteTriggerToValidate: updatedFlatRouteTrigger,
|
||||
optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: RouteTriggerValidationArgs): FailedFlatEntityValidation<FlatRouteTrigger> {
|
||||
const errors = [];
|
||||
|
||||
const existingFlatRouteTrigger =
|
||||
optimisticFlatRouteTriggerMaps.byId[updatedFlatRouteTrigger.id];
|
||||
|
||||
if (!isDefined(existingFlatRouteTrigger)) {
|
||||
errors.push({
|
||||
code: RouteTriggerExceptionCode.ROUTE_NOT_FOUND,
|
||||
message: t`Route not found`,
|
||||
userFriendlyMessage: t`Route not found`,
|
||||
});
|
||||
}
|
||||
|
||||
const serverlessFunction =
|
||||
dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
|
||||
updatedFlatRouteTrigger.serverlessFunctionId
|
||||
];
|
||||
|
||||
if (!isDefined(serverlessFunction)) {
|
||||
errors.push({
|
||||
code: RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
||||
message: t`Serverless function not found`,
|
||||
userFriendlyMessage: t`Serverless function not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'update_route_trigger',
|
||||
errors,
|
||||
flatEntityMinimalInformation: {
|
||||
id: updatedFlatRouteTrigger.id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public validateFlatRouteTriggerDeletion({
|
||||
flatRouteTriggerToValidate: { id: routeTriggerIdToDelete },
|
||||
optimisticFlatRouteTriggerMaps,
|
||||
}: RouteTriggerValidationArgs): FailedFlatEntityValidation<FlatRouteTrigger> {
|
||||
const errors = [];
|
||||
|
||||
const existingFlatRouteTrigger =
|
||||
optimisticFlatRouteTriggerMaps.byId[routeTriggerIdToDelete];
|
||||
|
||||
if (!isDefined(existingFlatRouteTrigger)) {
|
||||
errors.push({
|
||||
code: RouteTriggerExceptionCode.ROUTE_NOT_FOUND,
|
||||
message: t`Route not found`,
|
||||
userFriendlyMessage: t`Route not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'delete_route_trigger',
|
||||
errors,
|
||||
flatEntityMinimalInformation: {
|
||||
id: routeTriggerIdToDelete,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async validateFlatRouteTriggerCreation({
|
||||
flatRouteTriggerToValidate,
|
||||
optimisticFlatRouteTriggerMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: RouteTriggerValidationArgs): Promise<
|
||||
FailedFlatEntityValidation<FlatRouteTrigger>
|
||||
> {
|
||||
const errors = [];
|
||||
|
||||
if (
|
||||
isDefined(
|
||||
optimisticFlatRouteTriggerMaps.byId[flatRouteTriggerToValidate.id],
|
||||
)
|
||||
) {
|
||||
errors.push({
|
||||
code: RouteTriggerExceptionCode.ROUTE_ALREADY_EXIST,
|
||||
message: t`Route with same id already exists`,
|
||||
userFriendlyMessage: t`Route already exists`,
|
||||
});
|
||||
}
|
||||
|
||||
const existingFlatRouteTriggers = Object.values(
|
||||
optimisticFlatRouteTriggerMaps.byId,
|
||||
).filter(isDefined);
|
||||
|
||||
if (
|
||||
existingFlatRouteTriggers.find(
|
||||
(flatRouteTrigger) =>
|
||||
flatRouteTrigger.path === flatRouteTriggerToValidate.path,
|
||||
)
|
||||
) {
|
||||
errors.push({
|
||||
code: RouteTriggerExceptionCode.ROUTE_PATH_ALREADY_EXIST,
|
||||
message: t`Route with same path already exists`,
|
||||
userFriendlyMessage: t`Route path already exists`,
|
||||
});
|
||||
}
|
||||
|
||||
const serverlessFunction =
|
||||
dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[
|
||||
flatRouteTriggerToValidate.serverlessFunctionId
|
||||
];
|
||||
|
||||
if (!isDefined(serverlessFunction)) {
|
||||
errors.push({
|
||||
code: RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
|
||||
message: t`Serverless function not found`,
|
||||
userFriendlyMessage: t`Serverless function not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'create_route_trigger',
|
||||
errors,
|
||||
flatEntityMinimalInformation: {
|
||||
id: flatRouteTriggerToValidate.id,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { ViewExceptionCode } from 'src/engine/core-modules/view/exceptions/view.
|
||||
import { FlatViewFieldMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-maps.type';
|
||||
import { FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/view-field-related-flat-entity-maps.type';
|
||||
import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/view-field-related-flat-entity-maps.type';
|
||||
|
||||
type ViewFieldValidationArgs = {
|
||||
flatViewFieldToValidate: FlatViewField;
|
||||
|
||||
+5
-2
@@ -1,12 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service';
|
||||
import { FlatObjectMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service';
|
||||
import { FlatCronTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service';
|
||||
import { FlatDatabaseEventTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service';
|
||||
import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service';
|
||||
import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service';
|
||||
import { FlatObjectMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service';
|
||||
import { FlatRouteTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service';
|
||||
import { FlatServerlessFunctionValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-serverless-function-validator.service';
|
||||
import { FlatViewFieldValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service';
|
||||
import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service';
|
||||
@@ -23,6 +24,7 @@ import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace
|
||||
FlatDatabaseEventTriggerValidatorService,
|
||||
FlatCronTriggerValidatorService,
|
||||
FlatFieldMetadataTypeValidatorService,
|
||||
FlatRouteTriggerValidatorService,
|
||||
],
|
||||
exports: [
|
||||
FlatViewValidatorService,
|
||||
@@ -34,6 +36,7 @@ import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace
|
||||
FlatDatabaseEventTriggerValidatorService,
|
||||
FlatCronTriggerValidatorService,
|
||||
FlatFieldMetadataTypeValidatorService,
|
||||
FlatRouteTriggerValidatorService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMigrationBuilderValidatorsModule {}
|
||||
|
||||
+4
@@ -7,6 +7,7 @@ import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 's
|
||||
import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/services/workspace-migration-v2-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/services/workspace-migration-v2-object-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service';
|
||||
@@ -24,6 +25,7 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-
|
||||
WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2FieldActionsBuilderService,
|
||||
WorkspaceMigrationV2CronTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2RouteTriggerActionsBuilderService,
|
||||
],
|
||||
exports: [
|
||||
WorkspaceMigrationV2ViewActionsBuilderService,
|
||||
@@ -34,6 +36,8 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-
|
||||
WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
|
||||
WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2CronTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2RouteTriggerActionsBuilderService,
|
||||
FlatFieldMetadataTypeValidatorService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMigrationBuilderV2Module {}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { CreateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type';
|
||||
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class CreateRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'create_route_trigger',
|
||||
) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerArgs<CreateRouteTriggerAction>,
|
||||
): Promise<void> {
|
||||
const { action, queryRunner, workspaceId } = context;
|
||||
const { routeTrigger } = action;
|
||||
|
||||
const routeTriggerRepository =
|
||||
queryRunner.manager.getRepository<RouteTrigger>(RouteTrigger);
|
||||
|
||||
await routeTriggerRepository.insert({
|
||||
...routeTrigger,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { DeleteRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type';
|
||||
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class DeleteRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'delete_route_trigger',
|
||||
) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerArgs<DeleteRouteTriggerAction>,
|
||||
): Promise<void> {
|
||||
const { action, queryRunner, workspaceId } = context;
|
||||
const { routeTriggerId } = action;
|
||||
|
||||
const routeTriggerRepository =
|
||||
queryRunner.manager.getRepository<RouteTrigger>(RouteTrigger);
|
||||
|
||||
await routeTriggerRepository.delete({
|
||||
id: routeTriggerId,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity';
|
||||
import { UpdateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type';
|
||||
import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
|
||||
import { fromWorkspaceMigrationUpdateActionToPartialEntity } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/from-workspace-migration-update-action-to-partial-field-or-object-entity.util';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
|
||||
'update_route_trigger',
|
||||
) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async executeForMetadata(
|
||||
context: WorkspaceMigrationActionRunnerArgs<UpdateRouteTriggerAction>,
|
||||
): Promise<void> {
|
||||
const { action, queryRunner } = context;
|
||||
const { routeTriggerId } = action;
|
||||
|
||||
const routeTriggerRepository =
|
||||
queryRunner.manager.getRepository<RouteTrigger>(RouteTrigger);
|
||||
|
||||
await routeTriggerRepository.update(
|
||||
routeTriggerId,
|
||||
fromWorkspaceMigrationUpdateActionToPartialEntity(action),
|
||||
);
|
||||
}
|
||||
}
|
||||
+7
@@ -15,6 +15,9 @@ import { DeleteIndexActionHandlerService } from 'src/engine/workspace-manager/wo
|
||||
import { CreateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/create-object-action-handler.service';
|
||||
import { DeleteObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/delete-object-action-handler.service';
|
||||
import { UpdateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/update-object-action-handler.service';
|
||||
import { CreateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service';
|
||||
import { DeleteRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service';
|
||||
import { UpdateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service';
|
||||
import { CreateServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/create-serverless-function-action-handler.service';
|
||||
import { DeleteServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/delete-serverless-function-action-handler.service';
|
||||
import { UpdateServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service';
|
||||
@@ -58,6 +61,10 @@ import { UpdateViewActionHandlerService } from 'src/engine/workspace-manager/wor
|
||||
CreateCronTriggerActionHandlerService,
|
||||
DeleteCronTriggerActionHandlerService,
|
||||
UpdateCronTriggerActionHandlerService,
|
||||
|
||||
CreateRouteTriggerActionHandlerService,
|
||||
DeleteRouteTriggerActionHandlerService,
|
||||
UpdateRouteTriggerActionHandlerService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceSchemaMigrationRunnerActionHandlersModule {}
|
||||
|
||||
Reference in New Issue
Block a user