morph backend CORE api (#13517)

# Morph Relation needs some work on the core API

Especially on the Morph types

<img width="682" height="394" alt="Screenshot 2025-07-31 at 12 19 40"
src="https://github.com/user-attachments/assets/8b185ae3-3fe7-4886-97b1-ec143bb1b0f4"
/>


## Focus Areas:
- GraphQL schema generation
- Query parsing and field selection
- Morph relation field support
- Input type definition preparation
This commit is contained in:
Guillim
2025-08-12 11:47:02 +02:00
committed by GitHub
parent 6cc947ea01
commit 63c8bb9530
32 changed files with 742 additions and 111 deletions
@@ -3,8 +3,8 @@ import { Injectable } from '@nestjs/common';
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
import { capitalize, isDefined } from 'twenty-shared/utils';
import {
type FindOperator,
In,
type FindOperator,
type InsertResult,
type ObjectLiteral,
} from 'typeorm';
@@ -52,6 +52,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
executionArgs,
objectRecords,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
);
await this.processNestedRelationsIfNeeded({
@@ -73,12 +74,14 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
executionArgs: GraphqlQueryResolverExecutionArgs<CreateManyResolverArgs>,
): Promise<InsertResult> {
if (!executionArgs.args.upsert) {
const { objectMetadataItemWithFieldMaps } = executionArgs.options;
const { objectMetadataItemWithFieldMaps, objectMetadataMaps } =
executionArgs.options;
const selectedColumns = buildColumnsToReturn({
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
return await executionArgs.repository.insert(
@@ -94,7 +97,8 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
private async performUpsertOperation(
executionArgs: GraphqlQueryResolverExecutionArgs<CreateManyResolverArgs>,
): Promise<InsertResult> {
const { objectMetadataItemWithFieldMaps } = executionArgs.options;
const { objectMetadataItemWithFieldMaps, objectMetadataMaps } =
executionArgs.options;
const conflictingFields = this.getConflictingFields(
objectMetadataItemWithFieldMaps,
@@ -120,6 +124,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
if (recordsToUpdate.length > 0) {
@@ -375,6 +380,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
executionArgs: GraphqlQueryResolverExecutionArgs<CreateManyResolverArgs>,
objectRecords: InsertResult,
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps,
objectMetadataMaps: ObjectMetadataMaps,
): Promise<ObjectRecord[]> {
const queryBuilder = executionArgs.repository.createQueryBuilder(
objectMetadataItemWithFieldMaps.nameSingular,
@@ -384,6 +390,7 @@ export class GraphqlQueryCreateManyResolverService extends GraphqlQueryBaseResol
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const upsertedRecords = await queryBuilder
@@ -34,6 +34,7 @@ export class GraphqlQueryCreateOneResolverService extends GraphqlQueryBaseResolv
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const objectRecords: InsertResult = !executionArgs.args.upsert
@@ -60,6 +61,7 @@ export class GraphqlQueryCreateOneResolverService extends GraphqlQueryBaseResolv
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const upsertedRecords = (await queryBuilder
@@ -48,6 +48,7 @@ export class GraphqlQueryDeleteManyResolverService extends GraphqlQueryBaseResol
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const deletedObjectRecords = await queryBuilder
@@ -40,6 +40,7 @@ export class GraphqlQueryDeleteOneResolverService extends GraphqlQueryBaseResolv
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const deletedObjectRecords = await queryBuilder
@@ -46,6 +46,7 @@ export class GraphqlQueryDestroyManyResolverService extends GraphqlQueryBaseReso
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const deletedObjectRecords = await queryBuilder
@@ -38,6 +38,7 @@ export class GraphqlQueryDestroyOneResolverService extends GraphqlQueryBaseResol
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const deletedObjectRecords = await queryBuilder
@@ -68,6 +68,7 @@ export class GraphqlQueryFindDuplicatesResolverService extends GraphqlQueryBaseR
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
if (executionArgs.args.ids) {
@@ -122,6 +122,7 @@ export class GraphqlQueryFindManyResolverService extends GraphqlQueryBaseResolve
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const objectRecords = (await queryBuilder
@@ -56,6 +56,7 @@ export class GraphqlQueryFindOneResolverService extends GraphqlQueryBaseResolver
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const objectRecord = await queryBuilder
@@ -247,7 +247,8 @@ export class GraphqlQueryMergeManyResolverService extends GraphqlQueryBaseResolv
priorityRecordId: string,
mergedData: Partial<ObjectRecord>,
): Promise<ObjectRecord> {
const { objectMetadataItemWithFieldMaps } = executionArgs.options;
const { objectMetadataItemWithFieldMaps, objectMetadataMaps } =
executionArgs.options;
const queryBuilder = executionArgs.repository.createQueryBuilder(
objectMetadataItemWithFieldMaps.nameSingular,
@@ -257,6 +258,7 @@ export class GraphqlQueryMergeManyResolverService extends GraphqlQueryBaseResolv
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const updatedObjectRecords = await queryBuilder
@@ -48,6 +48,7 @@ export class GraphqlQueryRestoreManyResolverService extends GraphqlQueryBaseReso
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const restoredObjectRecords = await queryBuilder
@@ -40,6 +40,7 @@ export class GraphqlQueryRestoreOneResolverService extends GraphqlQueryBaseResol
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const restoredObjectRecords = await queryBuilder
@@ -48,6 +48,7 @@ export class GraphqlQueryUpdateManyResolverService extends GraphqlQueryBaseResol
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const updatedObjectRecords = await queryBuilder
@@ -40,6 +40,7 @@ export class GraphqlQueryUpdateOneResolverService extends GraphqlQueryBaseResolv
select: executionArgs.graphqlQuerySelectedFieldsResult.select,
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
objectMetadataItemWithFieldMaps,
objectMetadataMaps,
});
const updatedObjectRecords = await queryBuilder