nestjs-telegraf/lib/telegraf.explorer.ts

61 lines
2.0 KiB
TypeScript
Raw Normal View History

2020-03-19 16:21:35 +03:00
import { Injectable, OnModuleInit } from '@nestjs/common';
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,
) {}
onModuleInit(): void {
2020-03-19 16:21:35 +03:00
this.explore();
}
explore(): void {
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-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
);
});
}
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 16:24:38 +03:00
private registerIfListener(
instance: Record<string, Function>,
methodKey: string,
): void {
const methodRef = instance[methodKey];
const middlewareFn = methodRef.bind(instance);
const listenerMethod = this.metadataAccessor.getListenerMethod(methodRef);
if (!listenerMethod) return;
const listenerOptions = this.metadataAccessor.getListenerOptions(methodRef);
// 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 16:21:35 +03:00
}