Connect - Update Gql schema generation (#13001)

To test : 

```
mutation testMutation {
  createPerson(
    data: {company: {connect: {where: {domainName: {primaryLinkUrl: "airbnb.com"}}}}}
  ) {
    id
  }
}
```

closes https://github.com/twentyhq/core-team-issues/issues/1167
This commit is contained in:
Etienne
2025-07-02 16:37:24 +02:00
committed by GitHub
parent 54e233d7b9
commit ba67e0d5f4
14 changed files with 604 additions and 98 deletions

View File

@ -0,0 +1,151 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
import { IndexFieldMetadataInterface } from 'src/engine/metadata-modules/index-metadata/interfaces/index-field-metadata.interface';
import { IndexMetadataInterface } from 'src/engine/metadata-modules/index-metadata/interfaces/index-metadata.interface';
import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { getUniqueConstraintsFields } from 'src/engine/metadata-modules/index-metadata/utils/getUniqueConstraintsFields.util';
describe('getUniqueConstraintsFields', () => {
const mockIdField: FieldMetadataInterface = {
id: 'field-id-1',
name: 'id',
label: 'ID',
type: FieldMetadataType.UUID,
objectMetadataId: 'object-id-1',
isNullable: false,
isUnique: false,
isCustom: false,
isSystem: true,
isActive: true,
isLabelSyncedWithName: false,
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
};
const mockEmailField: FieldMetadataInterface = {
id: 'field-id-2',
name: 'email',
label: 'Email',
type: FieldMetadataType.EMAILS,
objectMetadataId: 'object-id-1',
isNullable: true,
isUnique: true,
isCustom: false,
isSystem: false,
isActive: true,
isLabelSyncedWithName: false,
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
};
const mockNameField: FieldMetadataInterface = {
id: 'field-id-3',
name: 'name',
label: 'Name',
type: FieldMetadataType.TEXT,
objectMetadataId: 'object-id-1',
isNullable: true,
isUnique: false,
isCustom: false,
isSystem: false,
isActive: true,
isLabelSyncedWithName: false,
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
};
const createMockIndexFieldMetadata = (
fieldMetadataId: string,
indexMetadataId: string,
order = 0,
): IndexFieldMetadataInterface =>
({
id: `index-field-${fieldMetadataId}-${indexMetadataId}`,
indexMetadataId,
fieldMetadataId,
order,
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
}) as IndexFieldMetadataInterface;
const createMockIndexMetadata = (
id: string,
name: string,
isUnique: boolean,
indexFieldMetadatas: IndexFieldMetadataInterface[],
): IndexMetadataInterface => ({
id,
name,
isUnique,
indexFieldMetadatas,
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
indexWhereClause: null,
indexType: IndexType.BTREE,
});
const createMockObjectMetadata = (
fields: FieldMetadataInterface[],
indexMetadatas: IndexMetadataInterface[] = [],
): ObjectMetadataInterface => ({
id: 'object-id-1',
workspaceId: 'workspace-id-1',
nameSingular: 'person',
namePlural: 'people',
labelSingular: 'Person',
labelPlural: 'People',
description: 'A person object',
icon: 'IconUser',
targetTableName: 'person',
fields,
indexMetadatas,
isSystem: false,
isCustom: false,
isActive: true,
isRemote: false,
isAuditLogged: true,
isSearchable: true,
});
it('should return the primary key constraint field if no unique indexes are present', () => {
const objectMetadata = createMockObjectMetadata([
mockIdField,
mockNameField,
]);
const result = getUniqueConstraintsFields(objectMetadata);
expect(result).toHaveLength(1);
expect(result[0]).toHaveLength(1);
expect(result[0][0]).toEqual(mockIdField);
});
it('should return the primary key constraint field and the unique indexes fields if unique indexes are present', () => {
const emailIndexFieldMetadata = createMockIndexFieldMetadata(
'field-id-2',
'index-id-1',
);
const emailIndex = createMockIndexMetadata(
'index-id-1',
'unique_email_index',
true,
[emailIndexFieldMetadata],
);
const objectMetadata = createMockObjectMetadata(
[mockIdField, mockEmailField, mockNameField],
[emailIndex],
);
const result = getUniqueConstraintsFields(objectMetadata);
expect(result).toHaveLength(2);
expect(result[0]).toHaveLength(1);
expect(result[0][0]).toEqual(mockIdField);
expect(result[1]).toHaveLength(1);
expect(result[1][0]).toEqual(mockEmailField);
});
});

View File

@ -0,0 +1,42 @@
import { isDefined } from 'twenty-shared/utils';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
export const getUniqueConstraintsFields = (
objectMetadata: ObjectMetadataInterface,
): FieldMetadataInterface[][] => {
const uniqueIndexes = objectMetadata.indexMetadatas.filter(
(index) => index.isUnique,
);
const fieldsMapById = new Map(
objectMetadata.fields.map((field) => [field.id, field]),
);
const primaryKeyConstraintField = objectMetadata.fields.find(
(field) => field.name === 'id',
);
if (!isDefined(primaryKeyConstraintField)) {
throw new Error(
`Primary key constraint field not found for object metadata ${objectMetadata.id}`,
);
}
const otherUniqueConstraintsFields = uniqueIndexes.map((index) =>
index.indexFieldMetadatas.map((field) => {
const indexField = fieldsMapById.get(field.fieldMetadataId);
if (!isDefined(indexField)) {
throw new Error(
`Index field not found for field id ${field.fieldMetadataId} in index metadata ${index.id}`,
);
}
return indexField;
}),
);
return [[primaryKeyConstraintField], ...otherUniqueConstraintsFields];
};