-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]>
- Loading branch information
Showing
32 changed files
with
472 additions
and
235 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 0 additions & 31 deletions
31
...raphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config.ts
This file was deleted.
Oops, something went wrong.
19 changes: 0 additions & 19 deletions
19
...raphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module.ts
This file was deleted.
Oops, something went wrong.
34 changes: 0 additions & 34 deletions
34
...aphql/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service.ts
This file was deleted.
Oops, something went wrong.
40 changes: 40 additions & 0 deletions
40
.../workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}; | ||
} |
2 changes: 1 addition & 1 deletion
2
...ces/workspace-pre-query-hook.interface.ts → ...erfaces/workspace-query-hook.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
...aphql/workspace-query-runner/workspace-query-hook/storage/workspace-query-hook.storage.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
...hql/workspace-query-runner/workspace-query-hook/workspace-query-hook-metadata.accessor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
...api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const WORKSPACE_QUERY_HOOK_METADATA = Symbol( | ||
'workspace-query-hook:query-hook-metadata', | ||
); |
Oops, something went wrong.