import type { DynamicModule } from '@nestjs/common'; import { RsdkMetadataProvider } from '@rsdk/metadata'; import { ConfigContextModule } from './config/context/module'; import { ConfigMetadataExtractor } from './rsdk-metadata/config-metadata.extractor'; import { RsdkMetadataGlobalModule } from './rsdk-metadata/rsdk-metadata.global-module'; import type { ContextAggregated } from './types/context-aggregated'; import { ConfigContext } from './config'; import type { PlatformContext } from './platform.context'; import { PlatformModule } from './platform.module'; export class ContextAggregator { private _aggregated?: ContextAggregated; constructor(private platformContext: PlatformContext) {} /** * Прежде всего этот метод предназачен для единой точки конфигурации трех главных компонентов от которых зависит работа приложения * RsdkMetadataProvider - хранит и предоставляет информацию о метаданных дерева модулей для приложения * ConfigContext - его существование конкретно здесь обусловлено единственной проблемой, хранит информацию о том как приложение должно/может быть сконфигурировано * root - Собственно рут модуль для создания DI * * И RsdkMetadataProvider, и ConfigContext должны быть внутри DI, они там собственно и будут. Но так как Nestjs считает иначе, а именно не даёт создать контекст приложения отдельно от транспорта... Кушаем кактус... */ async getAggregated(): Promise { if (this._aggregated) { return this._aggregated; } const platformRoot = PlatformModule.forRoot( this.platformContext.extendedOptions, ); const extractors = [ new ConfigMetadataExtractor(), ...(this.platformContext.options.plugins?.flatMap?.( (p) => p.extractors?.() ?? [], ) ?? []), ]; const rsdkMetadataProvider = await RsdkMetadataProvider.create( [platformRoot], extractors, ); const rsdkMetadataGlobalModule = await RsdkMetadataGlobalModule.fromProvider(rsdkMetadataProvider); await rsdkMetadataProvider.addResources( [rsdkMetadataGlobalModule], extractors, ); const configContext = new ConfigContext(rsdkMetadataProvider, { ...this.platformContext.options.config, appName: this.platformContext.extendedOptions.name, }); const root = { imports: [ platformRoot, rsdkMetadataGlobalModule, ConfigContextModule.forRoot(configContext), ], module: ContextAggregator, }; this._aggregated = { root, rsdkMetadataProvider, configContext }; return this._aggregated; } /** * Просто алиас чтобы везде не писать такую конструкцию */ async getConfigContext(): Promise { // eslint-disable-next-line unicorn/no-await-expression-member return (await this.getAggregated()).configContext; } async getRsdkMetadataProvider(): Promise { const aggregated = await this.getAggregated(); return aggregated.rsdkMetadataProvider; } async getRoot(): Promise { const { root } = await this.getAggregated(); return root; } }