Common - Update one/many, restore one/many, findDuplicates & mergeMany (#15279)

closes https://github.com/twentyhq/core-team-issues/issues/1739
This commit is contained in:
Etienne
2025-10-24 14:41:17 +02:00
committed by GitHub
parent 8f60f7e277
commit 10f4f1592f
60 changed files with 2346 additions and 74 deletions
@@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import isEmpty from 'lodash.isempty';
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
import { OrderByDirection, type ObjectRecord } from 'twenty-shared/types';
import { In } from 'typeorm';
@@ -114,6 +115,7 @@ export class GraphqlQueryFindDuplicatesResolverService extends GraphqlQueryBaseR
.setFindOptions({
select: columnsToSelect,
})
.take(QUERY_MAX_RECORDS)
.getMany()) as ObjectRecord[];
return typeORMObjectRecordsParser.createConnection({
@@ -302,7 +302,7 @@ export class QueryRunnerArgsFactory {
}
}
private async overrideValueByFieldMetadata(
async overrideValueByFieldMetadata(
key: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any,
@@ -12,7 +12,6 @@ import {
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonCreateManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-create-many-query-runner/common-create-many-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryCreateManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -52,7 +51,6 @@ export class CreateManyResolverFactory
const records = await this.commonCreateManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.CREATE_MANY,
);
const typeORMObjectRecordsParser =
@@ -70,7 +68,7 @@ export class CreateManyResolverFactory
}),
);
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -11,7 +11,6 @@ import {
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonCreateOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-create-one-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryCreateOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-create-one-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -49,7 +48,6 @@ export class CreateOneResolverFactory
const record = await this.commonCreateOneQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.CREATE_ONE,
);
const typeORMObjectRecordsParser =
@@ -65,7 +63,7 @@ export class CreateOneResolverFactory
totalCount: 1,
});
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -12,7 +12,6 @@ import {
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonDeleteManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-delete-many-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryDeleteManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -52,7 +51,6 @@ export class DeleteManyResolverFactory
const records = await this.commonDeleteManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.DELETE_MANY,
);
const typeORMObjectRecordsParser =
@@ -70,7 +68,7 @@ export class DeleteManyResolverFactory
}),
);
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -11,7 +11,6 @@ import {
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonDeleteOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-delete-one-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryDeleteOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-one-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -51,7 +50,6 @@ export class DeleteOneResolverFactory
const record = await this.commonDeleteOneQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.DELETE_ONE,
);
const typeORMObjectRecordsParser =
@@ -67,7 +65,7 @@ export class DeleteOneResolverFactory
totalCount: 1,
});
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -12,7 +12,6 @@ import {
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonDestroyManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-destroy-many-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryDestroyManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -53,7 +52,6 @@ export class DestroyManyResolverFactory
await this.commonDestroyManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.DESTROY_MANY,
);
const typeORMObjectRecordsParser =
@@ -71,7 +69,7 @@ export class DestroyManyResolverFactory
}),
);
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -11,7 +11,6 @@ import {
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonDestroyOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-destroy-one-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryDestroyOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-one-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -51,7 +50,6 @@ export class DestroyOneResolverFactory
const record = await this.commonDestroyOneQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.DESTROY_ONE,
);
const typeORMObjectRecordsParser =
@@ -67,7 +65,7 @@ export class DestroyOneResolverFactory
totalCount: 1,
});
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -1,5 +1,8 @@
import { Injectable } from '@nestjs/common';
import graphqlFields from 'graphql-fields';
import { OrderByDirection } from 'twenty-shared/types';
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { type WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import {
@@ -8,8 +11,13 @@ import {
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonFindDuplicatesQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-find-duplicates-query-runner.service';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryFindDuplicatesResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Injectable()
export class FindDuplicatesResolverFactory
@@ -19,6 +27,8 @@ export class FindDuplicatesResolverFactory
constructor(
private readonly graphqlQueryRunnerService: GraphqlQueryFindDuplicatesResolverService,
private readonly commonFindDuplicatesQueryRunnerService: CommonFindDuplicatesQueryRunnerService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {}
create(
@@ -27,6 +37,45 @@ export class FindDuplicatesResolverFactory
const internalContext = context;
return async (_source, args, _context, info) => {
const workspaceDataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
workspaceId: internalContext.authContext.workspace?.id as string,
});
const featureFlagsMap = workspaceDataSource.featureFlagMap;
if (featureFlagsMap[FeatureFlagKey.IS_COMMON_API_ENABLED]) {
const selectedFields = graphqlFields(info);
try {
const paginatedDuplicates =
await this.commonFindDuplicatesQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
);
const typeORMObjectRecordsParser =
new ObjectRecordsToGraphqlConnectionHelper(
internalContext.objectMetadataMaps,
);
return paginatedDuplicates.map((duplicate) =>
typeORMObjectRecordsParser.createConnection({
objectRecords: duplicate.records,
objectName:
internalContext.objectMetadataItemWithFieldMaps.nameSingular,
take: duplicate.records.length,
totalCount: duplicate.totalCount,
order: [{ id: OrderByDirection.AscNullsFirst }],
hasNextPage: duplicate.hasNextPage,
hasPreviousPage: duplicate.hasPreviousPage,
}),
);
} catch (error) {
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
const options: WorkspaceQueryRunnerOptions = {
authContext: internalContext.authContext,
info,
@@ -11,7 +11,6 @@ import {
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonFindManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-find-many-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryFindManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -55,7 +54,6 @@ export class FindManyResolverFactory
} = await this.commonFindManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.FIND_MANY,
);
const typeORMObjectRecordsParser =
@@ -76,7 +74,7 @@ export class FindManyResolverFactory
hasPreviousPage: pageInfo.hasPreviousPage,
});
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -10,7 +10,6 @@ import {
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonFindOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-find-one-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryFindOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
@@ -48,7 +47,6 @@ export class FindOneResolverFactory
const record = await this.commonFindOneQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.FIND_ONE,
);
const typeORMObjectRecordsParser =
@@ -64,7 +62,7 @@ export class FindOneResolverFactory
totalCount: 1,
});
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -11,7 +11,6 @@ import {
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonGroupByQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-group-by-query-runner.service';
import { CommonQueryNames } from 'src/engine/api/common/types/common-query-args.type';
import { GraphqlQueryGroupByResolverService } from 'src/engine/api/graphql/graphql-query-runner/group-by/resolvers/graphql-query-group-by-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
@@ -48,10 +47,9 @@ export class GroupByResolverFactory
return await this.commonGroupByQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
CommonQueryNames.GROUP_BY,
);
} catch (error) {
return workspaceQueryRunnerGraphqlApiExceptionHandler(error);
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
@@ -1,15 +1,22 @@
import { Injectable } from '@nestjs/common';
import graphqlFields from 'graphql-fields';
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { type WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import {
type MergeManyResolverArgs,
type Resolver,
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonMergeManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-merge-many-query-runner.service';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryMergeManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-merge-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
@Injectable()
export class MergeManyResolverFactory
@@ -19,6 +26,8 @@ export class MergeManyResolverFactory
constructor(
private readonly graphqlQueryRunnerService: GraphqlQueryMergeManyResolverService,
private readonly commonMergeManyQueryRunnerService: CommonMergeManyQueryRunnerService,
private readonly featureFlagService: FeatureFlagService,
) {}
create(
@@ -27,6 +36,37 @@ export class MergeManyResolverFactory
const internalContext = context;
return async (_source, args, _context, info) => {
const isCommonApiEnabled = await this.featureFlagService.isFeatureEnabled(
FeatureFlagKey.IS_COMMON_API_ENABLED,
internalContext.authContext.workspace?.id as string,
);
if (isCommonApiEnabled) {
const selectedFields = graphqlFields(info);
try {
const record = await this.commonMergeManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
);
const typeORMObjectRecordsParser =
new ObjectRecordsToGraphqlConnectionHelper(
internalContext.objectMetadataMaps,
);
return typeORMObjectRecordsParser.processRecord({
objectRecord: record,
objectName:
internalContext.objectMetadataItemWithFieldMaps.nameSingular,
take: 1,
totalCount: 1,
});
} catch (error) {
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
const options: WorkspaceQueryRunnerOptions = {
authContext: internalContext.authContext,
info,
@@ -1,5 +1,8 @@
import { Injectable } from '@nestjs/common';
import graphqlFields from 'graphql-fields';
import { ObjectRecord } from 'twenty-shared/types';
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { type WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import {
@@ -8,8 +11,13 @@ import {
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonRestoreManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-restore-many-query-runner.service';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryRestoreManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Injectable()
export class RestoreManyResolverFactory
@@ -19,6 +27,8 @@ export class RestoreManyResolverFactory
constructor(
private readonly graphqlQueryRunnerService: GraphqlQueryRestoreManyResolverService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly commonRestoreManyQueryRunnerService: CommonRestoreManyQueryRunnerService,
) {}
create(
@@ -27,6 +37,41 @@ export class RestoreManyResolverFactory
const internalContext = context;
return async (_source, args, _context, info) => {
const workspaceDataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
workspaceId: internalContext.authContext.workspace?.id as string,
});
const featureFlagsMap = workspaceDataSource.featureFlagMap;
if (featureFlagsMap[FeatureFlagKey.IS_COMMON_API_ENABLED]) {
const selectedFields = graphqlFields(info);
try {
const records =
await this.commonRestoreManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
);
const typeORMObjectRecordsParser =
new ObjectRecordsToGraphqlConnectionHelper(
internalContext.objectMetadataMaps,
);
return records.map((record: ObjectRecord) =>
typeORMObjectRecordsParser.processRecord({
objectRecord: record,
objectName:
internalContext.objectMetadataItemWithFieldMaps.nameSingular,
take: 1,
totalCount: 1,
}),
);
} catch (error) {
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
const options: WorkspaceQueryRunnerOptions = {
authContext: internalContext.authContext,
info,
@@ -1,5 +1,7 @@
import { Injectable } from '@nestjs/common';
import graphqlFields from 'graphql-fields';
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { type WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import {
@@ -8,8 +10,13 @@ import {
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonRestoreOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-restore-one-query-runner.service';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryRestoreOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Injectable()
export class RestoreOneResolverFactory
@@ -19,6 +26,8 @@ export class RestoreOneResolverFactory
constructor(
private readonly graphqlQueryRunnerService: GraphqlQueryRestoreOneResolverService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly commonRestoreOneQueryRunnerService: CommonRestoreOneQueryRunnerService,
) {}
create(
@@ -27,6 +36,39 @@ export class RestoreOneResolverFactory
const internalContext = context;
return async (_source, args, _context, info) => {
const workspaceDataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
workspaceId: internalContext.authContext.workspace?.id as string,
});
const featureFlagsMap = workspaceDataSource.featureFlagMap;
if (featureFlagsMap[FeatureFlagKey.IS_COMMON_API_ENABLED]) {
const selectedFields = graphqlFields(info);
try {
const record = await this.commonRestoreOneQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
);
const typeORMObjectRecordsParser =
new ObjectRecordsToGraphqlConnectionHelper(
internalContext.objectMetadataMaps,
);
return typeORMObjectRecordsParser.processRecord({
objectRecord: record,
objectName:
internalContext.objectMetadataItemWithFieldMaps.nameSingular,
take: 1,
totalCount: 1,
});
} catch (error) {
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
const options: WorkspaceQueryRunnerOptions = {
authContext: internalContext.authContext,
info,
@@ -1,5 +1,8 @@
import { Injectable } from '@nestjs/common';
import graphqlFields from 'graphql-fields';
import { ObjectRecord } from 'twenty-shared/types';
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { type WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import {
@@ -8,15 +11,24 @@ import {
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonUpdateManyQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-update-many-query-runner.service';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryUpdateManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Injectable()
export class UpdateManyResolverFactory
implements WorkspaceResolverBuilderFactoryInterface
{
public static methodName = RESOLVER_METHOD_NAMES.UPDATE_MANY;
constructor(
private readonly graphqlQueryRunnerService: GraphqlQueryUpdateManyResolverService,
private readonly commonUpdateManyQueryRunnerService: CommonUpdateManyQueryRunnerService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {}
create(
@@ -25,6 +37,41 @@ export class UpdateManyResolverFactory
const internalContext = context;
return async (_source, args, _context, info) => {
const workspaceDataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
workspaceId: internalContext.authContext.workspace?.id as string,
});
const featureFlagsMap = workspaceDataSource.featureFlagMap;
if (featureFlagsMap[FeatureFlagKey.IS_COMMON_API_ENABLED]) {
const selectedFields = graphqlFields(info);
try {
const records = await this.commonUpdateManyQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
);
const typeORMObjectRecordsParser =
new ObjectRecordsToGraphqlConnectionHelper(
internalContext.objectMetadataMaps,
);
return records.map((record: ObjectRecord) =>
typeORMObjectRecordsParser.processRecord({
objectRecord: record,
objectName:
internalContext.objectMetadataItemWithFieldMaps.nameSingular,
take: 1,
totalCount: 1,
}),
);
} catch (error) {
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
const options: WorkspaceQueryRunnerOptions = {
authContext: internalContext.authContext,
info,
@@ -1,5 +1,7 @@
import { Injectable } from '@nestjs/common';
import graphqlFields from 'graphql-fields';
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
import { type WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
import {
@@ -8,8 +10,13 @@ import {
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { type WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
import { CommonUpdateOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-update-one-query-runner.service';
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
import { GraphqlQueryUpdateOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service';
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
@Injectable()
export class UpdateOneResolverFactory
@@ -19,6 +26,8 @@ export class UpdateOneResolverFactory
constructor(
private readonly graphqlQueryRunnerService: GraphqlQueryUpdateOneResolverService,
private readonly commonUpdateOneQueryRunnerService: CommonUpdateOneQueryRunnerService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
) {}
create(
@@ -27,6 +36,39 @@ export class UpdateOneResolverFactory
const internalContext = context;
return async (_source, args, _context, info) => {
const workspaceDataSource =
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
workspaceId: internalContext.authContext.workspace?.id as string,
});
const featureFlagsMap = workspaceDataSource.featureFlagMap;
if (featureFlagsMap[FeatureFlagKey.IS_COMMON_API_ENABLED]) {
const selectedFields = graphqlFields(info);
try {
const record = await this.commonUpdateOneQueryRunnerService.execute(
{ ...args, selectedFields },
internalContext,
);
const typeORMObjectRecordsParser =
new ObjectRecordsToGraphqlConnectionHelper(
internalContext.objectMetadataMaps,
);
return typeORMObjectRecordsParser.processRecord({
objectRecord: record,
objectName:
internalContext.objectMetadataItemWithFieldMaps.nameSingular,
take: 1,
totalCount: 1,
});
} catch (error) {
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
}
}
const options: WorkspaceQueryRunnerOptions = {
authContext: internalContext.authContext,
info,