diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts index b2c778b4ec5..9d525ac3b85 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto.ts @@ -33,7 +33,6 @@ import { import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator'; import { FieldStandardOverridesDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-standard-overrides.dto'; -import { type FieldMetadataDefaultOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; import { transformEnumValue } from 'src/engine/utils/transform-enum-value'; @@ -132,9 +131,7 @@ export class FieldMetadataDTO { @Field(() => GraphQLJSON, { nullable: true }) defaultValue?: FieldMetadataDefaultValue; - @Transform(({ value }) => - transformEnumValue(value as FieldMetadataDefaultOption[]), - ) + @Transform(({ value }) => transformEnumValue(value)) @IsOptional() @Field(() => GraphQLJSON, { nullable: true }) options?: FieldMetadataOptions; diff --git a/packages/twenty-server/src/engine/utils/__tests__/transform-enum-value.spec.ts b/packages/twenty-server/src/engine/utils/__tests__/transform-enum-value.spec.ts new file mode 100644 index 00000000000..58f8892c321 --- /dev/null +++ b/packages/twenty-server/src/engine/utils/__tests__/transform-enum-value.spec.ts @@ -0,0 +1,59 @@ +import { transformEnumValue } from 'src/engine/utils/transform-enum-value'; + +describe('transformEnumValue', () => { + it('should return undefined when options is undefined', () => { + expect(transformEnumValue(undefined)).toBeUndefined(); + }); + + it('should prefix option values starting with a digit', () => { + const options = [ + { value: '1_OPTION', label: 'Option 1', color: 'green' as const }, + { value: 'OPTION_2', label: 'Option 2', color: 'blue' as const }, + ]; + + const result = transformEnumValue(options); + + expect(result).toEqual([ + { value: '_1_OPTION', label: 'Option 1', color: 'green' }, + { value: 'OPTION_2', label: 'Option 2', color: 'blue' }, + ]); + }); + + it('should parse and transform options passed as a JSON string', () => { + const options = JSON.stringify([ + { value: 'STARTUP', label: 'Startup', color: 'green' }, + { value: 'SME', label: 'SME', color: 'turquoise' }, + ]); + + const result = transformEnumValue(options); + + expect(result).toEqual([ + { value: 'STARTUP', label: 'Startup', color: 'green' }, + { value: 'SME', label: 'SME', color: 'turquoise' }, + ]); + }); + + it('should prefix digit-starting values in JSON string options', () => { + const options = JSON.stringify([ + { value: '3RD_PARTY', label: '3rd Party', color: 'red' }, + ]); + + const result = transformEnumValue(options); + + expect(result).toEqual([ + { value: '_3RD_PARTY', label: '3rd Party', color: 'red' }, + ]); + }); + + it('should return options unchanged when no values start with a digit', () => { + const options = [ + { value: 'STARTUP', label: 'Startup', color: 'green' as const }, + ]; + + const result = transformEnumValue(options); + + expect(result).toEqual([ + { value: 'STARTUP', label: 'Startup', color: 'green' }, + ]); + }); +}); diff --git a/packages/twenty-server/src/engine/utils/transform-enum-value.ts b/packages/twenty-server/src/engine/utils/transform-enum-value.ts index 74bd674e573..47a95544550 100644 --- a/packages/twenty-server/src/engine/utils/transform-enum-value.ts +++ b/packages/twenty-server/src/engine/utils/transform-enum-value.ts @@ -1,7 +1,20 @@ import { type FieldMetadataDefaultOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input'; -export function transformEnumValue(options?: FieldMetadataDefaultOption[]) { - return options?.map((option) => { +export function transformEnumValue( + options?: FieldMetadataDefaultOption[] | string, +) { + if (!options) { + return options; + } + + const parsedOptions = + typeof options === 'string' ? JSON.parse(options) : options; + + if (!Array.isArray(parsedOptions)) { + return parsedOptions; + } + + return parsedOptions.map((option: FieldMetadataDefaultOption) => { if (/^\d/.test(option.value)) { return { ...option,