mirror of
https://github.com/lingble/twenty.git
synced 2025-10-29 11:52:28 +00:00
[Flexible-schema] Refactor gql query runner to emit api event before processing to gql types
This commit is contained in:
@@ -28,7 +28,6 @@ import {
|
||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { GraphqlQueryResolverFactory } from 'src/engine/api/graphql/graphql-query-runner/factories/graphql-query-resolver.factory';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
import { QueryResultGettersFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/query-result-getters.factory';
|
||||
import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory';
|
||||
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
|
||||
@@ -42,7 +41,6 @@ export class GraphqlQueryRunnerService {
|
||||
private readonly queryRunnerArgsFactory: QueryRunnerArgsFactory,
|
||||
private readonly queryResultGettersFactory: QueryResultGettersFactory,
|
||||
private readonly graphqlQueryResolverFactory: GraphqlQueryResolverFactory,
|
||||
private readonly apiEventEmitterService: ApiEventEmitterService,
|
||||
) {}
|
||||
|
||||
/** QUERIES */
|
||||
@@ -109,15 +107,6 @@ export class GraphqlQueryRunnerService {
|
||||
T[]
|
||||
>('createMany', { data: [args.data], upsert: args.upsert }, options);
|
||||
|
||||
// TODO: emitCreateEvents should be moved to the ORM layer
|
||||
if (results) {
|
||||
this.apiEventEmitterService.emitCreateEvents(
|
||||
results,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
}
|
||||
|
||||
return results[0];
|
||||
}
|
||||
|
||||
@@ -126,20 +115,11 @@ export class GraphqlQueryRunnerService {
|
||||
args: CreateManyResolverArgs<Partial<T>>,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T[]> {
|
||||
const results = await this.executeQuery<
|
||||
CreateManyResolverArgs<Partial<T>>,
|
||||
T[]
|
||||
>('createMany', args, options);
|
||||
|
||||
if (results) {
|
||||
this.apiEventEmitterService.emitCreateEvents(
|
||||
results,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
return this.executeQuery<CreateManyResolverArgs<Partial<T>>, T[]>(
|
||||
'createMany',
|
||||
args,
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -147,28 +127,11 @@ export class GraphqlQueryRunnerService {
|
||||
args: UpdateOneResolverArgs<Partial<T>>,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T> {
|
||||
const existingRecord = await this.executeQuery<FindOneResolverArgs, T>(
|
||||
'findOne',
|
||||
{
|
||||
filter: { id: { eq: args.id } },
|
||||
},
|
||||
return await this.executeQuery<UpdateOneResolverArgs<Partial<T>>, T>(
|
||||
'updateOne',
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
const result = await this.executeQuery<
|
||||
UpdateOneResolverArgs<Partial<T>>,
|
||||
T
|
||||
>('updateOne', args, options);
|
||||
|
||||
this.apiEventEmitterService.emitUpdateEvents(
|
||||
[existingRecord],
|
||||
[result],
|
||||
Object.keys(args.data),
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -176,31 +139,11 @@ export class GraphqlQueryRunnerService {
|
||||
args: UpdateManyResolverArgs<Partial<T>>,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T[]> {
|
||||
const existingRecords = await this.executeQuery<
|
||||
FindManyResolverArgs,
|
||||
IConnection<T, IEdge<T>>
|
||||
>(
|
||||
'findMany',
|
||||
{
|
||||
filter: args.filter,
|
||||
},
|
||||
return this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T[]>(
|
||||
'updateMany',
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
const result = await this.executeQuery<
|
||||
UpdateManyResolverArgs<Partial<T>>,
|
||||
T[]
|
||||
>('updateMany', args, options);
|
||||
|
||||
this.apiEventEmitterService.emitUpdateEvents(
|
||||
existingRecords.edges.map((edge) => edge.node),
|
||||
result,
|
||||
Object.keys(args.data),
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -208,10 +151,7 @@ export class GraphqlQueryRunnerService {
|
||||
args: DeleteOneResolverArgs,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T> {
|
||||
const result = await this.executeQuery<
|
||||
UpdateOneResolverArgs<Partial<T>>,
|
||||
T
|
||||
>(
|
||||
return this.executeQuery<UpdateOneResolverArgs<Partial<T>>, T>(
|
||||
'deleteOne',
|
||||
{
|
||||
id: args.id,
|
||||
@@ -219,14 +159,6 @@ export class GraphqlQueryRunnerService {
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitDeletedEvents(
|
||||
[result],
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -234,10 +166,7 @@ export class GraphqlQueryRunnerService {
|
||||
args: DeleteManyResolverArgs,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T[]> {
|
||||
const result = await this.executeQuery<
|
||||
UpdateManyResolverArgs<Partial<T>>,
|
||||
T[]
|
||||
>(
|
||||
return this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T[]>(
|
||||
'deleteMany',
|
||||
{
|
||||
filter: args.filter,
|
||||
@@ -246,14 +175,6 @@ export class GraphqlQueryRunnerService {
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitDeletedEvents(
|
||||
result,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -261,19 +182,11 @@ export class GraphqlQueryRunnerService {
|
||||
args: DestroyOneResolverArgs,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T> {
|
||||
const result = await this.executeQuery<DestroyOneResolverArgs, T>(
|
||||
return this.executeQuery<DestroyOneResolverArgs, T>(
|
||||
'destroyOne',
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitDestroyEvents(
|
||||
[result],
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -281,19 +194,11 @@ export class GraphqlQueryRunnerService {
|
||||
args: DestroyManyResolverArgs,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T[]> {
|
||||
const result = await this.executeQuery<DestroyManyResolverArgs, T[]>(
|
||||
return this.executeQuery<DestroyManyResolverArgs, T[]>(
|
||||
'destroyMany',
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitDestroyEvents(
|
||||
result,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@LogExecutionTime()
|
||||
@@ -301,7 +206,7 @@ export class GraphqlQueryRunnerService {
|
||||
args: RestoreManyResolverArgs,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<T> {
|
||||
return await this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T>(
|
||||
return this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T>(
|
||||
'restoreMany',
|
||||
{
|
||||
filter: args.filter,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/c
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
||||
import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util';
|
||||
import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
@@ -23,6 +24,7 @@ export class GraphqlQueryCreateManyResolverService
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly apiEventEmitterService: ApiEventEmitterService,
|
||||
) {}
|
||||
|
||||
async resolve<T extends ObjectRecord = ObjectRecord>(
|
||||
@@ -80,6 +82,12 @@ export class GraphqlQueryCreateManyResolverService
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitCreateEvents(
|
||||
upsertedRecords,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
const processNestedRelationsHelper = new ProcessNestedRelationsHelper();
|
||||
|
||||
if (relations) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/c
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
||||
import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util';
|
||||
|
||||
@@ -20,6 +21,7 @@ export class GraphqlQueryDestroyManyResolverService
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly apiEventEmitterService: ApiEventEmitterService,
|
||||
) {}
|
||||
|
||||
async resolve<T extends ObjectRecord = ObjectRecord>(
|
||||
@@ -75,6 +77,12 @@ export class GraphqlQueryDestroyManyResolverService
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitDestroyEvents(
|
||||
deletedRecords,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
const processNestedRelationsHelper = new ProcessNestedRelationsHelper();
|
||||
|
||||
if (relations) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
||||
import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util';
|
||||
|
||||
@@ -24,6 +25,7 @@ export class GraphqlQueryDestroyOneResolverService
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly apiEventEmitterService: ApiEventEmitterService,
|
||||
) {}
|
||||
|
||||
async resolve<T extends ObjectRecord = ObjectRecord>(
|
||||
@@ -78,11 +80,17 @@ export class GraphqlQueryDestroyOneResolverService
|
||||
);
|
||||
}
|
||||
|
||||
const recordBeforeDeletion = formatResult(
|
||||
const deletedRecords = formatResult(
|
||||
nonFormattedDeletedObjectRecords.raw,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
)[0];
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitDestroyEvents(
|
||||
deletedRecords,
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
const processNestedRelationsHelper = new ProcessNestedRelationsHelper();
|
||||
|
||||
@@ -90,7 +98,7 @@ export class GraphqlQueryDestroyOneResolverService
|
||||
await processNestedRelationsHelper.processNestedRelations({
|
||||
objectMetadataMaps,
|
||||
parentObjectMetadataItem: objectMetadataItemWithFieldMaps,
|
||||
parentObjectRecords: [recordBeforeDeletion],
|
||||
parentObjectRecords: deletedRecords,
|
||||
relations,
|
||||
limit: QUERY_MAX_RECORDS,
|
||||
authContext,
|
||||
@@ -102,7 +110,7 @@ export class GraphqlQueryDestroyOneResolverService
|
||||
new ObjectRecordsToGraphqlConnectionHelper(objectMetadataMaps);
|
||||
|
||||
return typeORMObjectRecordsParser.processRecord({
|
||||
objectRecord: recordBeforeDeletion,
|
||||
objectRecord: deletedRecords[0],
|
||||
objectName: objectMetadataItemWithFieldMaps.nameSingular,
|
||||
take: 1,
|
||||
totalCount: 1,
|
||||
|
||||
@@ -11,6 +11,7 @@ import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/c
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
||||
import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util';
|
||||
import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
@@ -24,6 +25,7 @@ export class GraphqlQueryUpdateManyResolverService
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly apiEventEmitterService: ApiEventEmitterService,
|
||||
) {}
|
||||
|
||||
async resolve<T extends ObjectRecord = ObjectRecord>(
|
||||
@@ -73,6 +75,16 @@ export class GraphqlQueryUpdateManyResolverService
|
||||
args.filter,
|
||||
);
|
||||
|
||||
const existingRecordsBuilder = withFilterQueryBuilder.clone();
|
||||
|
||||
const existingRecords = await existingRecordsBuilder.getMany();
|
||||
|
||||
const formattedExistingRecords = formatResult(
|
||||
existingRecords,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
const data = formatData(args.data, objectMetadataItemWithFieldMaps);
|
||||
|
||||
const nonFormattedUpdatedObjectRecords = await withFilterQueryBuilder
|
||||
@@ -80,19 +92,27 @@ export class GraphqlQueryUpdateManyResolverService
|
||||
.returning('*')
|
||||
.execute();
|
||||
|
||||
const updatedRecords = formatResult(
|
||||
const formattedUpdatedRecords = formatResult(
|
||||
nonFormattedUpdatedObjectRecords.raw,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
this.apiEventEmitterService.emitUpdateEvents(
|
||||
formattedExistingRecords,
|
||||
formattedUpdatedRecords,
|
||||
Object.keys(args.data),
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
const processNestedRelationsHelper = new ProcessNestedRelationsHelper();
|
||||
|
||||
if (relations) {
|
||||
await processNestedRelationsHelper.processNestedRelations({
|
||||
objectMetadataMaps,
|
||||
parentObjectMetadataItem: objectMetadataItemWithFieldMaps,
|
||||
parentObjectRecords: updatedRecords,
|
||||
parentObjectRecords: formattedUpdatedRecords,
|
||||
relations,
|
||||
limit: QUERY_MAX_RECORDS,
|
||||
authContext,
|
||||
@@ -103,7 +123,7 @@ export class GraphqlQueryUpdateManyResolverService
|
||||
const typeORMObjectRecordsParser =
|
||||
new ObjectRecordsToGraphqlConnectionHelper(objectMetadataMaps);
|
||||
|
||||
return updatedRecords.map((record: T) =>
|
||||
return formattedUpdatedRecords.map((record: T) =>
|
||||
typeORMObjectRecordsParser.processRecord({
|
||||
objectRecord: record,
|
||||
objectName: objectMetadataItemWithFieldMaps.nameSingular,
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
||||
import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util';
|
||||
import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
@@ -27,6 +28,7 @@ export class GraphqlQueryUpdateOneResolverService
|
||||
{
|
||||
constructor(
|
||||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
private readonly apiEventEmitterService: ApiEventEmitterService,
|
||||
) {}
|
||||
|
||||
async resolve<T extends ObjectRecord = ObjectRecord>(
|
||||
@@ -67,6 +69,18 @@ export class GraphqlQueryUpdateOneResolverService
|
||||
|
||||
const data = formatData(args.data, objectMetadataItemWithFieldMaps);
|
||||
|
||||
const existingRecordBuilder = queryBuilder.clone();
|
||||
|
||||
const existingRecords = await existingRecordBuilder
|
||||
.where({ id: args.id })
|
||||
.execute();
|
||||
|
||||
const formattedExistingRecords = formatResult(
|
||||
existingRecords,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
const result = await queryBuilder
|
||||
.update(data)
|
||||
.where({ id: args.id })
|
||||
@@ -75,20 +89,28 @@ export class GraphqlQueryUpdateOneResolverService
|
||||
|
||||
const nonFormattedUpdatedObjectRecords = result.raw;
|
||||
|
||||
const updatedRecords = formatResult(
|
||||
const formattedUpdatedRecords = formatResult(
|
||||
nonFormattedUpdatedObjectRecords,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
if (updatedRecords.length === 0) {
|
||||
this.apiEventEmitterService.emitUpdateEvents(
|
||||
formattedExistingRecords,
|
||||
formattedUpdatedRecords,
|
||||
Object.keys(args.data),
|
||||
options.authContext,
|
||||
options.objectMetadataItemWithFieldMaps,
|
||||
);
|
||||
|
||||
if (formattedUpdatedRecords.length === 0) {
|
||||
throw new GraphqlQueryRunnerException(
|
||||
'Record not found',
|
||||
GraphqlQueryRunnerExceptionCode.RECORD_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const updatedRecord = updatedRecords[0] as T;
|
||||
const updatedRecord = formattedUpdatedRecords[0] as T;
|
||||
|
||||
const processNestedRelationsHelper = new ProcessNestedRelationsHelper();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user