Add ServerlessFunction to migration v2 (#14698)

This commit is contained in:
Weiko
2025-09-25 14:05:01 +02:00
committed by GitHub
parent edb331d68b
commit 188d66909d
45 changed files with 1671 additions and 112 deletions
@@ -15,4 +15,5 @@ export const EMPTY_ORCHESTRATOR_ACTIONS_REPORT = {
view: emptyCreatedDeletedUpdated,
viewField: emptyCreatedDeletedUpdated,
fieldMetadata: emptyCreatedDeletedUpdated,
serverlessFunction: emptyCreatedDeletedUpdated,
} as const satisfies OrchestratorActionsReport;
@@ -10,6 +10,7 @@ export const fromWorkspaceMigrationBuilderExceptionToValidationResponseError = (
invalidView: 0,
invalidViewField: 0,
invalidIndex: 0,
invalidServerlessFunction: 0,
totalErrors: 0,
},
errors: {
@@ -17,6 +18,7 @@ export const fromWorkspaceMigrationBuilderExceptionToValidationResponseError = (
objectMetadata: [],
view: [],
viewField: [],
serverlessFunction: [],
},
};
@@ -12,6 +12,7 @@ import {
WorkspaceMigrationOrchestratorSuccessfulResult,
} from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-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';
import { WorkspaceMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-migration-builder-v2.service';
@@ -27,6 +28,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
private readonly workspaceMigrationV2IndexActionsBuilderService: WorkspaceMigrationV2IndexActionsBuilderService,
private readonly workspaceMigrationV2ViewActionsBuilderService: WorkspaceMigrationV2ViewActionsBuilderService,
private readonly workspaceMigrationV2ViewFieldActionsBuilderService: WorkspaceMigrationV2ViewFieldActionsBuilderService,
private readonly workspaceMigrationV2ServerlessFunctionActionsBuilderService: WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
) {}
private setupOptimisticCache({
@@ -77,6 +79,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
view: [],
viewField: [],
index: [],
serverlessFunction: [],
};
const optimisticAllFlatEntityMaps = this.setupOptimisticCache({
@@ -88,6 +91,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
flatViewFieldMaps,
flatViewMaps,
flatIndexMaps,
flatServerlessFunctionMaps,
} = fromToAllFlatEntityMaps;
if (isDefined(flatObjectMetadataMaps)) {
@@ -189,6 +193,35 @@ export class WorkspaceMigrationBuildOrchestratorService {
}
}
if (isDefined(flatServerlessFunctionMaps)) {
const {
from: fromFlatServerlessFunctionMaps,
to: toFlatServerlessFunctionMaps,
} = flatServerlessFunctionMaps;
const serverlessFunctionResult =
await this.workspaceMigrationV2ServerlessFunctionActionsBuilderService.validateAndBuild(
{
from: fromFlatServerlessFunctionMaps,
to: toFlatServerlessFunctionMaps,
buildOptions,
dependencyOptimisticFlatEntityMaps: {} as AllFlatEntityMaps,
},
);
optimisticAllFlatEntityMaps.flatServerlessFunctionMaps =
serverlessFunctionResult.optimisticFlatEntityMaps;
if (serverlessFunctionResult.status === 'fail') {
orchestratorFailureReport.serverlessFunction.push(
...serverlessFunctionResult.errors,
);
} else {
orchestratorActionsReport.serverlessFunction =
serverlessFunctionResult.actions;
}
}
const allErrors = Object.values(orchestratorFailureReport);
if (allErrors.some((report) => report.length > 0)) {
@@ -207,7 +240,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
workspaceMigration: {
relatedFlatEntityMapsKeys,
actions: [
// Object and fields
// Object and fields and indexes
...orchestratorActionsReport.index.deleted,
...orchestratorActionsReport.fieldMetadata.deleted,
...orchestratorActionsReport.objectMetadata.deleted,
@@ -227,6 +260,12 @@ export class WorkspaceMigrationBuildOrchestratorService {
...orchestratorActionsReport.viewField.created,
...orchestratorActionsReport.viewField.updated,
///
// Serverless functions
...orchestratorActionsReport.serverlessFunction.deleted,
...orchestratorActionsReport.serverlessFunction.created,
...orchestratorActionsReport.serverlessFunction.updated,
///
],
workspaceId,
},
@@ -11,10 +11,6 @@ import {
WorkspaceEntityMigrationBuilderV2Service,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service';
import { WorkspaceMigrationIndexActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-index-action-v2';
import {
getWorkspaceMigrationV2CreateIndexAction,
getWorkspaceMigrationV2DeleteIndexAction,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/get-workspace-migration-v2-index-actions';
import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service';
export type IndexRelatedFlatEntityMaps = Pick<
@@ -62,7 +58,10 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
return {
status: 'success',
action: getWorkspaceMigrationV2CreateIndexAction(flatIndexToValidate),
action: {
type: 'create_index',
flatIndexMetadata: flatIndexToValidate,
},
};
}
@@ -95,7 +94,10 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
return {
status: 'success',
action: getWorkspaceMigrationV2DeleteIndexAction(flatIndexToValidate),
action: {
type: 'delete_index',
flatIndexMetadataId: flatIndexToValidate.id,
},
};
}
@@ -156,8 +158,14 @@ export class WorkspaceMigrationV2IndexActionsBuilderService extends WorkspaceEnt
return {
status: 'success',
action: [
getWorkspaceMigrationV2DeleteIndexAction(fromFlatIndex),
getWorkspaceMigrationV2CreateIndexAction(toFlatIndex),
{
type: 'delete_index',
flatIndexMetadataId: fromFlatIndex.id,
},
{
type: 'create_index',
flatIndexMetadata: toFlatIndex,
},
],
};
}
@@ -0,0 +1,162 @@
import { Injectable } from '@nestjs/common';
import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { compareTwoFlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/utils/compare-two-flat-serverless-function.util';
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 {
UpdateServerlessFunctionAction,
WorkspaceMigrationServerlessFunctionActionV2,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-serverless-function-action-v2.type';
import {
FlatServerlessFunctionValidatorService,
ServerlessFunctionRelatedFlatEntityMaps,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-serverless-function-validator.service';
@Injectable()
export class WorkspaceMigrationV2ServerlessFunctionActionsBuilderService extends WorkspaceEntityMigrationBuilderV2Service<
FlatServerlessFunction,
WorkspaceMigrationServerlessFunctionActionV2,
ServerlessFunctionRelatedFlatEntityMaps
> {
constructor(
private readonly flatServerlessFunctionValidatorService: FlatServerlessFunctionValidatorService,
) {
super();
}
protected async validateFlatEntityCreation({
dependencyOptimisticFlatEntityMaps,
flatEntityToValidate: flatServerlessFunctionToValidate,
optimisticFlatEntityMaps: optimisticFlatServerlessFunctionMaps,
}: FlatEntityValidationArgs<
FlatServerlessFunction,
ServerlessFunctionRelatedFlatEntityMaps
>): Promise<
FlatEntityValidationReturnType<
WorkspaceMigrationServerlessFunctionActionV2,
FlatServerlessFunction
>
> {
const validationResult =
await this.flatServerlessFunctionValidatorService.validateFlatServerlessFunctionCreation(
{
dependencyOptimisticFlatEntityMaps,
flatServerlessFunctionToValidate,
optimisticFlatServerlessFunctionMaps,
},
);
if (validationResult.errors.length > 0) {
return {
status: 'fail',
...validationResult,
};
}
return {
status: 'success',
action: {
type: 'create_serverless_function',
serverlessFunction: flatServerlessFunctionToValidate,
},
};
}
protected async validateFlatEntityDeletion({
dependencyOptimisticFlatEntityMaps,
flatEntityToValidate: flatServerlessFunctionToValidate,
optimisticFlatEntityMaps: optimisticFlatServerlessFunctionMaps,
}: FlatEntityValidationArgs<
FlatServerlessFunction,
ServerlessFunctionRelatedFlatEntityMaps
>): Promise<
FlatEntityValidationReturnType<
WorkspaceMigrationServerlessFunctionActionV2,
FlatServerlessFunction
>
> {
const validationResult =
this.flatServerlessFunctionValidatorService.validateFlatServerlessFunctionDeletion(
{
dependencyOptimisticFlatEntityMaps,
flatServerlessFunctionToValidate,
optimisticFlatServerlessFunctionMaps,
},
);
if (validationResult.errors.length > 0) {
return {
status: 'fail',
...validationResult,
};
}
return {
status: 'success',
action: {
type: 'delete_serverless_function',
serverlessFunctionId: flatServerlessFunctionToValidate.id,
},
};
}
protected async validateFlatEntityUpdate({
dependencyOptimisticFlatEntityMaps,
flatEntityUpdate: {
from: fromFlatServerlessFunction,
to: toFlatServerlessFunction,
},
optimisticFlatEntityMaps: optimisticFlatServerlessFunctionMaps,
}: FlatEntityUpdateValidationArgs<
FlatServerlessFunction,
ServerlessFunctionRelatedFlatEntityMaps
>): Promise<
| FlatEntityValidationReturnType<
WorkspaceMigrationServerlessFunctionActionV2,
FlatServerlessFunction
>
| undefined
> {
const serverlessFunctionUpdatedProperties =
compareTwoFlatServerlessFunction({
fromFlatServerlessFunction,
toFlatServerlessFunction,
});
if (serverlessFunctionUpdatedProperties.length === 0) {
return undefined;
}
const validationResult =
this.flatServerlessFunctionValidatorService.validateFlatServerlessFunctionUpdate(
{
dependencyOptimisticFlatEntityMaps,
flatServerlessFunctionToValidate: toFlatServerlessFunction,
optimisticFlatServerlessFunctionMaps,
},
);
if (validationResult.errors.length > 0) {
return {
status: 'fail',
...validationResult,
};
}
const updateServerlessFunctionAction: UpdateServerlessFunctionAction = {
type: 'update_serverless_function',
serverlessFunctionId: toFlatServerlessFunction.id,
updates: serverlessFunctionUpdatedProperties,
};
return {
status: 'success',
action: updateServerlessFunctionAction,
};
}
}
@@ -13,10 +13,6 @@ import {
UpdateViewFieldAction,
WorkspaceMigrationViewFieldActionV2,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-field-action-v2.type';
import {
getWorkspaceMigrationV2ViewFieldCreateAction,
getWorkspaceMigrationV2ViewFieldDeleteAction,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/get-workspace-migration-v2-view-field-action';
import { FlatViewFieldValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service';
@Injectable()
@@ -60,9 +56,10 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
return {
status: 'success',
action: getWorkspaceMigrationV2ViewFieldCreateAction(
flatViewFieldToValidate,
),
action: {
type: 'create_view_field',
viewField: flatViewFieldToValidate,
},
};
}
@@ -95,9 +92,10 @@ export class WorkspaceMigrationV2ViewFieldActionsBuilderService extends Workspac
return {
status: 'success',
action: getWorkspaceMigrationV2ViewFieldDeleteAction(
flatViewFieldToValidate,
),
action: {
type: 'delete_view_field',
viewFieldId: flatViewFieldToValidate.id,
},
};
}
@@ -13,10 +13,6 @@ import {
UpdateViewAction,
WorkspaceMigrationViewActionV2,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-action-v2.type';
import {
getWorkspaceMigrationV2ViewCreateAction,
getWorkspaceMigrationV2ViewDeleteAction,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/get-workspace-migration-v2-view-action';
import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service';
export type ViewRelatedFlatEntityMaps = Pick<
@@ -59,7 +55,10 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
return {
status: 'success',
action: getWorkspaceMigrationV2ViewCreateAction(flatViewToValidate),
action: {
type: 'create_view',
view: flatViewToValidate,
},
};
}
@@ -86,7 +85,10 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
return {
status: 'success',
action: getWorkspaceMigrationV2ViewDeleteAction(flatViewToValidate),
action: {
type: 'delete_view',
viewId: flatViewToValidate.id,
},
};
}
@@ -1,6 +1,7 @@
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 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';
@@ -9,7 +10,8 @@ export type WorkspaceMigrationActionV2 =
| WorkspaceMigrationFieldActionV2
| WorkspaceMigrationIndexActionV2
| WorkspaceMigrationViewActionV2
| WorkspaceMigrationViewFieldActionV2;
| WorkspaceMigrationViewFieldActionV2
| WorkspaceMigrationServerlessFunctionActionV2;
export type WorkspaceMigrationActionTypeV2 = WorkspaceMigrationActionV2['type'];
export type ExtractAction<T extends WorkspaceMigrationActionTypeV2> = Extract<
@@ -0,0 +1,39 @@
import { type FromTo } from 'twenty-shared/types';
import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { type FlatServerlessFunctionPropertiesToCompare } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function-properties-to-compare.type';
import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
export type FlatServerlessFunctionPropertyUpdate<
P extends FlatServerlessFunctionPropertiesToCompare,
> = {
property: P;
} & FromTo<ServerlessFunctionEntity[P]>;
export type CreateServerlessFunctionAction = {
type: 'create_serverless_function';
serverlessFunction: FlatServerlessFunction;
};
export type UpdateServerlessFunctionAction = {
type: 'update_serverless_function';
serverlessFunctionId: string;
updates: Array<
{
[P in FlatServerlessFunctionPropertiesToCompare]: FlatServerlessFunctionPropertyUpdate<P>;
}[FlatServerlessFunctionPropertiesToCompare]
>;
};
export type DeleteServerlessFunctionAction = {
type: 'delete_serverless_function';
serverlessFunctionId: string;
};
export type WorkspaceMigrationServerlessFunctionActionV2 =
| CreateServerlessFunctionAction
| UpdateServerlessFunctionAction
| DeleteServerlessFunctionAction;
export type WorkspaceMigrationServerlessFunctionActionTypeV2 =
WorkspaceMigrationServerlessFunctionActionV2['type'];
@@ -1,19 +0,0 @@
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import {
type CreateIndexAction,
type DeleteIndexAction,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-index-action-v2';
export const getWorkspaceMigrationV2CreateIndexAction = (
flatIndexMetadata: FlatIndexMetadata,
): CreateIndexAction => ({
type: 'create_index',
flatIndexMetadata,
});
export const getWorkspaceMigrationV2DeleteIndexAction = (
flatIndexMetadata: FlatIndexMetadata,
): DeleteIndexAction => ({
type: 'delete_index',
flatIndexMetadataId: flatIndexMetadata.id,
});
@@ -1,19 +0,0 @@
import { type FlatView } from 'src/engine/core-modules/view/flat-view/types/flat-view.type';
import {
type CreateViewAction,
type DeleteViewAction,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-action-v2.type';
export const getWorkspaceMigrationV2ViewCreateAction = (
flatView: FlatView,
): CreateViewAction => ({
type: 'create_view',
view: flatView,
});
export const getWorkspaceMigrationV2ViewDeleteAction = (
flatView: FlatView,
): DeleteViewAction => ({
type: 'delete_view',
viewId: flatView.id,
});
@@ -1,19 +0,0 @@
import { type FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type';
import {
type CreateViewFieldAction,
type DeleteViewFieldAction,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-field-action-v2.type';
export const getWorkspaceMigrationV2ViewFieldCreateAction = (
flatViewField: FlatViewField,
): CreateViewFieldAction => ({
type: 'create_view_field',
viewField: flatViewField,
});
export const getWorkspaceMigrationV2ViewFieldDeleteAction = (
flatViewField: FlatViewField,
): DeleteViewFieldAction => ({
type: 'delete_view_field',
viewFieldId: flatViewField.id,
});
@@ -0,0 +1,110 @@
import { Injectable } from '@nestjs/common';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
import { ServerlessFunctionExceptionCode } from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
export type ServerlessFunctionRelatedFlatEntityMaps = Pick<
AllFlatEntityMaps,
'flatServerlessFunctionMaps'
>;
type ServerlessFunctionValidationArgs = {
flatServerlessFunctionToValidate: FlatServerlessFunction;
optimisticFlatServerlessFunctionMaps: FlatEntityMaps<FlatServerlessFunction>;
dependencyOptimisticFlatEntityMaps: ServerlessFunctionRelatedFlatEntityMaps;
};
@Injectable()
export class FlatServerlessFunctionValidatorService {
constructor() {}
public validateFlatServerlessFunctionUpdate({
flatServerlessFunctionToValidate: updatedFlatServerlessFunction,
optimisticFlatServerlessFunctionMaps,
}: ServerlessFunctionValidationArgs): FailedFlatEntityValidation<FlatServerlessFunction> {
const errors = [];
const existingFlatServerlessFunction =
optimisticFlatServerlessFunctionMaps.byId[
updatedFlatServerlessFunction.id
];
if (!isDefined(existingFlatServerlessFunction)) {
errors.push({
code: ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
message: t`Serverless function not found`,
userFriendlyMessage: t`Serverless function not found`,
});
}
return {
type: 'update_serverless_function',
errors,
flatEntityMinimalInformation: {
id: updatedFlatServerlessFunction.id,
},
};
}
public validateFlatServerlessFunctionDeletion({
flatServerlessFunctionToValidate: { id: serverlessFunctionIdToDelete },
optimisticFlatServerlessFunctionMaps,
}: ServerlessFunctionValidationArgs): FailedFlatEntityValidation<FlatServerlessFunction> {
const errors = [];
const existingFlatServerlessFunction =
optimisticFlatServerlessFunctionMaps.byId[serverlessFunctionIdToDelete];
if (!isDefined(existingFlatServerlessFunction)) {
errors.push({
code: ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND,
message: t`Serverless function not found`,
userFriendlyMessage: t`Serverless function not found`,
});
}
return {
type: 'delete_serverless_function',
errors,
flatEntityMinimalInformation: {
id: serverlessFunctionIdToDelete,
},
};
}
public async validateFlatServerlessFunctionCreation({
flatServerlessFunctionToValidate,
optimisticFlatServerlessFunctionMaps,
}: ServerlessFunctionValidationArgs): Promise<
FailedFlatEntityValidation<FlatServerlessFunction>
> {
const errors = [];
if (
isDefined(
optimisticFlatServerlessFunctionMaps.byId[
flatServerlessFunctionToValidate.id
],
)
) {
errors.push({
code: ServerlessFunctionExceptionCode.SERVERLESS_FUNCTION_ALREADY_EXIST,
message: t`Serverless function with same id already exists`,
userFriendlyMessage: t`Serverless function already exists`,
});
}
return {
type: 'create_serverless_function',
errors,
flatEntityMinimalInformation: {
id: flatServerlessFunctionToValidate.id,
},
};
}
}
@@ -7,9 +7,11 @@ import { FlatObjectMetadataValidatorService } from 'src/engine/metadata-modules/
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 { 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';
import { WorkspaceMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-migration-builder-v2.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';
import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/workspace-migration-builder-validators.module';
@@ -26,16 +28,17 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-
WorkspaceMigrationV2ViewActionsBuilderService,
WorkspaceMigrationV2ViewFieldActionsBuilderService,
WorkspaceMigrationV2IndexActionsBuilderService,
WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
FlatViewValidatorService,
FlatViewFieldValidatorService,
FlatServerlessFunctionValidatorService,
],
exports: [
WorkspaceMigrationBuilderV2Service,
WorkspaceMigrationV2ViewActionsBuilderService,
WorkspaceMigrationV2IndexActionsBuilderService,
FlatViewValidatorService,
WorkspaceMigrationV2ViewFieldActionsBuilderService,
FlatViewFieldValidatorService,
WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
],
})
export class WorkspaceMigrationBuilderV2Module {}
@@ -0,0 +1,62 @@
import { Injectable } from '@nestjs/common';
import {
OptimisticallyApplyActionOnAllFlatEntityMapsArgs,
WorkspaceMigrationRunnerActionHandler,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { CreateServerlessFunctionAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-serverless-function-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 CreateServerlessFunctionActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
'create_serverless_function',
) {
constructor() {
super();
}
optimisticallyApplyActionOnAllFlatEntityMaps({
action,
allFlatEntityMaps,
}: OptimisticallyApplyActionOnAllFlatEntityMapsArgs<CreateServerlessFunctionAction>): Partial<AllFlatEntityMaps> {
const { flatServerlessFunctionMaps } = allFlatEntityMaps;
const { serverlessFunction } = action;
const updatedFlatServerlessFunctionMaps =
addFlatEntityToFlatEntityMapsOrThrow({
flatEntity: serverlessFunction,
flatEntityMaps: flatServerlessFunctionMaps,
});
return {
flatServerlessFunctionMaps: updatedFlatServerlessFunctionMaps,
};
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<CreateServerlessFunctionAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { serverlessFunction } = action;
const serverlessFunctionRepository =
queryRunner.manager.getRepository<ServerlessFunctionEntity>(
ServerlessFunctionEntity,
);
await serverlessFunctionRepository.insert({
...serverlessFunction,
workspaceId,
});
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<CreateServerlessFunctionAction>,
): Promise<void> {
return;
}
}
@@ -0,0 +1,62 @@
import { Injectable } from '@nestjs/common';
import {
OptimisticallyApplyActionOnAllFlatEntityMapsArgs,
WorkspaceMigrationRunnerActionHandler,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { DeleteServerlessFunctionAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-serverless-function-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 DeleteServerlessFunctionActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
'delete_serverless_function',
) {
constructor() {
super();
}
optimisticallyApplyActionOnAllFlatEntityMaps({
action,
allFlatEntityMaps,
}: OptimisticallyApplyActionOnAllFlatEntityMapsArgs<DeleteServerlessFunctionAction>): Partial<AllFlatEntityMaps> {
const { flatServerlessFunctionMaps } = allFlatEntityMaps;
const { serverlessFunctionId } = action;
const updatedFlatServerlessFunctionMaps =
deleteFlatEntityFromFlatEntityMapsOrThrow({
entityToDeleteId: serverlessFunctionId,
flatEntityMaps: flatServerlessFunctionMaps,
});
return {
flatServerlessFunctionMaps: updatedFlatServerlessFunctionMaps,
};
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<DeleteServerlessFunctionAction>,
): Promise<void> {
const { action, queryRunner, workspaceId } = context;
const { serverlessFunctionId } = action;
const serverlessFunctionRepository =
queryRunner.manager.getRepository<ServerlessFunctionEntity>(
ServerlessFunctionEntity,
);
await serverlessFunctionRepository.delete({
id: serverlessFunctionId,
workspaceId,
});
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<DeleteServerlessFunctionAction>,
): Promise<void> {
return;
}
}
@@ -0,0 +1,75 @@
import { Injectable } from '@nestjs/common';
import {
OptimisticallyApplyActionOnAllFlatEntityMapsArgs,
WorkspaceMigrationRunnerActionHandler,
} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface';
import { AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-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 { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
import { UpdateServerlessFunctionAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-serverless-function-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 UpdateServerlessFunctionActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
'update_serverless_function',
) {
constructor() {
super();
}
optimisticallyApplyActionOnAllFlatEntityMaps({
action,
allFlatEntityMaps,
}: OptimisticallyApplyActionOnAllFlatEntityMapsArgs<UpdateServerlessFunctionAction>): Partial<AllFlatEntityMaps> {
const { flatServerlessFunctionMaps } = allFlatEntityMaps;
const { serverlessFunctionId } = action;
const existingServerlessFunction =
findFlatEntityByIdInFlatEntityMapsOrThrow({
flatEntityId: serverlessFunctionId,
flatEntityMaps: flatServerlessFunctionMaps,
});
const updatedServerlessFunction = {
...existingServerlessFunction,
...fromWorkspaceMigrationUpdateActionToPartialEntity(action),
};
const updatedFlatServerlessFunctionMaps =
replaceFlatEntityInFlatEntityMapsOrThrow({
flatEntity: updatedServerlessFunction,
flatEntityMaps: flatServerlessFunctionMaps,
});
return {
flatServerlessFunctionMaps: updatedFlatServerlessFunctionMaps,
};
}
async executeForMetadata(
context: WorkspaceMigrationActionRunnerArgs<UpdateServerlessFunctionAction>,
): Promise<void> {
const { action, queryRunner } = context;
const { serverlessFunctionId } = action;
const serverlessFunctionRepository =
queryRunner.manager.getRepository<ServerlessFunctionEntity>(
ServerlessFunctionEntity,
);
await serverlessFunctionRepository.update(
serverlessFunctionId,
fromWorkspaceMigrationUpdateActionToPartialEntity(action),
);
}
async executeForWorkspaceSchema(
_context: WorkspaceMigrationActionRunnerArgs<UpdateServerlessFunctionAction>,
): Promise<void> {
return;
}
}
@@ -9,6 +9,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 { 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';
import { CreateViewFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-field/services/create-view-field-action-handler.service';
import { DeleteViewFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-field/services/delete-view-field-action-handler.service';
import { UpdateViewFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-field/services/update-view-field-action-handler.service';
@@ -37,6 +40,10 @@ import { UpdateViewActionHandlerService } from 'src/engine/workspace-manager/wor
CreateViewFieldActionHandlerService,
UpdateViewFieldActionHandlerService,
DeleteViewFieldActionHandlerService,
CreateServerlessFunctionActionHandlerService,
DeleteServerlessFunctionActionHandlerService,
UpdateServerlessFunctionActionHandlerService,
],
})
export class WorkspaceSchemaMigrationRunnerActionHandlersModule {}
@@ -1,14 +1,5 @@
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-field-action-v2';
import { type UpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-object-action-v2';
import { type UpdateViewAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-action-v2.type';
import { type UpdateViewFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-field-action-v2.type';
export const fromWorkspaceMigrationUpdateActionToPartialEntity = <
T extends
| UpdateFieldAction
| UpdateObjectAction
| UpdateViewAction
| UpdateViewFieldAction,
T extends { updates: Array<{ property: string; to: unknown }> },
>(
action: T,
) => {