2020-12-29 22:41:06 +03:00
|
|
|
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
|
2020-12-26 23:19:30 +03:00
|
|
|
import { DiscoveryService } from '@nestjs/core';
|
2020-03-19 16:21:35 +03:00
|
|
|
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
2020-12-27 21:35:01 +03:00
|
|
|
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
2020-12-29 22:41:06 +03:00
|
|
|
import { Telegraf } from 'telegraf';
|
2020-12-30 01:49:09 +03:00
|
|
|
import { TelegrafMetadataAccessor } from '../telegraf.metadata-accessor';
|
2020-03-19 16:21:35 +03:00
|
|
|
|
|
|
|
@Injectable()
|
2020-12-29 22:41:06 +03:00
|
|
|
export class TelegrafUpdateExplorer implements OnModuleInit {
|
2020-03-19 16:21:35 +03:00
|
|
|
constructor(
|
2020-12-29 22:41:06 +03:00
|
|
|
@Inject(Telegraf)
|
2021-01-02 15:23:30 +03:00
|
|
|
private readonly telegraf: Telegraf<never>,
|
2020-03-19 16:21:35 +03:00
|
|
|
private readonly discoveryService: DiscoveryService,
|
|
|
|
private readonly metadataAccessor: TelegrafMetadataAccessor,
|
|
|
|
private readonly metadataScanner: MetadataScanner,
|
|
|
|
) {}
|
|
|
|
|
2020-12-25 23:11:16 +03:00
|
|
|
onModuleInit(): void {
|
2020-03-19 16:21:35 +03:00
|
|
|
this.explore();
|
|
|
|
}
|
|
|
|
|
2020-12-29 22:41:06 +03:00
|
|
|
private explore(): void {
|
2020-12-26 23:19:30 +03:00
|
|
|
const updateClasses = this.filterUpdateClasses();
|
2020-12-26 16:11:09 +03:00
|
|
|
|
2020-12-26 16:24:38 +03:00
|
|
|
updateClasses.forEach((wrapper) => {
|
2020-12-26 16:11:09 +03:00
|
|
|
const { instance } = wrapper;
|
2020-12-25 23:11:16 +03:00
|
|
|
|
2020-12-26 16:11:09 +03:00
|
|
|
const prototype = Object.getPrototypeOf(instance);
|
|
|
|
this.metadataScanner.scanFromPrototype(
|
|
|
|
instance,
|
|
|
|
prototype,
|
2020-12-26 16:24:38 +03:00
|
|
|
(methodKey: string) => this.registerIfListener(instance, methodKey),
|
2020-12-26 16:11:09 +03:00
|
|
|
);
|
|
|
|
});
|
2020-12-25 23:11:16 +03:00
|
|
|
}
|
|
|
|
|
2020-12-26 23:19:30 +03:00
|
|
|
private filterUpdateClasses(): InstanceWrapper[] {
|
2020-12-26 16:11:09 +03:00
|
|
|
return this.discoveryService
|
|
|
|
.getProviders()
|
|
|
|
.filter((wrapper) => wrapper.instance)
|
2020-12-26 16:24:38 +03:00
|
|
|
.filter((wrapper) =>
|
|
|
|
this.metadataAccessor.isUpdate(wrapper.instance.constructor),
|
|
|
|
);
|
2020-12-26 14:54:10 +03:00
|
|
|
}
|
|
|
|
|
2020-12-26 16:24:38 +03:00
|
|
|
private registerIfListener(
|
2020-12-25 23:11:16 +03:00
|
|
|
instance: Record<string, Function>,
|
|
|
|
methodKey: string,
|
|
|
|
): void {
|
|
|
|
const methodRef = instance[methodKey];
|
|
|
|
const middlewareFn = methodRef.bind(instance);
|
|
|
|
|
2020-12-27 21:35:01 +03:00
|
|
|
const listenerMetadata = this.metadataAccessor.getListenerMetadata(
|
|
|
|
methodRef,
|
|
|
|
);
|
|
|
|
if (!listenerMetadata) return;
|
|
|
|
|
|
|
|
const { method, args } = listenerMetadata;
|
2020-12-29 22:41:06 +03:00
|
|
|
// NOTE: Use "any" to disable "Expected at least 1 arguments, but got 1 or more." error.
|
|
|
|
// Use telegraf instance for non-scene listeners
|
|
|
|
(this.telegraf[method] as any)(...args, middlewareFn);
|
2020-03-19 17:25:47 +03:00
|
|
|
}
|
2020-03-19 16:21:35 +03:00
|
|
|
}
|