ObjectMetadataServiceV2.updateOne (#13891)

# Introduction
Last service to get migrated, `updateOne` object metadata service v2
This commit is contained in:
Paul Rastoin
2025-08-14 11:37:52 +02:00
committed by GitHub
parent 3c034c4ab4
commit ad77d2f462
42 changed files with 798 additions and 282 deletions
@@ -0,0 +1,72 @@
import { t } from '@lingui/core/macro';
import {
isDefined,
isLabelIdentifierFieldMetadataTypes,
} from 'twenty-shared/utils';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import {
ObjectMetadataException,
ObjectMetadataExceptionCode,
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
export const validateFlatObjectMetadataIdentifiers = (
flatObjectMetadata: FlatObjectMetadata,
) => {
const errors: ObjectMetadataException[] = [];
const { labelIdentifierFieldMetadataId, imageIdentifierFieldMetadataId } =
flatObjectMetadata;
if (isDefined(labelIdentifierFieldMetadataId)) {
const relatedFlatFieldMetadata = flatObjectMetadata.flatFieldMetadatas.find(
(flatFieldMetadata) =>
flatFieldMetadata.id === labelIdentifierFieldMetadataId,
);
if (!isDefined(relatedFlatFieldMetadata)) {
errors.push(
new ObjectMetadataException(
'labelIdentifierFieldMetadataId validation failed: related field metadata not found',
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
{
userFriendlyMessage: t`Field declared as label identifier not found`,
},
),
);
} else if (
!isLabelIdentifierFieldMetadataTypes(relatedFlatFieldMetadata.type)
) {
errors.push(
new ObjectMetadataException(
'labelIdentifierFieldMetadataId validation failed: field type not compatible',
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
{
userFriendlyMessage: t`Field cannot be used as label identifier`,
},
),
);
}
}
if (isDefined(imageIdentifierFieldMetadataId)) {
const relatedFlatFieldMetadata = flatObjectMetadata.flatFieldMetadatas.find(
(flatFieldMetadata) =>
flatFieldMetadata.id === imageIdentifierFieldMetadataId,
);
if (!isDefined(relatedFlatFieldMetadata)) {
errors.push(
new ObjectMetadataException(
'imageIdentifierFieldMetadataId validation failed: related field metadata not found',
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
{
userFriendlyMessage: t`Field declared as image identifier not found`,
},
),
);
}
}
return errors;
};
@@ -0,0 +1,54 @@
import { t } from '@lingui/core/macro';
import { type FailedFlatObjectMetadataValidationExceptions } from 'src/engine/metadata-modules/flat-object-metadata/types/failed-flat-object-metadata-validation.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { runFlatObjectMetadataValidators } from 'src/engine/metadata-modules/flat-object-metadata/utils/run-flat-object-metadata-validators.util';
import {
ObjectMetadataException,
ObjectMetadataExceptionCode,
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { type FlatMetadataValidator } from 'src/engine/metadata-modules/types/flat-metadata-validator.type';
import {
beneathDatabaseIdentifierMinimumLength,
exceedsDatabaseIdentifierMaximumLength,
} from 'src/engine/metadata-modules/utils/validate-database-identifier-length.utils';
export const validateFlatObjectMetadataLabel = ({
labelPlural,
labelSingular,
}: Pick<
FlatObjectMetadata,
'labelPlural' | 'labelSingular'
>): FailedFlatObjectMetadataValidationExceptions[] => {
const errors: FailedFlatObjectMetadataValidationExceptions[] = [];
const validators: FlatMetadataValidator<string>[] = [
{
validator: (label) => beneathDatabaseIdentifierMinimumLength(label),
message: t`Object label is too short`,
},
{
validator: (label) => exceedsDatabaseIdentifierMaximumLength(label),
message: t`Object label is too long`,
},
];
errors.push(
...[labelSingular, labelPlural].flatMap((label) =>
runFlatObjectMetadataValidators(label, validators),
),
);
const labelsAreIdentical =
labelSingular.trim().toLowerCase() === labelPlural.trim().toLowerCase();
if (labelsAreIdentical) {
errors.push(
new ObjectMetadataException(
t`The singular and plural labels cannot be the same for an object`,
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
),
);
}
return errors;
};
@@ -0,0 +1,37 @@
import { t } from '@lingui/core/macro';
import { type FailedFlatObjectMetadataValidationExceptions } from 'src/engine/metadata-modules/flat-object-metadata/types/failed-flat-object-metadata-validation.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { runFlatObjectMetadataValidators } from 'src/engine/metadata-modules/flat-object-metadata/utils/run-flat-object-metadata-validators.util';
import {
ObjectMetadataException,
ObjectMetadataExceptionCode,
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
import { METADATA_NAME_VALIDATORS } from 'src/engine/metadata-modules/utils/constants/metadata-name-flat-metadata-validators.constants';
export const validateFlatObjectMetadataNames = ({
namePlural,
nameSingular,
}: Pick<FlatObjectMetadata, 'nameSingular' | 'namePlural'>) => {
const errors: FailedFlatObjectMetadataValidationExceptions[] = [];
errors.push(
...[nameSingular, namePlural].flatMap((name) =>
runFlatObjectMetadataValidators(name, METADATA_NAME_VALIDATORS),
),
);
const namesAreIdentical =
namePlural.trim().toLowerCase() === nameSingular.trim().toLowerCase();
if (namesAreIdentical) {
errors.push(
new ObjectMetadataException(
t`The singular and plural names cannot be the same for an object`,
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
),
);
}
return errors;
};