feat: Dynamic hook registration for WorkspaceQueryHooks (#6008)
#### Overview
This PR introduces a new API for dynamically registering and executing
pre and post query hooks in the Workspace Query Hook system using the
`@WorkspaceQueryHook` decorator. This approach eliminates the need for
manual provider registration, and fix the issue of `undefined` or `null`
repository using `@InjectWorkspaceRepository`.
#### New API
**Define a Hook**
Use the `@WorkspaceQueryHook` decorator to define pre or post hooks:
```typescript
@WorkspaceQueryHook({
key: `calendarEvent.findMany`,
scope: Scope.REQUEST,
})
export class CalendarEventFindManyPreQueryHook implements WorkspaceQueryHookInstance {
async execute(userId: string, workspaceId: string, payload: FindManyResolverArgs): Promise<void> {
if (!payload?.filter?.id?.eq) {
throw new BadRequestException('id filter is required');
}
// Implement hook logic here
}
}
```
This API simplifies the registration and execution of query hooks,
providing a more flexible and maintainable approach.
---------
Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
@ -141,8 +141,10 @@ export class GraphQLConfigService
|
||||
// Create a new contextId for each request
|
||||
const contextId = ContextIdFactory.create();
|
||||
|
||||
// Register the request in the contextId
|
||||
this.moduleRef.registerRequestByContextId(context.req, contextId);
|
||||
if (this.moduleRef.registerRequestByContextId) {
|
||||
// Register the request in the contextId
|
||||
this.moduleRef.registerRequestByContextId(context.req, contextId);
|
||||
}
|
||||
|
||||
// Resolve the WorkspaceSchemaFactory for the contextId
|
||||
const workspaceFactory = await this.moduleRef.resolve(
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type';
|
||||
import { CalendarEventFindManyPreQueryHook } from 'src/modules/calendar/query-hooks/calendar-event/calendar-event-find-many.pre-query.hook';
|
||||
import { CalendarEventFindOnePreQueryHook } from 'src/modules/calendar/query-hooks/calendar-event/calendar-event-find-one.pre-query-hook';
|
||||
import { BlocklistCreateManyPreQueryHook } from 'src/modules/connected-account/query-hooks/blocklist/blocklist-create-many.pre-query.hook';
|
||||
import { BlocklistUpdateManyPreQueryHook } from 'src/modules/connected-account/query-hooks/blocklist/blocklist-update-many.pre-query.hook';
|
||||
import { BlocklistUpdateOnePreQueryHook } from 'src/modules/connected-account/query-hooks/blocklist/blocklist-update-one.pre-query.hook';
|
||||
import { WorkspaceMemberDeleteOnePreQueryHook } from 'src/modules/workspace-member/query-hooks/workspace-member-delete-one.pre-query.hook';
|
||||
import { WorkspaceMemberDeleteManyPreQueryHook } from 'src/modules/workspace-member/query-hooks/workspace-member-delete-many.pre-query.hook';
|
||||
import { MessageFindManyPreQueryHook } from 'src/modules/messaging/common/query-hooks/message/message-find-many.pre-query.hook';
|
||||
import { MessageFindOnePreQueryHook } from 'src/modules/messaging/common/query-hooks/message/message-find-one.pre-query-hook';
|
||||
|
||||
// TODO: move to a decorator
|
||||
export const workspacePreQueryHooks: WorkspaceQueryHook = {
|
||||
message: {
|
||||
findOne: [MessageFindOnePreQueryHook.name],
|
||||
findMany: [MessageFindManyPreQueryHook.name],
|
||||
},
|
||||
calendarEvent: {
|
||||
findOne: [CalendarEventFindOnePreQueryHook.name],
|
||||
findMany: [CalendarEventFindManyPreQueryHook.name],
|
||||
},
|
||||
blocklist: {
|
||||
createMany: [BlocklistCreateManyPreQueryHook.name],
|
||||
updateMany: [BlocklistUpdateManyPreQueryHook.name],
|
||||
updateOne: [BlocklistUpdateOnePreQueryHook.name],
|
||||
},
|
||||
workspaceMember: {
|
||||
deleteOne: [WorkspaceMemberDeleteOnePreQueryHook.name],
|
||||
deleteMany: [WorkspaceMemberDeleteManyPreQueryHook.name],
|
||||
},
|
||||
};
|
||||
@ -1,19 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service';
|
||||
import { CalendarQueryHookModule } from 'src/modules/calendar/query-hooks/calendar-query-hook.module';
|
||||
import { ConnectedAccountQueryHookModule } from 'src/modules/connected-account/query-hooks/connected-account-query-hook.module';
|
||||
import { MessagingQueryHookModule } from 'src/modules/messaging/common/query-hooks/messaging-query-hook.module';
|
||||
import { WorkspaceMemberQueryHookModule } from 'src/modules/workspace-member/query-hooks/workspace-member-query-hook.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MessagingQueryHookModule,
|
||||
CalendarQueryHookModule,
|
||||
ConnectedAccountQueryHookModule,
|
||||
WorkspaceMemberQueryHookModule,
|
||||
],
|
||||
providers: [WorkspacePreQueryHookService],
|
||||
exports: [WorkspacePreQueryHookService],
|
||||
})
|
||||
export class WorkspacePreQueryHookModule {}
|
||||
@ -1,34 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
|
||||
import {
|
||||
ExecutePreHookMethod,
|
||||
WorkspacePreQueryHookPayload,
|
||||
} from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type';
|
||||
import { workspacePreQueryHooks } from 'src/engine/api/graphql/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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
import { Scope, SetMetadata } from '@nestjs/common';
|
||||
import { SCOPE_OPTIONS_METADATA } from '@nestjs/common/constants';
|
||||
|
||||
import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WORKSPACE_QUERY_HOOK_METADATA } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.constants';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
|
||||
export type WorkspaceQueryHookKey =
|
||||
`${string}.${WorkspaceResolverBuilderMethodNames}`;
|
||||
|
||||
export interface WorkspaceQueryHookOptions {
|
||||
key: WorkspaceQueryHookKey;
|
||||
type?: WorkspaceQueryHookType;
|
||||
scope?: Scope;
|
||||
}
|
||||
|
||||
export function WorkspaceQueryHook(key: WorkspaceQueryHookKey): ClassDecorator;
|
||||
export function WorkspaceQueryHook(
|
||||
options: WorkspaceQueryHookOptions,
|
||||
): ClassDecorator;
|
||||
export function WorkspaceQueryHook(
|
||||
keyOrOptions: WorkspaceQueryHookKey | WorkspaceQueryHookOptions,
|
||||
): ClassDecorator {
|
||||
const options: WorkspaceQueryHookOptions =
|
||||
keyOrOptions && typeof keyOrOptions === 'object'
|
||||
? keyOrOptions
|
||||
: { key: keyOrOptions };
|
||||
|
||||
// Default to PreHook
|
||||
if (!options.type) {
|
||||
options.type = WorkspaceQueryHookType.PreHook;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
return (target: Function) => {
|
||||
SetMetadata(SCOPE_OPTIONS_METADATA, options)(target);
|
||||
SetMetadata(WORKSPACE_QUERY_HOOK_METADATA, options)(target);
|
||||
};
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { ResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
export interface WorkspacePreQueryHook {
|
||||
export interface WorkspaceQueryHookInstance {
|
||||
execute(
|
||||
userId: string | undefined,
|
||||
workspaceId: string,
|
||||
@ -0,0 +1,59 @@
|
||||
// hook-registry.service.ts
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Module } from '@nestjs/core/injector/module';
|
||||
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { WorkspaceQueryHookKey } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
|
||||
interface WorkspaceQueryHookData<T> {
|
||||
instance: T;
|
||||
host: Module;
|
||||
isRequestScoped: boolean;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceQueryHookStorage {
|
||||
private preHookInstances = new Map<
|
||||
WorkspaceQueryHookKey,
|
||||
WorkspaceQueryHookData<WorkspaceQueryHookInstance>[]
|
||||
>();
|
||||
private postHookInstances = new Map<
|
||||
WorkspaceQueryHookKey,
|
||||
WorkspaceQueryHookData<WorkspaceQueryHookInstance>[]
|
||||
>();
|
||||
|
||||
registerWorkspaceQueryPreHookInstance(
|
||||
key: WorkspaceQueryHookKey,
|
||||
data: WorkspaceQueryHookData<WorkspaceQueryHookInstance>,
|
||||
) {
|
||||
if (!this.preHookInstances.has(key)) {
|
||||
this.preHookInstances.set(key, []);
|
||||
}
|
||||
|
||||
this.preHookInstances.get(key)?.push(data);
|
||||
}
|
||||
|
||||
getWorkspaceQueryPreHookInstances(
|
||||
key: WorkspaceQueryHookKey,
|
||||
): WorkspaceQueryHookData<WorkspaceQueryHookInstance>[] | undefined {
|
||||
return this.preHookInstances.get(key);
|
||||
}
|
||||
|
||||
registerWorkspaceQueryPostHookInstance(
|
||||
key: WorkspaceQueryHookKey,
|
||||
data: WorkspaceQueryHookData<WorkspaceQueryHookInstance>,
|
||||
) {
|
||||
if (!this.postHookInstances.has(key)) {
|
||||
this.postHookInstances.set(key, []);
|
||||
}
|
||||
|
||||
this.postHookInstances.get(key)?.push(data);
|
||||
}
|
||||
|
||||
getWorkspaceQueryPostHookInstances(
|
||||
key: WorkspaceQueryHookKey,
|
||||
): WorkspaceQueryHookData<WorkspaceQueryHookInstance>[] | undefined {
|
||||
return this.postHookInstances.get(key);
|
||||
}
|
||||
}
|
||||
@ -10,26 +10,10 @@ import {
|
||||
UpdateOneResolverArgs,
|
||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
export type ExecutePreHookMethod =
|
||||
| 'createMany'
|
||||
| 'createOne'
|
||||
| 'deleteMany'
|
||||
| 'deleteOne'
|
||||
| 'findMany'
|
||||
| 'findOne'
|
||||
| 'findDuplicates'
|
||||
| 'updateMany'
|
||||
| 'updateOne';
|
||||
|
||||
export type ObjectName = string;
|
||||
|
||||
export type HookName = string;
|
||||
|
||||
export type WorkspaceQueryHook = {
|
||||
[key in ObjectName]: {
|
||||
[key in ExecutePreHookMethod]?: HookName[];
|
||||
};
|
||||
};
|
||||
export enum WorkspaceQueryHookType {
|
||||
PreHook = 'PreHook',
|
||||
PostHook = 'PostHook',
|
||||
}
|
||||
|
||||
export type WorkspacePreQueryHookPayload<T> = T extends 'createMany'
|
||||
? CreateManyResolverArgs
|
||||
@ -0,0 +1,25 @@
|
||||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
import { Injectable, Type } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
|
||||
import { WORKSPACE_QUERY_HOOK_METADATA } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.constants';
|
||||
import { WorkspaceQueryHookOptions } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceQueryHookMetadataAccessor {
|
||||
constructor(private readonly reflector: Reflector) {}
|
||||
|
||||
isWorkspaceQueryHook(target: Type<any> | Function): boolean {
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!this.reflector.get(WORKSPACE_QUERY_HOOK_METADATA, target);
|
||||
}
|
||||
|
||||
getWorkspaceQueryHookMetadata(
|
||||
target: Type<any> | Function,
|
||||
): WorkspaceQueryHookOptions | undefined {
|
||||
return this.reflector.get(WORKSPACE_QUERY_HOOK_METADATA, target);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
export const WORKSPACE_QUERY_HOOK_METADATA = Symbol(
|
||||
'workspace-query-hook:query-hook-metadata',
|
||||
);
|
||||
@ -0,0 +1,139 @@
|
||||
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
||||
import { DiscoveryService, ModuleRef, createContextId } from '@nestjs/core';
|
||||
import { Module } from '@nestjs/core/injector/module';
|
||||
import { Injector } from '@nestjs/core/injector/injector';
|
||||
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { WorkspaceQueryHookMetadataAccessor } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook-metadata.accessor';
|
||||
import { WorkspaceQueryHookStorage } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/storage/workspace-query-hook.storage';
|
||||
import { WorkspaceQueryHookKey } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceQueryHookExplorer implements OnModuleInit {
|
||||
private readonly logger = new Logger('WorkspaceQueryHookModule');
|
||||
private readonly injector = new Injector();
|
||||
|
||||
constructor(
|
||||
private readonly moduleRef: ModuleRef,
|
||||
private readonly discoveryService: DiscoveryService,
|
||||
private readonly metadataAccessor: WorkspaceQueryHookMetadataAccessor,
|
||||
private readonly workspaceQueryHookStorage: WorkspaceQueryHookStorage,
|
||||
) {}
|
||||
|
||||
onModuleInit() {
|
||||
this.explore();
|
||||
}
|
||||
|
||||
async explore() {
|
||||
const hooks = this.discoveryService
|
||||
.getProviders()
|
||||
.filter((wrapper) =>
|
||||
this.metadataAccessor.isWorkspaceQueryHook(
|
||||
!wrapper.metatype || wrapper.inject
|
||||
? wrapper.instance?.constructor
|
||||
: wrapper.metatype,
|
||||
),
|
||||
);
|
||||
|
||||
for (const hook of hooks) {
|
||||
const { instance, metatype } = hook;
|
||||
|
||||
const { key, type } =
|
||||
this.metadataAccessor.getWorkspaceQueryHookMetadata(
|
||||
instance.constructor || metatype,
|
||||
) ?? {};
|
||||
|
||||
if (!key || !type) {
|
||||
this.logger.error(
|
||||
`PreHook ${hook.name} is missing key or type metadata`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hook.host) {
|
||||
this.logger.error(`PreHook ${hook.name} is missing host metadata`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.registerWorkspaceQueryHook(
|
||||
key,
|
||||
type,
|
||||
instance,
|
||||
hook.host,
|
||||
!hook.isDependencyTreeStatic(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async handleHook(
|
||||
payload: Parameters<WorkspaceQueryHookInstance['execute']>,
|
||||
instance: object,
|
||||
host: Module,
|
||||
isRequestScoped: boolean,
|
||||
) {
|
||||
const methodName = 'execute';
|
||||
|
||||
if (isRequestScoped) {
|
||||
const contextId = createContextId();
|
||||
|
||||
if (this.moduleRef.registerRequestByContextId) {
|
||||
this.moduleRef.registerRequestByContextId(
|
||||
{
|
||||
req: {
|
||||
workspaceId: payload?.[1],
|
||||
},
|
||||
},
|
||||
contextId,
|
||||
);
|
||||
}
|
||||
|
||||
const contextInstance = await this.injector.loadPerContext(
|
||||
instance,
|
||||
host,
|
||||
host.providers,
|
||||
contextId,
|
||||
);
|
||||
|
||||
await contextInstance[methodName].call(contextInstance, ...payload);
|
||||
} else {
|
||||
await instance[methodName].call(instance, ...payload);
|
||||
}
|
||||
}
|
||||
|
||||
private registerWorkspaceQueryHook(
|
||||
key: WorkspaceQueryHookKey,
|
||||
type: WorkspaceQueryHookType,
|
||||
instance: object,
|
||||
host: Module,
|
||||
isRequestScoped: boolean,
|
||||
) {
|
||||
switch (type) {
|
||||
case WorkspaceQueryHookType.PreHook:
|
||||
this.workspaceQueryHookStorage.registerWorkspaceQueryPreHookInstance(
|
||||
key,
|
||||
{
|
||||
instance: instance as WorkspaceQueryHookInstance,
|
||||
host,
|
||||
isRequestScoped,
|
||||
},
|
||||
);
|
||||
break;
|
||||
case WorkspaceQueryHookType.PostHook:
|
||||
this.workspaceQueryHookStorage.registerWorkspaceQueryPostHookInstance(
|
||||
key,
|
||||
{
|
||||
instance: instance as WorkspaceQueryHookInstance,
|
||||
host,
|
||||
isRequestScoped,
|
||||
},
|
||||
);
|
||||
break;
|
||||
default:
|
||||
this.logger.error(`Unknown WorkspaceQueryHookType: ${type}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DiscoveryModule } from '@nestjs/core';
|
||||
|
||||
import { WorkspaceQueryHookStorage } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/storage/workspace-query-hook.storage';
|
||||
import { WorkspaceQueryHookMetadataAccessor } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook-metadata.accessor';
|
||||
import { WorkspaceQueryHookExplorer } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.explorer';
|
||||
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
|
||||
import { CalendarQueryHookModule } from 'src/modules/calendar/query-hooks/calendar-query-hook.module';
|
||||
import { ConnectedAccountQueryHookModule } from 'src/modules/connected-account/query-hooks/connected-account-query-hook.module';
|
||||
import { MessagingQueryHookModule } from 'src/modules/messaging/common/query-hooks/messaging-query-hook.module';
|
||||
import { WorkspaceMemberQueryHookModule } from 'src/modules/workspace-member/query-hooks/workspace-member-query-hook.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MessagingQueryHookModule,
|
||||
CalendarQueryHookModule,
|
||||
ConnectedAccountQueryHookModule,
|
||||
WorkspaceMemberQueryHookModule,
|
||||
DiscoveryModule,
|
||||
],
|
||||
providers: [
|
||||
WorkspaceQueryHookService,
|
||||
WorkspaceQueryHookExplorer,
|
||||
WorkspaceQueryHookMetadataAccessor,
|
||||
WorkspaceQueryHookStorage,
|
||||
],
|
||||
exports: [WorkspaceQueryHookService],
|
||||
})
|
||||
export class WorkspaceQueryHookModule {}
|
||||
@ -0,0 +1,43 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHookStorage } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/storage/workspace-query-hook.storage';
|
||||
import { WorkspaceQueryHookKey } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookExplorer } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.explorer';
|
||||
import { WorkspacePreQueryHookPayload } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceQueryHookService {
|
||||
constructor(
|
||||
private readonly workspaceQueryHookStorage: WorkspaceQueryHookStorage,
|
||||
private readonly workspaceQueryHookExplorer: WorkspaceQueryHookExplorer,
|
||||
) {}
|
||||
|
||||
public async executePreQueryHooks<
|
||||
T extends WorkspaceResolverBuilderMethodNames,
|
||||
>(
|
||||
userId: string | undefined,
|
||||
workspaceId: string,
|
||||
objectName: string,
|
||||
methodName: T,
|
||||
payload: WorkspacePreQueryHookPayload<T>,
|
||||
): Promise<void> {
|
||||
const key: WorkspaceQueryHookKey = `${objectName}.${methodName}`;
|
||||
const preHookInstances =
|
||||
this.workspaceQueryHookStorage.getWorkspaceQueryPreHookInstances(key);
|
||||
|
||||
if (!preHookInstances) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const preHookInstance of preHookInstances) {
|
||||
await this.workspaceQueryHookExplorer.handleHook(
|
||||
[userId, workspaceId, payload],
|
||||
preHookInstance.instance,
|
||||
preHookInstance.host,
|
||||
preHookInstance.isRequestScoped,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceQueryBuilderModule } from 'src/engine/api/graphql/workspace-query-builder/workspace-query-builder.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { WorkspacePreQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module';
|
||||
import { WorkspaceQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module';
|
||||
import { workspaceQueryRunnerFactories } from 'src/engine/api/graphql/workspace-query-runner/factories';
|
||||
import { AuthModule } from 'src/engine/core-modules/auth/auth.module';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
@ -20,7 +20,7 @@ import { EntityEventsToDbListener } from './listeners/entity-events-to-db.listen
|
||||
AuthModule,
|
||||
WorkspaceQueryBuilderModule,
|
||||
WorkspaceDataSourceModule,
|
||||
WorkspacePreQueryHookModule,
|
||||
WorkspaceQueryHookModule,
|
||||
ObjectMetadataRepositoryModule.forFeature([WorkspaceMemberWorkspaceEntity]),
|
||||
AnalyticsModule,
|
||||
],
|
||||
|
||||
@ -42,7 +42,7 @@ import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target
|
||||
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
||||
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
||||
import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event';
|
||||
import { WorkspacePreQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service';
|
||||
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { NotFoundError } from 'src/engine/utils/graphql-errors.util';
|
||||
import { QueryRunnerArgsFactory } from 'src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory';
|
||||
@ -75,7 +75,7 @@ export class WorkspaceQueryRunnerService {
|
||||
@InjectMessageQueue(MessageQueue.webhookQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly workspacePreQueryHookService: WorkspacePreQueryHookService,
|
||||
private readonly workspaceQueryHookService: WorkspaceQueryHookService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
) {}
|
||||
|
||||
@ -101,7 +101,7 @@ export class WorkspaceQueryRunnerService {
|
||||
options,
|
||||
);
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -148,7 +148,7 @@ export class WorkspaceQueryRunnerService {
|
||||
options,
|
||||
);
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -223,7 +223,7 @@ export class WorkspaceQueryRunnerService {
|
||||
existingRecord,
|
||||
);
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -260,7 +260,7 @@ export class WorkspaceQueryRunnerService {
|
||||
ResolverArgsType.CreateMany,
|
||||
)) as CreateManyResolverArgs<Record>;
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -333,7 +333,7 @@ export class WorkspaceQueryRunnerService {
|
||||
options,
|
||||
);
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -389,7 +389,7 @@ export class WorkspaceQueryRunnerService {
|
||||
atMost: maximumRecordAffected,
|
||||
});
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -441,7 +441,7 @@ export class WorkspaceQueryRunnerService {
|
||||
atMost: maximumRecordAffected,
|
||||
});
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
@ -509,7 +509,7 @@ export class WorkspaceQueryRunnerService {
|
||||
);
|
||||
// TODO END
|
||||
|
||||
await this.workspacePreQueryHookService.executePreHooks(
|
||||
await this.workspaceQueryHookService.executePreQueryHooks(
|
||||
userId,
|
||||
workspaceId,
|
||||
objectMetadataItem.nameSingular,
|
||||
|
||||
@ -47,10 +47,17 @@ export class PgBossDriver
|
||||
}
|
||||
: {},
|
||||
async (job) => {
|
||||
// PGBoss work with wildcard job name
|
||||
const jobName = job.name.split('.')?.[1];
|
||||
|
||||
if (!jobName) {
|
||||
throw new Error('Job name could not be splited from the job.');
|
||||
}
|
||||
|
||||
await handler({
|
||||
data: job.data,
|
||||
id: job.id,
|
||||
name: job.name.split('.')[1],
|
||||
name: jobName,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@ -14,7 +14,7 @@ export class ScopedWorkspaceDatasourceFactory {
|
||||
|
||||
public async create(entities: EntitySchema[]) {
|
||||
const workspaceId: string | undefined =
|
||||
this.request['req']?.['workspaceId'];
|
||||
this.request?.['req']?.['workspaceId'];
|
||||
|
||||
if (!workspaceId) {
|
||||
return null;
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, NotFoundException, Scope } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.workspace-entity';
|
||||
import { CanAccessCalendarEventService } from 'src/modules/calendar/query-hooks/calendar-event/services/can-access-calendar-event.service';
|
||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceQueryHook({
|
||||
key: `calendarEvent.findMany`,
|
||||
scope: Scope.REQUEST,
|
||||
})
|
||||
export class CalendarEventFindManyPreQueryHook
|
||||
implements WorkspacePreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
||||
@ -27,25 +31,24 @@ export class CalendarEventFindManyPreQueryHook
|
||||
throw new BadRequestException('id filter is required');
|
||||
}
|
||||
|
||||
// TODO: Re-implement this using twenty ORM
|
||||
// const calendarChannelCalendarEventAssociations =
|
||||
// await this.calendarChannelEventAssociationRepository.find({
|
||||
// where: {
|
||||
// calendarEvent: {
|
||||
// id: payload?.filter?.id?.eq,
|
||||
// },
|
||||
// },
|
||||
// relations: ['calendarChannel.connectedAccount'],
|
||||
// });
|
||||
const calendarChannelCalendarEventAssociations =
|
||||
await this.calendarChannelEventAssociationRepository.find({
|
||||
where: {
|
||||
calendarEvent: {
|
||||
id: payload?.filter?.id?.eq,
|
||||
},
|
||||
},
|
||||
relations: ['calendarChannel.connectedAccount'],
|
||||
});
|
||||
|
||||
// if (calendarChannelCalendarEventAssociations.length === 0) {
|
||||
// throw new NotFoundException();
|
||||
// }
|
||||
if (calendarChannelCalendarEventAssociations.length === 0) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
// await this.canAccessCalendarEventService.canAccessCalendarEvent(
|
||||
// userId,
|
||||
// workspaceId,
|
||||
// calendarChannelCalendarEventAssociations,
|
||||
// );
|
||||
await this.canAccessCalendarEventService.canAccessCalendarEvent(
|
||||
userId,
|
||||
workspaceId,
|
||||
calendarChannelCalendarEventAssociations,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,21 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, NotFoundException, Scope } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { CanAccessCalendarEventService } from 'src/modules/calendar/query-hooks/calendar-event/services/can-access-calendar-event.service';
|
||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class CalendarEventFindOnePreQueryHook implements WorkspacePreQueryHook {
|
||||
@WorkspaceQueryHook({
|
||||
key: `calendarEvent.findOne`,
|
||||
scope: Scope.REQUEST,
|
||||
})
|
||||
export class CalendarEventFindOnePreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
||||
private readonly calendarChannelEventAssociationRepository: WorkspaceRepository<CalendarChannelEventAssociationWorkspaceEntity>,
|
||||
@ -26,23 +32,24 @@ export class CalendarEventFindOnePreQueryHook implements WorkspacePreQueryHook {
|
||||
}
|
||||
|
||||
// TODO: Re-implement this using twenty ORM
|
||||
// const calendarChannelCalendarEventAssociations =
|
||||
// await this.calendarChannelEventAssociationRepository.find({
|
||||
// where: {
|
||||
// calendarEvent: {
|
||||
// id: payload?.filter?.id?.eq,
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
const calendarChannelCalendarEventAssociations =
|
||||
await this.calendarChannelEventAssociationRepository.find({
|
||||
where: {
|
||||
calendarEvent: {
|
||||
id: payload?.filter?.id?.eq,
|
||||
},
|
||||
},
|
||||
relations: ['calendarChannel.connectedAccount'],
|
||||
});
|
||||
|
||||
// if (calendarChannelCalendarEventAssociations.length === 0) {
|
||||
// throw new NotFoundException();
|
||||
// }
|
||||
if (calendarChannelCalendarEventAssociations.length === 0) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
// await this.canAccessCalendarEventService.canAccessCalendarEvent(
|
||||
// userId,
|
||||
// workspaceId,
|
||||
// calendarChannelCalendarEventAssociations,
|
||||
// );
|
||||
await this.canAccessCalendarEventService.canAccessCalendarEvent(
|
||||
userId,
|
||||
workspaceId,
|
||||
calendarChannelCalendarEventAssociations,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ export class CanAccessCalendarEventService {
|
||||
|
||||
const calendarChannelsConnectedAccounts =
|
||||
await this.connectedAccountRepository.getByIds(
|
||||
calendarChannels.map((channel) => channel.connectedAccount.id),
|
||||
calendarChannels.map((channel) => channel.connectedAccountId),
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
|
||||
@ -23,14 +23,8 @@ import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
|
||||
],
|
||||
providers: [
|
||||
CanAccessCalendarEventService,
|
||||
{
|
||||
provide: CalendarEventFindOnePreQueryHook.name,
|
||||
useClass: CalendarEventFindOnePreQueryHook,
|
||||
},
|
||||
{
|
||||
provide: CalendarEventFindManyPreQueryHook.name,
|
||||
useClass: CalendarEventFindManyPreQueryHook,
|
||||
},
|
||||
CalendarEventFindOnePreQueryHook,
|
||||
CalendarEventFindManyPreQueryHook,
|
||||
],
|
||||
})
|
||||
export class CalendarQueryHookModule {}
|
||||
|
||||
@ -237,6 +237,8 @@ export class CalendarChannelWorkspaceEntity extends BaseWorkspaceEntity {
|
||||
})
|
||||
connectedAccount: Relation<ConnectedAccountWorkspaceEntity>;
|
||||
|
||||
connectedAccountId: string;
|
||||
|
||||
@WorkspaceRelation({
|
||||
standardId:
|
||||
CALENDAR_CHANNEL_STANDARD_FIELD_IDS.calendarChannelEventAssociations,
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { CreateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import {
|
||||
BlocklistItem,
|
||||
BlocklistValidationService,
|
||||
} from 'src/modules/connected-account/services/blocklist/blocklist-validation.service';
|
||||
|
||||
@Injectable()
|
||||
export class BlocklistCreateManyPreQueryHook implements WorkspacePreQueryHook {
|
||||
@WorkspaceQueryHook(`blocklist.createMany`)
|
||||
export class BlocklistCreateManyPreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
private readonly blocklistValidationService: BlocklistValidationService,
|
||||
) {}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
import { Injectable, MethodNotAllowedException } from '@nestjs/common';
|
||||
import { MethodNotAllowedException } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
@Injectable()
|
||||
export class BlocklistUpdateManyPreQueryHook implements WorkspacePreQueryHook {
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
|
||||
@WorkspaceQueryHook(`blocklist.updateMany`)
|
||||
export class BlocklistUpdateManyPreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor() {}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { UpdateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import {
|
||||
BlocklistItem,
|
||||
BlocklistValidationService,
|
||||
} from 'src/modules/connected-account/services/blocklist/blocklist-validation.service';
|
||||
|
||||
@Injectable()
|
||||
export class BlocklistUpdateOnePreQueryHook implements WorkspacePreQueryHook {
|
||||
@WorkspaceQueryHook(`blocklist.updateOne`)
|
||||
export class BlocklistUpdateOnePreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
private readonly blocklistValidationService: BlocklistValidationService,
|
||||
) {}
|
||||
|
||||
@ -8,18 +8,9 @@ import { BlocklistValidationModule } from 'src/modules/connected-account/service
|
||||
@Module({
|
||||
imports: [BlocklistValidationModule],
|
||||
providers: [
|
||||
{
|
||||
provide: BlocklistCreateManyPreQueryHook.name,
|
||||
useClass: BlocklistCreateManyPreQueryHook,
|
||||
},
|
||||
{
|
||||
provide: BlocklistUpdateManyPreQueryHook.name,
|
||||
useClass: BlocklistUpdateManyPreQueryHook,
|
||||
},
|
||||
{
|
||||
provide: BlocklistUpdateOnePreQueryHook.name,
|
||||
useClass: BlocklistUpdateOnePreQueryHook,
|
||||
},
|
||||
BlocklistCreateManyPreQueryHook,
|
||||
BlocklistUpdateManyPreQueryHook,
|
||||
BlocklistUpdateOnePreQueryHook,
|
||||
],
|
||||
})
|
||||
export class ConnectedAccountQueryHookModule {}
|
||||
|
||||
@ -1,19 +1,16 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { BadRequestException, NotFoundException } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import { CanAccessMessageThreadService } from 'src/modules/messaging/common/query-hooks/message/can-access-message-thread.service';
|
||||
import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/common/repositories/message-channel-message-association.repository';
|
||||
import { MessageChannelMessageAssociationWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class MessageFindManyPreQueryHook implements WorkspacePreQueryHook {
|
||||
@WorkspaceQueryHook(`message.findMany`)
|
||||
export class MessageFindManyPreQueryHook implements WorkspaceQueryHookInstance {
|
||||
constructor(
|
||||
@InjectObjectMetadataRepository(
|
||||
MessageChannelMessageAssociationWorkspaceEntity,
|
||||
|
||||
@ -1,16 +1,17 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import { CanAccessMessageThreadService } from 'src/modules/messaging/common/query-hooks/message/can-access-message-thread.service';
|
||||
import { MessageChannelMessageAssociationRepository } from 'src/modules/messaging/common/repositories/message-channel-message-association.repository';
|
||||
import { MessageChannelMessageAssociationWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class MessageFindOnePreQueryHook implements WorkspacePreQueryHook {
|
||||
@WorkspaceQueryHook(`message.findOne`)
|
||||
export class MessageFindOnePreQueryHook implements WorkspaceQueryHookInstance {
|
||||
constructor(
|
||||
@InjectObjectMetadataRepository(
|
||||
MessageChannelMessageAssociationWorkspaceEntity,
|
||||
|
||||
@ -20,14 +20,8 @@ import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/stan
|
||||
],
|
||||
providers: [
|
||||
CanAccessMessageThreadService,
|
||||
{
|
||||
provide: MessageFindOnePreQueryHook.name,
|
||||
useClass: MessageFindOnePreQueryHook,
|
||||
},
|
||||
{
|
||||
provide: MessageFindManyPreQueryHook.name,
|
||||
useClass: MessageFindManyPreQueryHook,
|
||||
},
|
||||
MessageFindOnePreQueryHook,
|
||||
MessageFindManyPreQueryHook,
|
||||
],
|
||||
})
|
||||
export class MessagingQueryHookModule {}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { Injectable, MethodNotAllowedException } from '@nestjs/common';
|
||||
import { MethodNotAllowedException } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
@Injectable()
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
|
||||
@WorkspaceQueryHook(`workspaceMember.deleteMany`)
|
||||
export class WorkspaceMemberDeleteManyPreQueryHook
|
||||
implements WorkspacePreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor() {}
|
||||
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
|
||||
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceQueryHook(`workspaceMember.deleteOne`)
|
||||
export class WorkspaceMemberDeleteOnePreQueryHook
|
||||
implements WorkspacePreQueryHook
|
||||
implements WorkspaceQueryHookInstance
|
||||
{
|
||||
constructor(
|
||||
@InjectWorkspaceRepository(AttachmentWorkspaceEntity)
|
||||
|
||||
@ -14,14 +14,8 @@ import { WorkspaceMemberDeleteOnePreQueryHook } from 'src/modules/workspace-memb
|
||||
]),
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: WorkspaceMemberDeleteOnePreQueryHook.name,
|
||||
useClass: WorkspaceMemberDeleteOnePreQueryHook,
|
||||
},
|
||||
{
|
||||
provide: WorkspaceMemberDeleteManyPreQueryHook.name,
|
||||
useClass: WorkspaceMemberDeleteManyPreQueryHook,
|
||||
},
|
||||
WorkspaceMemberDeleteOnePreQueryHook,
|
||||
WorkspaceMemberDeleteManyPreQueryHook,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMemberQueryHookModule {}
|
||||
|
||||
Reference in New Issue
Block a user