UNPKG

rage-framework

Version:

## How to Install *server-side* ```bash npm install @rage-framework/server ```

222 lines 8.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ContainerInstance = void 0; const Container_1 = require("./Container"); const MissingProvidedServiceTypeError_1 = require("./error/MissingProvidedServiceTypeError"); const ServiceNotFoundError_1 = require("./error/ServiceNotFoundError"); const Token_1 = require("./Token"); const constructor_watcher_service_1 = require("../services/utils/constructor-watcher.service"); class ContainerInstance { // ------------------------------------------------------------------------- // Constructor // ------------------------------------------------------------------------- constructor(id) { // ------------------------------------------------------------------------- // Private Properties // ------------------------------------------------------------------------- this.services = new Map(); this.id = id; } has(identifier) { return !!this.findService(identifier); } get(identifier) { const globalContainer = Container_1.Container.of(undefined); const service = globalContainer.findService(identifier); const scopedService = this.findService(identifier); if (service && service.global === true) { return this.getServiceValue(identifier, service); } if (scopedService) { return this.getServiceValue(identifier, scopedService); } if (service && this !== globalContainer) { const clonedService = Object.assign({}, service); clonedService.value = undefined; const value = this.getServiceValue(identifier, clonedService); this.set(identifier, value); return value; } return this.getServiceValue(identifier, service); } getMany(id) { return this.filterServices(id).map((service) => this.getServiceValue(id, service)); } set(identifierOrServiceMetadata, value) { if (identifierOrServiceMetadata instanceof Array) { identifierOrServiceMetadata.forEach((v) => this.set(v)); return this; } if (typeof identifierOrServiceMetadata === 'string' || identifierOrServiceMetadata instanceof Token_1.Token) { return this.set({ id: identifierOrServiceMetadata, value: value }); } if (typeof identifierOrServiceMetadata === 'object' && identifierOrServiceMetadata.service) { return this.set({ id: identifierOrServiceMetadata.service, value: value, }); } if (identifierOrServiceMetadata instanceof Function) { return this.set({ type: identifierOrServiceMetadata, id: identifierOrServiceMetadata, value: value, }); } // const newService: ServiceMetadata<any, any> = arguments.length === 1 && typeof identifierOrServiceMetadata === 'object' && !(identifierOrServiceMetadata instanceof Token) ? identifierOrServiceMetadata : undefined; const newService = identifierOrServiceMetadata; const service = this.services.get(newService); if (service && service.multiple !== true) { Object.assign(service, newService); } else { this.services.set(newService, newService); } return this; } remove(...ids) { ids.forEach((id) => { this.filterServices(id).forEach((service) => { this.services.delete(service); }); }); return this; } reset() { this.services.clear(); return this; } // ------------------------------------------------------------------------- // Private Methods // ------------------------------------------------------------------------- filterServices(identifier) { return Array.from(this.services.values()).filter((service) => { if (service.id) { return service.id === identifier; } if (service.type && identifier instanceof Function) { return (service.type === identifier || identifier.prototype instanceof service.type); } return false; }); } findService(identifier) { return Array.from(this.services.values()).find((service) => { if (service.id) { if (identifier instanceof Object && service.id instanceof Token_1.Token && identifier.service instanceof Token_1.Token) { return service.id === identifier.service; } return service.id === identifier; } if (service.type && identifier instanceof Function) { return service.type === identifier; // todo: not sure why it was here || identifier.prototype instanceof service.type; } return false; }); } getServiceValue(identifier, service) { if (service && service.value !== undefined) { return service.value; } if ((!service || !service.type) && (!service || !service.factory) && (typeof identifier === 'string' || identifier instanceof Token_1.Token)) { throw new ServiceNotFoundError_1.ServiceNotFoundError(identifier); } let type = undefined; if (service && service.type) { type = service.type; } else if (service && service.id instanceof Function) { type = service.id; } else if (identifier instanceof Function) { type = identifier; } if (!service) { if (!type) { throw new MissingProvidedServiceTypeError_1.MissingProvidedServiceTypeError(identifier); } service = { type: type }; this.services.set(service, service); } const paramTypes = type && Reflect && Reflect.getMetadata ? Reflect.getMetadata('design:paramtypes', type) : undefined; let params = paramTypes ? this.initializeParams(type, paramTypes) : []; let value; if (service.factory) { params = params.filter((param) => param !== undefined); if (service.factory instanceof Array) { value = this.get(service.factory[0])[service.factory[1]](...params); } else { value = service.factory(...params, this); } } else { if (!type) { throw new MissingProvidedServiceTypeError_1.MissingProvidedServiceTypeError(identifier); } params.unshift(null); params.push(this); if (type.prototype.OnBefore) { type.prototype.OnBefore.bind(type)(); } value = new (type.bind.apply(type, params))(); constructor_watcher_service_1.constructorWatcherService.createConstructor(type['name'], { type, value, }); if (value.onInit) { value.onInit.bind(value)(); } } if (service && !service.transient && value) { service.value = value; } if (type) { this.applyPropertyHandlers(type, value); } return value; } initializeParams(type, paramTypes) { return paramTypes.map((paramType, index) => { const paramHandler = Array.from(Container_1.Container.handlers.values()).find((handler) => handler.object === type && handler.index === index); if (paramHandler) { return paramHandler.value(this); } if (paramType && paramType.name && !this.isTypePrimitive(paramType.name)) { return this.get(paramType); } return undefined; }); } isTypePrimitive(param) { return (['string', 'boolean', 'number', 'object'].indexOf(param.toLowerCase()) !== -1); } applyPropertyHandlers(target, instance) { Container_1.Container.handlers.forEach((handler) => { if (typeof handler.index === 'number') { return; } if (handler.object.constructor !== target && !(target.prototype instanceof handler.object.constructor)) { return; } instance[handler.propertyName] = handler.value(this); }); } } exports.ContainerInstance = ContainerInstance; //# sourceMappingURL=ContainerInstance.js.map