Added a RelationFromOneSide ResolveField in FieldMetadata GraphQL Resolver (#4378)

* Added a ResolveField for relationDefinition on a FieldMetadataItem
This commit is contained in:
Lucas Bordeau 2024-03-11 15:04:52 +01:00 committed by GitHub
parent 581dfafe11
commit a5b41e09f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 143 additions and 5 deletions

View File

@ -0,0 +1,43 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { IsEnum, IsNotEmpty } from 'class-validator';
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
import { ObjectMetadataDTO } from 'src/metadata/object-metadata/dtos/object-metadata.dto';
import { RelationMetadataType } from 'src/metadata/relation-metadata/relation-metadata.entity';
export enum RelationDefinitionType {
ONE_TO_ONE = RelationMetadataType.ONE_TO_ONE,
ONE_TO_MANY = RelationMetadataType.ONE_TO_MANY,
MANY_TO_MANY = RelationMetadataType.MANY_TO_MANY,
MANY_TO_ONE = 'MANY_TO_ONE',
}
registerEnumType(RelationDefinitionType, {
name: 'RelationDefinitionType',
description: 'Relation definition type',
});
@ObjectType('RelationDefinition')
export class RelationDefinitionDTO {
@IsNotEmpty()
@Field(() => ObjectMetadataDTO)
sourceObjectMetadata: ObjectMetadataDTO;
@IsNotEmpty()
@Field(() => ObjectMetadataDTO)
targetObjectMetadata: ObjectMetadataDTO;
@IsNotEmpty()
@Field(() => FieldMetadataDTO)
sourceFieldMetadata: FieldMetadataDTO;
@IsNotEmpty()
@Field(() => FieldMetadataDTO)
targetFieldMetadata: FieldMetadataDTO;
@IsEnum(RelationDefinitionType)
@IsNotEmpty()
@Field(() => RelationDefinitionType)
direction: RelationDefinitionType;
}

View File

@ -17,6 +17,7 @@ import { IsFieldMetadataDefaultValue } from 'src/metadata/field-metadata/validat
import { FieldMetadataResolver } from 'src/metadata/field-metadata/field-metadata.resolver'; import { FieldMetadataResolver } from 'src/metadata/field-metadata/field-metadata.resolver';
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto'; import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
import { IsFieldMetadataOptions } from 'src/metadata/field-metadata/validators/is-field-metadata-options.validator'; import { IsFieldMetadataOptions } from 'src/metadata/field-metadata/validators/is-field-metadata-options.validator';
import { RelationMetadataEntity } from 'src/metadata/relation-metadata/relation-metadata.entity';
import { FieldMetadataService } from './field-metadata.service'; import { FieldMetadataService } from './field-metadata.service';
import { FieldMetadataEntity } from './field-metadata.entity'; import { FieldMetadataEntity } from './field-metadata.entity';
@ -28,7 +29,10 @@ import { UpdateFieldInput } from './dtos/update-field.input';
imports: [ imports: [
NestjsQueryGraphQLModule.forFeature({ NestjsQueryGraphQLModule.forFeature({
imports: [ imports: [
NestjsQueryTypeOrmModule.forFeature([FieldMetadataEntity], 'metadata'), NestjsQueryTypeOrmModule.forFeature(
[FieldMetadataEntity, RelationMetadataEntity],
'metadata',
),
WorkspaceMigrationModule, WorkspaceMigrationModule,
WorkspaceMigrationRunnerModule, WorkspaceMigrationRunnerModule,
ObjectMetadataModule, ObjectMetadataModule,

View File

@ -1,11 +1,18 @@
import { UseGuards } from '@nestjs/common'; import { UseGuards } from '@nestjs/common';
import { Args, Mutation, Resolver } from '@nestjs/graphql'; import {
Args,
Mutation,
Parent,
ResolveField,
Resolver,
} from '@nestjs/graphql';
import { Workspace } from 'src/core/workspace/workspace.entity'; import { Workspace } from 'src/core/workspace/workspace.entity';
import { AuthWorkspace } from 'src/decorators/auth/auth-workspace.decorator'; import { AuthWorkspace } from 'src/decorators/auth/auth-workspace.decorator';
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard'; import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
import { CreateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/create-field.input'; import { CreateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/create-field.input';
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto'; import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
import { RelationDefinitionDTO } from 'src/metadata/field-metadata/dtos/relation-definition.dto';
import { UpdateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/update-field.input'; import { UpdateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/update-field.input';
import { FieldMetadataService } from 'src/metadata/field-metadata/field-metadata.service'; import { FieldMetadataService } from 'src/metadata/field-metadata/field-metadata.service';
@ -35,4 +42,11 @@ export class FieldMetadataResolver {
workspaceId, workspaceId,
}); });
} }
@ResolveField(() => RelationDefinitionDTO, { nullable: true })
async relationDefinition(
@Parent() fieldMetadata: FieldMetadataDTO,
): Promise<RelationDefinitionDTO | null> {
return await this.fieldMetadataService.getRelationDefinition(fieldMetadata);
}
} }

View File

@ -26,6 +26,15 @@ import { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/work
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util'; import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util'; import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
import { generateNullable } from 'src/metadata/field-metadata/utils/generate-nullable'; import { generateNullable } from 'src/metadata/field-metadata/utils/generate-nullable';
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
import {
RelationDefinitionDTO,
RelationDefinitionType,
} from 'src/metadata/field-metadata/dtos/relation-definition.dto';
import {
RelationMetadataEntity,
RelationMetadataType,
} from 'src/metadata/relation-metadata/relation-metadata.entity';
import { import {
FieldMetadataEntity, FieldMetadataEntity,
@ -41,7 +50,8 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
constructor( constructor(
@InjectRepository(FieldMetadataEntity, 'metadata') @InjectRepository(FieldMetadataEntity, 'metadata')
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>, private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
@InjectRepository(RelationMetadataEntity, 'metadata')
private readonly relationMetadataRepository: Repository<RelationMetadataEntity>,
private readonly objectMetadataService: ObjectMetadataService, private readonly objectMetadataService: ObjectMetadataService,
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory, private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
private readonly workspaceMigrationService: WorkspaceMigrationService, private readonly workspaceMigrationService: WorkspaceMigrationService,
@ -340,4 +350,71 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
return fieldMetadataInputOverrided as UpdateFieldInput; return fieldMetadataInputOverrided as UpdateFieldInput;
} }
public async getRelationDefinition(
fieldMetadata: FieldMetadataDTO,
): Promise<RelationDefinitionDTO | null> {
if (fieldMetadata.type !== FieldMetadataType.RELATION) {
return null;
}
const foundRelationMetadata = await this.relationMetadataRepository.findOne(
{
where: [
{ fromFieldMetadataId: fieldMetadata.id },
{ toFieldMetadataId: fieldMetadata.id },
],
relations: [
'fromObjectMetadata',
'toObjectMetadata',
'fromFieldMetadata',
'toFieldMetadata',
],
},
);
if (!foundRelationMetadata) {
throw new Error('RelationMetadata not found');
}
const isRelationFromSource =
foundRelationMetadata.fromFieldMetadata.id === fieldMetadata.id;
// TODO: implement MANY_TO_MANY
if (
foundRelationMetadata.relationType === RelationMetadataType.MANY_TO_MANY
) {
throw new Error(`
Relation type ${foundRelationMetadata.relationType} not supported
`);
}
if (isRelationFromSource) {
const direction =
foundRelationMetadata.relationType === RelationMetadataType.ONE_TO_ONE
? RelationDefinitionType.ONE_TO_ONE
: RelationDefinitionType.ONE_TO_MANY;
return {
sourceObjectMetadata: foundRelationMetadata.fromObjectMetadata,
sourceFieldMetadata: foundRelationMetadata.fromFieldMetadata,
targetObjectMetadata: foundRelationMetadata.toObjectMetadata,
targetFieldMetadata: foundRelationMetadata.toFieldMetadata,
direction,
};
} else {
const direction =
foundRelationMetadata.relationType === RelationMetadataType.ONE_TO_ONE
? RelationDefinitionType.ONE_TO_ONE
: RelationDefinitionType.MANY_TO_ONE;
return {
sourceObjectMetadata: foundRelationMetadata.toObjectMetadata,
sourceFieldMetadata: foundRelationMetadata.toFieldMetadata,
targetObjectMetadata: foundRelationMetadata.fromObjectMetadata,
targetFieldMetadata: foundRelationMetadata.fromFieldMetadata,
direction,
};
}
}
} }

View File

@ -69,8 +69,8 @@ export class ObjectMetadataDTO {
updatedAt: Date; updatedAt: Date;
@Field({ nullable: true }) @Field({ nullable: true })
labelIdentifierFieldMetadataId: string; labelIdentifierFieldMetadataId?: string;
@Field({ nullable: true }) @Field({ nullable: true })
imageIdentifierFieldMetadataId: string; imageIdentifierFieldMetadataId?: string;
} }