feat: populate relation join column (#10212)
Fix https://github.com/twentyhq/core-team-issues/issues/241#issue-2793030259
This commit is contained in:
@ -64,9 +64,7 @@ registerEnumType(FieldMetadataType, {
|
||||
@Relation('object', () => ObjectMetadataDTO, {
|
||||
nullable: true,
|
||||
})
|
||||
export class FieldMetadataDTO<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
> {
|
||||
export class FieldMetadataDTO<T extends FieldMetadataType = FieldMetadataType> {
|
||||
@IsUUID()
|
||||
@IsNotEmpty()
|
||||
@IDField(() => UUIDScalarType)
|
||||
@ -75,7 +73,7 @@ export class FieldMetadataDTO<
|
||||
@IsEnum(FieldMetadataType)
|
||||
@IsNotEmpty()
|
||||
@Field(() => FieldMetadataType)
|
||||
type: FieldMetadataType;
|
||||
type: T;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
|
||||
@ -44,7 +44,7 @@ class TextSettingsValidation {
|
||||
|
||||
@Injectable()
|
||||
export class FieldMetadataValidationService<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> {
|
||||
constructor() {}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-met
|
||||
'relationTargetObjectMetadataId',
|
||||
])
|
||||
export class FieldMetadataEntity<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> implements FieldMetadataInterface<T>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
@ -59,7 +59,7 @@ export class FieldMetadataEntity<
|
||||
nullable: false,
|
||||
type: 'varchar',
|
||||
})
|
||||
type: FieldMetadataType;
|
||||
type: T;
|
||||
|
||||
@Column({ nullable: false })
|
||||
name: string;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
import { FieldMetadataType, IsExactly } from 'twenty-shared';
|
||||
|
||||
import {
|
||||
FieldMetadataDefaultActor,
|
||||
@ -60,17 +60,14 @@ export type FieldMetadataFunctionDefaultValue = ExtractValueType<
|
||||
FieldMetadataDefaultValueUuidFunction | FieldMetadataDefaultValueNowFunction
|
||||
>;
|
||||
|
||||
type DefaultValueByFieldMetadata<T extends FieldMetadataType | 'default'> = [
|
||||
T,
|
||||
] extends [keyof FieldMetadataDefaultValueMapping]
|
||||
? ExtractValueType<FieldMetadataDefaultValueMapping[T]> | null
|
||||
: T extends 'default'
|
||||
? ExtractValueType<UnionOfValues<FieldMetadataDefaultValueMapping>> | null
|
||||
: never;
|
||||
|
||||
export type FieldMetadataDefaultValue<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
> = DefaultValueByFieldMetadata<T>;
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> =
|
||||
IsExactly<T, FieldMetadataType> extends true
|
||||
? ExtractValueType<UnionOfValues<FieldMetadataDefaultValueMapping>> | null
|
||||
: T extends keyof FieldMetadataDefaultValueMapping
|
||||
? ExtractValueType<FieldMetadataDefaultValueMapping[T]> | null
|
||||
: never;
|
||||
|
||||
type FieldMetadataDefaultValueExtractedTypes = {
|
||||
[K in keyof FieldMetadataDefaultValueMapping]: ExtractValueType<
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
import { FieldMetadataType, IsExactly } from 'twenty-shared';
|
||||
|
||||
import {
|
||||
FieldMetadataComplexOption,
|
||||
@ -11,13 +11,11 @@ type FieldMetadataOptionsMapping = {
|
||||
[FieldMetadataType.MULTI_SELECT]: FieldMetadataComplexOption[];
|
||||
};
|
||||
|
||||
type OptionsByFieldMetadata<T extends FieldMetadataType | 'default'> =
|
||||
T extends keyof FieldMetadataOptionsMapping
|
||||
? FieldMetadataOptionsMapping[T]
|
||||
: T extends 'default'
|
||||
? FieldMetadataDefaultOption[] | FieldMetadataComplexOption[]
|
||||
: never;
|
||||
|
||||
export type FieldMetadataOptions<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
> = OptionsByFieldMetadata<T>;
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> =
|
||||
IsExactly<T, FieldMetadataType> extends true
|
||||
? FieldMetadataDefaultOption[] | FieldMetadataComplexOption[]
|
||||
: T extends keyof FieldMetadataOptionsMapping
|
||||
? FieldMetadataOptionsMapping[T]
|
||||
: never;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
import { FieldMetadataType, IsExactly } from 'twenty-shared';
|
||||
|
||||
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-on-delete-action.interface';
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
@ -36,6 +36,7 @@ export type FieldMetadataDateTimeSettings = {
|
||||
export type FieldMetadataRelationSettings = {
|
||||
relationType: RelationType;
|
||||
onDelete?: RelationOnDeleteAction;
|
||||
joinColumnName?: string;
|
||||
};
|
||||
|
||||
type FieldMetadataSettingsMapping = {
|
||||
@ -46,13 +47,11 @@ type FieldMetadataSettingsMapping = {
|
||||
[FieldMetadataType.RELATION]: FieldMetadataRelationSettings;
|
||||
};
|
||||
|
||||
type SettingsByFieldMetadata<T extends FieldMetadataType | 'default'> =
|
||||
T extends keyof FieldMetadataSettingsMapping
|
||||
? FieldMetadataSettingsMapping[T] & FieldMetadataDefaultSettings
|
||||
: T extends 'default'
|
||||
? FieldMetadataDefaultSettings
|
||||
: never;
|
||||
|
||||
export type FieldMetadataSettings<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
> = SettingsByFieldMetadata<T>;
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> =
|
||||
IsExactly<T, FieldMetadataType> extends true
|
||||
? FieldMetadataDefaultSettings
|
||||
: T extends keyof FieldMetadataSettingsMapping
|
||||
? FieldMetadataSettingsMapping[T] & FieldMetadataDefaultSettings
|
||||
: never;
|
||||
|
||||
@ -9,10 +9,10 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
|
||||
export interface FieldMetadataInterface<
|
||||
T extends FieldMetadataType | 'default' = 'default',
|
||||
T extends FieldMetadataType = FieldMetadataType,
|
||||
> {
|
||||
id: string;
|
||||
type: FieldMetadataType;
|
||||
type: T;
|
||||
name: string;
|
||||
label: string;
|
||||
defaultValue?: FieldMetadataDefaultValue<T>;
|
||||
|
||||
@ -21,12 +21,12 @@ export function computeColumnName(
|
||||
fieldName: string,
|
||||
options?: ComputeColumnNameOptions,
|
||||
): string;
|
||||
export function computeColumnName<T extends FieldMetadataType | 'default'>(
|
||||
export function computeColumnName<T extends FieldMetadataType>(
|
||||
fieldMetadata: FieldMetadataInterface<T>,
|
||||
ioptions?: ComputeColumnNameOptions,
|
||||
): string;
|
||||
// TODO: If we need to implement custom name logic for columns, we can do it here
|
||||
export function computeColumnName<T extends FieldMetadataType | 'default'>(
|
||||
export function computeColumnName<T extends FieldMetadataType>(
|
||||
fieldMetadataOrFieldName: FieldMetadataInterface<T> | string,
|
||||
options?: ComputeColumnNameOptions,
|
||||
): string {
|
||||
@ -51,15 +51,11 @@ export function computeCompositeColumnName(
|
||||
fieldName: string,
|
||||
compositeProperty: CompositeProperty,
|
||||
): string;
|
||||
export function computeCompositeColumnName<
|
||||
T extends FieldMetadataType | 'default',
|
||||
>(
|
||||
export function computeCompositeColumnName<T extends FieldMetadataType>(
|
||||
fieldMetadata: FieldTypeAndNameMetadata | FieldMetadataInterface<T>,
|
||||
compositeProperty: CompositeProperty,
|
||||
): string;
|
||||
export function computeCompositeColumnName<
|
||||
T extends FieldMetadataType | 'default',
|
||||
>(
|
||||
export function computeCompositeColumnName<T extends FieldMetadataType>(
|
||||
fieldMetadataOrFieldName:
|
||||
| FieldTypeAndNameMetadata
|
||||
| FieldMetadataInterface<T>
|
||||
|
||||
@ -67,9 +67,7 @@ export class CreateObjectInput {
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => GraphQLJSON, { nullable: true })
|
||||
primaryKeyFieldMetadataSettings?: FieldMetadataSettings<
|
||||
FieldMetadataType | 'default'
|
||||
>;
|
||||
primaryKeyFieldMetadataSettings?: FieldMetadataSettings<FieldMetadataType>;
|
||||
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
|
||||
@ -73,7 +73,7 @@ export class ObjectMetadataRelationService {
|
||||
createdObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyType: FieldMetadataType,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
relationObjectMetadataStandardId: string,
|
||||
) {
|
||||
@ -109,7 +109,7 @@ export class ObjectMetadataRelationService {
|
||||
relatedObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyType: FieldMetadataType,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
) {
|
||||
return this.fieldMetadataRepository.save([
|
||||
@ -340,7 +340,7 @@ export class ObjectMetadataRelationService {
|
||||
relatedObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyType: FieldMetadataType,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
isUpdate = false,
|
||||
) {
|
||||
|
||||
@ -147,7 +147,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
toObjectMetadata,
|
||||
[
|
||||
foreignKeyFieldMetadata,
|
||||
deletedAtFieldMetadata as FieldMetadataEntity<'default'>,
|
||||
deletedAtFieldMetadata as FieldMetadataEntity<FieldMetadataType>,
|
||||
],
|
||||
false,
|
||||
false,
|
||||
@ -451,7 +451,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
relationMetadata.toObjectMetadata,
|
||||
[
|
||||
foreignKeyFieldMetadata,
|
||||
deletedAtFieldMetadata as FieldMetadataEntity<'default'>,
|
||||
deletedAtFieldMetadata as FieldMetadataEntity<FieldMetadataType>,
|
||||
],
|
||||
);
|
||||
|
||||
@ -570,7 +570,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
}
|
||||
|
||||
private throwIfDeletedAtFieldMetadataNotFound(
|
||||
deletedAtFieldMetadata?: FieldMetadataEntity<'default'> | null,
|
||||
deletedAtFieldMetadata?: FieldMetadataEntity<FieldMetadataType> | null,
|
||||
) {
|
||||
if (!isDefined(deletedAtFieldMetadata)) {
|
||||
throw new RelationMetadataException(
|
||||
|
||||
@ -36,7 +36,7 @@ export class RemoteTableRelationsService {
|
||||
workspaceId: string,
|
||||
remoteObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
objectPrimaryKeyColumnType?: string,
|
||||
) {
|
||||
@ -150,7 +150,7 @@ export class RemoteTableRelationsService {
|
||||
createdObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyType: FieldMetadataType,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
) {
|
||||
const attachmentObjectMetadata =
|
||||
@ -190,7 +190,7 @@ export class RemoteTableRelationsService {
|
||||
createdObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyType: FieldMetadataType,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
) {
|
||||
const timelineActivityObjectMetadata =
|
||||
@ -230,7 +230,7 @@ export class RemoteTableRelationsService {
|
||||
createdObjectMetadata: ObjectMetadataEntity,
|
||||
objectPrimaryKeyType: FieldMetadataType,
|
||||
objectPrimaryKeyFieldSettings:
|
||||
| FieldMetadataSettings<FieldMetadataType | 'default'>
|
||||
| FieldMetadataSettings<FieldMetadataType>
|
||||
| undefined,
|
||||
) {
|
||||
const favoriteObjectMetadata =
|
||||
|
||||
@ -37,12 +37,12 @@ export const mapUdtNameToFieldSettings = (
|
||||
case 'int4':
|
||||
return {
|
||||
dataType: NumberDataType.INT,
|
||||
} satisfies FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
||||
} as FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
||||
case 'int8':
|
||||
case 'bigint':
|
||||
return {
|
||||
dataType: NumberDataType.BIGINT,
|
||||
} satisfies FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
||||
} as FieldMetadataSettings<FieldMetadataType.NUMBER>;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -18,9 +18,8 @@ import {
|
||||
WorkspaceMigrationExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.exception';
|
||||
|
||||
export class ColumnActionAbstractFactory<
|
||||
T extends FieldMetadataType | 'default',
|
||||
> implements WorkspaceColumnActionFactory<T>
|
||||
export class ColumnActionAbstractFactory<T extends FieldMetadataType>
|
||||
implements WorkspaceColumnActionFactory<T>
|
||||
{
|
||||
protected readonly logger = new Logger(ColumnActionAbstractFactory.name);
|
||||
|
||||
|
||||
@ -8,9 +8,7 @@ import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
|
||||
export interface WorkspaceColumnActionFactory<
|
||||
T extends FieldMetadataType | 'default',
|
||||
> {
|
||||
export interface WorkspaceColumnActionFactory<T extends FieldMetadataType> {
|
||||
create(
|
||||
action:
|
||||
| WorkspaceMigrationColumnActionType.CREATE
|
||||
|
||||
Reference in New Issue
Block a user