@notjustcoders/ioc-arise
Version:
Arise type-safe IoC containers from your code. Zero overhead, zero coupling.
78 lines • 4.7 kB
JavaScript
"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