Spaces:
Build error
Build error
twenty / packages /twenty-server /src /engine /metadata-modules /object-metadata /object-metadata.resolver.ts
| import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; | |
| import { | |
| Args, | |
| Context, | |
| Mutation, | |
| Parent, | |
| Query, | |
| ResolveField, | |
| } from '@nestjs/graphql'; | |
| import { PermissionFlagType } from 'twenty-shared/constants'; | |
| import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; | |
| import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; | |
| import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; | |
| import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; | |
| import { I18nService } from 'src/engine/core-modules/i18n/i18n.service'; | |
| import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type'; | |
| import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; | |
| import { type IDataloaders } from 'src/engine/dataloaders/dataloader.interface'; | |
| import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; | |
| import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; | |
| import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; | |
| import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto'; | |
| import { fromFlatObjectMetadataToObjectMetadataDto } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util'; | |
| import { IndexMetadataDTO } from 'src/engine/metadata-modules/index-metadata/dtos/index-metadata.dto'; | |
| import { CreateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input'; | |
| import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input'; | |
| import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto'; | |
| import { ObjectRecordCountDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-record-count.dto'; | |
| import { UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input'; | |
| import { getEffectiveImageIdentifierFieldMetadataId } from 'src/engine/metadata-modules/object-metadata/utils/get-effective-image-identifier-field-metadata-id.util'; | |
| import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; | |
| import { ObjectRecordCountService } from 'src/engine/metadata-modules/object-metadata/object-record-count.service'; | |
| import { objectMetadataGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/object-metadata/utils/object-metadata-graphql-api-exception-handler.util'; | |
| import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; | |
| import { SearchFieldMetadataDTO } from 'src/engine/metadata-modules/search-field-metadata/dtos/search-field-metadata.dto'; | |
| import { resolveEffectiveEntityProperty } from 'src/engine/metadata-modules/utils/resolve-effective-entity-property.util'; | |
| (WorkspaceAuthGuard) | |
| (() => ObjectMetadataDTO) | |
| (ResolverValidationPipe) | |
| ( | |
| PreventNestToAutoLogGraphqlErrorsFilter, | |
| PermissionsGraphqlApiExceptionFilter, | |
| ) | |
| export class ObjectMetadataResolver { | |
| constructor( | |
| private readonly objectMetadataService: ObjectMetadataService, | |
| private readonly objectRecordCountService: ObjectRecordCountService, | |
| private readonly i18nService: I18nService, | |
| ) {} | |
| (() => Boolean, { | |
| deprecationReason: 'Use isUIEditable', | |
| }) | |
| async isUIReadOnly( | |
| () objectMetadata: ObjectMetadataDTO, | |
| ): Promise<boolean> { | |
| return !objectMetadata.isUIEditable; | |
| } | |
| (SettingsPermissionGuard(PermissionFlagType.DATA_MODEL)) | |
| (() => [ObjectRecordCountDTO]) | |
| async objectRecordCounts( | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<ObjectRecordCountDTO[]> { | |
| return this.objectRecordCountService.getRecordCounts(workspaceId); | |
| } | |
| private async resolveStandardOverride( | |
| objectMetadata: ObjectMetadataDTO, | |
| labelKey: | |
| | 'color' | |
| | 'labelPlural' | |
| | 'labelSingular' | |
| | 'description' | |
| | 'icon', | |
| context: { loaders: IDataloaders } & I18nContext, | |
| workspaceId: string, | |
| ): Promise<string> { | |
| const i18n = this.i18nService.getI18nInstance(context.req.locale); | |
| const standardApplicationId = | |
| await context.loaders.standardApplicationIdLoader.load({ workspaceId }); | |
| const isStandardApp = | |
| objectMetadata.applicationId === standardApplicationId; | |
| const applicationCatalog = | |
| await context.loaders.applicationTranslationCatalogLoader.load({ | |
| applicationId: objectMetadata.applicationId, | |
| workspaceId, | |
| locale: context.req.locale, | |
| }); | |
| return resolveEffectiveEntityProperty({ | |
| metadataName: 'objectMetadata', | |
| baseValue: objectMetadata[labelKey], | |
| overrides: objectMetadata.overrides, | |
| property: labelKey, | |
| i18nContext: { | |
| locale: context.req.locale, | |
| i18nInstance: i18n, | |
| isStandardApp, | |
| applicationCatalog, | |
| }, | |
| }); | |
| } | |
| (() => String, { nullable: true }) | |
| async labelPlural( | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders } & I18nContext, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<string> { | |
| return this.resolveStandardOverride( | |
| objectMetadata, | |
| 'labelPlural', | |
| context, | |
| workspaceId, | |
| ); | |
| } | |
| (() => String, { nullable: true }) | |
| async labelSingular( | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders } & I18nContext, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<string> { | |
| return this.resolveStandardOverride( | |
| objectMetadata, | |
| 'labelSingular', | |
| context, | |
| workspaceId, | |
| ); | |
| } | |
| (() => String, { nullable: true }) | |
| async description( | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders } & I18nContext, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<string> { | |
| return this.resolveStandardOverride( | |
| objectMetadata, | |
| 'description', | |
| context, | |
| workspaceId, | |
| ); | |
| } | |
| (SettingsPermissionGuard(PermissionFlagType.DATA_MODEL)) | |
| (() => String, { nullable: true }) | |
| async icon( | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders } & I18nContext, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<string> { | |
| return this.resolveStandardOverride( | |
| objectMetadata, | |
| 'icon', | |
| context, | |
| workspaceId, | |
| ); | |
| } | |
| (() => String, { nullable: true }) | |
| async color( | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders } & I18nContext, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ): Promise<string> { | |
| return this.resolveStandardOverride( | |
| objectMetadata, | |
| 'color', | |
| context, | |
| workspaceId, | |
| ); | |
| } | |
| (() => UUIDScalarType, { nullable: true }) | |
| imageIdentifierFieldMetadataId( | |
| () objectMetadata: ObjectMetadataDTO, | |
| ): string | null { | |
| return getEffectiveImageIdentifierFieldMetadataId(objectMetadata); | |
| } | |
| (SettingsPermissionGuard(PermissionFlagType.DATA_MODEL)) | |
| (() => ObjectMetadataDTO) | |
| async createOneObject( | |
| ('input') input: CreateOneObjectInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ) { | |
| try { | |
| const flatobjectMetadata = | |
| await this.objectMetadataService.createOneObject({ | |
| createObjectInput: input.object, | |
| workspaceId, | |
| }); | |
| return fromFlatObjectMetadataToObjectMetadataDto(flatobjectMetadata); | |
| } catch (error) { | |
| objectMetadataGraphqlApiExceptionHandler(error); | |
| } | |
| } | |
| (SettingsPermissionGuard(PermissionFlagType.DATA_MODEL)) | |
| (() => ObjectMetadataDTO) | |
| async deleteOneObject( | |
| ('input') deleteObjectInput: DeleteOneObjectInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ) { | |
| try { | |
| const flatobjectMetadata = | |
| await this.objectMetadataService.deleteOneObject({ | |
| deleteObjectInput, | |
| workspaceId, | |
| }); | |
| return fromFlatObjectMetadataToObjectMetadataDto(flatobjectMetadata); | |
| } catch (error) { | |
| objectMetadataGraphqlApiExceptionHandler(error); | |
| } | |
| } | |
| (SettingsPermissionGuard(PermissionFlagType.DATA_MODEL)) | |
| (() => ObjectMetadataDTO) | |
| async updateOneObject( | |
| ('input') updateObjectInput: UpdateOneObjectInput, | |
| () { id: workspaceId }: WorkspaceEntity, | |
| ) { | |
| try { | |
| const flatobjectMetadata = | |
| await this.objectMetadataService.updateOneObject({ | |
| updateObjectInput, | |
| workspaceId, | |
| }); | |
| return fromFlatObjectMetadataToObjectMetadataDto(flatobjectMetadata); | |
| } catch (error) { | |
| objectMetadataGraphqlApiExceptionHandler(error); | |
| } | |
| } | |
| (() => [FieldMetadataDTO], { nullable: false }) | |
| async fieldsList( | |
| () workspace: WorkspaceEntity, | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders } & I18nContext, | |
| ): Promise<FieldMetadataDTO[]> { | |
| try { | |
| const fieldMetadataItems = await context.loaders.fieldMetadataLoader.load( | |
| { | |
| objectMetadata, | |
| workspaceId: workspace.id, | |
| locale: context.req.locale, | |
| }, | |
| ); | |
| return fieldMetadataItems; | |
| } catch (error) { | |
| objectMetadataGraphqlApiExceptionHandler(error); | |
| return []; | |
| } | |
| } | |
| (() => [IndexMetadataDTO], { nullable: false }) | |
| async indexMetadataList( | |
| () workspace: WorkspaceEntity, | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders }, | |
| ): Promise<IndexMetadataDTO[]> { | |
| try { | |
| const indexMetadataItems = await context.loaders.indexMetadataLoader.load( | |
| { | |
| objectMetadata, | |
| workspaceId: workspace.id, | |
| }, | |
| ); | |
| return indexMetadataItems; | |
| } catch (error) { | |
| objectMetadataGraphqlApiExceptionHandler(error); | |
| return []; | |
| } | |
| } | |
| (() => [SearchFieldMetadataDTO], { nullable: false }) | |
| async searchFieldMetadataList( | |
| () workspace: WorkspaceEntity, | |
| () objectMetadata: ObjectMetadataDTO, | |
| () context: { loaders: IDataloaders }, | |
| ): Promise<SearchFieldMetadataDTO[]> { | |
| try { | |
| const searchFieldMetadataItems = | |
| await context.loaders.searchFieldMetadataLoader.load({ | |
| objectMetadata, | |
| workspaceId: workspace.id, | |
| }); | |
| return searchFieldMetadataItems; | |
| } catch (error) { | |
| objectMetadataGraphqlApiExceptionHandler(error); | |
| return []; | |
| } | |
| } | |
| } | |