UNPKG

artmapper

Version:

Spring Boot clone for Node.js with TypeScript/JavaScript - JPA-like ORM, Lombok decorators, dependency injection, and MySQL support

171 lines 5.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Container = void 0; require("reflect-metadata"); const component_1 = require("../decorators/component"); class Container { constructor() { this.beans = new Map(); this.beanTypes = new Map(); this.config = new Map(); this.pool = null; } static getInstance() { if (!Container.instance) { Container.instance = new Container(); } return Container.instance; } /** * Set database pool for repositories */ setPool(pool) { this.pool = pool; } /** * Register a configuration value */ setConfig(key, value) { this.config.set(key, value); } /** * Get a configuration value */ getConfig(key) { return this.config.get(key); } /** * Register a bean (component, service, controller, repository) */ registerBean(target, instance) { const componentMetadata = Reflect.getMetadata(component_1.COMPONENT_METADATA_KEY, target); const serviceMetadata = Reflect.getMetadata(component_1.SERVICE_METADATA_KEY, target); const controllerMetadata = Reflect.getMetadata(component_1.CONTROLLER_METADATA_KEY, target); const repositoryMetadata = Reflect.getMetadata(component_1.REPOSITORY_METADATA_KEY, target); let beanName; if (componentMetadata) { beanName = componentMetadata.name || target.name; } else if (serviceMetadata) { beanName = serviceMetadata.name || target.name; } else if (controllerMetadata) { beanName = target.name; } else if (repositoryMetadata) { beanName = repositoryMetadata.name || target.name; } else { beanName = target.name; } this.beanTypes.set(beanName, target); if (instance) { this.beans.set(beanName, instance); } } /** * Get a bean by name or type */ getBean(nameOrType) { let beanName; if (typeof nameOrType === 'function') { // Find by type for (const [name, type] of this.beanTypes.entries()) { if (type === nameOrType || type.prototype instanceof nameOrType) { beanName = name; break; } } if (!beanName) { throw new Error(`Bean of type ${nameOrType.name} not found`); } } else { beanName = nameOrType; } // Return existing instance if available if (this.beans.has(beanName)) { return this.beans.get(beanName); } // Create new instance const beanType = this.beanTypes.get(beanName); if (!beanType) { throw new Error(`Bean ${beanName} not found`); } const instance = this.createInstance(beanType); this.beans.set(beanName, instance); return instance; } /** * Create an instance of a class with dependency injection */ createInstance(target) { // Get constructor parameters const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []; const autowiredMetadata = Reflect.getMetadata(component_1.AUTOWIRED_METADATA_KEY, target) || {}; const valueMetadata = Reflect.getMetadata(component_1.VALUE_METADATA_KEY, target) || {}; const qualifierMetadata = Reflect.getMetadata(component_1.QUALIFIER_METADATA_KEY, target) || {}; // Resolve constructor dependencies const constructorArgs = paramTypes.map((paramType, index) => { if (paramType && paramType.name === 'Pool' && this.pool) { return this.pool; } // Try to find bean by type try { return this.getBean(paramType); } catch { return undefined; } }); // Create instance const instance = new target(...constructorArgs); // Inject field dependencies Object.keys(autowiredMetadata).forEach(propertyKey => { const autowiredInfo = autowiredMetadata[propertyKey]; const qualifier = qualifierMetadata[propertyKey]; let dependency; if (qualifier) { dependency = this.getBean(qualifier); } else if (autowiredInfo.type) { dependency = this.getBean(autowiredInfo.type); } if (dependency) { instance[propertyKey] = dependency; } }); // Inject configuration values Object.keys(valueMetadata).forEach(propertyKey => { const configKey = valueMetadata[propertyKey]; const configValue = this.getConfig(configKey); if (configValue !== undefined) { instance[propertyKey] = configValue; } }); return instance; } /** * Scan and register all beans from a directory */ async scanAndRegister(modulePath) { // In a real implementation, this would scan the file system // For now, we'll rely on manual registration or explicit imports } /** * Get all registered beans */ getAllBeans() { return new Map(this.beans); } /** * Clear all beans */ clear() { this.beans.clear(); this.beanTypes.clear(); this.config.clear(); } } exports.Container = Container; //# sourceMappingURL=Container.js.map