feat: add GlobalUpdate decorator (#2)

This commit is contained in:
Maxim Slipenko 2023-07-23 15:38:05 +03:00 committed by GitHub
parent 7f43458c55
commit dca35a0c7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 2 deletions

View File

@ -0,0 +1,9 @@
import { SetMetadata } from '@nestjs/common';
import { GLOBAL_UPDATE_METADATA } from '../../telegraf.constants';
/**
* `@GlobalUpdate` decorator, it's like `@Update` decorator,
* but processed before the scenes
*/
export const GlobalUpdate = (): ClassDecorator =>
SetMetadata(GLOBAL_UPDATE_METADATA, true);

View File

@ -1,4 +1,5 @@
export * from './update.decorator'; export * from './update.decorator';
export * from './global-update.decorator';
export * from './scene.decorator'; export * from './scene.decorator';
export * from './wizard.decorator'; export * from './wizard.decorator';
export * from './inject-bot.decorator'; export * from './inject-bot.decorator';

View File

@ -48,8 +48,6 @@ export class ListenersExplorerService
this.bot = this.moduleRef.get<Telegraf<any>>(this.botName, { this.bot = this.moduleRef.get<Telegraf<any>>(this.botName, {
strict: false, strict: false,
}); });
this.bot.use(this.stage.middleware());
this.explore(); this.explore();
} }
@ -59,10 +57,23 @@ export class ListenersExplorerService
this.telegrafOptions.include || [], this.telegrafOptions.include || [],
); );
this.registerGlobalUpdates(modules);
this.bot.use(this.stage.middleware());
this.registerUpdates(modules); this.registerUpdates(modules);
this.registerScenes(modules); this.registerScenes(modules);
} }
private registerGlobalUpdates(modules: Module[]): void {
const globalUpdates = this.flatMap<InstanceWrapper>(modules, (instance) =>
this.filterGlobalUpdates(instance),
);
globalUpdates.forEach((wrapper) =>
this.registerListeners(this.bot, wrapper),
);
}
private registerUpdates(modules: Module[]): void { private registerUpdates(modules: Module[]): void {
const updates = this.flatMap<InstanceWrapper>(modules, (instance) => const updates = this.flatMap<InstanceWrapper>(modules, (instance) =>
this.filterUpdates(instance), this.filterUpdates(instance),
@ -92,6 +103,20 @@ export class ListenersExplorerService
}); });
} }
private filterGlobalUpdates(
wrapper: InstanceWrapper,
): InstanceWrapper<unknown> {
const { instance } = wrapper;
if (!instance) return undefined;
const isGlobalUpdate = this.metadataAccessor.isGlobalUpdate(
wrapper.metatype,
);
if (!isGlobalUpdate) return undefined;
return wrapper;
}
private filterUpdates(wrapper: InstanceWrapper): InstanceWrapper<unknown> { private filterUpdates(wrapper: InstanceWrapper): InstanceWrapper<unknown> {
const { instance } = wrapper; const { instance } = wrapper;
if (!instance) return undefined; if (!instance) return undefined;

View File

@ -3,6 +3,7 @@ import { Reflector } from '@nestjs/core';
import { import {
SCENE_METADATA, SCENE_METADATA,
LISTENERS_METADATA, LISTENERS_METADATA,
GLOBAL_UPDATE_METADATA,
UPDATE_METADATA, UPDATE_METADATA,
WIZARD_STEP_METADATA, WIZARD_STEP_METADATA,
} from '../telegraf.constants'; } from '../telegraf.constants';
@ -16,6 +17,11 @@ import {
export class MetadataAccessorService { export class MetadataAccessorService {
constructor(private readonly reflector: Reflector) {} constructor(private readonly reflector: Reflector) {}
isGlobalUpdate(target: Function): boolean {
if (!target) return false;
return !!this.reflector.get(GLOBAL_UPDATE_METADATA, target);
}
isUpdate(target: Function): boolean { isUpdate(target: Function): boolean {
if (!target) return false; if (!target) return false;
return !!this.reflector.get(UPDATE_METADATA, target); return !!this.reflector.get(UPDATE_METADATA, target);

View File

@ -5,6 +5,7 @@ export const TELEGRAF_BOT_NAME = 'TELEGRAF_BOT_NAME';
export const DEFAULT_BOT_NAME = 'DEFAULT_BOT_NAME'; export const DEFAULT_BOT_NAME = 'DEFAULT_BOT_NAME';
export const UPDATE_METADATA = 'UPDATE_METADATA'; export const UPDATE_METADATA = 'UPDATE_METADATA';
export const GLOBAL_UPDATE_METADATA = 'GLOBAL_UPDATE_METADATA';
export const SCENE_METADATA = 'SCENE_METADATA'; export const SCENE_METADATA = 'SCENE_METADATA';
export const LISTENERS_METADATA = 'LISTENERS_METADATA'; export const LISTENERS_METADATA = 'LISTENERS_METADATA';
export const WIZARD_STEP_METADATA = 'WIZARD_STEP_METADATA'; export const WIZARD_STEP_METADATA = 'WIZARD_STEP_METADATA';