import { HttpModule, HttpService } from '@nestjs/axios'; import { DynamicModule, Global, Logger, Module } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { GraphQLModule } from '@nestjs/graphql'; import { join } from 'path'; import { ENGINE_MODULE_OPTIONS, ENGINE_SERVICE } from './engine.constants'; import { EngineController } from './engine.controller'; import { IEngineOptions, IEngineService } from './engine.interfaces'; import { EngineResolver } from './engine.resolver'; @Global() @Module({}) export class EngineModule { private static readonly logger = new Logger(EngineModule.name); static async forRootAsync(options: IEngineOptions): Promise<DynamicModule> { const optionsProvider = { provide: ENGINE_MODULE_OPTIONS, useValue: options, }; const engineProvider = { provide: ENGINE_SERVICE, useFactory: async (httpService: HttpService, req: Request) => { return await this.createEngineConnection(options, httpService, req); }, inject: [HttpService, REQUEST], }; return { module: EngineModule, imports: [ HttpModule, GraphQLModule.forRoot({ autoSchemaFile: join(process.cwd(), 'src/schema.gql'), }), ], providers: [optionsProvider, engineProvider, EngineResolver], controllers: [EngineController], exports: [optionsProvider, engineProvider], }; } private static async createEngineConnection( options: IEngineOptions, httpService: HttpService, req: Request, ): Promise<IEngineService> { try { const service = await import( `./connectors/${options.type}/main.connector` ); const engine = new service.default(options, httpService, req); return engine; } catch (e) { this.logger.error( `There is a problem with the connector '${options.type}'`, ); this.logger.verbose(e); process.exit(); // We can't continue without an engine, shutdown the process... } } }