UNPKG

@notjustcoders/ioc-arise

Version:

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

145 lines 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SplitFileWriter = void 0; const fs_1 = require("fs"); const path_1 = require("path"); const index_js_1 = require("../../errors/index.js"); const import_generator_js_1 = require("../import-generator.js"); const index_js_2 = require("../shared/index.js"); /** * Handles writing split module files when there are more than 3 modules. * Each module gets its own <moduleName>.gen.ts file, plus a main container.gen.ts aggregator. */ class SplitFileWriter { constructor(outputPath) { this.outputPath = outputPath; this.outputDir = (0, path_1.dirname)(outputPath); } /** * Writes split module files and main aggregator file. */ writeSplitModules(moduleGroupedClasses, sortedModules, moduleDependencies, moduleContainerFunctionGenerator, moduleInstantiationGenerator, globalImportGenerator) { // Ensure output directory exists (0, fs_1.mkdirSync)(this.outputDir, { recursive: true }); // Write individual module files for (const moduleName of sortedModules) { const moduleClasses = moduleGroupedClasses.get(moduleName); if (!moduleClasses) continue; const moduleFilePath = (0, path_1.join)(this.outputDir, `${moduleName}.gen.ts`); const moduleContent = this.generateModuleFileContent(moduleName, moduleClasses, moduleDependencies, moduleContainerFunctionGenerator, moduleInstantiationGenerator, globalImportGenerator); try { (0, fs_1.writeFileSync)(moduleFilePath, moduleContent, 'utf-8'); } catch (error) { throw index_js_1.ErrorFactory.fileWriteError(moduleFilePath, error instanceof Error ? error.message : String(error)); } } // Write main aggregator file const aggregatorContent = this.generateAggregatorFileContent(sortedModules, moduleDependencies); try { (0, fs_1.writeFileSync)(this.outputPath, aggregatorContent, 'utf-8'); } catch (error) { throw index_js_1.ErrorFactory.fileWriteError(this.outputPath, error instanceof Error ? error.message : String(error)); } } /** * Generates content for an individual module file. */ generateModuleFileContent(moduleName, moduleClasses, moduleDependencies, moduleContainerFunctionGenerator, moduleInstantiationGenerator, globalImportGenerator) { // Create a module-specific import generator const moduleImportGenerator = new import_generator_js_1.ImportGenerator(moduleClasses); const moduleImports = moduleImportGenerator.generateImports(); // Generate module container function const moduleContainerFunctions = moduleContainerFunctionGenerator.generateModuleContainerFunctions([moduleName], moduleDependencies); // Generate module dependencies import statements const moduleDeps = moduleDependencies.get(moduleName) || new Set(); const dependencyImports = this.generateDependencyImports(moduleDeps); // Generate module type definitions const moduleTypeExport = this.generateModuleTypeExport(moduleName); return [ moduleImports, dependencyImports, '', moduleContainerFunctions.join('\n\n'), '', moduleTypeExport ].filter(line => line.trim() !== '').join('\n'); } /** * Generates dependency import statements for a module. */ generateDependencyImports(moduleDeps) { if (moduleDeps.size === 0) return ''; const imports = Array.from(moduleDeps).map(depModule => `import { create${depModule}Container } from './${depModule}.gen';`); return imports.join('\n'); } /** * Generates type export for a module. */ generateModuleTypeExport(moduleName) { const functionName = `create${moduleName}Container`; return `export { ${functionName} }; export type ${moduleName}Container = ReturnType<typeof ${functionName}>;`; } /** * Generates content for the main aggregator file. */ generateAggregatorFileContent(sortedModules, moduleDependencies) { // Generate imports for all module files const moduleImports = sortedModules.map(moduleName => `import { create${moduleName}Container } from './${moduleName}.gen';`).join('\n'); // Generate module instantiations in dependency order const moduleInstantiations = this.generateModuleInstantiationsForAggregator(sortedModules, moduleDependencies); // Generate aggregated container const aggregatedContainer = this.generateAggregatedContainerForSplit(sortedModules); // Generate type export with path utilities and preserve onInit const typeExport = index_js_2.InstantiationUtils.generateModularContainerTypeExportWithPathUtils(this.outputPath); return [ moduleImports, '', moduleInstantiations.join('\n'), '', aggregatedContainer, '', typeExport ].join('\n'); } /** * Generates module instantiations for the aggregator file. */ generateModuleInstantiationsForAggregator(sortedModules, moduleDependencies) { const instantiations = []; for (const moduleName of sortedModules) { const moduleDeps = moduleDependencies.get(moduleName) || new Set(); const moduleVarName = this.toCamelCase(moduleName) + 'Container'; const moduleFunctionName = `create${moduleName}Container`; const functionArgs = Array.from(moduleDeps).map(depModule => this.toCamelCase(depModule) + 'Container'); const functionCall = functionArgs.length > 0 ? `${moduleFunctionName}(${functionArgs.join(', ')})` : `${moduleFunctionName}()`; instantiations.push(`const ${moduleVarName} = ${functionCall};`); } return instantiations; } /** * Generates the aggregated container for split files. */ generateAggregatedContainerForSplit(sortedModules) { const moduleExports = sortedModules.map(moduleName => { const moduleVarName = this.toCamelCase(moduleName) + 'Container'; const moduleKey = this.toCamelCase(moduleName); return ` ${moduleKey}: ${moduleVarName}`; }); return `export const container = {\n${moduleExports.join(',\n')}\n};`; } /** * Converts a string to camelCase. */ toCamelCase(str) { return str.charAt(0).toLowerCase() + str.slice(1).replace(/[^a-zA-Z0-9]/g, ''); } } exports.SplitFileWriter = SplitFileWriter; //# sourceMappingURL=split-file-writer.js.map