From fb0cf11499d9a765370a4d179a830c398bd8819f Mon Sep 17 00:00:00 2001 From: Guillim Date: Tue, 24 Jun 2025 20:20:37 +0200 Subject: [PATCH] check on label metadata (#12852) Better catching label input - there were absolutely no check on label when creating the target field while doing a relation : we crearted these checks here. - We keep the label quite open to special char as discussed with Felix. so mostly checking length of label. - We check that label does not already exists on the targetted object - making sure the Target fieldinput label is checked before we create it. The previous checks are not enough since the label goes through anoteher merthod before going in the database - validate-metadata-name-is-camel-case.utils.ts : making sure we can use this error message for metadata name and for target label --------- Co-authored-by: Charles Bochet Co-authored-by: prastoin --- .../field-metadata/field-metadata.service.ts | 30 +++++++++++++++++-- ...te-object-metadata-input.util.spec.ts.snap | 4 +-- .../validate-metadata-name.spec.ts.snap | 8 ++--- .../exceptions/invalid-metadata.exception.ts | 1 + ...idate-metadata-name-is-camel-case.utils.ts | 2 +- ...e-object-metadata.integration-spec.ts.snap | 10 +++---- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts index bf63cdba3..d082cafc1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts @@ -44,6 +44,7 @@ import { isSelectOrMultiSelectFieldMetadata } from 'src/engine/metadata-modules/ import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-on-delete-action.type'; import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps'; +import { ObjectMetadataMaps } from 'src/engine/metadata-modules/types/object-metadata-maps'; import { InvalidMetadataException } from 'src/engine/metadata-modules/utils/exceptions/invalid-metadata.exception'; import { validateFieldNameAvailabilityOrThrow } from 'src/engine/metadata-modules/utils/validate-field-name-availability.utils'; import { validateMetadataNameOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name.utils'; @@ -82,6 +83,7 @@ type ValidateFieldMetadataArgs = fieldMetadataInput: T; objectMetadata: ObjectMetadataItemWithFieldMaps; existingFieldMetadata?: FieldMetadataInterface; + objectMetadataMaps: ObjectMetadataMaps; }; @Injectable() @@ -208,6 +210,7 @@ export class FieldMetadataService extends TypeOrmQueryService): Promise { if (fieldMetadataInput.name) { try { @@ -602,6 +606,21 @@ export class FieldMetadataService extends TypeOrmQueryService, + objectMetadataMaps: ObjectMetadataMaps, ): Promise { if (!fieldMetadataInput.isRemoteCreation) { assertMutationNotOnRemoteObject(objectMetadata); @@ -747,6 +767,7 @@ export class FieldMetadataService extends TypeOrmQueryService { if (name !== camelCase(name)) { throw new InvalidMetadataException( - `Name should be in camelCase: ${name}`, + `${name} should be in camelCase`, InvalidMetadataExceptionCode.NOT_CAMEL_CASE, ); } diff --git a/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata.integration-spec.ts.snap index 5cc944696..9a0ffe538 100644 --- a/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata.integration-spec.ts.snap @@ -24,11 +24,11 @@ exports[`Object metadata creation should fail when namePlural is a reserved keyw exports[`Object metadata creation should fail when namePlural is an empty string 1`] = `"Input is too short: """`; -exports[`Object metadata creation should fail when namePlural is not camelCased 1`] = `"Name should be in camelCase: Not_Camel_Case"`; +exports[`Object metadata creation should fail when namePlural is not camelCased 1`] = `"Not_Camel_Case should be in camelCase"`; -exports[`Object metadata creation should fail when nameSingular contains only one char and whitespaces 1`] = `"Name should be in camelCase: a a "`; +exports[`Object metadata creation should fail when nameSingular contains only one char and whitespaces 1`] = `" a a should be in camelCase"`; -exports[`Object metadata creation should fail when nameSingular contains only whitespaces 1`] = `"Name should be in camelCase: "`; +exports[`Object metadata creation should fail when nameSingular contains only whitespaces 1`] = `" should be in camelCase"`; exports[`Object metadata creation should fail when nameSingular has invalid characters 1`] = `"String "μ" is not valid: must start with lowercase letter and contain only alphanumeric letters"`; @@ -36,8 +36,8 @@ exports[`Object metadata creation should fail when nameSingular is a reserved ke exports[`Object metadata creation should fail when nameSingular is an empty string 1`] = `"Input is too short: """`; -exports[`Object metadata creation should fail when nameSingular is not camelCased 1`] = `"Name should be in camelCase: Not_Camel_Case"`; +exports[`Object metadata creation should fail when nameSingular is not camelCased 1`] = `"Not_Camel_Case should be in camelCase"`; exports[`Object metadata creation should fail when names are identical 1`] = `"The singular and plural names cannot be the same for an object"`; -exports[`Object metadata creation should fail when names with whitespaces result to be identical 1`] = `"Name should be in camelCase: fooBar "`; +exports[`Object metadata creation should fail when names with whitespaces result to be identical 1`] = `" fooBar should be in camelCase"`;