UNPKG

@glandjs/core

Version:

Glands is a web framework for Node.js (@core)

114 lines (113 loc) 4.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DependenciesScanner = void 0; const common_1 = require("@glandjs/common"); const container_1 = require("../container"); class DependenciesScanner { constructor(logger) { this.container = new container_1.Container(logger); this.logger = logger?.child('Scanner'); } get modules() { return this.container.modules; } async scan(rootModule) { this.logger?.debug('Starting full module scan'); await this.scanForModules(rootModule); this.logger?.debug('Completed scanning module structure, scanning dependencies'); await this.scanModulesForDependencies(); this.logger?.debug('- Done.'); } async scanForModules(rootModule) { const moduleRef = await this.container.register(rootModule); this.logger?.debug(`Registered module: ${moduleRef.token}`); this.modules.set(moduleRef.token, moduleRef); for (const importedModule of moduleRef.imports) { if (!this.modules.has(importedModule.token)) { this.modules.set(importedModule.token, importedModule); const moduleType = this.getModuleByToken(importedModule.token); if (moduleType) { await this.scanForModules(moduleType); } } } } async scanModulesForDependencies() { for (const [_, moduleRef] of this.modules.entries()) { await this.scanModuleDependencies(moduleRef); } } async scanModuleDependencies(moduleRef) { const token = moduleRef.token; const moduleType = this.getModuleByToken(token); if (!moduleType) { throw new Error(`Could not find module type for token: ${token}`); } const metadata = this.extractModuleMetadata(moduleType); this.logger?.debug(`Scanning dependencies for module: ${token}`); if (metadata.imports && metadata.imports.length > 0) { this.logger?.debug(` - Imports found: ${metadata.imports.length}`); await this.scanModuleImports(metadata.imports, moduleRef); } if (metadata.controllers && metadata.controllers.length > 0) { this.logger?.debug(` - Controllers found: ${metadata.controllers.map((c) => c.name).join(', ')}`); this.scanControllers(metadata.controllers, moduleRef); } if (metadata.channels && metadata.channels.length > 0) { this.logger?.debug(` - Channels found: ${metadata.channels.map((c) => c.name).join(', ')}`); this.scanChannels(metadata.channels, moduleRef); } } getModuleByToken(token) { const moduleRef = this.modules.getByToken(token); return moduleRef ? moduleRef.metatype : undefined; } extractModuleMetadata(moduleType) { return (Reflect.getMetadata(common_1.MODULE_METADATA, moduleType) ?? { imports: [], controllers: [], channels: [], }); } async getModuleType(moduleDefinition) { if ((0, common_1.isDynamicModule)(moduleDefinition)) { return moduleDefinition.module; } if (moduleDefinition instanceof Promise) { const resolvedModule = await moduleDefinition; return (0, common_1.isDynamicModule)(resolvedModule) ? resolvedModule.module : resolvedModule; } return moduleDefinition; } async getModuleToken(moduleDefinition) { const moduleType = await this.getModuleType(moduleDefinition); return moduleType.name; } async scanModuleImports(imports, moduleRef) { for (const importedModule of imports) { const token = await this.getModuleToken(importedModule); const importedRef = this.modules.getByToken(token); if (importedRef) { moduleRef.addImports([importedRef]); } else { this.logger?.warn(`Could not find imported module with token: ${token}`); } } } scanControllers(controllers, moduleRef) { controllers.forEach((controller) => { const instance = this.container.resolve(controller); moduleRef.addController(controller, instance); this.logger?.debug(`Added controller: ${controller.name} to module: ${moduleRef.token}`); }); } scanChannels(channels, moduleRef) { channels.forEach((channel) => { const instance = this.container.resolve(channel); moduleRef.addChannel(channel, instance); this.logger?.debug(`Added channel: ${channel.name} to module: ${moduleRef.token}`); }); } } exports.DependenciesScanner = DependenciesScanner;