Add workspacePreQueryHook module (#3879)
* rebase * reorganise messaging folders * fix * fix after review * fix yarn lock
This commit is contained in:
@ -5,6 +5,7 @@ import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/
|
||||
|
||||
export interface WorkspaceQueryRunnerOptions {
|
||||
workspaceId: string;
|
||||
userId: string | undefined;
|
||||
info: GraphQLResolveInfo;
|
||||
objectMetadataItem: ObjectMetadataInterface;
|
||||
fieldMetadataCollection: FieldMetadataInterface[];
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import { ResolverArgs } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
export interface WorkspacePreQueryHook {
|
||||
execute(
|
||||
userId: string | undefined,
|
||||
workspaceId: string,
|
||||
payload: ResolverArgs,
|
||||
): Promise<void>;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
import {
|
||||
CreateManyResolverArgs,
|
||||
CreateOneResolverArgs,
|
||||
DeleteManyResolverArgs,
|
||||
DeleteOneResolverArgs,
|
||||
FindManyResolverArgs,
|
||||
FindOneResolverArgs,
|
||||
UpdateManyResolverArgs,
|
||||
UpdateOneResolverArgs,
|
||||
} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
export type ExecutePreHookMethod =
|
||||
| 'createMany'
|
||||
| 'createOne'
|
||||
| 'deleteMany'
|
||||
| 'deleteOne'
|
||||
| 'findMany'
|
||||
| 'findOne'
|
||||
| 'updateMany'
|
||||
| 'updateOne';
|
||||
|
||||
export type ObjectName = string;
|
||||
|
||||
export type HookName = string;
|
||||
|
||||
export type WorkspaceQueryHook = {
|
||||
[key in ObjectName]: {
|
||||
[key in ExecutePreHookMethod]?: HookName[];
|
||||
};
|
||||
};
|
||||
|
||||
export type WorkspacePreQueryHookPayload<T> = T extends 'createMany'
|
||||
? CreateManyResolverArgs
|
||||
: T extends 'createOne'
|
||||
? CreateOneResolverArgs
|
||||
: T extends 'deleteMany'
|
||||
? DeleteManyResolverArgs
|
||||
: T extends 'deleteOne'
|
||||
? DeleteOneResolverArgs
|
||||
: T extends 'findMany'
|
||||
? FindManyResolverArgs
|
||||
: T extends 'findOne'
|
||||
? FindOneResolverArgs
|
||||
: T extends 'updateMany'
|
||||
? UpdateManyResolverArgs
|
||||
: T extends 'updateOne'
|
||||
? UpdateOneResolverArgs
|
||||
: never;
|
||||
@ -0,0 +1,11 @@
|
||||
import { MessageFindManyPreQueryHook } from 'src/workspace/messaging/query-hooks/message/message-find-many.pre-query.hook';
|
||||
import { MessageFindOnePreQueryHook } from 'src/workspace/messaging/query-hooks/message/message-find-one.pre-query-hook';
|
||||
import { WorkspaceQueryHook } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type';
|
||||
|
||||
// TODO: move to a decorator
|
||||
export const workspacePreQueryHooks: WorkspaceQueryHook = {
|
||||
message: {
|
||||
findOne: [MessageFindOnePreQueryHook.name],
|
||||
findMany: [MessageFindManyPreQueryHook.name],
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { MessagingQueryHookModule } from 'src/workspace/messaging/query-hooks/messaging-query-hook.module';
|
||||
import { WorkspacePreQueryHookService } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service';
|
||||
|
||||
@Module({
|
||||
imports: [MessagingQueryHookModule],
|
||||
providers: [WorkspacePreQueryHookService],
|
||||
exports: [WorkspacePreQueryHookService],
|
||||
})
|
||||
export class WorkspacePreQueryHookModule {}
|
||||
@ -0,0 +1,34 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
|
||||
import {
|
||||
ExecutePreHookMethod,
|
||||
WorkspacePreQueryHookPayload,
|
||||
} from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type';
|
||||
import { workspacePreQueryHooks } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspacePreQueryHookService {
|
||||
constructor(private readonly workspaceQueryHookModuleRef: ModuleRef) {}
|
||||
|
||||
public async executePreHooks<T extends ExecutePreHookMethod>(
|
||||
userId: string | undefined,
|
||||
workspaceId: string,
|
||||
objectName: string,
|
||||
method: T,
|
||||
payload: WorkspacePreQueryHookPayload<T>,
|
||||
): Promise<void> {
|
||||
const hooks = workspacePreQueryHooks[objectName] || [];
|
||||
|
||||
for (const hookName of Object.values(hooks[method] ?? [])) {
|
||||
const hook: WorkspacePreQueryHook =
|
||||
await this.workspaceQueryHookModuleRef.get(hookName, {
|
||||
strict: false,
|
||||
});
|
||||
|
||||
await hook.execute(userId, workspaceId, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,11 +2,16 @@ import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceQueryBuilderModule } from 'src/workspace/workspace-query-builder/workspace-query-builder.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||
import { WorkspacePreQueryHookModule } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module';
|
||||
|
||||
import { WorkspaceQueryRunnerService } from './workspace-query-runner.service';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceQueryBuilderModule, WorkspaceDataSourceModule],
|
||||
imports: [
|
||||
WorkspaceQueryBuilderModule,
|
||||
WorkspaceDataSourceModule,
|
||||
WorkspacePreQueryHookModule,
|
||||
],
|
||||
providers: [WorkspaceQueryRunnerService],
|
||||
exports: [WorkspaceQueryRunnerService],
|
||||
})
|
||||
|
||||
@ -38,6 +38,7 @@ import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-tar
|
||||
import { ObjectRecordDeleteEvent } from 'src/integrations/event-emitter/types/object-record-delete.event';
|
||||
import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event';
|
||||
import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event';
|
||||
import { WorkspacePreQueryHookService } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service';
|
||||
|
||||
import { WorkspaceQueryRunnerOptions } from './interfaces/query-runner-option.interface';
|
||||
import {
|
||||
@ -53,6 +54,7 @@ export class WorkspaceQueryRunnerService {
|
||||
@Inject(MessageQueue.webhookQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly workspacePreQueryHookService: WorkspacePreQueryHookService,
|
||||
) {}
|
||||
|
||||
async findMany<
|
||||
@ -63,7 +65,7 @@ export class WorkspaceQueryRunnerService {
|
||||
args: FindManyResolverArgs<Filter, OrderBy>,
|
||||
options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<IConnection<Record> | undefined> {
|
||||
const { workspaceId, objectMetadataItem } = options;
|
||||
const { workspaceId, userId, objectMetadataItem } = options;
|
||||
const start = performance.now();
|
||||
|
||||
const query = await this.workspaceQueryBuilderFactory.findMany(
|
||||
@ -71,6 +73,14 @@ export class WorkspaceQueryRunnerService {
|
||||
options,
|
||||
);
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
'findMany',
|
||||
args,
|
||||
);
|
||||
|
||||
const result = await this.execute(query, workspaceId);
|
||||
const end = performance.now();
|
||||
|
||||
@ -97,11 +107,20 @@ export class WorkspaceQueryRunnerService {
|
||||
if (!args.filter || Object.keys(args.filter).length === 0) {
|
||||
throw new BadRequestException('Missing filter argument');
|
||||
}
|
||||
const { workspaceId, objectMetadataItem } = options;
|
||||
const { workspaceId, userId, objectMetadataItem } = options;
|
||||
const query = await this.workspaceQueryBuilderFactory.findOne(
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
'findOne',
|
||||
args,
|
||||
);
|
||||
|
||||
const result = await this.execute(query, workspaceId);
|
||||
const parsedResult = this.parseResult<IConnection<Record>>(
|
||||
result,
|
||||
@ -170,6 +189,7 @@ export class WorkspaceQueryRunnerService {
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
const result = await this.execute(query, workspaceId);
|
||||
|
||||
const parsedResults = this.parseResult<PGGraphQLMutation<Record>>(
|
||||
@ -232,6 +252,7 @@ export class WorkspaceQueryRunnerService {
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
const result = await this.execute(query, workspaceId);
|
||||
|
||||
const parsedResults = this.parseResult<PGGraphQLMutation<Record>>(
|
||||
@ -338,7 +359,7 @@ export class WorkspaceQueryRunnerService {
|
||||
const result = graphqlResult?.[0]?.resolve?.data?.[entityKey];
|
||||
const errors = graphqlResult?.[0]?.resolve?.errors;
|
||||
|
||||
if (!result) {
|
||||
if (errors && errors.length > 0) {
|
||||
throw new InternalServerErrorException(
|
||||
`GraphQL errors on ${command}${
|
||||
objectMetadataItem.nameSingular
|
||||
|
||||
Reference in New Issue
Block a user