import type { DynamicModule, NestModule } from '@nestjs/common'; import { Inject } from '@nestjs/common'; import type { MiddlewareConsumer } from '@nestjs/common/interfaces'; import { AsyncContextModule } from '@rsdk/actx'; import type { Constructor } from '@rsdk/common'; import { PlatformPluginModule } from './plugin/plugin.module'; import { PlatformTransportModule } from './transport/transport.module'; import { AppMetadataModule } from './app-metadata'; import { PlatformConfigModule } from './config'; import { LoggerInitializingModule } from './logging'; import { TracingModule } from './tracing'; import type { PlatformAppPlugin, PlatformExtendedOptions } from './types'; import { APP_PLUGINS, APP_TRANSPORTS } from './types'; export class PlatformModule implements NestModule { constructor(@Inject(APP_PLUGINS) private plugins: Set) {} static forRoot(options: PlatformExtendedOptions): DynamicModule { const imports: (DynamicModule | Constructor)[] = [ /** * Последовательность принципиально важна так как в этом модуле происходит * инициализация глобального асинхронного контекста (AsyncLocalStorage) */ AsyncContextModule, TracingModule.forRoot(options), // Plugins PlatformPluginModule.forOptions(options), // Infrastructure AppMetadataModule.forRoot(options), PlatformConfigModule.forRoot(options), LoggerInitializingModule, ...(options.modules ?? []), PlatformTransportModule.forOptions(options), ]; const providers = [ { provide: APP_PLUGINS, useValue: new Set(options.plugins), }, { provide: APP_TRANSPORTS, useValue: new Set(options.transports), }, ]; return { module: PlatformModule, imports, global: true, providers, exports: providers, }; } configure(consumer: MiddlewareConsumer): void { for (const plugin of this.plugins) { plugin?.configureMiddleware?.(consumer); } } }