diff --git a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts index 37ee2af4e7e4..1a20e09c9c55 100644 --- a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts +++ b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts @@ -2,6 +2,12 @@ import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/com import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +export const FIELD_LINKS_MOCK_NAME = 'fieldLinks'; +export const FIELD_CURRENCY_MOCK_NAME = 'fieldCurrency'; +export const FIELD_ADDRESS_MOCK_NAME = 'fieldAddress'; +export const FIELD_ACTOR_MOCK_NAME = 'fieldActor'; +export const FIELD_FULL_NAME_MOCK_NAME = 'fieldFullName'; + export const fieldNumberMock = { name: 'fieldNumber', type: FieldMetadataType.NUMBER, @@ -16,15 +22,8 @@ export const fieldTextMock = { defaultValue: null, }; -export const fieldLinkMock = { - name: 'fieldLink', - type: FieldMetadataType.LINK, - isNullable: false, - defaultValue: { label: '', url: '' }, -}; - export const fieldCurrencyMock = { - name: 'fieldCurrency', + name: FIELD_CURRENCY_MOCK_NAME, type: FieldMetadataType.CURRENCY, isNullable: true, defaultValue: { amountMicros: null, currencyCode: "''" }, @@ -89,7 +88,7 @@ export const fieldRelationMock = { }; const fieldLinksMock = { - name: 'fieldLinks', + name: FIELD_LINKS_MOCK_NAME, type: FieldMetadataType.LINKS, isNullable: false, defaultValue: [ @@ -147,7 +146,7 @@ const fieldNumericMock = { }; const fieldFullNameMock = { - name: 'fieldFullName', + name: FIELD_FULL_NAME_MOCK_NAME, type: FieldMetadataType.FULL_NAME, isNullable: true, defaultValue: { firstName: '', lastName: '' }, @@ -168,7 +167,7 @@ const fieldPositionMock = { }; const fieldAddressMock = { - name: 'fieldAddress', + name: FIELD_ADDRESS_MOCK_NAME, type: FieldMetadataType.ADDRESS, isNullable: true, defaultValue: { @@ -198,7 +197,7 @@ const fieldRichTextMock = { }; const fieldActorMock = { - name: 'fieldActor', + name: FIELD_ACTOR_MOCK_NAME, type: FieldMetadataType.ACTOR, isNullable: true, defaultValue: { @@ -217,7 +216,6 @@ export const fields = [ fieldBooleanMock, fieldNumberMock, fieldNumericMock, - fieldLinkMock, fieldLinksMock, fieldCurrencyMock, fieldFullNameMock, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts index 5703a9747035..f5ccbf97515d 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/args-alias.factory.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; @@ -52,7 +52,7 @@ export class ArgsAliasFactory { isCompositeFieldMetadataType(fieldMetadata.type) ) { // Get composite type definition - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { this.logger.error( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts index 67a22534f875..e50028109e6f 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-builder/factories/field-alias.factory.ts @@ -2,13 +2,13 @@ import { Injectable, Logger } from '@nestjs/common'; import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; -import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { createCompositeFieldKey } from 'src/engine/api/graphql/workspace-query-builder/utils/composite-field-metadata.util'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { computeColumnName, computeCompositeColumnName, } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; @Injectable() export class FieldAliasFactory { @@ -23,7 +23,7 @@ export class FieldAliasFactory { } // If it's a composite field, we need to get the definition - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { this.logger.error( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts index 142db1f7a686..57e959dfc34c 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/type-definitions.generator.ts @@ -1,27 +1,27 @@ import { Injectable, Logger } from '@nestjs/common'; -import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { CompositeType } from 'src/engine/metadata-modules/field-metadata/interfaces/composite-type.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; -import { EnumTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; -import { CompositeObjectTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-object-type-definition.factory'; -import { CompositeInputTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-input-type-definition.factory'; import { CompositeEnumTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-enum-type-definition.factory'; +import { CompositeInputTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-input-type-definition.factory'; +import { CompositeObjectTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/composite-object-type-definition.factory'; +import { EnumTypeDefinitionFactory } from 'src/engine/api/graphql/workspace-schema-builder/factories/enum-type-definition.factory'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; -import { TypeDefinitionsStorage } from './storages/type-definitions.storage'; -import { - ObjectTypeDefinitionFactory, - ObjectTypeDefinitionKind, -} from './factories/object-type-definition.factory'; +import { ConnectionTypeDefinitionFactory } from './factories/connection-type-definition.factory'; +import { EdgeTypeDefinitionFactory } from './factories/edge-type-definition.factory'; +import { ExtendObjectTypeDefinitionFactory } from './factories/extend-object-type-definition.factory'; import { InputTypeDefinitionFactory, InputTypeDefinitionKind, } from './factories/input-type-definition.factory'; +import { + ObjectTypeDefinitionFactory, + ObjectTypeDefinitionKind, +} from './factories/object-type-definition.factory'; import { WorkspaceBuildSchemaOptions } from './interfaces/workspace-build-schema-optionts.interface'; -import { ConnectionTypeDefinitionFactory } from './factories/connection-type-definition.factory'; -import { EdgeTypeDefinitionFactory } from './factories/edge-type-definition.factory'; -import { ExtendObjectTypeDefinitionFactory } from './factories/extend-object-type-definition.factory'; +import { TypeDefinitionsStorage } from './storages/type-definitions.storage'; import { objectContainsRelationField } from './utils/object-contains-relation-field'; @Injectable() @@ -55,7 +55,7 @@ export class TypeDefinitionsGenerator { * GENERATE COMPOSITE TYPE OBJECTS */ private generateCompositeTypeDefs(options: WorkspaceBuildSchemaOptions) { - const compositeTypeCollection = [...compositeTypeDefintions.values()]; + const compositeTypeCollection = [...compositeTypeDefinitions.values()]; this.logger.log( `Generating composite type objects: [${compositeTypeCollection diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts index 473c6f8408d8..4fec6c7ab443 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/__tests__/map-field-metadata-to-graphql-query.utils.spec.ts @@ -1,6 +1,5 @@ import { fieldCurrencyMock, - fieldLinkMock, fieldNumberMock, fieldTextMock, objectMetadataItemMock, @@ -17,15 +16,6 @@ describe('mapFieldMetadataToGraphqlQuery', () => { expect( mapFieldMetadataToGraphqlQuery([objectMetadataItemMock], fieldTextMock), ).toEqual('fieldText'); - expect( - mapFieldMetadataToGraphqlQuery([objectMetadataItemMock], fieldLinkMock), - ).toEqual(` - fieldLink - { - label - url - } - `); expect( mapFieldMetadataToGraphqlQuery( [objectMetadataItemMock], diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-fields.utils.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-fields.utils.ts index 00f5ec990c6c..df9141b99a4a 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-fields.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-fields.utils.ts @@ -2,7 +2,7 @@ import { BadRequestException } from '@nestjs/common'; import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; @@ -13,7 +13,7 @@ export const checkFields = ( const fieldMetadataNames = objectMetadata.fields .map((field) => { if (isCompositeFieldMetadataType(field.type)) { - const compositeType = compositeTypeDefintions.get(field.type); + const compositeType = compositeTypeDefinitions.get(field.type); if (!compositeType) { throw new BadRequestException( diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-order-by.utils.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-order-by.utils.ts index ce14a02bd276..851282b6727b 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-order-by.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/check-order-by.utils.ts @@ -1,9 +1,9 @@ import { BadRequestException } from '@nestjs/common'; -import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; import { Record } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; +import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; @@ -14,7 +14,7 @@ export const checkArrayFields = ( const fieldMetadataNames = objectMetadata.fields .map((field) => { if (isCompositeFieldMetadataType(field.type)) { - const compositeType = compositeTypeDefintions.get(field.type); + const compositeType = compositeTypeDefinitions.get(field.type); if (!compositeType) { throw new BadRequestException( diff --git a/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/order-by-input.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/order-by-input.factory.spec.ts index 63b3179ee68d..9f6923c23802 100644 --- a/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/order-by-input.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/order-by-input.factory.spec.ts @@ -54,7 +54,7 @@ describe('OrderByInputFactory', () => { ]); }); - it('should handler complex fields', () => { + it('should handle complex fields', () => { const request: any = { query: { order_by: 'fieldCurrency.amountMicros', @@ -66,7 +66,7 @@ describe('OrderByInputFactory', () => { ]); }); - it('should handler complex fields with direction', () => { + it('should handle complex fields with direction', () => { const request: any = { query: { order_by: 'fieldCurrency.amountMicros[DescNullsLast]', @@ -78,17 +78,17 @@ describe('OrderByInputFactory', () => { ]); }); - it('should handler multiple complex fields with direction', () => { + it('should handle multiple complex fields with direction', () => { const request: any = { query: { order_by: - 'fieldCurrency.amountMicros[DescNullsLast],fieldLink.label[AscNullsLast]', + 'fieldCurrency.amountMicros[DescNullsLast],fieldText.label[AscNullsLast]', }, }; expect(service.create(request, objectMetadata)).toEqual([ { fieldCurrency: { amountMicros: OrderByDirection.DescNullsLast } }, - { fieldLink: { label: OrderByDirection.AscNullsLast } }, + { fieldText: { label: OrderByDirection.AscNullsLast } }, ]); }); diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts index a99a07ef36ed..3275b8392d01 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts @@ -7,9 +7,11 @@ import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/fi import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; describe('computeSchemaComponents', () => { - it('should test all field types', () => { + it('should test all non-deprecated field types', () => { expect(fields.map((field) => field.type)).toEqual( - Object.keys(FieldMetadataType), + Object.keys(FieldMetadataType).filter( + (key) => key !== FieldMetadataType.LINK, + ), ); }); it('should compute schema components', () => { @@ -55,13 +57,6 @@ describe('computeSchemaComponents', () => { fieldNumeric: { type: 'number', }, - fieldLink: { - properties: { - label: { type: 'string' }, - url: { type: 'string' }, - }, - type: 'object', - }, fieldLinks: { properties: { primaryLinkLabel: { type: 'string' }, diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts index ea26a3118349..bd7248cc0939 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts @@ -9,7 +9,7 @@ import { computeOrderByParameters, computeStartingAfterParameters, } from 'src/engine/core-modules/open-api/utils/parameters.utils'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { capitalize } from 'src/utils/capitalize'; @@ -74,7 +74,7 @@ const getSchemaComponentsProperties = ( case FieldMetadataType.ACTOR: itemProperty = { type: 'object', - properties: compositeTypeDefintions + properties: compositeTypeDefinitions .get(field.type) ?.properties?.reduce((properties, property) => { properties[property.name] = getFieldProperties(property.type); diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts index 442fe63566ee..7f1a2f129b86 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/composite-types/index.ts @@ -13,7 +13,7 @@ export type CompositeFieldsDefinitionFunction = ( fieldMetadata?: FieldMetadataInterface, ) => FieldMetadataInterface[]; -export const compositeTypeDefintions = new Map< +export const compositeTypeDefinitions = new Map< FieldMetadataType, CompositeType >([ 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 6cb1cdebefad..277db13e4f43 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 @@ -8,7 +8,7 @@ import { v4 as uuidV4 } from 'uuid'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; import { DeleteOneFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/delete-field.input'; import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; @@ -28,18 +28,19 @@ import { } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; import { generateNullable } from 'src/engine/metadata-modules/field-metadata/utils/generate-nullable'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { RelationMetadataEntity, RelationMetadataType, } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { InvalidStringException } from 'src/engine/metadata-modules/utils/exceptions/invalid-string.exception'; +import { NameNotAvailableException } from 'src/engine/metadata-modules/utils/exceptions/name-not-available.exception'; +import { NameTooLongException } from 'src/engine/metadata-modules/utils/exceptions/name-too-long.exception'; import { exceedsDatabaseIdentifierMaximumLength } from 'src/engine/metadata-modules/utils/validate-database-identifier-length.utils'; -import { - InvalidStringException, - NameTooLongException, - validateMetadataNameOrThrow, -} from 'src/engine/metadata-modules/utils/validate-metadata-name.utils'; +import { validateFieldNameAvailabilityOrThrow } from 'src/engine/metadata-modules/utils/validate-field-name-availability.utils'; +import { validateMetadataNameValidityOrThrow as validateFieldNameValidityOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name-validity.utils'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.service'; import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { @@ -140,7 +141,10 @@ export class FieldMetadataService extends TypeOrmQueryService(fieldMetadataInput); + this.validateFieldMetadataInput( + fieldMetadataInput, + objectMetadata, + ); const fieldAlreadyExists = await fieldMetadataRepository.findOne({ where: { @@ -355,7 +359,10 @@ export class FieldMetadataService extends TypeOrmQueryService(fieldMetadataInput); + this.validateFieldMetadataInput( + fieldMetadataInput, + objectMetadata, + ); const updatableFieldInput = existingFieldMetadata.isCustom === false @@ -485,7 +492,7 @@ export class FieldMetadataService extends TypeOrmQueryService(fieldMetadataInput: T): T { + >(fieldMetadataInput: T, objectMetadata: ObjectMetadataEntity): T { if (fieldMetadataInput.name) { try { - validateMetadataNameOrThrow(fieldMetadataInput.name); + validateFieldNameValidityOrThrow(fieldMetadataInput.name); + validateFieldNameAvailabilityOrThrow( + fieldMetadataInput.name, + objectMetadata, + ); } catch (error) { if (error instanceof InvalidStringException) { throw new FieldMetadataException( @@ -688,6 +699,11 @@ export class FieldMetadataService extends TypeOrmQueryService { const validateNameCharactersOrThrow = (name?: string) => { try { if (name) { - validateMetadataNameOrThrow(name); + validateMetadataNameValidityOrThrow(name); } } catch (error) { if (error instanceof InvalidStringException) { diff --git a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts index 4e01a8a0ebaf..a08006adbf87 100644 --- a/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/relation-metadata/relation-metadata.service.ts @@ -18,10 +18,9 @@ import { RelationMetadataException, RelationMetadataExceptionCode, } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.exception'; -import { - InvalidStringException, - validateMetadataNameOrThrow, -} from 'src/engine/metadata-modules/utils/validate-metadata-name.utils'; +import { InvalidStringException } from 'src/engine/metadata-modules/utils/exceptions/invalid-string.exception'; +import { validateFieldNameAvailabilityOrThrow } from 'src/engine/metadata-modules/utils/validate-field-name-availability.utils'; +import { validateMetadataNameValidityOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name-validity.utils'; import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.service'; import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { @@ -63,8 +62,8 @@ export class RelationMetadataService extends TypeOrmQueryService { + const objectMetadata = objectMetadataItemMock; + + it('does not throw if name is not reserved', () => { + const name = 'testName'; + + expect(() => + validateFieldNameAvailabilityOrThrow(name, objectMetadata), + ).not.toThrow(); + }); + + describe('error cases', () => { + it('throws error with LINKS suffixes', () => { + const name = `${FIELD_LINKS_MOCK_NAME}PrimaryLinkLabel`; + + expect(() => + validateFieldNameAvailabilityOrThrow(name, objectMetadata), + ).toThrow(NameNotAvailableException); + }); + it('throws error with CURRENCY suffixes', () => { + const name = `${FIELD_CURRENCY_MOCK_NAME}AmountMicros`; + + expect(() => + validateFieldNameAvailabilityOrThrow(name, objectMetadata), + ).toThrow(NameNotAvailableException); + }); + it('throws error with FULL_NAME suffixes', () => { + const name = `${FIELD_FULL_NAME_MOCK_NAME}FirstName`; + + expect(() => + validateFieldNameAvailabilityOrThrow(name, objectMetadata), + ).toThrow(NameNotAvailableException); + }); + it('throws error with ACTOR suffixes', () => { + const name = `${FIELD_ACTOR_MOCK_NAME}Name`; + + expect(() => + validateFieldNameAvailabilityOrThrow(name, objectMetadata), + ).toThrow(NameNotAvailableException); + }); + it('throws error with ADDRESS suffixes', () => { + const name = `${FIELD_ADDRESS_MOCK_NAME}AddressStreet1`; + + expect(() => + validateFieldNameAvailabilityOrThrow(name, objectMetadata), + ).toThrow(NameNotAvailableException); + }); + }); +}); diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/__tests__/validate-metadata-name.spec.ts b/packages/twenty-server/src/engine/metadata-modules/utils/__tests__/validate-metadata-name-validity.spec.ts similarity index 51% rename from packages/twenty-server/src/engine/metadata-modules/utils/__tests__/validate-metadata-name.spec.ts rename to packages/twenty-server/src/engine/metadata-modules/utils/__tests__/validate-metadata-name-validity.spec.ts index 445620dd4236..6cd9bd2d6478 100644 --- a/packages/twenty-server/src/engine/metadata-modules/utils/__tests__/validate-metadata-name.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/utils/__tests__/validate-metadata-name-validity.spec.ts @@ -1,26 +1,24 @@ -import { - validateMetadataNameOrThrow, - InvalidStringException, - NameTooLongException, -} from 'src/engine/metadata-modules/utils/validate-metadata-name.utils'; +import { InvalidStringException } from 'src/engine/metadata-modules/utils/exceptions/invalid-string.exception'; +import { NameTooLongException } from 'src/engine/metadata-modules/utils/exceptions/name-too-long.exception'; +import { validateMetadataNameValidityOrThrow } from 'src/engine/metadata-modules/utils/validate-metadata-name-validity.utils'; -describe('validateMetadataNameOrThrow', () => { +describe('validateMetadataNameValidityOrThrow', () => { it('does not throw if string is valid', () => { const input = 'testName'; - expect(validateMetadataNameOrThrow(input)).not.toThrow; + expect(validateMetadataNameValidityOrThrow(input)).not.toThrow; }); it('throws error if string has spaces', () => { const input = 'name with spaces'; - expect(() => validateMetadataNameOrThrow(input)).toThrow( + expect(() => validateMetadataNameValidityOrThrow(input)).toThrow( InvalidStringException, ); }); it('throws error if string starts with capital letter', () => { const input = 'StringStartingWithCapitalLetter'; - expect(() => validateMetadataNameOrThrow(input)).toThrow( + expect(() => validateMetadataNameValidityOrThrow(input)).toThrow( InvalidStringException, ); }); @@ -28,7 +26,7 @@ describe('validateMetadataNameOrThrow', () => { it('throws error if string has non latin characters', () => { const input = 'בְרִבְרִ'; - expect(() => validateMetadataNameOrThrow(input)).toThrow( + expect(() => validateMetadataNameValidityOrThrow(input)).toThrow( InvalidStringException, ); }); @@ -36,7 +34,7 @@ describe('validateMetadataNameOrThrow', () => { it('throws error if starts with digits', () => { const input = '123string'; - expect(() => validateMetadataNameOrThrow(input)).toThrow( + expect(() => validateMetadataNameValidityOrThrow(input)).toThrow( InvalidStringException, ); }); @@ -44,14 +42,15 @@ describe('validateMetadataNameOrThrow', () => { const inputWith63Characters = 'thisIsAstringWithSixtyThreeCharacters11111111111111111111111111'; - expect(validateMetadataNameOrThrow(inputWith63Characters)).not.toThrow; + expect(validateMetadataNameValidityOrThrow(inputWith63Characters)).not + .toThrow; }); it('throws error if string is above 63 characters', () => { const inputWith64Characters = 'thisIsAstringWithSixtyFourCharacters1111111111111111111111111111'; - expect(() => validateMetadataNameOrThrow(inputWith64Characters)).toThrow( - NameTooLongException, - ); + expect(() => + validateMetadataNameValidityOrThrow(inputWith64Characters), + ).toThrow(NameTooLongException); }); }); diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/invalid-string.exception.ts b/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/invalid-string.exception.ts new file mode 100644 index 000000000000..0404de70b53e --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/invalid-string.exception.ts @@ -0,0 +1,7 @@ +export class InvalidStringException extends Error { + constructor(string: string) { + const message = `String "${string}" is not valid`; + + super(message); + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/name-not-available.exception.ts b/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/name-not-available.exception.ts new file mode 100644 index 000000000000..308fc6ddd84f --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/name-not-available.exception.ts @@ -0,0 +1,7 @@ +export class NameNotAvailableException extends Error { + constructor(name: string) { + const message = `Name "${name}" is not available`; + + super(message); + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/name-too-long.exception.ts b/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/name-too-long.exception.ts new file mode 100644 index 000000000000..0c9cf45f6342 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/utils/exceptions/name-too-long.exception.ts @@ -0,0 +1,7 @@ +export class NameTooLongException extends Error { + constructor(string: string) { + const message = `String "${string}" exceeds 63 characters limit`; + + super(message); + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/validate-field-name-availability.utils.ts b/packages/twenty-server/src/engine/metadata-modules/utils/validate-field-name-availability.utils.ts new file mode 100644 index 000000000000..07db05aacfbd --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/utils/validate-field-name-availability.utils.ts @@ -0,0 +1,38 @@ +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; +import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { NameNotAvailableException } from 'src/engine/metadata-modules/utils/exceptions/name-not-available.exception'; + +const getReservedCompositeFieldNames = ( + objectMetadata: ObjectMetadataEntity, +) => { + const reservedCompositeFieldsNames: string[] = []; + + for (const field of objectMetadata.fields) { + if (isCompositeFieldMetadataType(field.type)) { + const base = field.name; + const compositeType = compositeTypeDefinitions.get(field.type); + + compositeType?.properties.map((property) => + reservedCompositeFieldsNames.push( + computeCompositeColumnName(base, property), + ), + ); + } + } + + return reservedCompositeFieldsNames; +}; + +export const validateFieldNameAvailabilityOrThrow = ( + name: string, + objectMetadata: ObjectMetadataEntity, +) => { + const reservedCompositeFieldsNames = + getReservedCompositeFieldNames(objectMetadata); + + if (reservedCompositeFieldsNames.includes(name)) { + throw new NameNotAvailableException(name); + } +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/validate-metadata-name-validity.utils.ts b/packages/twenty-server/src/engine/metadata-modules/utils/validate-metadata-name-validity.utils.ts new file mode 100644 index 000000000000..42cb2fc70945 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/utils/validate-metadata-name-validity.utils.ts @@ -0,0 +1,14 @@ +import { InvalidStringException } from 'src/engine/metadata-modules/utils/exceptions/invalid-string.exception'; +import { NameTooLongException } from 'src/engine/metadata-modules/utils/exceptions/name-too-long.exception'; +import { exceedsDatabaseIdentifierMaximumLength } from 'src/engine/metadata-modules/utils/validate-database-identifier-length.utils'; + +const VALID_STRING_PATTERN = /^[a-z][a-zA-Z0-9]*$/; + +export const validateMetadataNameValidityOrThrow = (name: string) => { + if (!name.match(VALID_STRING_PATTERN)) { + throw new InvalidStringException(name); + } + if (exceedsDatabaseIdentifierMaximumLength(name)) { + throw new NameTooLongException(name); + } +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/utils/validate-metadata-name.utils.ts b/packages/twenty-server/src/engine/metadata-modules/utils/validate-metadata-name.utils.ts deleted file mode 100644 index 72835eead45e..000000000000 --- a/packages/twenty-server/src/engine/metadata-modules/utils/validate-metadata-name.utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { exceedsDatabaseIdentifierMaximumLength } from 'src/engine/metadata-modules/utils/validate-database-identifier-length.utils'; - -const VALID_STRING_PATTERN = /^[a-z][a-zA-Z0-9]*$/; - -export const validateMetadataNameOrThrow = (name: string) => { - if (!name.match(VALID_STRING_PATTERN)) { - throw new InvalidStringException(name); - } - if (exceedsDatabaseIdentifierMaximumLength(name)) { - throw new NameTooLongException(name); - } -}; - -export class InvalidStringException extends Error { - constructor(string: string) { - const message = `String "${string}" is not valid`; - - super(message); - } -} - -export class NameTooLongException extends Error { - constructor(string: string) { - const message = `String "${string}" exceeds 63 characters limit`; - - super(message); - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts index 827092daaff7..2a6ed45b0fcd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory.ts @@ -2,17 +2,17 @@ import { Injectable, Logger } from '@nestjs/common'; import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; +import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; +import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory'; +import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnCreate, } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; -import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; -import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; -import { ColumnActionAbstractFactory } from 'src/engine/metadata-modules/workspace-migration/factories/column-action-abstract.factory'; -import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { WorkspaceMigrationException, WorkspaceMigrationExceptionCode, @@ -32,7 +32,7 @@ export class CompositeColumnActionFactory extends ColumnActionAbstractFactory, ): WorkspaceMigrationColumnCreate[] { - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { this.logger.error( @@ -80,10 +80,10 @@ export class CompositeColumnActionFactory extends ColumnActionAbstractFactory, alteredFieldMetadata: FieldMetadataInterface, ): WorkspaceMigrationColumnAlter[] { - const currentCompositeType = compositeTypeDefintions.get( + const currentCompositeType = compositeTypeDefinitions.get( currentFieldMetadata.type, ); - const alteredCompositeType = compositeTypeDefintions.get( + const alteredCompositeType = compositeTypeDefinitions.get( alteredFieldMetadata.type, ); diff --git a/packages/twenty-server/src/engine/twenty-orm/factories/entity-schema-column.factory.ts b/packages/twenty-server/src/engine/twenty-orm/factories/entity-schema-column.factory.ts index 251e3058d778..6b4564efaaea 100644 --- a/packages/twenty-server/src/engine/twenty-orm/factories/entity-schema-column.factory.ts +++ b/packages/twenty-server/src/engine/twenty-orm/factories/entity-schema-column.factory.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { ColumnType, EntitySchemaColumnOptions } from 'typeorm'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { FieldMetadataEntity, FieldMetadataType, @@ -105,11 +105,11 @@ export class EntitySchemaColumnFactory { fieldMetadata: FieldMetadataEntity, ): EntitySchemaColumnMap { const entitySchemaColumnMap: EntitySchemaColumnMap = {}; - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { throw new Error( - `Composite type ${fieldMetadata.type} is not defined in compositeTypeDefintions`, + `Composite type ${fieldMetadata.type} is not defined in compositeTypeDefinitions`, ); } diff --git a/packages/twenty-server/src/engine/twenty-orm/repository/workspace.repository.ts b/packages/twenty-server/src/engine/twenty-orm/repository/workspace.repository.ts index 3adb6e21dc97..6a436ced71aa 100644 --- a/packages/twenty-server/src/engine/twenty-orm/repository/workspace.repository.ts +++ b/packages/twenty-server/src/engine/twenty-orm/repository/workspace.repository.ts @@ -24,7 +24,7 @@ import { UpsertOptions } from 'typeorm/repository/UpsertOptions'; import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; @@ -697,7 +697,7 @@ export class WorkspaceRepository< continue; } - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { continue; @@ -751,7 +751,7 @@ export class WorkspaceRepository< const compositeFieldMetadataMap = new Map( compositeFieldMetadataCollection.flatMap((fieldMetadata) => { - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) return []; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts index c4fab96efe34..82dd9fdbd258 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/database-structure.service.ts @@ -3,28 +3,28 @@ import { Injectable } from '@nestjs/common'; import { ColumnType } from 'typeorm'; import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata'; -import { - WorkspaceTableStructure, - WorkspaceTableStructureResult, -} from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; import { FieldMetadataDefaultValue, FieldMetadataFunctionDefaultValue, } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; +import { + WorkspaceTableStructure, + WorkspaceTableStructureResult, +} from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; import { TypeORMService } from 'src/database/typeorm/typeorm.service'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { FieldMetadataDefaultValueFunctionNames } from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input'; import { FieldMetadataEntity, FieldMetadataType, } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; -import { serializeFunctionDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-function-default-value.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; -import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; import { isFunctionDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/is-function-default-value.util'; -import { FieldMetadataDefaultValueFunctionNames } from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { serializeFunctionDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-function-default-value.util'; +import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util'; import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; +import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; @Injectable() export class DatabaseStructureService { @@ -192,7 +192,7 @@ export class DatabaseStructureService { }; if (isCompositeFieldMetadataType(fieldMetadata.type)) { - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { throw new Error( @@ -310,7 +310,7 @@ export class DatabaseStructureService { }; if (isCompositeFieldMetadataType(fieldMetadataType)) { - const compositeType = compositeTypeDefintions.get(fieldMetadataType); + const compositeType = compositeTypeDefinitions.get(fieldMetadataType); if (!compositeType) { throw new Error( diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts index 28652c50b6ed..994b91ec70ba 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-health/services/field-metadata-health.service.ts @@ -1,34 +1,34 @@ import { Injectable } from '@nestjs/common'; +import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; import { WorkspaceHealthIssue, WorkspaceHealthIssueType, } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-issue.interface'; -import { WorkspaceTableStructure } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; import { WorkspaceHealthOptions } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-health-options.interface'; -import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; +import { WorkspaceTableStructure } from 'src/engine/workspace-manager/workspace-health/interfaces/workspace-table-definition.interface'; +import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types'; import { FieldMetadataEntity, FieldMetadataType, } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { + computeColumnName, + computeCompositeColumnName, +} from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; -import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; -import { validName } from 'src/engine/workspace-manager/workspace-health/utils/valid-name.util'; -import { validateDefaultValueForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util'; import { EnumFieldMetadataUnionType, isEnumFieldMetadataType, } from 'src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util'; -import { validateOptionsForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util'; import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value'; +import { validateDefaultValueForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util'; +import { validateOptionsForType } from 'src/engine/metadata-modules/field-metadata/utils/validate-options-for-type.util'; import { customNamePrefix } from 'src/engine/utils/compute-table-name.util'; import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util'; -import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; -import { - computeColumnName, - computeCompositeColumnName, -} from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util'; +import { DatabaseStructureService } from 'src/engine/workspace-manager/workspace-health/services/database-structure.service'; +import { validName } from 'src/engine/workspace-manager/workspace-health/utils/valid-name.util'; @Injectable() export class FieldMetadataHealthService { @@ -101,7 +101,7 @@ export class FieldMetadataHealthService { let columnNames: string[] = []; if (isCompositeFieldMetadataType(fieldMetadata.type)) { - const compositeType = compositeTypeDefintions.get(fieldMetadata.type); + const compositeType = compositeTypeDefinitions.get(fieldMetadata.type); if (!compositeType) { throw new Error(`Composite type ${fieldMetadata.type} is not defined`);