import { Module, DynamicModule, Provider, Type } from '@nestjs/common'; import { TelegrafModuleOptions, TelegrafModuleAsyncOptions, TelegrafOptionsFactory, } from './interfaces'; import { TELEGRAF_MODULE_OPTIONS, TELEGRAF_PROVIDER, } from './telegraf.constants'; import { TelegrafMetadataAccessor } from './telegraf-metadata.accessor'; import { TelegrafExplorer } from './telegraf.explorer'; import { DiscoveryModule } from '@nestjs/core'; import { TelegrafProvider } from './telegraf.provider'; @Module({ imports: [DiscoveryModule], providers: [TelegrafMetadataAccessor, TelegrafExplorer], }) export class TelegrafCoreModule { public static forRoot(options: TelegrafModuleOptions): DynamicModule { const telegrafProvider = { provide: TELEGRAF_PROVIDER, useClass: TelegrafProvider, inject: [TELEGRAF_MODULE_OPTIONS], }; return { module: TelegrafCoreModule, providers: [ { provide: TELEGRAF_MODULE_OPTIONS, useValue: options }, telegrafProvider, ], exports: [telegrafProvider], }; } public static forRootAsync( options: TelegrafModuleAsyncOptions, ): DynamicModule { const telegrafProvider = { provide: TELEGRAF_PROVIDER, useClass: TelegrafProvider, inject: [TELEGRAF_MODULE_OPTIONS], }; const asyncProviders = this.createAsyncProviders(options); return { module: TelegrafCoreModule, imports: options.imports, providers: [...asyncProviders, telegrafProvider], exports: [telegrafProvider], }; } private static createAsyncProviders( options: TelegrafModuleAsyncOptions, ): Provider[] { if (options.useExisting || options.useFactory) { return [this.createAsyncOptionsProvider(options)]; } const useClass = options.useClass as Type; return [ this.createAsyncOptionsProvider(options), { provide: useClass, useClass, }, ]; } private static createAsyncOptionsProvider( options: TelegrafModuleAsyncOptions, ): Provider { if (options.useFactory) { return { provide: TELEGRAF_MODULE_OPTIONS, useFactory: options.useFactory, inject: options.inject || [], }; } // `as Type` is a workaround for microsoft/TypeScript#31603 const inject = [ (options.useClass || options.useExisting) as Type, ]; return { provide: TELEGRAF_MODULE_OPTIONS, useFactory: async (optionsFactory: TelegrafOptionsFactory) => await optionsFactory.createTelegrafOptions(), inject, }; } }