Extract field metadata build out of object metadata build (#14763)
# Introduction Extracting the legacy fields build and dispatch out of the object one to follow the generic flat entity build, also update caches entries for object ## Main tasks - flat field map cache - flat field builder - refactored the dispatch matrix to return flat entity maps instead of flat entity arrays - orchestrator aggregator - removing legacy code - making universal identifier aka standardId of standard field for custom object deterministically dynamic - perfs debug logs for v2 ## TODO - [x] Refactor the generic entity builder to be dependency flat maps in order to main foreign keys list in flat parent - [x] Refactor the flat object metadata to contain the array of related fields and avoid costy find object fields - [ ] Improve the create field handler to handle multiple field at once - [ ] Refactor the dispatch to embbed the comparison - [ ] Improve perf by extracting from elements out of existing - [ ] Fix the labelIdentifierId validators on object before field creation ( integ tests are in failing mode ) ## Debug logs snippet ```ts [EntityBuilder fieldMetadata] matrix computation: 0.027ms [EntityBuilder fieldMetadata] creation validation: 0.001ms [EntityBuilder fieldMetadata] deletion validation: 0.293ms [EntityBuilder fieldMetadata] update validation: 0.006ms [EntityBuilder fieldMetadata] entity processing: 0.363ms [EntityBuilder fieldMetadata] validateAndBuild: 0.455ms [EntityBuilder index] matrix computation: 0.005ms [EntityBuilder index] creation validation: 0.001ms [EntityBuilder index] deletion validation: 0.146ms [EntityBuilder index] update validation: 0.004ms [EntityBuilder index] entity processing: 0.199ms [EntityBuilder index] validateAndBuild: 0.228ms [Runner] Initial cache retrieval: 0.549ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForWorkspaceSchema: 11.665ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForMetadata: 12.864ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 1.476ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 6.816ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 0.062ms [BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 0.889ms [Runner] Transaction execution: 23.434ms [Runner] Cache invalidation: 316.662ms [Runner] Total execution: 340.767ms ``` As you can see cache invalidation is way to long, we could replace the cache by the optimistic in the end
This commit is contained in:
+9
-5
@@ -1,17 +1,20 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { findFlatFieldMetadatasRelatedToMorphRelationOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-flat-field-metadatas-related-to-morph-relation-or-throw.util';
|
||||
import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
|
||||
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
export const computeFlatFieldMetadataRelatedFlatFieldMetadata = ({
|
||||
flatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
flatFieldMetadataMaps,
|
||||
}: {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
flatFieldMetadata: FlatFieldMetadata;
|
||||
flatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
}): FlatFieldMetadata[] => {
|
||||
if (
|
||||
isFlatFieldMetadataOfType(flatFieldMetadata, FieldMetadataType.RELATION)
|
||||
@@ -19,7 +22,7 @@ export const computeFlatFieldMetadataRelatedFlatFieldMetadata = ({
|
||||
return [
|
||||
findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow({
|
||||
flatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
}),
|
||||
];
|
||||
}
|
||||
@@ -32,7 +35,8 @@ export const computeFlatFieldMetadataRelatedFlatFieldMetadata = ({
|
||||
) {
|
||||
return findFlatFieldMetadatasRelatedToMorphRelationOrThrow({
|
||||
flatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+23
-29
@@ -1,48 +1,42 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
|
||||
import {
|
||||
FlatObjectMetadataMapsException,
|
||||
FlatObjectMetadataMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-object-metadata-maps/flat-object-metadata-maps.exception';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/core-modules/common/exceptions/flat-entity-maps.exception';
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
|
||||
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
export type FindAllMorphRelationFlatFieldMetadatasOrThrowArgs = {
|
||||
flatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
flatFieldMetadata: FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
};
|
||||
export const findAllOthersMorphRelationFlatFieldMetadatasOrThrow = ({
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
flatFieldMetadata: morphRelationFlatFieldMetadata,
|
||||
}: FindAllMorphRelationFlatFieldMetadatasOrThrowArgs): FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>[] => {
|
||||
const flatObjectMetadataWithFlatFieldMaps =
|
||||
flatObjectMetadataMaps.byId[
|
||||
morphRelationFlatFieldMetadata.objectMetadataId
|
||||
];
|
||||
|
||||
if (!isDefined(flatObjectMetadataWithFlatFieldMaps)) {
|
||||
throw new FlatObjectMetadataMapsException(
|
||||
'Morph field relation object metadata not found',
|
||||
FlatObjectMetadataMapsExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!isDefined(
|
||||
flatObjectMetadataWithFlatFieldMaps.fieldsById[
|
||||
morphRelationFlatFieldMetadata.id
|
||||
],
|
||||
)
|
||||
!isDefined(flatFieldMetadataMaps.byId[morphRelationFlatFieldMetadata.id])
|
||||
) {
|
||||
throw new FlatObjectMetadataMapsException(
|
||||
'Morph relation field not found in related object metadata',
|
||||
FlatObjectMetadataMapsExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||
throw new FlatEntityMapsException(
|
||||
'Morph relation field not found in flat field metadata maps',
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return flatObjectMetadataWithFlatFieldMaps.flatFieldMetadatas.filter(
|
||||
const { objectFlatFieldMetadatas } =
|
||||
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
|
||||
return objectFlatFieldMetadatas.filter(
|
||||
(
|
||||
flatFieldMetadata,
|
||||
): flatFieldMetadata is FlatFieldMetadata<FieldMetadataType.MORPH_RELATION> =>
|
||||
|
||||
+9
-5
@@ -1,23 +1,27 @@
|
||||
import { type FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type MorphOrRelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/morph-or-relation-field-metadata-type.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { findAllOthersMorphRelationFlatFieldMetadatasOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-all-others-morph-relation-flat-field-metadatas-or-throw.util';
|
||||
import { findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
export type FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs = {
|
||||
flatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
flatFieldMetadata: FlatFieldMetadata<FieldMetadataType.MORPH_RELATION>;
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
};
|
||||
export const findFlatFieldMetadatasRelatedToMorphRelationOrThrow = ({
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
flatFieldMetadata: morphRelationFlatFieldMetadata,
|
||||
flatObjectMetadata,
|
||||
}: FindFlatFieldMetadatasRelatedToMorphRelationOrThrowArgs): FlatFieldMetadata<MorphOrRelationFieldMetadataType>[] => {
|
||||
const allMorphFlatFieldMetadatas =
|
||||
findAllOthersMorphRelationFlatFieldMetadatasOrThrow({
|
||||
flatFieldMetadata: morphRelationFlatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
|
||||
return [
|
||||
@@ -27,7 +31,7 @@ export const findFlatFieldMetadatasRelatedToMorphRelationOrThrow = ({
|
||||
const relationTargetFlatFieldMetadata =
|
||||
findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow({
|
||||
flatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (flatFieldMetadata.id === morphRelationFlatFieldMetadata.id) {
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { getSubFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/get-sub-flat-entity-maps-or-throw.util';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
type FindObjectFieldsInFlatFieldMetadataMapsArgs = {
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
};
|
||||
export const findObjectFieldsInFlatFieldMetadataMapsOrThrow = ({
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
}: FindObjectFieldsInFlatFieldMetadataMapsArgs): {
|
||||
objectFlatFieldMetadataById: FlatEntityMaps<FlatFieldMetadata>;
|
||||
objectFlatFieldMetadatas: FlatFieldMetadata[];
|
||||
} => {
|
||||
const objectFlatFieldMetadataById = getSubFlatEntityMapsOrThrow({
|
||||
flatEntityIds: flatObjectMetadata.fieldMetadataIds,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
const objectFlatFieldMetadatas = Object.values(
|
||||
objectFlatFieldMetadataById.byId,
|
||||
).filter(isDefined);
|
||||
|
||||
return {
|
||||
objectFlatFieldMetadataById,
|
||||
objectFlatFieldMetadatas,
|
||||
};
|
||||
};
|
||||
+5
-15
@@ -1,5 +1,6 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
@@ -7,31 +8,20 @@ import {
|
||||
import { type MorphOrRelationFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/types/morph-or-relation-field-metadata-type.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
|
||||
export type GetRelationFlatFieldMetadatasUtilArgs = {
|
||||
flatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
flatFieldMetadata: FlatFieldMetadata<MorphOrRelationFieldMetadataType>;
|
||||
};
|
||||
|
||||
export const findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow = ({
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
flatFieldMetadata,
|
||||
}: GetRelationFlatFieldMetadatasUtilArgs): FlatFieldMetadata<MorphOrRelationFieldMetadataType> => {
|
||||
const { relationTargetFieldMetadataId, relationTargetObjectMetadataId } =
|
||||
flatFieldMetadata;
|
||||
const { relationTargetFieldMetadataId } = flatFieldMetadata;
|
||||
|
||||
const relatedFlatObjectMetadata =
|
||||
flatObjectMetadataMaps.byId[relationTargetObjectMetadataId];
|
||||
|
||||
if (!isDefined(relatedFlatObjectMetadata)) {
|
||||
throw new FieldMetadataException(
|
||||
`Deleted field metadata relation object metadata target not found`,
|
||||
FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
const relatedFlatFieldMetadata =
|
||||
relatedFlatObjectMetadata.fieldsById[relationTargetFieldMetadataId];
|
||||
flatFieldMetadataMaps.byId[relationTargetFieldMetadataId];
|
||||
|
||||
if (!isDefined(relatedFlatFieldMetadata)) {
|
||||
throw new FieldMetadataException(
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
import {
|
||||
findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow,
|
||||
type GetRelationFlatFieldMetadatasUtilArgs,
|
||||
} from 'src/engine/metadata-modules/flat-field-metadata/utils/find-relation-flat-field-metadatas-target-flat-field-metadata-or-throw.util';
|
||||
|
||||
export const findRelationFlatFieldMetadataTargetFlatFieldMetadata = (
|
||||
args: GetRelationFlatFieldMetadatasUtilArgs,
|
||||
):
|
||||
| ReturnType<
|
||||
typeof findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow
|
||||
>
|
||||
| undefined => {
|
||||
try {
|
||||
return findRelationFlatFieldMetadataTargetFlatFieldMetadataOrThrow(args);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
+9
-15
@@ -9,6 +9,7 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { type FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { generateRatingOptions } from 'src/engine/metadata-modules/field-metadata/utils/generate-rating-optionts.util';
|
||||
@@ -18,19 +19,16 @@ import { fromMorphRelationCreateFieldInputToFlatFieldMetadatas } from 'src/engin
|
||||
import { fromRelationCreateFieldInputToFlatFieldMetadatas } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-relation-create-field-input-to-flat-field-metadatas.util';
|
||||
import { getDefaultFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/get-default-flat-field-metadata-from-create-field-input.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { fromFlatObjectMetadataWithFlatFieldMapsToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-with-flat-field-maps-to-flat-object-metadatas.util';
|
||||
|
||||
type FromCreateFieldInputToFlatObjectMetadataArgs = {
|
||||
rawCreateFieldInput: Omit<CreateFieldInput, 'workspaceId'>;
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
export type FromCreateFieldInputToFlatObjectMetadataArgs = {
|
||||
createFieldInput: Omit<CreateFieldInput, 'workspaceId'>;
|
||||
workspaceId: string;
|
||||
};
|
||||
} & Pick<AllFlatEntityMaps, 'flatObjectMetadataMaps'>;
|
||||
|
||||
export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
rawCreateFieldInput,
|
||||
createFieldInput: rawCreateFieldInput,
|
||||
workspaceId,
|
||||
existingFlatObjectMetadataMaps,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
}: FromCreateFieldInputToFlatObjectMetadataArgs): Promise<
|
||||
FieldInputTranspilationResult<{
|
||||
flatFieldMetadatas: FlatFieldMetadata[];
|
||||
@@ -46,15 +44,16 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const createFieldInput =
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties(
|
||||
rawCreateFieldInput,
|
||||
['description', 'icon', 'label', 'name', 'objectMetadataId', 'type'],
|
||||
);
|
||||
const parentFlatObjectMetadataWithFlatFieldMaps =
|
||||
const parentFlatObjectMetadata =
|
||||
existingFlatObjectMetadataMaps.byId[createFieldInput.objectMetadataId];
|
||||
|
||||
if (!isDefined(parentFlatObjectMetadataWithFlatFieldMaps)) {
|
||||
if (!isDefined(parentFlatObjectMetadata)) {
|
||||
return {
|
||||
status: 'fail',
|
||||
error: {
|
||||
@@ -65,11 +64,6 @@ export const fromCreateFieldInputToFlatFieldMetadatasToCreate = async ({
|
||||
};
|
||||
}
|
||||
|
||||
const parentFlatObjectMetadata =
|
||||
fromFlatObjectMetadataWithFlatFieldMapsToFlatObjectMetadata(
|
||||
parentFlatObjectMetadataWithFlatFieldMaps,
|
||||
);
|
||||
|
||||
const fieldMetadataId = v4();
|
||||
const commonFlatFieldMetadata = getDefaultFlatFieldMetadata({
|
||||
createFieldInput,
|
||||
|
||||
+38
-19
@@ -3,7 +3,9 @@ import {
|
||||
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type 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 { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type DeleteOneFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/delete-field.input';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
@@ -11,22 +13,22 @@ import {
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { computeFlatFieldMetadataRelatedFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-metadata-related-flat-field-metadata.util';
|
||||
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-with-field-id-only.util';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
|
||||
type FromDeleteFieldInputToFlatFieldMetadatasToDeleteArgs = {
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
existingFlatIndexMaps: FlatEntityMaps<FlatIndexMetadata>;
|
||||
deleteOneFieldInput: DeleteOneFieldInput;
|
||||
};
|
||||
} & Pick<
|
||||
AllFlatEntityMaps,
|
||||
'flatFieldMetadataMaps' | 'flatIndexMaps' | 'flatObjectMetadataMaps'
|
||||
>;
|
||||
// TODO refactor as a side effect service
|
||||
export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
|
||||
existingFlatObjectMetadataMaps,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
deleteOneFieldInput: rawDeleteOneInput,
|
||||
existingFlatIndexMaps,
|
||||
flatIndexMaps: existingFlatIndexMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
}: FromDeleteFieldInputToFlatFieldMetadatasToDeleteArgs): {
|
||||
flatFieldMetadatasToDelete: FlatFieldMetadata[];
|
||||
flatIndexesToUpdate: FlatIndexMetadata[];
|
||||
@@ -38,11 +40,10 @@ export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
|
||||
['id'],
|
||||
);
|
||||
|
||||
const flatFieldMetadataToDelete =
|
||||
findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId({
|
||||
fieldMetadataId: fieldMetadataToDeleteId,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
});
|
||||
const flatFieldMetadataToDelete = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: fieldMetadataToDeleteId,
|
||||
flatEntityMaps: existingFlatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatFieldMetadataToDelete)) {
|
||||
throw new FieldMetadataException(
|
||||
@@ -51,10 +52,23 @@ export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
|
||||
);
|
||||
}
|
||||
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: flatFieldMetadataToDelete.objectMetadataId,
|
||||
flatEntityMaps: existingFlatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatObjectMetadata)) {
|
||||
throw new FieldMetadataException(
|
||||
'Field to delete object metadata not found',
|
||||
FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const relatedFlatFieldMetadataToDelete =
|
||||
computeFlatFieldMetadataRelatedFlatFieldMetadata({
|
||||
flatFieldMetadata: flatFieldMetadataToDelete,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
|
||||
const flatFieldMetadatasToDelete = [
|
||||
@@ -122,15 +136,20 @@ export const fromDeleteFieldInputToFlatFieldMetadatasToDelete = ({
|
||||
};
|
||||
}
|
||||
|
||||
const flatObjectMetadata =
|
||||
findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
objectMetadataId: flatIndex.objectMetadataId,
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: existingFlatObjectMetadataMaps,
|
||||
flatEntityId: flatIndex.objectMetadataId,
|
||||
});
|
||||
const { objectFlatFieldMetadatas } =
|
||||
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
|
||||
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatObjectMetadata,
|
||||
flatIndex,
|
||||
objectFlatFieldMetadatas,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
+1
-80
@@ -1,95 +1,18 @@
|
||||
import {
|
||||
FieldMetadataType,
|
||||
type RelationAndMorphRelationFieldMetadataType,
|
||||
} from 'twenty-shared/types';
|
||||
import { type FieldMetadataType } from 'twenty-shared/types';
|
||||
import { removePropertiesFromRecord } from 'twenty-shared/utils';
|
||||
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import {
|
||||
type FieldMetadataEntityRelationProperties,
|
||||
type FlatFieldMetadata,
|
||||
fieldMetadataRelationProperties,
|
||||
} from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatRelationTargetFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-relation-target-field-metadata.type';
|
||||
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
import { fromObjectMetadataEntityToFlatObjectMetadataWithoutFields } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/from-object-metadata-entity-to-flat-object-metadata-without-fields.util';
|
||||
|
||||
export const fromFieldMetadataEntityToFlatRelationTargetFieldMetadata = (
|
||||
fieldMetadataEntity: FieldMetadataEntity<RelationAndMorphRelationFieldMetadataType>,
|
||||
): FlatRelationTargetFieldMetadata => {
|
||||
return {
|
||||
universalIdentifier:
|
||||
fieldMetadataEntity.standardId ?? fieldMetadataEntity.id,
|
||||
...removePropertiesFromRecord(fieldMetadataEntity, [
|
||||
'relationTargetObjectMetadata',
|
||||
'relationTargetFieldMetadata',
|
||||
]),
|
||||
};
|
||||
};
|
||||
|
||||
// TODO refactor this method should not be recursive but depth 1
|
||||
export const fromFieldMetadataEntityToFlatFieldMetadata = <
|
||||
T extends FieldMetadataType,
|
||||
>(
|
||||
fieldMetadataEntity: FieldMetadataEntity<T>,
|
||||
// This is intended to be abstract
|
||||
): FlatFieldMetadata => {
|
||||
if (
|
||||
isFieldMetadataEntityOfType(
|
||||
fieldMetadataEntity,
|
||||
FieldMetadataType.RELATION,
|
||||
) ||
|
||||
isFieldMetadataEntityOfType(
|
||||
fieldMetadataEntity,
|
||||
FieldMetadataType.MORPH_RELATION,
|
||||
)
|
||||
) {
|
||||
const fieldMetadataWithoutRelations = removePropertiesFromRecord<
|
||||
FieldMetadataEntity<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>,
|
||||
FieldMetadataEntityRelationProperties
|
||||
>(fieldMetadataEntity, fieldMetadataRelationProperties);
|
||||
|
||||
if (
|
||||
!isFieldMetadataEntityOfType(
|
||||
fieldMetadataEntity.relationTargetFieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
)
|
||||
) {
|
||||
throw new FieldMetadataException(
|
||||
'Relation target field is not a field metadata type relation',
|
||||
FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
|
||||
);
|
||||
}
|
||||
|
||||
const flatRelationTargetFieldMetadata =
|
||||
fromFieldMetadataEntityToFlatRelationTargetFieldMetadata(
|
||||
fieldMetadataEntity.relationTargetFieldMetadata,
|
||||
);
|
||||
|
||||
const flatRelationTargetObjectMetadata =
|
||||
fromObjectMetadataEntityToFlatObjectMetadataWithoutFields(
|
||||
fieldMetadataEntity.relationTargetObjectMetadata,
|
||||
);
|
||||
|
||||
return {
|
||||
...fieldMetadataWithoutRelations,
|
||||
universalIdentifier:
|
||||
fieldMetadataWithoutRelations.standardId ??
|
||||
fieldMetadataWithoutRelations.id,
|
||||
flatRelationTargetFieldMetadata,
|
||||
flatRelationTargetObjectMetadata,
|
||||
type: fieldMetadataEntity.type,
|
||||
} satisfies FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
}
|
||||
|
||||
const fieldMetadataWithoutRelations = removePropertiesFromRecord(
|
||||
fieldMetadataEntity,
|
||||
fieldMetadataRelationProperties,
|
||||
@@ -100,7 +23,5 @@ export const fromFieldMetadataEntityToFlatFieldMetadata = <
|
||||
universalIdentifier:
|
||||
fieldMetadataWithoutRelations.standardId ??
|
||||
fieldMetadataWithoutRelations.id,
|
||||
flatRelationTargetFieldMetadata: null,
|
||||
flatRelationTargetObjectMetadata: null,
|
||||
};
|
||||
};
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatRelationTargetFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-relation-target-field-metadata.type';
|
||||
|
||||
export const fromFlatFieldMetadataToFieldMetadataDto = (
|
||||
flatFieldMetadata: FlatFieldMetadata | FlatRelationTargetFieldMetadata,
|
||||
flatFieldMetadata: FlatFieldMetadata,
|
||||
): FieldMetadataDTO => {
|
||||
const {
|
||||
createdAt,
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadataWithFlatFieldMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-with-flat-field-metadata-maps.type';
|
||||
import { fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-object-metadata-item-with-field-maps-to-flat-object-metadata.util';
|
||||
import { type ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
import { type ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps';
|
||||
|
||||
export type FromObjectMetadataItemWithFieldMapsToFlatObjectWithFlatFieldMetadataMapsArgs =
|
||||
{
|
||||
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps;
|
||||
objectMetadataMaps: ObjectMetadataMaps;
|
||||
};
|
||||
export const fromObjectMetadataItemWithFieldMapsToFlatObjectWithFlatFieldMetadataMaps =
|
||||
({
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
}: FromObjectMetadataItemWithFieldMapsToFlatObjectWithFlatFieldMetadataMapsArgs): FlatObjectMetadataWithFlatFieldMaps => {
|
||||
const flatObjectMetadata =
|
||||
fromObjectMetadataItemWithFieldMapsToFlatObjectMetadata({
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
});
|
||||
|
||||
const initialAccumulator: Record<string, FlatFieldMetadata> = {};
|
||||
|
||||
const fieldsById = flatObjectMetadata.flatFieldMetadatas.reduce(
|
||||
(acc, flatFieldMetadata) => ({
|
||||
...acc,
|
||||
[flatFieldMetadata.id]: flatFieldMetadata,
|
||||
}),
|
||||
initialAccumulator,
|
||||
);
|
||||
|
||||
const { fieldIdByJoinColumnName, fieldIdByName } =
|
||||
objectMetadataItemWithFieldMaps;
|
||||
|
||||
return {
|
||||
...flatObjectMetadata,
|
||||
fieldsById,
|
||||
fieldIdByJoinColumnName,
|
||||
fieldIdByName,
|
||||
};
|
||||
};
|
||||
+17
-11
@@ -4,23 +4,29 @@ import { fromFlatFieldMetadataToFieldMetadataDto } from 'src/engine/metadata-mod
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { fromFlatObjectMetadataToObjectMetadataDto } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util';
|
||||
|
||||
export const fromMorphOrRelationFlatFieldMetadataToRelationDto = ({
|
||||
flatFieldMetadata,
|
||||
sourceFlatObjectMetadata,
|
||||
}: {
|
||||
type FromMorphOrRelationFlatFieldMetadataToRelationDtoArgs = {
|
||||
sourceFlatObjectMetadata: FlatObjectMetadata;
|
||||
flatFieldMetadata: FlatFieldMetadata<MorphOrRelationFieldMetadataType>;
|
||||
}) => ({
|
||||
type: flatFieldMetadata.settings.relationType,
|
||||
targetFlatObjectMetadata: FlatObjectMetadata;
|
||||
sourceFlatFieldMetadata: FlatFieldMetadata<MorphOrRelationFieldMetadataType>;
|
||||
targetFlatFieldMetadata: FlatFieldMetadata<MorphOrRelationFieldMetadataType>;
|
||||
};
|
||||
export const fromMorphOrRelationFlatFieldMetadataToRelationDto = ({
|
||||
sourceFlatFieldMetadata,
|
||||
sourceFlatObjectMetadata,
|
||||
targetFlatFieldMetadata,
|
||||
targetFlatObjectMetadata,
|
||||
}: FromMorphOrRelationFlatFieldMetadataToRelationDtoArgs) => ({
|
||||
type: sourceFlatFieldMetadata.settings.relationType,
|
||||
sourceObjectMetadata: fromFlatObjectMetadataToObjectMetadataDto(
|
||||
sourceFlatObjectMetadata,
|
||||
),
|
||||
sourceFieldMetadata:
|
||||
fromFlatFieldMetadataToFieldMetadataDto(flatFieldMetadata),
|
||||
sourceFieldMetadata: fromFlatFieldMetadataToFieldMetadataDto(
|
||||
sourceFlatFieldMetadata,
|
||||
),
|
||||
targetObjectMetadata: fromFlatObjectMetadataToObjectMetadataDto(
|
||||
flatFieldMetadata.flatRelationTargetObjectMetadata,
|
||||
targetFlatObjectMetadata,
|
||||
),
|
||||
targetFieldMetadata: fromFlatFieldMetadataToFieldMetadataDto(
|
||||
flatFieldMetadata.flatRelationTargetFieldMetadata,
|
||||
targetFlatFieldMetadata,
|
||||
),
|
||||
});
|
||||
|
||||
+2
-2
@@ -3,6 +3,7 @@ import { type FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
|
||||
@@ -12,14 +13,13 @@ import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-m
|
||||
import { generateMorphOrRelationFlatFieldMetadataPair } from 'src/engine/metadata-modules/flat-field-metadata/utils/generate-morph-or-relation-flat-field-metadata-pair.util';
|
||||
import { validateMorphRelationCreationPayload } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-morph-relation-creation-payload.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
type FromMorphRelationCreateFieldInputToFlatFieldMetadatasArgs = {
|
||||
createFieldInput: Omit<CreateFieldInput, 'workspaceId'> & {
|
||||
type: FieldMetadataType.MORPH_RELATION;
|
||||
};
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
existingFlatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>;
|
||||
sourceFlatObjectMetadata: FlatObjectMetadata;
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
+2
-2
@@ -2,6 +2,7 @@ import { t } from '@lingui/core/macro';
|
||||
import { type FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type';
|
||||
import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
|
||||
@@ -11,14 +12,13 @@ import {
|
||||
type SourceTargetMorphOrRelationFlatFieldAndFlatIndex,
|
||||
} from 'src/engine/metadata-modules/flat-field-metadata/utils/generate-morph-or-relation-flat-field-metadata-pair.util';
|
||||
import { validateRelationCreationPayload } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-relation-creation-payload.util';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
|
||||
type FromRelationCreateFieldInputToFlatFieldMetadataArgs = {
|
||||
createFieldInput: Omit<CreateFieldInput, 'workspaceId'> & {
|
||||
type: FieldMetadataType.RELATION;
|
||||
};
|
||||
existingFlatObjectMetadataMaps: FlatObjectMetadataMaps;
|
||||
existingFlatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>;
|
||||
sourceFlatObjectMetadata: FlatObjectMetadata;
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
+40
-48
@@ -6,9 +6,14 @@ import {
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type 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 { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { FIELD_METADATA_STANDARD_OVERRIDES_PROPERTIES } from 'src/engine/metadata-modules/field-metadata/constants/field-metadata-standard-overrides-properties.constant';
|
||||
import { type UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
|
||||
import { FieldMetadataExceptionCode } from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { type FieldMetadataStandardOverridesProperties } from 'src/engine/metadata-modules/field-metadata/types/field-metadata-standard-overrides-properties.type';
|
||||
import { FLAT_FIELD_METADATA_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-field-metadata/constants/flat-field-metadata-editable-properties.constant';
|
||||
import { type FieldInputTranspilationResult } from 'src/engine/metadata-modules/flat-field-metadata/types/field-input-transpilation-result.type';
|
||||
@@ -17,9 +22,6 @@ import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-m
|
||||
import { computeFlatFieldMetadataRelatedFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/compute-flat-field-metadata-related-flat-field-metadata.util';
|
||||
import { recomputeIndexOnFlatFieldMetadataNameUpdate } from 'src/engine/metadata-modules/flat-field-metadata/utils/recompute-index-on-flat-field-metadata-name-update.util';
|
||||
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
|
||||
import { findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-field-metadata-in-flat-object-metadata-maps-with-field-id-only.util';
|
||||
import { findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/find-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { fromFlatObjectMetadataWithFlatFieldMapsToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-with-flat-field-maps-to-flat-object-metadatas.util';
|
||||
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
|
||||
|
||||
type UpdatedFlatFieldMetadataAndIndexToUpdate = {
|
||||
@@ -37,13 +39,17 @@ type SanitizedUpdateFieldInput = ReturnType<
|
||||
type ApplyUpdatesToFlatFieldMetadataArgs = {
|
||||
updatedEditableFieldProperties: SanitizedUpdateFieldInput;
|
||||
fromFlatFieldMetadata: FlatFieldMetadata;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps' | 'flatObjectMetadataMaps'>;
|
||||
} & Pick<
|
||||
AllFlatEntityMaps,
|
||||
'flatIndexMaps' | 'flatObjectMetadataMaps' | 'flatFieldMetadataMaps'
|
||||
>;
|
||||
|
||||
const applyUpdatesToFlatFieldMetadata = ({
|
||||
updatedEditableFieldProperties,
|
||||
fromFlatFieldMetadata,
|
||||
flatObjectMetadataMaps,
|
||||
flatIndexMaps,
|
||||
flatFieldMetadataMaps,
|
||||
}: ApplyUpdatesToFlatFieldMetadataArgs) => {
|
||||
return FLAT_FIELD_METADATA_EDITABLE_PROPERTIES.reduce<UpdatedFlatFieldMetadataAndIndexToUpdate>(
|
||||
({ flatFieldMetadata, flatIndexMetadataToUpdate }, property) => {
|
||||
@@ -74,14 +80,14 @@ const applyUpdatesToFlatFieldMetadata = ({
|
||||
let newFlatIndexMetadataToUpdate: FlatIndexMetadata[] = [];
|
||||
|
||||
if (property === 'name') {
|
||||
const flatObjectMetadata =
|
||||
findFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps,
|
||||
objectMetadataId: flatFieldMetadata.objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityMaps: flatObjectMetadataMaps,
|
||||
flatEntityId: flatFieldMetadata.objectMetadataId,
|
||||
});
|
||||
|
||||
newFlatIndexMetadataToUpdate =
|
||||
recomputeIndexOnFlatFieldMetadataNameUpdate({
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
fromFlatFieldMetadata,
|
||||
toFlatFieldMetadata: {
|
||||
@@ -108,7 +114,10 @@ const applyUpdatesToFlatFieldMetadata = ({
|
||||
|
||||
type FromUpdateFieldInputToFlatFieldMetadataArgs = {
|
||||
updateFieldInput: UpdateFieldInput;
|
||||
} & Pick<AllFlatEntityMaps, 'flatObjectMetadataMaps' | 'flatIndexMaps'>;
|
||||
} & Pick<
|
||||
AllFlatEntityMaps,
|
||||
'flatObjectMetadataMaps' | 'flatIndexMaps' | 'flatFieldMetadataMaps'
|
||||
>;
|
||||
|
||||
type FlatFieldMetadataAndIndexToUpdate = {
|
||||
flatFieldMetadatasToUpdate: FlatFieldMetadata[];
|
||||
@@ -117,6 +126,7 @@ type FlatFieldMetadataAndIndexToUpdate = {
|
||||
export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
flatIndexMaps,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
updateFieldInput: rawUpdateFieldInput,
|
||||
}: FromUpdateFieldInputToFlatFieldMetadataArgs): FieldInputTranspilationResult<FlatFieldMetadataAndIndexToUpdate> => {
|
||||
const updateFieldInputInformalProperties =
|
||||
@@ -129,11 +139,10 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
FLAT_FIELD_METADATA_EDITABLE_PROPERTIES,
|
||||
);
|
||||
|
||||
const existingFlatFieldMetadataToUpdate =
|
||||
findFlatFieldMetadataInFlatObjectMetadataMapsWithOnlyFieldId({
|
||||
fieldMetadataId: updateFieldInputInformalProperties.id,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
});
|
||||
const existingFlatFieldMetadataToUpdate = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: updateFieldInputInformalProperties.id,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatFieldMetadataToUpdate)) {
|
||||
return {
|
||||
@@ -146,37 +155,6 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
};
|
||||
}
|
||||
|
||||
const flatObjectMetadataWithFlatFieldMaps =
|
||||
existingFlatObjectMetadataMaps.byId[
|
||||
existingFlatFieldMetadataToUpdate.objectMetadataId
|
||||
];
|
||||
|
||||
if (!isDefined(flatObjectMetadataWithFlatFieldMaps)) {
|
||||
return {
|
||||
status: 'fail',
|
||||
error: {
|
||||
code: FieldMetadataExceptionCode.FIELD_METADATA_NOT_FOUND,
|
||||
message: 'Field metadata to update object metadata not found',
|
||||
userFriendlyMessage: t`Field metadata to update object metadata not found`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const flatObjectMetadata =
|
||||
fromFlatObjectMetadataWithFlatFieldMapsToFlatObjectMetadata(
|
||||
flatObjectMetadataWithFlatFieldMaps,
|
||||
);
|
||||
|
||||
if (flatObjectMetadata.isRemote) {
|
||||
return {
|
||||
status: 'fail',
|
||||
error: {
|
||||
code: FieldMetadataExceptionCode.FIELD_MUTATION_NOT_ALLOWED,
|
||||
message: 'Remote objects are read-only',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (isStandardMetadata(existingFlatFieldMetadataToUpdate)) {
|
||||
const invalidUpdatedProperties = Object.keys(
|
||||
updatedEditableFieldProperties,
|
||||
@@ -224,10 +202,23 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
};
|
||||
}
|
||||
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: existingFlatFieldMetadataToUpdate.objectMetadataId,
|
||||
flatEntityMaps: existingFlatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatObjectMetadata)) {
|
||||
throw new FieldMetadataException(
|
||||
'Field to update object metadata not found',
|
||||
FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const relatedFlatFieldMetadatasToUpdate =
|
||||
computeFlatFieldMetadataRelatedFlatFieldMetadata({
|
||||
flatFieldMetadata: existingFlatFieldMetadataToUpdate,
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
|
||||
const flatFieldMetadatasToUpdate = [
|
||||
@@ -242,6 +233,7 @@ export const fromUpdateFieldInputToFlatFieldMetadata = ({
|
||||
applyUpdatesToFlatFieldMetadata({
|
||||
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
|
||||
fromFlatFieldMetadata,
|
||||
flatFieldMetadataMaps,
|
||||
flatIndexMaps,
|
||||
updatedEditableFieldProperties,
|
||||
});
|
||||
|
||||
+9
-26
@@ -86,7 +86,6 @@ export const generateMorphOrRelationFlatFieldMetadataPair = ({
|
||||
options: null,
|
||||
relationTargetFieldMetadataId: targetRelationTargetFieldMetadataId,
|
||||
relationTargetObjectMetadataId: targetFlatObjectMetadata.id,
|
||||
flatRelationTargetObjectMetadata: targetFlatObjectMetadata,
|
||||
};
|
||||
|
||||
const targetCreateFieldInput: CreateFieldInput = {
|
||||
@@ -122,14 +121,16 @@ export const generateMorphOrRelationFlatFieldMetadataPair = ({
|
||||
options: null,
|
||||
relationTargetFieldMetadataId: sourceRelationTargetFieldMetadataId,
|
||||
relationTargetObjectMetadataId: sourceFlatObjectMetadata.id,
|
||||
flatRelationTargetFieldMetadata: sourceFlatFieldMetadata,
|
||||
flatRelationTargetObjectMetadata: sourceFlatObjectMetadata,
|
||||
};
|
||||
|
||||
const indexId = v4();
|
||||
const createdAt = new Date();
|
||||
const indexMetadata: FlatIndexMetadata =
|
||||
generateFlatIndexMetadataWithNameOrThrow({
|
||||
objectFlatFieldMetadatas:
|
||||
relationCreationPayload.type === RelationType.MANY_TO_ONE
|
||||
? [sourceFlatFieldMetadata]
|
||||
: [targetFlatFieldMetadata],
|
||||
flatIndex: {
|
||||
createdAt,
|
||||
flatIndexFieldMetadatas: [
|
||||
@@ -158,32 +159,14 @@ export const generateMorphOrRelationFlatFieldMetadataPair = ({
|
||||
updatedAt: createdAt,
|
||||
workspaceId,
|
||||
},
|
||||
flatObjectMetadata: (relationCreationPayload.type ===
|
||||
RelationType.MANY_TO_ONE
|
||||
? {
|
||||
...sourceFlatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
...sourceFlatObjectMetadata.flatFieldMetadatas,
|
||||
sourceFlatFieldMetadata,
|
||||
],
|
||||
}
|
||||
: {
|
||||
...targetFlatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
...targetFlatObjectMetadata.flatFieldMetadatas,
|
||||
targetFlatFieldMetadata,
|
||||
],
|
||||
}) as FlatObjectMetadata,
|
||||
flatObjectMetadata:
|
||||
relationCreationPayload.type === RelationType.MANY_TO_ONE
|
||||
? sourceFlatObjectMetadata
|
||||
: targetFlatObjectMetadata,
|
||||
});
|
||||
|
||||
return {
|
||||
flatFieldMetadatas: [
|
||||
{
|
||||
...sourceFlatFieldMetadata,
|
||||
flatRelationTargetFieldMetadata: targetFlatFieldMetadata,
|
||||
},
|
||||
targetFlatFieldMetadata,
|
||||
],
|
||||
flatFieldMetadatas: [sourceFlatFieldMetadata, targetFlatFieldMetadata],
|
||||
indexMetadatas: [indexMetadata],
|
||||
};
|
||||
};
|
||||
|
||||
-2
@@ -46,8 +46,6 @@ export const getDefaultFlatFieldMetadata = ({
|
||||
type: createFieldInput.type,
|
||||
universalIdentifier: fieldMetadataId,
|
||||
workspaceId,
|
||||
flatRelationTargetFieldMetadata: null,
|
||||
flatRelationTargetObjectMetadata: null,
|
||||
options: null,
|
||||
defaultValue: defaultValue ?? generateDefaultValue(createFieldInput.type),
|
||||
settings: settings ?? null,
|
||||
|
||||
+21
-16
@@ -2,6 +2,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { findObjectFieldsInFlatFieldMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-field-metadata/utils/find-object-fields-in-flat-field-metadata-maps-or-throw.util';
|
||||
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 { generateFlatIndexMetadataWithNameOrThrow } from 'src/engine/metadata-modules/index-metadata/utils/generate-flat-index.util';
|
||||
@@ -10,13 +11,14 @@ type RecomputeIndexOnFlatFieldMetadataNameUpdateArgs = {
|
||||
flatObjectMetadata: FlatObjectMetadata;
|
||||
fromFlatFieldMetadata: FlatFieldMetadata;
|
||||
toFlatFieldMetadata: Pick<FlatFieldMetadata, 'name'>;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps'>;
|
||||
} & Pick<AllFlatEntityMaps, 'flatIndexMaps' | 'flatFieldMetadataMaps'>;
|
||||
|
||||
export const recomputeIndexOnFlatFieldMetadataNameUpdate = ({
|
||||
fromFlatFieldMetadata,
|
||||
toFlatFieldMetadata,
|
||||
flatObjectMetadata,
|
||||
flatIndexMaps,
|
||||
flatFieldMetadataMaps,
|
||||
}: RecomputeIndexOnFlatFieldMetadataNameUpdateArgs): FlatIndexMetadata[] => {
|
||||
const relatedFlatIndexMetadata = Object.values(flatIndexMaps.byId).filter(
|
||||
(flatIndexMetadata): flatIndexMetadata is FlatIndexMetadata =>
|
||||
@@ -33,26 +35,29 @@ export const recomputeIndexOnFlatFieldMetadataNameUpdate = ({
|
||||
return [];
|
||||
}
|
||||
|
||||
const optimisticFlatObjectMetadata = {
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: flatObjectMetadata.flatFieldMetadatas.map(
|
||||
(flatFieldMetadata) => {
|
||||
if (flatFieldMetadata.id === fromFlatFieldMetadata.id) {
|
||||
return {
|
||||
...flatFieldMetadata,
|
||||
name: toFlatFieldMetadata.name,
|
||||
};
|
||||
}
|
||||
const { objectFlatFieldMetadatas } =
|
||||
findObjectFieldsInFlatFieldMetadataMapsOrThrow({
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadata,
|
||||
});
|
||||
const optimisticObjectFlatFieldMetadatas = objectFlatFieldMetadatas.map(
|
||||
(flatFieldMetadata) => {
|
||||
if (flatFieldMetadata.id === fromFlatFieldMetadata.id) {
|
||||
return {
|
||||
...flatFieldMetadata,
|
||||
name: toFlatFieldMetadata.name,
|
||||
};
|
||||
}
|
||||
|
||||
return flatFieldMetadata;
|
||||
},
|
||||
),
|
||||
};
|
||||
return flatFieldMetadata;
|
||||
},
|
||||
);
|
||||
|
||||
return relatedFlatIndexMetadata.map<FlatIndexMetadata>((flatIndex) => {
|
||||
const newIndex = generateFlatIndexMetadataWithNameOrThrow({
|
||||
flatObjectMetadata: optimisticFlatObjectMetadata,
|
||||
flatIndex,
|
||||
flatObjectMetadata,
|
||||
objectFlatFieldMetadatas: optimisticObjectFlatFieldMetadatas,
|
||||
});
|
||||
|
||||
return newIndex;
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ export const throwOnFieldInputTranspilationsError: ThrowOnFieldInputTranspilatio
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
{
|
||||
report: {
|
||||
fieldMetadata: [],
|
||||
index: [],
|
||||
view: [],
|
||||
viewField: [],
|
||||
|
||||
Reference in New Issue
Block a user