[BREAKING_CHANGE] Deprecate remaining entities standardId (#17639)
# Introduction Following https://github.com/twentyhq/twenty/pull/17632 and https://github.com/twentyhq/twenty/pull/17572 This PR deprecates the agent, skill, field metadata and role `standardId` in favor of the `universalIdentifier` usage ## Note - Removed previous standard ids declaration modules - Twenty-sdk now re-exports the `STANDARD_OBJECTS` universalIdentifier hashmap constant - deleted some sync-metadata deadcode too ( mainly types )
This commit is contained in:
-1
@@ -155,7 +155,6 @@ describe('WorkspaceEntityManager', () => {
|
||||
isUnique: false,
|
||||
options: null,
|
||||
settings: null,
|
||||
standardId: null,
|
||||
standardOverrides: null,
|
||||
workspaceId: 'test-workspace-id',
|
||||
viewFieldIds: [],
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { type FactoryProvider, type ModuleMetadata } from '@nestjs/common';
|
||||
|
||||
export interface TwentyORMOptions {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export type TwentyORMModuleAsyncOptions = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
useFactory: (...args: any[]) => TwentyORMOptions | Promise<TwentyORMOptions>;
|
||||
} & Pick<ModuleMetadata, 'imports'> &
|
||||
Pick<FactoryProvider, 'inject'>;
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
import { type ObjectType } from 'typeorm';
|
||||
import { type RelationOnDeleteAction } from 'twenty-shared/types';
|
||||
|
||||
import { type RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
import { type Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
export type WorkspaceDynamicRelationMetadataArgsFactory = (
|
||||
oppositeObjectMetadata: ObjectMetadataEntity,
|
||||
) => {
|
||||
/**
|
||||
* Standard id.
|
||||
*/
|
||||
readonly standardId: string;
|
||||
|
||||
/**
|
||||
* Relation name.
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* Relation label.
|
||||
*/
|
||||
readonly label: string;
|
||||
|
||||
/**
|
||||
* Relation description.
|
||||
*/
|
||||
readonly description?: string;
|
||||
|
||||
/**
|
||||
* Relation icon.
|
||||
*/
|
||||
readonly icon?: string;
|
||||
|
||||
/**
|
||||
* Relation join column.
|
||||
*/
|
||||
readonly joinColumn?: string;
|
||||
};
|
||||
|
||||
export interface WorkspaceDynamicRelationMetadataArgs {
|
||||
/**
|
||||
* Class to which relation is applied.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Factory function
|
||||
*/
|
||||
readonly argsFactory: WorkspaceDynamicRelationMetadataArgsFactory;
|
||||
|
||||
/**
|
||||
* Relation type.
|
||||
*/
|
||||
readonly type: RelationType;
|
||||
|
||||
/**
|
||||
* Relation inverse side target.
|
||||
*/
|
||||
readonly inverseSideTarget: () => ObjectType<object>;
|
||||
|
||||
/**
|
||||
* Relation inverse side field key.
|
||||
*/
|
||||
readonly inverseSideFieldKey?: string;
|
||||
|
||||
/**
|
||||
* Relation on delete action.
|
||||
*/
|
||||
readonly onDelete?: RelationOnDeleteAction;
|
||||
|
||||
/**
|
||||
* Is primary field.
|
||||
*/
|
||||
readonly isPrimary: boolean;
|
||||
|
||||
/**
|
||||
* Is system field.
|
||||
*/
|
||||
readonly isSystem: boolean;
|
||||
|
||||
/**
|
||||
* Is nullable field.
|
||||
*/
|
||||
readonly isNullable: boolean;
|
||||
|
||||
/**
|
||||
* Field gate.
|
||||
*/
|
||||
readonly gate?: Gate;
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
import { type Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
|
||||
|
||||
import { type WorkspaceEntityDuplicateCriteria } from 'src/engine/api/graphql/workspace-query-builder/types/workspace-entity-duplicate-criteria.type';
|
||||
|
||||
export interface WorkspaceEntityMetadataArgs {
|
||||
/**
|
||||
* Standard id.
|
||||
*/
|
||||
readonly standardId: string;
|
||||
|
||||
/**
|
||||
* Class to which table is applied.
|
||||
* Function target is a table defined in the class.
|
||||
* String target is a table defined in a json schema.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Entity name.
|
||||
*/
|
||||
readonly nameSingular: string;
|
||||
readonly namePlural: string;
|
||||
|
||||
/**
|
||||
* Entity label.
|
||||
*/
|
||||
readonly labelSingular: string;
|
||||
readonly labelPlural: string;
|
||||
|
||||
/**
|
||||
* Entity description.
|
||||
*/
|
||||
readonly description?: string;
|
||||
|
||||
/**
|
||||
* Entity icon.
|
||||
*/
|
||||
readonly icon?: string;
|
||||
|
||||
/**
|
||||
* Entity shortcut.
|
||||
*/
|
||||
readonly shortcut?: string;
|
||||
|
||||
/**
|
||||
* Is audit logged.
|
||||
*/
|
||||
readonly isAuditLogged: boolean;
|
||||
|
||||
/**
|
||||
* Is system object.
|
||||
*/
|
||||
readonly isSystem: boolean;
|
||||
|
||||
/**
|
||||
* Is UI read-only object.
|
||||
*/
|
||||
readonly isUIReadOnly: boolean;
|
||||
|
||||
/**
|
||||
* Entity gate.
|
||||
*/
|
||||
readonly gate?: Gate;
|
||||
|
||||
/**
|
||||
* Label identifier.
|
||||
*/
|
||||
readonly labelIdentifierStandardId: string | null;
|
||||
|
||||
/**
|
||||
* Image identifier.
|
||||
*/
|
||||
readonly imageIdentifierStandardId: string | null;
|
||||
|
||||
/**
|
||||
* Duplicate criteria.
|
||||
*/
|
||||
readonly duplicateCriteria?: WorkspaceEntityDuplicateCriteria[];
|
||||
|
||||
/**
|
||||
* Is searchable object.
|
||||
*/
|
||||
readonly isSearchable: boolean;
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
import { type Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
|
||||
|
||||
export interface WorkspaceExtendedEntityMetadataArgs {
|
||||
/**
|
||||
* Class to which table is applied.
|
||||
* Function target is a table defined in the class.
|
||||
* String target is a table defined in a json schema.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Entity gate.
|
||||
*/
|
||||
readonly gate?: Gate;
|
||||
}
|
||||
-117
@@ -1,117 +0,0 @@
|
||||
import {
|
||||
type FieldMetadataOptions,
|
||||
type FieldMetadataSettings,
|
||||
type FieldMetadataType,
|
||||
type FieldMetadataDefaultValue,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { type Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
export interface WorkspaceFieldMetadataArgs {
|
||||
/**
|
||||
* Standard id.
|
||||
*/
|
||||
readonly standardId: string;
|
||||
|
||||
/**
|
||||
* Class to which field is applied.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Field name.
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* Field label.
|
||||
*/
|
||||
readonly label: string | ((objectMetadata: ObjectMetadataEntity) => string);
|
||||
|
||||
/**
|
||||
* Field type.
|
||||
*/
|
||||
readonly type: FieldMetadataType;
|
||||
|
||||
/**
|
||||
* Field description.
|
||||
*/
|
||||
readonly description?:
|
||||
| string
|
||||
| ((objectMetadata: ObjectMetadataEntity) => string);
|
||||
|
||||
/**
|
||||
* Field icon.
|
||||
*/
|
||||
readonly icon?: string;
|
||||
|
||||
/**
|
||||
* Field default value.
|
||||
*/
|
||||
readonly defaultValue?: FieldMetadataDefaultValue;
|
||||
|
||||
/**
|
||||
* Field options.
|
||||
*/
|
||||
readonly options?: FieldMetadataOptions;
|
||||
|
||||
/**
|
||||
* Field settings.
|
||||
*/
|
||||
readonly settings?: FieldMetadataSettings;
|
||||
|
||||
/**
|
||||
* Is primary field.
|
||||
*/
|
||||
readonly isPrimary: boolean;
|
||||
|
||||
/**
|
||||
* Is system field.
|
||||
*/
|
||||
readonly isSystem: boolean;
|
||||
|
||||
/**
|
||||
* Is UI read-only field.
|
||||
*/
|
||||
readonly isUIReadOnly: boolean;
|
||||
|
||||
/**
|
||||
* Is nullable field.
|
||||
*/
|
||||
readonly isNullable: boolean;
|
||||
|
||||
/**
|
||||
* Is unique field.
|
||||
*/
|
||||
readonly isUnique: boolean;
|
||||
|
||||
/**
|
||||
* Field gate.
|
||||
*/
|
||||
readonly gate?: Gate;
|
||||
|
||||
/**
|
||||
* Is deprecated field.
|
||||
*/
|
||||
readonly isDeprecated?: boolean;
|
||||
|
||||
/**
|
||||
* Is active field.
|
||||
*/
|
||||
readonly isActive?: boolean;
|
||||
|
||||
/**
|
||||
* Is active field.
|
||||
*/
|
||||
readonly generatedType?: 'STORED' | 'VIRTUAL';
|
||||
|
||||
/**
|
||||
* Is active field.
|
||||
*/
|
||||
readonly asExpression?: string;
|
||||
|
||||
readonly isLabelSyncedWithName: boolean;
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
import { type Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
|
||||
|
||||
import { type IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
|
||||
export interface WorkspaceIndexMetadataArgs {
|
||||
/**
|
||||
* Class to which index is applied.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/*
|
||||
* Index name.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/*
|
||||
* Index columns.
|
||||
*/
|
||||
columns: string[];
|
||||
|
||||
/**
|
||||
* Is index unique.
|
||||
*/
|
||||
isUnique: boolean;
|
||||
|
||||
/*
|
||||
* Index type. Defaults to Btree.
|
||||
*/
|
||||
type?: IndexType;
|
||||
|
||||
/**
|
||||
* Index where clause.
|
||||
*/
|
||||
whereClause: string | null;
|
||||
|
||||
/**
|
||||
* Field gate.
|
||||
*/
|
||||
readonly gate?: Gate;
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
export interface WorkspaceJoinColumnsMetadataArgs {
|
||||
/**
|
||||
* Class to which relation is applied.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Relation name.
|
||||
*/
|
||||
readonly relationName: string;
|
||||
|
||||
/**
|
||||
* Relation label.
|
||||
*/
|
||||
readonly joinColumn: string;
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
import { type ObjectType } from 'typeorm';
|
||||
import { type RelationOnDeleteAction } from 'twenty-shared/types';
|
||||
|
||||
import { type RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
import { type Gate } from 'src/engine/twenty-orm/interfaces/gate.interface';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
export interface WorkspaceRelationMetadataArgs {
|
||||
/**
|
||||
* Standard id.
|
||||
*/
|
||||
readonly standardId: string;
|
||||
|
||||
/**
|
||||
* Class to which relation is applied.
|
||||
*/
|
||||
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Relation name.
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* Relation label.
|
||||
*/
|
||||
readonly label: string | ((objectMetadata: ObjectMetadataEntity) => string);
|
||||
|
||||
/**
|
||||
* Relation type.
|
||||
*/
|
||||
readonly type: RelationType;
|
||||
|
||||
/**
|
||||
* Relation description.
|
||||
*/
|
||||
readonly description?:
|
||||
| string
|
||||
| ((objectMetadata: ObjectMetadataEntity) => string);
|
||||
|
||||
/**
|
||||
* Relation icon.
|
||||
*/
|
||||
readonly icon?: string;
|
||||
|
||||
/**
|
||||
* Relation inverse side target.
|
||||
*/
|
||||
readonly inverseSideTarget: () => ObjectType<object>;
|
||||
|
||||
/**
|
||||
* Relation inverse side field key.
|
||||
*/
|
||||
readonly inverseSideFieldKey?: string;
|
||||
|
||||
/**
|
||||
* Relation on delete action.
|
||||
*/
|
||||
readonly onDelete?: RelationOnDeleteAction;
|
||||
|
||||
/**
|
||||
* Is primary field.
|
||||
*/
|
||||
readonly isPrimary: boolean;
|
||||
|
||||
/**
|
||||
* Is system field.
|
||||
*/
|
||||
readonly isSystem: boolean;
|
||||
|
||||
/**
|
||||
* Is UI read-only field.
|
||||
*/
|
||||
readonly isUIReadOnly: boolean;
|
||||
|
||||
/**
|
||||
* Is nullable field.
|
||||
*/
|
||||
readonly isNullable: boolean;
|
||||
|
||||
/**
|
||||
* Field gate.
|
||||
*/
|
||||
readonly gate?: Gate;
|
||||
|
||||
/**
|
||||
* Is active field.
|
||||
*/
|
||||
readonly isActive?: boolean;
|
||||
|
||||
readonly isLabelSyncedWithName: boolean;
|
||||
|
||||
/**
|
||||
* Is morph relation.
|
||||
*/
|
||||
readonly isMorphRelation: boolean;
|
||||
|
||||
/**
|
||||
* Morph id.
|
||||
*/
|
||||
readonly morphId?: string;
|
||||
}
|
||||
-1
@@ -87,7 +87,6 @@ describe('WorkspaceRepository', () => {
|
||||
options: null,
|
||||
settings: null,
|
||||
morphId: null,
|
||||
standardId: null,
|
||||
standardOverrides: null,
|
||||
applicationId: 'application-id',
|
||||
relationTargetFieldMetadataId: null,
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
import { type WorkspaceDynamicRelationMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-dynamic-relation-metadata-args.interface';
|
||||
import { type WorkspaceEntityMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-entity-metadata-args.interface';
|
||||
import { type WorkspaceExtendedEntityMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-extended-entity-metadata-args.interface';
|
||||
import { type WorkspaceFieldMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-field-metadata-args.interface';
|
||||
import { type WorkspaceIndexMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-index-metadata-args.interface';
|
||||
import { type WorkspaceJoinColumnsMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-join-columns-metadata-args.interface';
|
||||
import { type WorkspaceRelationMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-relation-metadata-args.interface';
|
||||
|
||||
export class MetadataArgsStorage {
|
||||
private readonly entities: WorkspaceEntityMetadataArgs[] = [];
|
||||
private readonly extendedEntities: WorkspaceExtendedEntityMetadataArgs[] = [];
|
||||
private readonly fields: WorkspaceFieldMetadataArgs[] = [];
|
||||
private readonly relations: WorkspaceRelationMetadataArgs[] = [];
|
||||
private readonly dynamicRelations: WorkspaceDynamicRelationMetadataArgs[] =
|
||||
[];
|
||||
private readonly indexes: WorkspaceIndexMetadataArgs[] = [];
|
||||
private readonly joinColumns: WorkspaceJoinColumnsMetadataArgs[] = [];
|
||||
|
||||
addEntities(...entities: WorkspaceEntityMetadataArgs[]): void {
|
||||
this.entities.push(...entities);
|
||||
}
|
||||
|
||||
addExtendedEntities(
|
||||
...extendedEntities: WorkspaceExtendedEntityMetadataArgs[]
|
||||
): void {
|
||||
this.extendedEntities.push(...extendedEntities);
|
||||
}
|
||||
|
||||
addFields(...fields: WorkspaceFieldMetadataArgs[]): void {
|
||||
this.fields.push(...fields);
|
||||
}
|
||||
|
||||
addRelations(...relations: WorkspaceRelationMetadataArgs[]): void {
|
||||
this.relations.push(...relations);
|
||||
}
|
||||
|
||||
addIndexes(...indexes: WorkspaceIndexMetadataArgs[]): void {
|
||||
this.indexes.push(...indexes);
|
||||
}
|
||||
|
||||
addDynamicRelations(
|
||||
...dynamicRelations: WorkspaceDynamicRelationMetadataArgs[]
|
||||
): void {
|
||||
this.dynamicRelations.push(...dynamicRelations);
|
||||
}
|
||||
|
||||
addJoinColumns(...joinColumns: WorkspaceJoinColumnsMetadataArgs[]): void {
|
||||
this.joinColumns.push(...joinColumns);
|
||||
}
|
||||
|
||||
filterEntities(
|
||||
target: Function | string,
|
||||
): WorkspaceEntityMetadataArgs | undefined;
|
||||
|
||||
filterEntities(target: (Function | string)[]): WorkspaceEntityMetadataArgs[];
|
||||
|
||||
filterEntities(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): WorkspaceEntityMetadataArgs | undefined | WorkspaceEntityMetadataArgs[] {
|
||||
const objects = this.filterByTarget(this.entities, target);
|
||||
|
||||
return Array.isArray(objects) ? objects[0] : objects;
|
||||
}
|
||||
|
||||
filterExtendedEntities(
|
||||
target: Function | string,
|
||||
): WorkspaceExtendedEntityMetadataArgs | undefined;
|
||||
|
||||
filterExtendedEntities(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
):
|
||||
| WorkspaceExtendedEntityMetadataArgs
|
||||
| undefined
|
||||
| WorkspaceExtendedEntityMetadataArgs[] {
|
||||
const objects = this.filterByTarget(this.extendedEntities, target);
|
||||
|
||||
return Array.isArray(objects) ? objects[0] : objects;
|
||||
}
|
||||
|
||||
filterFields(target: Function | string): WorkspaceFieldMetadataArgs[];
|
||||
|
||||
filterFields(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): WorkspaceFieldMetadataArgs[] {
|
||||
return this.filterByTarget(this.fields, target);
|
||||
}
|
||||
|
||||
filterRelations(target: Function | string): WorkspaceRelationMetadataArgs[];
|
||||
|
||||
filterRelations(
|
||||
target: (Function | string)[],
|
||||
): WorkspaceRelationMetadataArgs[];
|
||||
|
||||
filterRelations(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): WorkspaceRelationMetadataArgs[] {
|
||||
return this.filterByTarget(this.relations, target);
|
||||
}
|
||||
|
||||
filterIndexes(target: Function | string): WorkspaceIndexMetadataArgs[];
|
||||
|
||||
filterIndexes(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): WorkspaceIndexMetadataArgs[] {
|
||||
return this.filterByTarget(this.indexes, target);
|
||||
}
|
||||
|
||||
filterDynamicRelations(
|
||||
target: Function | string,
|
||||
): WorkspaceDynamicRelationMetadataArgs[];
|
||||
|
||||
filterDynamicRelations(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): WorkspaceDynamicRelationMetadataArgs[] {
|
||||
return this.filterByTarget(this.dynamicRelations, target);
|
||||
}
|
||||
|
||||
filterJoinColumns(
|
||||
target: Function | string,
|
||||
): WorkspaceJoinColumnsMetadataArgs[];
|
||||
|
||||
filterJoinColumns(
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): WorkspaceJoinColumnsMetadataArgs[] {
|
||||
return this.filterByTarget(this.joinColumns, target);
|
||||
}
|
||||
|
||||
protected filterByTarget<T extends { target: Function | string }>(
|
||||
array: T[],
|
||||
target: (Function | string) | (Function | string)[],
|
||||
): T[] {
|
||||
if (Array.isArray(target)) {
|
||||
return target.flatMap((targetItem) => {
|
||||
if (typeof targetItem === 'function') {
|
||||
return this.collectFromClass(array, targetItem);
|
||||
}
|
||||
|
||||
return this.collectFromString(array, targetItem);
|
||||
});
|
||||
} else {
|
||||
return typeof target === 'function'
|
||||
? this.collectFromClass(array, target)
|
||||
: this.collectFromString(array, target);
|
||||
}
|
||||
}
|
||||
|
||||
// Private helper to collect metadata from class prototypes
|
||||
private collectFromClass<T extends { target: Function | string }>(
|
||||
array: T[],
|
||||
cls: Function,
|
||||
): T[] {
|
||||
const collectedMetadata: T[] = [];
|
||||
let currentTarget = cls;
|
||||
|
||||
// Collect metadata from the current class and all its parent classes
|
||||
while (currentTarget !== Function.prototype) {
|
||||
collectedMetadata.push(
|
||||
...array.filter((item) => item.target === currentTarget),
|
||||
);
|
||||
currentTarget = Object.getPrototypeOf(currentTarget);
|
||||
}
|
||||
|
||||
return collectedMetadata;
|
||||
}
|
||||
|
||||
// Private helper to collect metadata directly by string comparison
|
||||
private collectFromString<T extends { target: Function | string }>(
|
||||
array: T[],
|
||||
targetString: string,
|
||||
): T[] {
|
||||
return array.filter((item) => item.target === targetString);
|
||||
}
|
||||
}
|
||||
|
||||
export const metadataArgsStorage = new MetadataArgsStorage();
|
||||
-1
@@ -233,7 +233,6 @@ describe('computeRelationConnectQueryConfigs', () => {
|
||||
description: null,
|
||||
standardOverrides: null,
|
||||
isUIReadOnly: false,
|
||||
standardId: null,
|
||||
labelIdentifierFieldMetadataId: null,
|
||||
imageIdentifierFieldMetadataId: null,
|
||||
duplicateCriteria: null,
|
||||
|
||||
+1
-1
@@ -12,6 +12,7 @@ import {
|
||||
isDefined,
|
||||
isNonEmptyArray,
|
||||
} from 'twenty-shared/utils';
|
||||
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
|
||||
|
||||
import type { ObjectLiteral } from 'typeorm';
|
||||
|
||||
@@ -26,7 +27,6 @@ import {
|
||||
TwentyORMExceptionCode,
|
||||
} from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
|
||||
import { type DatabaseBatchEventInput } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
|
||||
export const formatTwentyOrmEventToDatabaseBatchEvent = <
|
||||
T extends ObjectLiteral,
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
import { type WorkspaceJoinColumnsMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-join-columns-metadata-args.interface';
|
||||
import { type WorkspaceRelationMetadataArgs } from 'src/engine/twenty-orm/interfaces/workspace-relation-metadata-args.interface';
|
||||
|
||||
import {
|
||||
RelationException,
|
||||
RelationExceptionCode,
|
||||
} from 'src/engine/twenty-orm/exceptions/relation.exception';
|
||||
import { metadataArgsStorage } from 'src/engine/twenty-orm/storage/metadata-args.storage';
|
||||
|
||||
export const getJoinColumn = (
|
||||
joinColumnsMetadataArgsCollection: WorkspaceJoinColumnsMetadataArgs[],
|
||||
relationMetadataArgs: WorkspaceRelationMetadataArgs,
|
||||
): string | null => {
|
||||
if (relationMetadataArgs.type === RelationType.ONE_TO_MANY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const inverseSideTarget = relationMetadataArgs.inverseSideTarget();
|
||||
const inverseSideJoinColumnsMetadataArgsCollection =
|
||||
metadataArgsStorage.filterJoinColumns(inverseSideTarget);
|
||||
const filteredJoinColumnsMetadataArgsCollection =
|
||||
joinColumnsMetadataArgsCollection.filter(
|
||||
(joinColumnsMetadataArgs) =>
|
||||
joinColumnsMetadataArgs.relationName === relationMetadataArgs.name,
|
||||
);
|
||||
const oppositeFilteredJoinColumnsMetadataArgsCollection =
|
||||
inverseSideJoinColumnsMetadataArgsCollection.filter(
|
||||
(joinColumnsMetadataArgs) =>
|
||||
joinColumnsMetadataArgs.relationName === relationMetadataArgs.name,
|
||||
);
|
||||
|
||||
if (
|
||||
filteredJoinColumnsMetadataArgsCollection.length > 0 &&
|
||||
oppositeFilteredJoinColumnsMetadataArgsCollection.length > 0
|
||||
) {
|
||||
throw new RelationException(
|
||||
`Join column for ${relationMetadataArgs.name} relation is present on both sides`,
|
||||
RelationExceptionCode.RELATION_JOIN_COLUMN_ON_BOTH_SIDES,
|
||||
);
|
||||
}
|
||||
|
||||
// Check if there are multiple join columns for the relation
|
||||
if (filteredJoinColumnsMetadataArgsCollection.length > 1) {
|
||||
throw new RelationException(
|
||||
`Multiple join columns found for relation ${relationMetadataArgs.name}`,
|
||||
RelationExceptionCode.MULTIPLE_JOIN_COLUMNS_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const joinColumnsMetadataArgs = filteredJoinColumnsMetadataArgsCollection[0];
|
||||
|
||||
if (!joinColumnsMetadataArgs) {
|
||||
throw new RelationException(
|
||||
`Join column is missing for relation ${relationMetadataArgs.name}`,
|
||||
RelationExceptionCode.MISSING_RELATION_JOIN_COLUMN,
|
||||
);
|
||||
}
|
||||
|
||||
return joinColumnsMetadataArgs.joinColumn;
|
||||
};
|
||||
Reference in New Issue
Block a user