Files
twenty_crm/packages/twenty-front/src/modules/object-metadata/utils/mapObjectMetadataToGraphQLQuery.ts
Jérémy M cc29c25176 feat: new relation sync-metadata, twenty-orm, create/update (#10217)
Fix
https://github.com/twentyhq/core-team-issues/issues/330#issue-2827026606
and
https://github.com/twentyhq/core-team-issues/issues/327#issue-2827001814

What this PR does when `isNewRelationEnabled` is set to `true`:
- [x] Drop the creation of the  foreign key as a `FieldMetadata`
- [x] Stop creating `RelationMetadata`
- [x] Properly fill `FieldMetadata` of type `RELATION` during the sync
command
- [x] Use new relation settings in TwentyORM
- [x] Properly create `FieldMetadata` relations when we create a new
object
- [x] Handle `database:reset` with new relations

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-22 19:01:39 +02:00

86 lines
2.9 KiB
TypeScript

import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { mapFieldMetadataToGraphQLQuery } from '@/object-metadata/utils/mapFieldMetadataToGraphQLQuery';
import { shouldFieldBeQueried } from '@/object-metadata/utils/shouldFieldBeQueried';
import { RecordGqlFields } from '@/object-record/graphql/types/RecordGqlFields';
import { isRecordGqlFieldsNode } from '@/object-record/graphql/utils/isRecordGraphlFieldsNode';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
type MapObjectMetadataToGraphQLQueryArgs = {
objectMetadataItems: ObjectMetadataItem[];
objectMetadataItem: Pick<ObjectMetadataItem, 'nameSingular' | 'fields'>;
recordGqlFields?: RecordGqlFields;
computeReferences?: boolean;
isRootLevel?: boolean;
};
export const mapObjectMetadataToGraphQLQuery = ({
objectMetadataItems,
objectMetadataItem,
recordGqlFields,
computeReferences = false,
isRootLevel = true,
}: MapObjectMetadataToGraphQLQueryArgs): string => {
const manyToOneRelationFields = objectMetadataItem?.fields
.filter((field) => field.isActive)
.filter((field) => field.type === FieldMetadataType.RELATION)
.filter((field) => isDefined(field.settings?.joinColumnName));
const manyToOneRelationGqlFieldWithFieldMetadata =
manyToOneRelationFields.map((field) => ({
gqlField: field.settings?.joinColumnName,
fieldMetadata: field,
}));
const gqlFieldWithFieldMetadataThatCouldBeQueried = [
...objectMetadataItem.fields
.filter((fieldMetadata) => fieldMetadata.isActive)
.map((fieldMetadata) => ({
gqlField: fieldMetadata.name,
fieldMetadata,
})),
...manyToOneRelationGqlFieldWithFieldMetadata,
].sort((gqlFieldWithFieldMetadataA, gqlFieldWithFieldMetadataB) =>
gqlFieldWithFieldMetadataA.gqlField.localeCompare(
gqlFieldWithFieldMetadataB.gqlField,
),
);
const gqlFieldWithFieldMetadataThatSouldBeQueried =
gqlFieldWithFieldMetadataThatCouldBeQueried.filter(
(gqlFieldWithFieldMetadata) =>
shouldFieldBeQueried({
gqlField: gqlFieldWithFieldMetadata.gqlField,
fieldMetadata: gqlFieldWithFieldMetadata.fieldMetadata,
recordGqlFields,
}),
);
if (!isRootLevel && computeReferences) {
return `{
__ref
}`;
}
return `{
__typename
${gqlFieldWithFieldMetadataThatSouldBeQueried
.map((gqlFieldWithFieldMetadata) => {
const currentRecordGqlFields =
recordGqlFields?.[gqlFieldWithFieldMetadata.gqlField];
const relationRecordGqlFields = isRecordGqlFieldsNode(
currentRecordGqlFields,
)
? currentRecordGqlFields
: undefined;
return mapFieldMetadataToGraphQLQuery({
objectMetadataItems,
gqlField: gqlFieldWithFieldMetadata.gqlField,
fieldMetadata: gqlFieldWithFieldMetadata.fieldMetadata,
relationRecordGqlFields,
computeReferences,
});
})
.join('\n')}
}`;
};