From a4cb8df4340845faa008ab12d1c910e42dda0a09 Mon Sep 17 00:00:00 2001 From: "xTCry [Vladislav Kh]" Date: Sun, 1 Aug 2021 07:31:09 +0300 Subject: [PATCH] feat(listeners): support for chaining method listeners --- lib/services/listeners-explorer.service.ts | 35 +++++++++++---------- lib/services/metadata-accessor.service.ts | 6 ++-- lib/telegraf.constants.ts | 2 +- lib/utils/create-listener-decorator.util.ts | 26 ++++++++++----- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/lib/services/listeners-explorer.service.ts b/lib/services/listeners-explorer.service.ts index 6a5dbc8..e4c145e 100644 --- a/lib/services/listeners-explorer.service.ts +++ b/lib/services/listeners-explorer.service.ts @@ -22,7 +22,8 @@ import { TelegrafModuleOptions } from '../interfaces'; @Injectable() export class ListenersExplorerService extends BaseExplorerService - implements OnModuleInit { + implements OnModuleInit +{ private readonly telegrafParamsFactory = new TelegrafParamsFactory(); private bot: Telegraf; @@ -123,7 +124,7 @@ export class ListenersExplorerService ): void { const methodRef = prototype[methodName]; const metadata = this.metadataAccessor.getListenerMetadata(methodRef); - if (!metadata) { + if (!metadata || metadata.length < 1) { return undefined; } @@ -133,22 +134,22 @@ export class ListenersExplorerService methodName, ); - const { method, args } = metadata; + for (const { method, args } of metadata) { + /* Basic callback */ + // composer[method](...args, listenerCallbackFn); - /* Basic callback */ - // composer[method](...args, listenerCallbackFn); - - /* Complex callback return value handing */ - composer[method]( - ...args, - async (ctx: Context, next: Function): Promise => { - const result = await listenerCallbackFn(ctx, next); - if (result) { - await ctx.reply(String(result)); - } - // TODO-Possible-Feature: Add more supported return types - }, - ); + /* Complex callback return value handing */ + composer[method]( + ...args, + async (ctx: Context, next: Function): Promise => { + const result = await listenerCallbackFn(ctx, next); + if (result) { + await ctx.reply(String(result)); + } + // TODO-Possible-Feature: Add more supported return types + }, + ); + } } createContextCallback>( diff --git a/lib/services/metadata-accessor.service.ts b/lib/services/metadata-accessor.service.ts index 75fb79c..2e5b343 100644 --- a/lib/services/metadata-accessor.service.ts +++ b/lib/services/metadata-accessor.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { SCENE_METADATA, - LISTENER_METADATA, + LISTENERS_METADATA, UPDATE_METADATA, } from '../telegraf.constants'; import { ListenerMetadata } from '../interfaces'; @@ -21,8 +21,8 @@ export class MetadataAccessorService { return !!this.reflector.get(SCENE_METADATA, target); } - getListenerMetadata(target: Function): ListenerMetadata | undefined { - return this.reflector.get(LISTENER_METADATA, target); + getListenerMetadata(target: Function): ListenerMetadata[] | undefined { + return this.reflector.get(LISTENERS_METADATA, target); } getSceneMetadata(target: Function): string | undefined { diff --git a/lib/telegraf.constants.ts b/lib/telegraf.constants.ts index 56e78f2..70c6a90 100644 --- a/lib/telegraf.constants.ts +++ b/lib/telegraf.constants.ts @@ -6,7 +6,7 @@ export const DEFAULT_BOT_NAME = 'DEFAULT_BOT_NAME'; export const UPDATE_METADATA = 'UPDATE_METADATA'; export const SCENE_METADATA = 'SCENE_METADATA'; -export const LISTENER_METADATA = 'LISTENER_METADATA'; +export const LISTENERS_METADATA = 'LISTENERS_METADATA'; export const PARAM_ARGS_METADATA = ROUTE_ARGS_METADATA; diff --git a/lib/utils/create-listener-decorator.util.ts b/lib/utils/create-listener-decorator.util.ts index c423ff3..1b3cb9a 100644 --- a/lib/utils/create-listener-decorator.util.ts +++ b/lib/utils/create-listener-decorator.util.ts @@ -1,17 +1,29 @@ -import { SetMetadata } from '@nestjs/common'; import { Composer } from 'telegraf'; import { ComposerMethodArgs, OnlyFunctionPropertyNames } from '../types'; -import { LISTENER_METADATA } from '../telegraf.constants'; +import { LISTENERS_METADATA } from '../telegraf.constants'; import { ListenerMetadata } from '../interfaces'; export function createListenerDecorator< TComposer extends Composer, - TMethod extends OnlyFunctionPropertyNames = OnlyFunctionPropertyNames + TMethod extends OnlyFunctionPropertyNames = OnlyFunctionPropertyNames, >(method: TMethod) { return (...args: ComposerMethodArgs): MethodDecorator => { - return SetMetadata(LISTENER_METADATA, { - method, - args, - } as ListenerMetadata); + return ( + _target: any, + _key?: string | symbol, + descriptor?: TypedPropertyDescriptor, + ) => { + const metadata = [ + { + method, + args, + } as ListenerMetadata, + ]; + + const previousValue = Reflect.getMetadata(LISTENERS_METADATA, descriptor.value) || []; + const value = [...previousValue, ...metadata]; + Reflect.defineMetadata(LISTENERS_METADATA, value, descriptor.value); + return descriptor; + }; }; }