feat: new relation resolver (#9794)
Fix [#240](https://github.com/twentyhq/core-team-issues/issues/240)
This commit is contained in:
@ -75,6 +75,11 @@ export const seedFeatureFlags = async (
|
||||
workspaceId: workspaceId,
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
key: FeatureFlagKey.IsNewRelationEnabled,
|
||||
workspaceId: workspaceId,
|
||||
value: false,
|
||||
},
|
||||
])
|
||||
.execute();
|
||||
};
|
||||
|
||||
@ -14,4 +14,5 @@ export enum FeatureFlagKey {
|
||||
IsJsonFilterEnabled = 'IS_JSON_FILTER_ENABLED',
|
||||
IsLocalizationEnabled = 'IS_LOCALIZATION_ENABLED',
|
||||
IsBillingPlansEnabled = 'IS_BILLING_PLANS_ENABLED',
|
||||
IsNewRelationEnabled = 'IS_NEW_RELATION_ENABLED',
|
||||
}
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
import DataLoader from 'dataloader';
|
||||
|
||||
import { RelationMetadataLoaderPayload } from 'src/engine/dataloaders/dataloader.service';
|
||||
import {
|
||||
RelationLoaderPayload,
|
||||
RelationMetadataLoaderPayload,
|
||||
} from 'src/engine/dataloaders/dataloader.service';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
|
||||
export interface IDataloaders {
|
||||
@ -8,4 +13,14 @@ export interface IDataloaders {
|
||||
RelationMetadataLoaderPayload,
|
||||
RelationMetadataEntity
|
||||
>;
|
||||
|
||||
relationLoader: DataLoader<
|
||||
RelationLoaderPayload,
|
||||
{
|
||||
sourceObjectMetadata: ObjectMetadataEntity;
|
||||
targetObjectMetadata: ObjectMetadataEntity;
|
||||
sourceFieldMetadata: FieldMetadataEntity;
|
||||
targetFieldMetadata: FieldMetadataEntity;
|
||||
}
|
||||
>;
|
||||
}
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { DataloaderService } from 'src/engine/dataloaders/dataloader.service';
|
||||
import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module';
|
||||
import { RelationMetadataModule } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.module';
|
||||
|
||||
@Module({
|
||||
imports: [RelationMetadataModule, FieldMetadataModule],
|
||||
providers: [DataloaderService],
|
||||
imports: [RelationMetadataModule],
|
||||
exports: [DataloaderService],
|
||||
})
|
||||
export class DataloaderModule {}
|
||||
|
||||
@ -5,6 +5,9 @@ import DataLoader from 'dataloader';
|
||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||
|
||||
import { IDataloaders } from 'src/engine/dataloaders/dataloader.interface';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { FieldMetadataRelationService } from 'src/engine/metadata-modules/field-metadata/relation/field-metadata-relation.service';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
import { RelationMetadataService } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.service';
|
||||
|
||||
@ -16,14 +19,37 @@ export type RelationMetadataLoaderPayload = {
|
||||
>;
|
||||
};
|
||||
|
||||
export type RelationLoaderPayload = {
|
||||
workspaceId: string;
|
||||
fieldMetadata: Pick<
|
||||
FieldMetadataInterface,
|
||||
| 'type'
|
||||
| 'id'
|
||||
| 'objectMetadataId'
|
||||
| 'relationTargetFieldMetadataId'
|
||||
| 'relationTargetObjectMetadataId'
|
||||
>;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class DataloaderService {
|
||||
constructor(
|
||||
private readonly relationMetadataService: RelationMetadataService,
|
||||
private readonly fieldMetadataRelationService: FieldMetadataRelationService,
|
||||
) {}
|
||||
|
||||
createLoaders(): IDataloaders {
|
||||
const relationMetadataLoader = new DataLoader<
|
||||
const relationMetadataLoader = this.createRelationMetadataLoader();
|
||||
const relationLoader = this.createRelationLoader();
|
||||
|
||||
return {
|
||||
relationMetadataLoader,
|
||||
relationLoader,
|
||||
};
|
||||
}
|
||||
|
||||
private createRelationMetadataLoader() {
|
||||
return new DataLoader<
|
||||
RelationMetadataLoaderPayload,
|
||||
RelationMetadataEntity
|
||||
>(async (dataLoaderParams: RelationMetadataLoaderPayload[]) => {
|
||||
@ -40,9 +66,30 @@ export class DataloaderService {
|
||||
|
||||
return relationsMetadataCollection;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
relationMetadataLoader,
|
||||
};
|
||||
private createRelationLoader() {
|
||||
return new DataLoader<
|
||||
RelationLoaderPayload,
|
||||
{
|
||||
sourceObjectMetadata: ObjectMetadataEntity;
|
||||
targetObjectMetadata: ObjectMetadataEntity;
|
||||
sourceFieldMetadata: FieldMetadataEntity;
|
||||
targetFieldMetadata: FieldMetadataEntity;
|
||||
}
|
||||
>(async (dataLoaderParams: RelationLoaderPayload[]) => {
|
||||
const workspaceId = dataLoaderParams[0].workspaceId;
|
||||
const fieldMetadataItems = dataLoaderParams.map(
|
||||
(dataLoaderParam) => dataLoaderParam.fieldMetadata,
|
||||
);
|
||||
|
||||
const fieldMetadataRelationCollection =
|
||||
await this.fieldMetadataRelationService.findCachedFieldMetadataRelation(
|
||||
fieldMetadataItems,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
return fieldMetadataRelationCollection;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { IsEnum, IsNotEmpty } from 'class-validator';
|
||||
import { Relation } from 'typeorm';
|
||||
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
|
||||
import { ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
|
||||
|
||||
registerEnumType(RelationType, {
|
||||
name: 'RelationType',
|
||||
description: 'Relation type',
|
||||
});
|
||||
|
||||
@ObjectType('Relation')
|
||||
export class RelationDTO {
|
||||
@IsEnum(RelationType)
|
||||
@IsNotEmpty()
|
||||
@Field(() => RelationType)
|
||||
type: RelationType;
|
||||
|
||||
@IsNotEmpty()
|
||||
@Field(() => ObjectMetadataDTO)
|
||||
sourceObjectMetadata: Relation<ObjectMetadataDTO>;
|
||||
|
||||
@IsNotEmpty()
|
||||
@Field(() => ObjectMetadataDTO)
|
||||
targetObjectMetadata: Relation<ObjectMetadataDTO>;
|
||||
|
||||
@IsNotEmpty()
|
||||
@Field(() => FieldMetadataDTO)
|
||||
sourceFieldMetadata: Relation<FieldMetadataDTO>;
|
||||
|
||||
@IsNotEmpty()
|
||||
@Field(() => FieldMetadataDTO)
|
||||
targetFieldMetadata: Relation<FieldMetadataDTO>;
|
||||
}
|
||||
@ -14,4 +14,6 @@ export enum FieldMetadataExceptionCode {
|
||||
FIELD_ALREADY_EXISTS = 'FIELD_ALREADY_EXISTS',
|
||||
OBJECT_METADATA_NOT_FOUND = 'OBJECT_METADATA_NOT_FOUND',
|
||||
INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR',
|
||||
FIELD_METADATA_RELATION_NOT_ENABLED = 'FIELD_METADATA_RELATION_NOT_ENABLED',
|
||||
FIELD_METADATA_RELATION_MALFORMED = 'FIELD_METADATA_RELATION_MALFORMED',
|
||||
}
|
||||
|
||||
@ -9,12 +9,14 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||
|
||||
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
||||
import { ActorModule } from 'src/engine/core-modules/actor/actor.module';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
|
||||
import { FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
|
||||
import { FieldMetadataValidationService } from 'src/engine/metadata-modules/field-metadata/field-metadata-validation.service';
|
||||
import { FieldMetadataResolver } from 'src/engine/metadata-modules/field-metadata/field-metadata.resolver';
|
||||
import { FieldMetadataGraphqlApiExceptionInterceptor } from 'src/engine/metadata-modules/field-metadata/interceptors/field-metadata-graphql-api-exception.interceptor';
|
||||
import { FieldMetadataRelationService } from 'src/engine/metadata-modules/field-metadata/relation/field-metadata-relation.service';
|
||||
import { FieldMetadataRelatedRecordsService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata-related-records.service';
|
||||
import { IsFieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-default-value.validator';
|
||||
import { IsFieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/validators/is-field-metadata-options.validator';
|
||||
@ -22,6 +24,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module';
|
||||
import { ViewModule } from 'src/modules/view/view.module';
|
||||
|
||||
@ -42,6 +45,8 @@ import { UpdateFieldInput } from './dtos/update-field.input';
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
WorkspaceCacheStorageModule,
|
||||
FeatureFlagModule,
|
||||
ObjectMetadataModule,
|
||||
DataSourceModule,
|
||||
TypeORMModule,
|
||||
@ -86,9 +91,14 @@ import { UpdateFieldInput } from './dtos/update-field.input';
|
||||
IsFieldMetadataDefaultValue,
|
||||
IsFieldMetadataOptions,
|
||||
FieldMetadataService,
|
||||
FieldMetadataRelationService,
|
||||
FieldMetadataRelatedRecordsService,
|
||||
FieldMetadataResolver,
|
||||
],
|
||||
exports: [FieldMetadataService, FieldMetadataRelatedRecordsService],
|
||||
exports: [
|
||||
FieldMetadataService,
|
||||
FieldMetadataRelationService,
|
||||
FieldMetadataRelatedRecordsService,
|
||||
],
|
||||
})
|
||||
export class FieldMetadataModule {}
|
||||
|
||||
@ -14,6 +14,8 @@ import {
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { IDataloaders } from 'src/engine/dataloaders/dataloader.interface';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
@ -22,14 +24,24 @@ import { CreateOneFieldMetadataInput } from 'src/engine/metadata-modules/field-m
|
||||
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';
|
||||
import { RelationDefinitionDTO } from 'src/engine/metadata-modules/field-metadata/dtos/relation-definition.dto';
|
||||
import { RelationDTO } from 'src/engine/metadata-modules/field-metadata/dtos/relation.dto';
|
||||
import { UpdateOneFieldMetadataInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
|
||||
import { fieldMetadataGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/field-metadata/utils/field-metadata-graphql-api-exception-handler.util';
|
||||
import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util';
|
||||
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@Resolver(() => FieldMetadataDTO)
|
||||
export class FieldMetadataResolver {
|
||||
constructor(private readonly fieldMetadataService: FieldMetadataService) {}
|
||||
constructor(
|
||||
private readonly fieldMetadataService: FieldMetadataService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {}
|
||||
|
||||
@Mutation(() => FieldMetadataDTO)
|
||||
async createOneField(
|
||||
@ -127,4 +139,56 @@ export class FieldMetadataResolver {
|
||||
fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
@ResolveField(() => RelationDTO, { nullable: true })
|
||||
async relation(
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Parent() fieldMetadata: FieldMetadataEntity<FieldMetadataType.RELATION>,
|
||||
@Context() context: { loaders: IDataloaders },
|
||||
): Promise<RelationDTO | null | undefined> {
|
||||
if (!isRelationFieldMetadataType(fieldMetadata.type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const isNewRelationEnabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IsNewRelationEnabled,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
if (!isNewRelationEnabled) {
|
||||
throw new FieldMetadataException(
|
||||
'New relation feature is not enabled for this workspace',
|
||||
FieldMetadataExceptionCode.FIELD_METADATA_RELATION_NOT_ENABLED,
|
||||
);
|
||||
}
|
||||
const {
|
||||
sourceObjectMetadata,
|
||||
targetObjectMetadata,
|
||||
sourceFieldMetadata,
|
||||
targetFieldMetadata,
|
||||
} = await context.loaders.relationLoader.load({
|
||||
fieldMetadata,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
if (!fieldMetadata.settings) {
|
||||
throw new FieldMetadataException(
|
||||
'Relation settings are required',
|
||||
FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
type: fieldMetadata.settings.relationType,
|
||||
sourceObjectMetadata,
|
||||
targetObjectMetadata,
|
||||
sourceFieldMetadata,
|
||||
targetFieldMetadata,
|
||||
};
|
||||
} catch (error) {
|
||||
fieldMetadataGraphqlApiExceptionHandler(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-met
|
||||
import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface';
|
||||
import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
|
||||
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
|
||||
export interface FieldMetadataInterface<
|
||||
@ -23,6 +25,10 @@ export interface FieldMetadataInterface<
|
||||
isUnique?: boolean;
|
||||
fromRelationMetadata?: RelationMetadataEntity;
|
||||
toRelationMetadata?: RelationMetadataEntity;
|
||||
relationTargetFieldMetadataId?: string;
|
||||
relationTargetFieldMetadata?: FieldMetadataEntity;
|
||||
relationTargetObjectMetadataId?: string;
|
||||
relationTargetObjectMetadata?: ObjectMetadataEntity;
|
||||
isCustom?: boolean;
|
||||
generatedType?: 'STORED' | 'VIRTUAL';
|
||||
asExpression?: string;
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
|
||||
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import {
|
||||
FieldMetadataException,
|
||||
FieldMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.exception';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { cleanObjectMetadata } from 'src/engine/metadata-modules/utils/clean-object-metadata.util';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
@Injectable()
|
||||
export class FieldMetadataRelationService {
|
||||
constructor(
|
||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||
) {}
|
||||
|
||||
async findCachedFieldMetadataRelation(
|
||||
fieldMetadataItems: Array<
|
||||
Pick<
|
||||
FieldMetadataInterface,
|
||||
| 'id'
|
||||
| 'type'
|
||||
| 'objectMetadataId'
|
||||
| 'relationTargetFieldMetadataId'
|
||||
| 'relationTargetObjectMetadataId'
|
||||
>
|
||||
>,
|
||||
workspaceId: string,
|
||||
): Promise<
|
||||
Array<{
|
||||
sourceObjectMetadata: ObjectMetadataEntity;
|
||||
sourceFieldMetadata: FieldMetadataEntity;
|
||||
targetObjectMetadata: ObjectMetadataEntity;
|
||||
targetFieldMetadata: FieldMetadataEntity;
|
||||
}>
|
||||
> {
|
||||
const metadataVersion =
|
||||
await this.workspaceCacheStorageService.getMetadataVersion(workspaceId);
|
||||
|
||||
if (!metadataVersion) {
|
||||
throw new FieldMetadataException(
|
||||
`Metadata version not found for workspace ${workspaceId}`,
|
||||
FieldMetadataExceptionCode.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
const objectMetadataMaps =
|
||||
await this.workspaceCacheStorageService.getObjectMetadataMaps(
|
||||
workspaceId,
|
||||
metadataVersion,
|
||||
);
|
||||
|
||||
if (!objectMetadataMaps) {
|
||||
throw new FieldMetadataException(
|
||||
`Object metadata map not found for workspace ${workspaceId} and metadata version ${metadataVersion}`,
|
||||
FieldMetadataExceptionCode.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
return fieldMetadataItems.map((fieldMetadataItem) => {
|
||||
const {
|
||||
id,
|
||||
objectMetadataId,
|
||||
relationTargetFieldMetadataId,
|
||||
relationTargetObjectMetadataId,
|
||||
} = fieldMetadataItem;
|
||||
|
||||
if (!relationTargetObjectMetadataId || !relationTargetFieldMetadataId) {
|
||||
throw new FieldMetadataException(
|
||||
`Relation target object metadata id or relation target field metadata id not found for field metadata ${id}`,
|
||||
FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
|
||||
);
|
||||
}
|
||||
|
||||
const sourceObjectMetadata = objectMetadataMaps.byId[objectMetadataId];
|
||||
const targetObjectMetadata =
|
||||
objectMetadataMaps.byId[relationTargetObjectMetadataId];
|
||||
const sourceFieldMetadata = sourceObjectMetadata.fieldsById[id];
|
||||
const targetFieldMetadata =
|
||||
targetObjectMetadata.fieldsById[relationTargetFieldMetadataId];
|
||||
|
||||
if (
|
||||
!sourceObjectMetadata ||
|
||||
!targetObjectMetadata ||
|
||||
!sourceFieldMetadata ||
|
||||
!targetFieldMetadata
|
||||
) {
|
||||
throw new FieldMetadataException(
|
||||
`Field relation metadata not found for field metadata ${id}`,
|
||||
FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
sourceObjectMetadata: cleanObjectMetadata(
|
||||
sourceObjectMetadata,
|
||||
) as ObjectMetadataEntity,
|
||||
sourceFieldMetadata: sourceFieldMetadata as FieldMetadataEntity,
|
||||
targetObjectMetadata: cleanObjectMetadata(
|
||||
targetObjectMetadata,
|
||||
) as ObjectMetadataEntity,
|
||||
targetFieldMetadata: targetFieldMetadata as FieldMetadataEntity,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,8 @@ export const fieldMetadataGraphqlApiExceptionHandler = (error: Error) => {
|
||||
throw new ConflictError(error.message);
|
||||
case FieldMetadataExceptionCode.OBJECT_METADATA_NOT_FOUND:
|
||||
case FieldMetadataExceptionCode.INTERNAL_SERVER_ERROR:
|
||||
case FieldMetadataExceptionCode.FIELD_METADATA_RELATION_NOT_ENABLED:
|
||||
case FieldMetadataExceptionCode.FIELD_METADATA_RELATION_MALFORMED:
|
||||
default:
|
||||
throw new InternalServerError(error.message);
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import omit from 'lodash.omit';
|
||||
|
||||
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
|
||||
export const cleanObjectMetadata = (
|
||||
objectMetadata: ObjectMetadataItemWithFieldMaps,
|
||||
): ObjectMetadataInterface =>
|
||||
omit(objectMetadata, ['fieldsById', 'fieldsByName']);
|
||||
Reference in New Issue
Block a user