mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-30 20:27:55 +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'; | } 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 { 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 { 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 { 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'; | 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 queryRunnerArgsFactory: QueryRunnerArgsFactory, | ||||||
|     private readonly queryResultGettersFactory: QueryResultGettersFactory, |     private readonly queryResultGettersFactory: QueryResultGettersFactory, | ||||||
|     private readonly graphqlQueryResolverFactory: GraphqlQueryResolverFactory, |     private readonly graphqlQueryResolverFactory: GraphqlQueryResolverFactory, | ||||||
|     private readonly apiEventEmitterService: ApiEventEmitterService, |  | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|   /** QUERIES */ |   /** QUERIES */ | ||||||
| @@ -109,15 +107,6 @@ export class GraphqlQueryRunnerService { | |||||||
|       T[] |       T[] | ||||||
|     >('createMany', { data: [args.data], upsert: args.upsert }, options); |     >('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]; |     return results[0]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -126,20 +115,11 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: CreateManyResolverArgs<Partial<T>>, |     args: CreateManyResolverArgs<Partial<T>>, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T[]> { |   ): Promise<T[]> { | ||||||
|     const results = await this.executeQuery< |     return this.executeQuery<CreateManyResolverArgs<Partial<T>>, T[]>( | ||||||
|       CreateManyResolverArgs<Partial<T>>, |       'createMany', | ||||||
|       T[] |       args, | ||||||
|     >('createMany', args, options); |       options, | ||||||
|  |     ); | ||||||
|     if (results) { |  | ||||||
|       this.apiEventEmitterService.emitCreateEvents( |  | ||||||
|         results, |  | ||||||
|         options.authContext, |  | ||||||
|         options.objectMetadataItemWithFieldMaps, |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return results; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @LogExecutionTime() |   @LogExecutionTime() | ||||||
| @@ -147,28 +127,11 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: UpdateOneResolverArgs<Partial<T>>, |     args: UpdateOneResolverArgs<Partial<T>>, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T> { |   ): Promise<T> { | ||||||
|     const existingRecord = await this.executeQuery<FindOneResolverArgs, T>( |     return await this.executeQuery<UpdateOneResolverArgs<Partial<T>>, T>( | ||||||
|       'findOne', |       'updateOne', | ||||||
|       { |       args, | ||||||
|         filter: { id: { eq: args.id } }, |  | ||||||
|       }, |  | ||||||
|       options, |       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() |   @LogExecutionTime() | ||||||
| @@ -176,31 +139,11 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: UpdateManyResolverArgs<Partial<T>>, |     args: UpdateManyResolverArgs<Partial<T>>, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T[]> { |   ): Promise<T[]> { | ||||||
|     const existingRecords = await this.executeQuery< |     return this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T[]>( | ||||||
|       FindManyResolverArgs, |       'updateMany', | ||||||
|       IConnection<T, IEdge<T>> |       args, | ||||||
|     >( |  | ||||||
|       'findMany', |  | ||||||
|       { |  | ||||||
|         filter: args.filter, |  | ||||||
|       }, |  | ||||||
|       options, |       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() |   @LogExecutionTime() | ||||||
| @@ -208,10 +151,7 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: DeleteOneResolverArgs, |     args: DeleteOneResolverArgs, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T> { |   ): Promise<T> { | ||||||
|     const result = await this.executeQuery< |     return this.executeQuery<UpdateOneResolverArgs<Partial<T>>, T>( | ||||||
|       UpdateOneResolverArgs<Partial<T>>, |  | ||||||
|       T |  | ||||||
|     >( |  | ||||||
|       'deleteOne', |       'deleteOne', | ||||||
|       { |       { | ||||||
|         id: args.id, |         id: args.id, | ||||||
| @@ -219,14 +159,6 @@ export class GraphqlQueryRunnerService { | |||||||
|       }, |       }, | ||||||
|       options, |       options, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     this.apiEventEmitterService.emitDeletedEvents( |  | ||||||
|       [result], |  | ||||||
|       options.authContext, |  | ||||||
|       options.objectMetadataItemWithFieldMaps, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     return result; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @LogExecutionTime() |   @LogExecutionTime() | ||||||
| @@ -234,10 +166,7 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: DeleteManyResolverArgs, |     args: DeleteManyResolverArgs, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T[]> { |   ): Promise<T[]> { | ||||||
|     const result = await this.executeQuery< |     return this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T[]>( | ||||||
|       UpdateManyResolverArgs<Partial<T>>, |  | ||||||
|       T[] |  | ||||||
|     >( |  | ||||||
|       'deleteMany', |       'deleteMany', | ||||||
|       { |       { | ||||||
|         filter: args.filter, |         filter: args.filter, | ||||||
| @@ -246,14 +175,6 @@ export class GraphqlQueryRunnerService { | |||||||
|       }, |       }, | ||||||
|       options, |       options, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     this.apiEventEmitterService.emitDeletedEvents( |  | ||||||
|       result, |  | ||||||
|       options.authContext, |  | ||||||
|       options.objectMetadataItemWithFieldMaps, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     return result; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @LogExecutionTime() |   @LogExecutionTime() | ||||||
| @@ -261,19 +182,11 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: DestroyOneResolverArgs, |     args: DestroyOneResolverArgs, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T> { |   ): Promise<T> { | ||||||
|     const result = await this.executeQuery<DestroyOneResolverArgs, T>( |     return this.executeQuery<DestroyOneResolverArgs, T>( | ||||||
|       'destroyOne', |       'destroyOne', | ||||||
|       args, |       args, | ||||||
|       options, |       options, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     this.apiEventEmitterService.emitDestroyEvents( |  | ||||||
|       [result], |  | ||||||
|       options.authContext, |  | ||||||
|       options.objectMetadataItemWithFieldMaps, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     return result; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @LogExecutionTime() |   @LogExecutionTime() | ||||||
| @@ -281,19 +194,11 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: DestroyManyResolverArgs, |     args: DestroyManyResolverArgs, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T[]> { |   ): Promise<T[]> { | ||||||
|     const result = await this.executeQuery<DestroyManyResolverArgs, T[]>( |     return this.executeQuery<DestroyManyResolverArgs, T[]>( | ||||||
|       'destroyMany', |       'destroyMany', | ||||||
|       args, |       args, | ||||||
|       options, |       options, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     this.apiEventEmitterService.emitDestroyEvents( |  | ||||||
|       result, |  | ||||||
|       options.authContext, |  | ||||||
|       options.objectMetadataItemWithFieldMaps, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     return result; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @LogExecutionTime() |   @LogExecutionTime() | ||||||
| @@ -301,7 +206,7 @@ export class GraphqlQueryRunnerService { | |||||||
|     args: RestoreManyResolverArgs, |     args: RestoreManyResolverArgs, | ||||||
|     options: WorkspaceQueryRunnerOptions, |     options: WorkspaceQueryRunnerOptions, | ||||||
|   ): Promise<T> { |   ): Promise<T> { | ||||||
|     return await this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T>( |     return this.executeQuery<UpdateManyResolverArgs<Partial<T>>, T>( | ||||||
|       'restoreMany', |       'restoreMany', | ||||||
|       { |       { | ||||||
|         filter: args.filter, |         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 { 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 { 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 { 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 { 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 { 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'; | import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||||||
| @@ -23,6 +24,7 @@ export class GraphqlQueryCreateManyResolverService | |||||||
| { | { | ||||||
|   constructor( |   constructor( | ||||||
|     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, |     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||||||
|  |     private readonly apiEventEmitterService: ApiEventEmitterService, | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|   async resolve<T extends ObjectRecord = ObjectRecord>( |   async resolve<T extends ObjectRecord = ObjectRecord>( | ||||||
| @@ -80,6 +82,12 @@ export class GraphqlQueryCreateManyResolverService | |||||||
|       objectMetadataMaps, |       objectMetadataMaps, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     this.apiEventEmitterService.emitCreateEvents( | ||||||
|  |       upsertedRecords, | ||||||
|  |       options.authContext, | ||||||
|  |       options.objectMetadataItemWithFieldMaps, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); |     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); | ||||||
|  |  | ||||||
|     if (relations) { |     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 { 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 { 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 { 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 { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||||||
| import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; | import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; | ||||||
|  |  | ||||||
| @@ -20,6 +21,7 @@ export class GraphqlQueryDestroyManyResolverService | |||||||
| { | { | ||||||
|   constructor( |   constructor( | ||||||
|     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, |     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||||||
|  |     private readonly apiEventEmitterService: ApiEventEmitterService, | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|   async resolve<T extends ObjectRecord = ObjectRecord>( |   async resolve<T extends ObjectRecord = ObjectRecord>( | ||||||
| @@ -75,6 +77,12 @@ export class GraphqlQueryDestroyManyResolverService | |||||||
|       objectMetadataMaps, |       objectMetadataMaps, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     this.apiEventEmitterService.emitDestroyEvents( | ||||||
|  |       deletedRecords, | ||||||
|  |       options.authContext, | ||||||
|  |       options.objectMetadataItemWithFieldMaps, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); |     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); | ||||||
|  |  | ||||||
|     if (relations) { |     if (relations) { | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import { | |||||||
| import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser'; | 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 { 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 { 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 { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||||||
| import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; | import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; | ||||||
|  |  | ||||||
| @@ -24,6 +25,7 @@ export class GraphqlQueryDestroyOneResolverService | |||||||
| { | { | ||||||
|   constructor( |   constructor( | ||||||
|     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, |     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||||||
|  |     private readonly apiEventEmitterService: ApiEventEmitterService, | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|   async resolve<T extends ObjectRecord = ObjectRecord>( |   async resolve<T extends ObjectRecord = ObjectRecord>( | ||||||
| @@ -78,11 +80,17 @@ export class GraphqlQueryDestroyOneResolverService | |||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const recordBeforeDeletion = formatResult( |     const deletedRecords = formatResult( | ||||||
|       nonFormattedDeletedObjectRecords.raw, |       nonFormattedDeletedObjectRecords.raw, | ||||||
|       objectMetadataItemWithFieldMaps, |       objectMetadataItemWithFieldMaps, | ||||||
|       objectMetadataMaps, |       objectMetadataMaps, | ||||||
|     )[0]; |     ); | ||||||
|  |  | ||||||
|  |     this.apiEventEmitterService.emitDestroyEvents( | ||||||
|  |       deletedRecords, | ||||||
|  |       options.authContext, | ||||||
|  |       options.objectMetadataItemWithFieldMaps, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); |     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); | ||||||
|  |  | ||||||
| @@ -90,7 +98,7 @@ export class GraphqlQueryDestroyOneResolverService | |||||||
|       await processNestedRelationsHelper.processNestedRelations({ |       await processNestedRelationsHelper.processNestedRelations({ | ||||||
|         objectMetadataMaps, |         objectMetadataMaps, | ||||||
|         parentObjectMetadataItem: objectMetadataItemWithFieldMaps, |         parentObjectMetadataItem: objectMetadataItemWithFieldMaps, | ||||||
|         parentObjectRecords: [recordBeforeDeletion], |         parentObjectRecords: deletedRecords, | ||||||
|         relations, |         relations, | ||||||
|         limit: QUERY_MAX_RECORDS, |         limit: QUERY_MAX_RECORDS, | ||||||
|         authContext, |         authContext, | ||||||
| @@ -102,7 +110,7 @@ export class GraphqlQueryDestroyOneResolverService | |||||||
|       new ObjectRecordsToGraphqlConnectionHelper(objectMetadataMaps); |       new ObjectRecordsToGraphqlConnectionHelper(objectMetadataMaps); | ||||||
|  |  | ||||||
|     return typeORMObjectRecordsParser.processRecord({ |     return typeORMObjectRecordsParser.processRecord({ | ||||||
|       objectRecord: recordBeforeDeletion, |       objectRecord: deletedRecords[0], | ||||||
|       objectName: objectMetadataItemWithFieldMaps.nameSingular, |       objectName: objectMetadataItemWithFieldMaps.nameSingular, | ||||||
|       take: 1, |       take: 1, | ||||||
|       totalCount: 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 { 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 { 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 { 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 { 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 { 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'; | import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||||||
| @@ -24,6 +25,7 @@ export class GraphqlQueryUpdateManyResolverService | |||||||
| { | { | ||||||
|   constructor( |   constructor( | ||||||
|     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, |     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||||||
|  |     private readonly apiEventEmitterService: ApiEventEmitterService, | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|   async resolve<T extends ObjectRecord = ObjectRecord>( |   async resolve<T extends ObjectRecord = ObjectRecord>( | ||||||
| @@ -73,6 +75,16 @@ export class GraphqlQueryUpdateManyResolverService | |||||||
|       args.filter, |       args.filter, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     const existingRecordsBuilder = withFilterQueryBuilder.clone(); | ||||||
|  |  | ||||||
|  |     const existingRecords = await existingRecordsBuilder.getMany(); | ||||||
|  |  | ||||||
|  |     const formattedExistingRecords = formatResult( | ||||||
|  |       existingRecords, | ||||||
|  |       objectMetadataItemWithFieldMaps, | ||||||
|  |       objectMetadataMaps, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     const data = formatData(args.data, objectMetadataItemWithFieldMaps); |     const data = formatData(args.data, objectMetadataItemWithFieldMaps); | ||||||
|  |  | ||||||
|     const nonFormattedUpdatedObjectRecords = await withFilterQueryBuilder |     const nonFormattedUpdatedObjectRecords = await withFilterQueryBuilder | ||||||
| @@ -80,19 +92,27 @@ export class GraphqlQueryUpdateManyResolverService | |||||||
|       .returning('*') |       .returning('*') | ||||||
|       .execute(); |       .execute(); | ||||||
|  |  | ||||||
|     const updatedRecords = formatResult( |     const formattedUpdatedRecords = formatResult( | ||||||
|       nonFormattedUpdatedObjectRecords.raw, |       nonFormattedUpdatedObjectRecords.raw, | ||||||
|       objectMetadataItemWithFieldMaps, |       objectMetadataItemWithFieldMaps, | ||||||
|       objectMetadataMaps, |       objectMetadataMaps, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     this.apiEventEmitterService.emitUpdateEvents( | ||||||
|  |       formattedExistingRecords, | ||||||
|  |       formattedUpdatedRecords, | ||||||
|  |       Object.keys(args.data), | ||||||
|  |       options.authContext, | ||||||
|  |       options.objectMetadataItemWithFieldMaps, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); |     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); | ||||||
|  |  | ||||||
|     if (relations) { |     if (relations) { | ||||||
|       await processNestedRelationsHelper.processNestedRelations({ |       await processNestedRelationsHelper.processNestedRelations({ | ||||||
|         objectMetadataMaps, |         objectMetadataMaps, | ||||||
|         parentObjectMetadataItem: objectMetadataItemWithFieldMaps, |         parentObjectMetadataItem: objectMetadataItemWithFieldMaps, | ||||||
|         parentObjectRecords: updatedRecords, |         parentObjectRecords: formattedUpdatedRecords, | ||||||
|         relations, |         relations, | ||||||
|         limit: QUERY_MAX_RECORDS, |         limit: QUERY_MAX_RECORDS, | ||||||
|         authContext, |         authContext, | ||||||
| @@ -103,7 +123,7 @@ export class GraphqlQueryUpdateManyResolverService | |||||||
|     const typeORMObjectRecordsParser = |     const typeORMObjectRecordsParser = | ||||||
|       new ObjectRecordsToGraphqlConnectionHelper(objectMetadataMaps); |       new ObjectRecordsToGraphqlConnectionHelper(objectMetadataMaps); | ||||||
|  |  | ||||||
|     return updatedRecords.map((record: T) => |     return formattedUpdatedRecords.map((record: T) => | ||||||
|       typeORMObjectRecordsParser.processRecord({ |       typeORMObjectRecordsParser.processRecord({ | ||||||
|         objectRecord: record, |         objectRecord: record, | ||||||
|         objectName: objectMetadataItemWithFieldMaps.nameSingular, |         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 { 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 { 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 { 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 { 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 { 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'; | import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||||||
| @@ -27,6 +28,7 @@ export class GraphqlQueryUpdateOneResolverService | |||||||
| { | { | ||||||
|   constructor( |   constructor( | ||||||
|     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, |     private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||||||
|  |     private readonly apiEventEmitterService: ApiEventEmitterService, | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|   async resolve<T extends ObjectRecord = ObjectRecord>( |   async resolve<T extends ObjectRecord = ObjectRecord>( | ||||||
| @@ -67,6 +69,18 @@ export class GraphqlQueryUpdateOneResolverService | |||||||
|  |  | ||||||
|     const data = formatData(args.data, objectMetadataItemWithFieldMaps); |     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 |     const result = await queryBuilder | ||||||
|       .update(data) |       .update(data) | ||||||
|       .where({ id: args.id }) |       .where({ id: args.id }) | ||||||
| @@ -75,20 +89,28 @@ export class GraphqlQueryUpdateOneResolverService | |||||||
|  |  | ||||||
|     const nonFormattedUpdatedObjectRecords = result.raw; |     const nonFormattedUpdatedObjectRecords = result.raw; | ||||||
|  |  | ||||||
|     const updatedRecords = formatResult( |     const formattedUpdatedRecords = formatResult( | ||||||
|       nonFormattedUpdatedObjectRecords, |       nonFormattedUpdatedObjectRecords, | ||||||
|       objectMetadataItemWithFieldMaps, |       objectMetadataItemWithFieldMaps, | ||||||
|       objectMetadataMaps, |       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( |       throw new GraphqlQueryRunnerException( | ||||||
|         'Record not found', |         'Record not found', | ||||||
|         GraphqlQueryRunnerExceptionCode.RECORD_NOT_FOUND, |         GraphqlQueryRunnerExceptionCode.RECORD_NOT_FOUND, | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const updatedRecord = updatedRecords[0] as T; |     const updatedRecord = formattedUpdatedRecords[0] as T; | ||||||
|  |  | ||||||
|     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); |     const processNestedRelationsHelper = new ProcessNestedRelationsHelper(); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Weiko
					Weiko