UNPKG

@notjustcoders/ioc-arise

Version:

Arise type-safe IoC containers from your code. Zero overhead, zero coupling.

78 lines 4.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModularContainerGenerator = void 0; const dependency_resolver_1 = require("../../analyser/dependency-resolver"); const base_container_generator_1 = require("../base-container-generator"); const split_file_writer_1 = require("./split-file-writer"); const index_js_1 = require("../../errors/index.js"); /** * Generator for modular container structure. * Handles module-based dependency injection with inter-module dependencies. */ class ModularContainerGenerator extends base_container_generator_1.BaseContainerGenerator { constructor(fileWriter, moduleGroupedClasses, moduleDependencyResolver, importGenerator, moduleContainerFunctionGenerator, moduleInstantiationGenerator, containerAggregator) { super(fileWriter, importGenerator); this.moduleGroupedClasses = moduleGroupedClasses; this.moduleDependencyResolver = moduleDependencyResolver; this.moduleContainerFunctionGenerator = moduleContainerFunctionGenerator; this.moduleInstantiationGenerator = moduleInstantiationGenerator; this.containerAggregator = containerAggregator; } generate() { // First, check for module-level cycles const moduleResult = this.moduleDependencyResolver.resolve(); if (moduleResult.cycles.length > 0) { const cycleDescription = moduleResult.cycles.map(cycle => cycle.join(' -> ')).join('; '); throw index_js_1.ErrorFactory.circularDependency('modules', moduleResult.cycles.flat()); } // Then resolve class-level dependencies within each module const allClasses = Array.from(this.moduleGroupedClasses.values()).flat(); const dependencyResolver = new dependency_resolver_1.DependencyResolver(allClasses); const sortResult = dependencyResolver.resolve(); if (sortResult.cycles.length > 0) { const firstCycle = sortResult.cycles[0]; if (firstCycle && firstCycle.length > 0) { const className = firstCycle[0] || 'unknown'; throw index_js_1.ErrorFactory.circularDependency(className, firstCycle); } else { throw index_js_1.ErrorFactory.generationFailed('Circular dependencies detected but cycle information is incomplete'); } } // Check if we need to split files (more than 2 modules) if (moduleResult.sortedModules.length >= 2) { this.generateSplitFiles(moduleResult.sortedModules, moduleResult.moduleDependencies); } else { const containerCode = this.generateContainerCode(moduleResult.sortedModules, moduleResult.moduleDependencies); this.writeContainer(containerCode); } } generateContainerCode(sortedModules, moduleDependencies) { if (!sortedModules || !moduleDependencies) { const moduleResult = this.moduleDependencyResolver.resolve(); sortedModules = moduleResult.sortedModules; moduleDependencies = moduleResult.moduleDependencies; } const imports = this.importGenerator.generateImports(); const moduleContainers = this.generateModuleContainers(sortedModules, moduleDependencies); const aggregatedContainer = this.containerAggregator.generateAggregatedContainer(sortedModules); const typeExport = this.containerAggregator.generateModularTypeExportWithPathUtils(this.fileWriter.getOutputPath()); return `${imports}\n\n${moduleContainers}\n\n${aggregatedContainer}\n\n${typeExport}\n`; } generateModuleContainers(sortedModules, moduleDependencies) { const moduleContainerFunctions = this.moduleContainerFunctionGenerator.generateModuleContainerFunctions(sortedModules, moduleDependencies); const moduleInstantiations = this.moduleInstantiationGenerator.generateModuleInstantiations(sortedModules, moduleDependencies); return moduleContainerFunctions.join('\n\n') + '\n\n' + moduleInstantiations.join('\n'); } /** * Generates split files when there are more than 3 modules. * Each module gets its own file, plus a main aggregator file. */ generateSplitFiles(sortedModules, moduleDependencies) { const splitFileWriter = new split_file_writer_1.SplitFileWriter(this.fileWriter.getOutputPath()); splitFileWriter.writeSplitModules(this.moduleGroupedClasses, sortedModules, moduleDependencies, this.moduleContainerFunctionGenerator, this.moduleInstantiationGenerator, this.importGenerator); } } exports.ModularContainerGenerator = ModularContainerGenerator; //# sourceMappingURL=modular-container-generator.js.map