2020-03-19 16:21:35 +03:00
|
|
|
import { 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-26 16:11:09 +03:00
|
|
|
import { TelegrafMetadataAccessor } from './telegraf.metadata-accessor';
|
2020-03-19 16:21:35 +03:00
|
|
|
import { TelegrafProvider } from './telegraf.provider';
|
2020-12-26 16:11:09 +03:00
|
|
|
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
2020-03-19 16:21:35 +03:00
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class TelegrafExplorer implements OnModuleInit {
|
|
|
|
constructor(
|
2020-12-26 16:24:38 +03:00
|
|
|
private readonly telegraf: TelegrafProvider,
|
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-25 23:11:16 +03:00
|
|
|
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-26 23:19:30 +03:00
|
|
|
const listenerMethod = this.metadataAccessor.getListenerMethod(methodRef);
|
|
|
|
if (!listenerMethod) return;
|
2020-12-25 23:11:16 +03:00
|
|
|
|
|
|
|
const listenerOptions = this.metadataAccessor.getListenerOptions(methodRef);
|
|
|
|
|
2020-12-26 23:19:30 +03:00
|
|
|
// NOTE: Disable spread operator checking because of error: "Expected at least 1 arguments, but got 1 or more."
|
|
|
|
(this.telegraf as any)[listenerMethod](...listenerOptions, middlewareFn);
|
2020-03-19 17:25:47 +03:00
|
|
|
}
|
2020-03-19 16:21:35 +03:00
|
|
|
}
|