fix(api): enhance event typing

This commit is contained in:
yassinedorbozgithub 2024-10-19 07:10:59 +01:00
parent 08b1deae50
commit 3c14ddd76a
2 changed files with 94 additions and 69 deletions

View File

@ -17,7 +17,7 @@ import { WebsocketGateway } from '@/websocket/websocket.gateway';
import { MessageCreateDto } from '../dto/message.dto'; import { MessageCreateDto } from '../dto/message.dto';
import { Conversation } from '../schemas/conversation.schema'; import { Conversation } from '../schemas/conversation.schema';
import { Subscriber } from '../schemas/subscriber.schema'; import { SubscriberDocument } from '../schemas/subscriber.schema';
import { OutgoingMessage } from '../schemas/types/message'; import { OutgoingMessage } from '../schemas/types/message';
import { BotService } from './bot.service'; import { BotService } from './bot.service';
@ -289,7 +289,8 @@ export class ChatService {
* @param subscriber - The end user (subscriber) * @param subscriber - The end user (subscriber)
*/ */
@OnEvent('hook:subscriber:postCreate') @OnEvent('hook:subscriber:postCreate')
onSubscriberCreate(subscriber: Subscriber) { async onSubscriberCreate({ _id }: SubscriberDocument) {
const subscriber = await this.subscriberService.findOne(_id);
this.websocketGateway.broadcastSubscriberNew(subscriber); this.websocketGateway.broadcastSubscriberNew(subscriber);
} }
@ -299,7 +300,8 @@ export class ChatService {
* @param subscriber - The end user (subscriber) * @param subscriber - The end user (subscriber)
*/ */
@OnEvent('hook:subscriber:postUpdate') @OnEvent('hook:subscriber:postUpdate')
onSubscriberUpdate(subscriber: Subscriber) { async onSubscriberUpdate({ _id }: SubscriberDocument) {
const subscriber = await this.subscriberService.findOne(_id);
this.websocketGateway.broadcastSubscriberUpdate(subscriber); this.websocketGateway.broadcastSubscriberUpdate(subscriber);
} }
} }

View File

@ -1,11 +1,17 @@
import { type OnEventOptions } from '@nestjs/event-emitter/dist/interfaces'; import { type OnEventOptions } from '@nestjs/event-emitter/dist/interfaces';
import type { Document, HydratedDocument, Query, TFilterQuery } from 'mongoose'; import type { Listener, OnOptions } from 'eventemitter2';
import type {
Document,
Query,
TFilterQuery,
THydratedDocument,
} from 'mongoose';
import { type Socket } from 'socket.io'; import { type Socket } from 'socket.io';
import { type BotStats } from '@/analytics/schemas/bot-stats.schema'; import { type BotStats } from '@/analytics/schemas/bot-stats.schema';
import { type Attachment } from '@/attachment/schemas/attachment.schema'; import { type Attachment } from '@/attachment/schemas/attachment.schema';
import type EventWrapper from '@/channel/lib/EventWrapper'; import type EventWrapper from '@/channel/lib/EventWrapper';
import { BlockFull, type Block } from '@/chat/schemas/block.schema'; import type { Block, BlockFull } from '@/chat/schemas/block.schema';
import { type Category } from '@/chat/schemas/category.schema'; import { type Category } from '@/chat/schemas/category.schema';
import { type ContextVar } from '@/chat/schemas/context-var.schema'; import { type ContextVar } from '@/chat/schemas/context-var.schema';
import { type Conversation } from '@/chat/schemas/conversation.schema'; import { type Conversation } from '@/chat/schemas/conversation.schema';
@ -23,9 +29,9 @@ import type {
} from '@/nlp/schemas/nlp-entity.schema'; } from '@/nlp/schemas/nlp-entity.schema';
import { type NlpSampleEntity } from '@/nlp/schemas/nlp-sample-entity.schema'; import { type NlpSampleEntity } from '@/nlp/schemas/nlp-sample-entity.schema';
import { type NlpSample } from '@/nlp/schemas/nlp-sample.schema'; import { type NlpSample } from '@/nlp/schemas/nlp-sample.schema';
import type { import {
NlpValue,
NlpValueDocument, NlpValueDocument,
type NlpValue,
} from '@/nlp/schemas/nlp-value.schema'; } from '@/nlp/schemas/nlp-value.schema';
import { type Setting } from '@/setting/schemas/setting.schema'; import { type Setting } from '@/setting/schemas/setting.schema';
import type { CheckboxSetting, TextSetting } from '@/setting/schemas/types'; import type { CheckboxSetting, TextSetting } from '@/setting/schemas/types';
@ -181,10 +187,10 @@ declare module '@nestjs/event-emitter' {
type EventNamespaces = keyof IHookEntityOperationMap; type EventNamespaces = keyof IHookEntityOperationMap;
/* pre hooks */ /* pre hooks */
type TPreValidate<T> = HydratedDocument<T>; type TPreValidate<T> = THydratedDocument<T>;
type TPreCreate<T> = HydratedDocument<T>; type TPreCreate<T> = THydratedDocument<T>;
type TPreUpdate<T> = TFilterQuery<T> & object; type TPreUpdate<T> = TFilterQuery<T> & object;
type TPreDelete = Query< type TPreDelete<T> = Query<
DeleteResult, DeleteResult,
Document<T>, Document<T>,
unknown, unknown,
@ -196,12 +202,12 @@ declare module '@nestjs/event-emitter' {
| TPreValidate<T> | TPreValidate<T>
| TPreCreate<T> | TPreCreate<T>
| TPreUpdate<T> | TPreUpdate<T>
| TPreDelete; | TPreDelete<T>;
/* post hooks */ /* post hooks */
type TPostValidate<T> = HydratedDocument<T>; type TPostValidate<T> = THydratedDocument<T>;
type TPostCreate<T> = HydratedDocument<T>; type TPostCreate<T> = THydratedDocument<T>;
type TPostUpdate<T> = HydratedDocument<T>; type TPostUpdate<T> = THydratedDocument<T>;
type TPostDelete = DeleteResult; type TPostDelete = DeleteResult;
type TPostUnion<T> = type TPostUnion<T> =
| TPostValidate<T> | TPostValidate<T>
@ -209,16 +215,14 @@ declare module '@nestjs/event-emitter' {
| TPostUpdate<T> | TPostUpdate<T>
| TPostDelete; | TPostDelete;
/* union hooks */ type TCustomOperations<E extends keyof IHookEntityOperationMap> =
type TUnion<G, E> = E extends keyof IHookOperationMap IHookEntityOperationMap[E]['operations'][keyof IHookEntityOperationMap[E]['operations']];
? IHookEntityOperationMap[E]['operations'][keyof IHookEntityOperationMap[E]['operations']]
:
| TPreUnion<G>
| TPostUnion<G>
| IHookEntityOperationMap[E]['operations'][keyof IHookEntityOperationMap[E]['operations']];
type THookSplitter<H> = H extends `hook:${infer E}:${infer O}` /* union hooks */
? [E, O] type TUnion<G, E> = E extends keyof IHookEntityOperationMap
? E extends keyof IHookOperationMap
? TCustomOperations<E>
: TPreUnion<G> | TPostUnion<G> | TCustomOperations<E>
: never; : never;
/* Normalized hook */ /* Normalized hook */
@ -235,45 +239,60 @@ declare module '@nestjs/event-emitter' {
type TPreHook = TCompatibleHook<EHookPrefix.pre>; type TPreHook = TCompatibleHook<EHookPrefix.pre>;
type TPostHook = TCompatibleHook<EHookPrefix.post>; type TPostHook = TCompatibleHook<EHookPrefix.post>;
type hookTypes<O = never> = O extends keyof IHookOperationMap type TNormalizedEvents = '*' | TPreHook | TPostHook;
? '*'
: '*' | TPreHook | TPostHook;
type TNormalizedPreHook<E, O> = O extends `${EHook.preValidate}` type TNormalizedHooks<
? TPreValidate<IHookEntityOperationMap[E]['schema']> E extends keyof IHookEntityOperationMap,
: O extends `${EHook.preCreate}` T = IHookEntityOperationMap[E]['schema'],
? TPreCreate<IHookEntityOperationMap[E]['schema']> > =
: O extends `${EHook.preUpdate}` | {
? TPreUpdate<IHookEntityOperationMap[E]['schema']> [EHook.preValidate]: TPreValidate<T>;
: O extends `${EHook.preDelete}` }
? TPreDelete | {
: never; [EHook.preCreate]: TPreCreate<T>;
type TNormalizedPostHook<E, O> = O extends `${EHook.postValidate}` }
? TPostValidate<IHookEntityOperationMap[E]['schema']> | {
: O extends `${EHook.postCreate}` [EHook.preUpdate]: TPostUpdate<T>;
? TPostCreate<IHookEntityOperationMap[E]['schema']> }
: O extends `${EHook.postUpdate}` | {
? TPostUpdate<IHookEntityOperationMap[E]['schema']> [EHook.preDelete]: TPreDelete<T>;
: O extends `${EHook.postDelete}` }
? TPostDelete | {
: never; [EHook.postValidate]: TPostValidate<T>;
type TNormalizedHook<E, O> = TNormalizedPreHook<E, O> & }
TNormalizedPostHook<E, O>; | {
[EHook.postCreate]: TPostCreate<T>;
}
| {
[EHook.postUpdate]: TPostUpdate<T>;
}
| {
[EHook.postDelete]: TPostDelete;
};
type TNormalizedHook<E extends keyof IHookEntityOperationMap, O> = Extract<
TNormalizedHooks<E>,
{ [key in O]: unknown }
>[O];
/* Extended hook */ /* Extended hook */
type TExtendedHook<E, O> = IHookEntityOperationMap[E]['operations'][O]; type TExtendedHook<
E extends keyof IHookEntityOperationMap,
O extends keyof IHookEntityOperationMap[E]['operations'],
> = IHookEntityOperationMap[E]['operations'][O];
type EventValueOf< type EventValueOf<G> = G extends `hook:${infer E}:${infer O}`
G, ? O extends '*'
E = THookSplitter<G>[0],
O = THookSplitter<G>[1],
> = O extends '*'
? TUnion<G, E> ? TUnion<G, E>
: O extends hookTypes : E extends keyof IHookEntityOperationMap
? TNormalizedHook<E, O> ? O extends keyof IHookEntityOperationMap[E]['operations']
: TExtendedHook<E, O>; ? TExtendedHook<E, O>
: TNormalizedHook<E, O>
: never
: never;
type IsHookEvent<G extends EventNamespaces> = G extends EventNamespaces type IsHookEvent<G extends EventNamespaces | ConstrainedString> =
G extends EventNamespaces
? true ? true
: G extends `hook:${infer N}:${string}` : G extends `hook:${infer N}:${string}`
? N extends keyof IHookEntityOperationMap ? N extends keyof IHookEntityOperationMap
@ -281,10 +300,14 @@ declare module '@nestjs/event-emitter' {
: false : false
: false; : false;
type customEvent<G extends EventNamespaces> = G extends EventNamespaces type TCustomEvents<G extends keyof IHookEntityOperationMap> =
keyof IHookEntityOperationMap[G]['operations'] & string;
type customEvent<G extends EventNamespaces | ConstrainedString> =
G extends EventNamespaces
? G extends `hook:${string}` ? G extends `hook:${string}`
? G ? G
: `hook:${G}:${hookTypes<G> | keyof IHookEntityOperationMap[G]['operations']}` : `hook:${G}:${TNormalizedEvents | TCustomEvents<G>}`
: never; : never;
export interface ListenerFn<G extends EventNamespaces | ConstrainedString> { export interface ListenerFn<G extends EventNamespaces | ConstrainedString> {