@notjustcoders/ioc-arise
Version:
Arise type-safe IoC containers from your code. Zero overhead, zero coupling.
141 lines • 5.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleResolver = void 0;
const minimatch_1 = require("minimatch");
const path_1 = require("path");
const errorFactory_1 = require("../errors/errorFactory");
class ModuleResolver {
constructor(moduleConfig, sourceDirectory) {
this.moduleConfig = moduleConfig;
this.sourceDirectory = (0, path_1.normalize)(sourceDirectory);
}
/**
* Determines which module a file belongs to based on its path
* @param filePath - Absolute path to the file
* @returns Module name or null if no match found
*/
getModuleForFile(filePath) {
const relativePath = this.normalizeFilePath(filePath);
for (const [moduleName, patterns] of Object.entries(this.moduleConfig)) {
for (const pattern of patterns) {
if (this.matchesPattern(relativePath, pattern)) {
return moduleName;
}
}
}
return null; // Will be assigned to CoreModule
}
/**
* Groups classes by their assigned modules
* @param classes - Array of ClassInfo objects
* @returns Map of module names to their classes
*/
groupClassesByModule(classes) {
const moduleGroups = new Map();
for (const classInfo of classes) {
const moduleName = this.getModuleForFile(classInfo.filePath) || 'CoreModule';
if (!moduleGroups.has(moduleName)) {
moduleGroups.set(moduleName, []);
}
moduleGroups.get(moduleName).push(classInfo);
}
return moduleGroups;
}
/**
* Groups factory functions by their assigned modules
* @param factories - Array of FactoryInfo objects
* @returns Map of module names to their factories
*/
groupFactoriesByModule(factories) {
const moduleGroups = new Map();
for (const factoryInfo of factories) {
const moduleName = this.getModuleForFile(factoryInfo.filePath) || 'CoreModule';
if (!moduleGroups.has(moduleName)) {
moduleGroups.set(moduleName, []);
}
moduleGroups.get(moduleName).push(factoryInfo);
}
return moduleGroups;
}
/**
* Groups values by their assigned modules
* @param values - Array of ValueInfo objects
* @returns Map of module names to their values
*/
groupValuesByModule(values) {
const moduleGroups = new Map();
for (const valueInfo of values) {
const moduleName = this.getModuleForFile(valueInfo.filePath) || 'CoreModule';
if (!moduleGroups.has(moduleName)) {
moduleGroups.set(moduleName, []);
}
moduleGroups.get(moduleName).push(valueInfo);
}
return moduleGroups;
}
/**
* Checks if a file path matches a given pattern
* @param filePath - Normalized relative file path
* @param pattern - Pattern to match against
* @returns True if the pattern matches
*/
matchesPattern(filePath, pattern) {
// Handle exact file matches
if (pattern.endsWith('.ts') || pattern.endsWith('.js')) {
return filePath === pattern || filePath.endsWith('/' + pattern);
}
// Handle folder patterns
if (!pattern.includes('*') && !pattern.includes('?')) {
// Exact folder match
return filePath.startsWith(pattern + '/') || filePath === pattern;
}
// Handle glob patterns
return (0, minimatch_1.minimatch)(filePath, pattern, { matchBase: true });
}
/**
* Converts absolute path to relative path from source directory
* @param filePath - Absolute file path
* @returns Normalized relative path
*/
normalizeFilePath(filePath) {
const relativePath = (0, path_1.relative)(this.sourceDirectory, filePath);
return (0, path_1.normalize)(relativePath).replace(/\\/g, '/');
}
/**
* Validates module configuration
* @param moduleConfig - Module configuration to validate
* @returns Array of validation errors
*/
static validateModuleConfig(moduleConfig) {
const errors = [];
const allPatterns = new Set();
for (const [moduleName, patterns] of Object.entries(moduleConfig)) {
// Validate module name
if (!moduleName || typeof moduleName !== 'string') {
errors.push(errorFactory_1.ErrorFactory.moduleConfigInvalid(moduleName, 'Invalid module name'));
continue;
}
// Validate patterns
if (!Array.isArray(patterns)) {
errors.push(errorFactory_1.ErrorFactory.moduleConfigInvalid(moduleName, 'patterns must be an array'));
continue;
}
for (const pattern of patterns) {
if (typeof pattern !== 'string') {
errors.push(errorFactory_1.ErrorFactory.moduleConfigInvalid(moduleName, `contains invalid pattern: ${pattern}`));
continue;
}
// Check for duplicate patterns
if (allPatterns.has(pattern)) {
errors.push(errorFactory_1.ErrorFactory.modulePatternInvalid(pattern, moduleName));
}
else {
allPatterns.add(pattern);
}
}
}
return errors;
}
}
exports.ModuleResolver = ModuleResolver;
//# sourceMappingURL=moduleResolver.js.map