UNPKG

nestjs-custom-injector

Version:

Custom injecting logic for NestJS with support multi providing

339 lines 17.2 kB
"use strict"; var CustomInjectorService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.CustomInjectorService = void 0; const tslib_1 = require("tslib"); const common_1 = require("@nestjs/common"); const core_1 = require("@nestjs/core"); const constants_1 = require("@nestjs/core/injector/constants"); const custom_injector_types_1 = require("./custom-injector.types"); const custom_injector_utils_1 = require("./custom-injector.utils"); let CustomInjectorService = CustomInjectorService_1 = class CustomInjectorService { constructor(discoveryService) { this.discoveryService = discoveryService; CustomInjectorService_1._instance = this; } static getInstance() { return CustomInjectorService_1._instance; } getProvider(token, options) { return this._getProvider(token, options || {}, undefined); } getAsyncProvider(token, options) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this._getAsyncProvider(token, options || {}, undefined); }); } getProviders(token, options) { return this._getProviders(token, options || {}, undefined); } getAsyncProviders(token, options) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this._getAsyncProviders(token, options || {}, undefined); }); } createInjectedProvidersStorageItem(token, target, options) { return { appiled: false, instance: null, init: function () { var _a, _b; this.options = Object.assign(Object.assign({}, (this.options || {})), { multi: Boolean(this.options.multi) }); if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lazy) && this.appiled) { return; } if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.multi) { this.instance = CustomInjectorService_1.getInstance()._getProviders(this.token, this.options, this); } else { this.instance = CustomInjectorService_1.getInstance()._getProvider(this.token, this.options, this); } this.appiled = true; }, asyncInit: function () { var _a, _b; return tslib_1.__awaiter(this, void 0, void 0, function* () { this.options = Object.assign(Object.assign({}, (this.options || {})), { multi: Boolean(this.options.multi) }); if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lazy) && this.appiled) { return; } if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.multi) { this.instance = yield CustomInjectorService_1.getInstance()._getAsyncProviders(this.token, this.options, this); } else { this.instance = yield CustomInjectorService_1.getInstance()._getAsyncProvider(this.token, this.options, this); } this.appiled = true; }); }, target, token, options, }; } initAllNeedProviders() { var _a, _b; return tslib_1.__awaiter(this, void 0, void 0, function* () { const items = this.discoveryService .getProviders() .map((component) => this.toDiscoveredClass(component)) .filter(Boolean) .map((c) => { try { return Reflect.getMetadataKeys(c) .filter((k) => k.indexOf(custom_injector_types_1.CUSTOM_INJECTOR_METADATA) === 0) .map((k) => Reflect.getMetadata(k, c)); } catch (err) { // todo: add support debug for library and catch all errors if (process.env.DEBUG) { console.debug(c); console.error(err); } return []; } }) .reduce((all, cur) => [...all, ...cur], []); for (let index = 0; index < items.length; index++) { if (!((_b = (_a = items[index]) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.lazy) && items[index].asyncInit) { yield items[index].asyncInit(); } } }); } _getProvider(token, options, injectedProvidersStorageItem) { var _a, _b; const object = this.getOneProvider(token, options, injectedProvidersStorageItem); if (Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) { const propertyName = (_a = Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) === null || _a === void 0 ? void 0 : _a.value; if (Object.getOwnPropertyDescriptor(object || {}, propertyName)) { const propertyObject = (_b = Object.getOwnPropertyDescriptor(object || {}, propertyName)) === null || _b === void 0 ? void 0 : _b.value; return propertyObject; } throw this.errorFactory(token, injectedProvidersStorageItem, options === null || options === void 0 ? void 0 : options.errorFactory); } return object; } _getAsyncProvider(token, options, injectedProvidersStorageItem) { var _a, _b; return tslib_1.__awaiter(this, void 0, void 0, function* () { let object = this.getOneProvider(token, options, injectedProvidersStorageItem); if (Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) { const propertyName = (_a = Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) === null || _a === void 0 ? void 0 : _a.value; if ((0, custom_injector_utils_1.isPromise)(object)) { object = yield object; } if (Object.getOwnPropertyDescriptor(object || {}, propertyName)) { const propertyObject = (_b = Object.getOwnPropertyDescriptor(object || {}, propertyName)) === null || _b === void 0 ? void 0 : _b.value; if ((0, custom_injector_utils_1.isPromise)(propertyObject)) { return yield propertyObject; } else { return propertyObject; } } throw this.errorFactory(token, injectedProvidersStorageItem, options === null || options === void 0 ? void 0 : options.errorFactory); } if ((0, custom_injector_utils_1.isPromise)(object)) { return yield object; } else { return object; } }); } getOneProvider(token, options, injectedProvidersStorageItem) { return typeof token === 'string' || typeof token === 'symbol' || String(token).includes('Abstract') || String(token).includes('abstract') ? this._getLastComponentByName(token, options, injectedProvidersStorageItem) : this._getLastComponentsByClass(token, options, injectedProvidersStorageItem); } _getProviders(token, options, injectedProvidersStorageItem) { var _a; const objects = this.getManyProviders(token, options, injectedProvidersStorageItem); if (Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) { const propertyName = (_a = Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) === null || _a === void 0 ? void 0 : _a.value; const resolvedObjects = []; for (let index = 0; index < objects.length; index++) { resolvedObjects.push(objects[index]); } return resolvedObjects .filter((o) => Object.getOwnPropertyDescriptor(o || {}, propertyName)) .map((o) => { var _a; return (_a = Object.getOwnPropertyDescriptor(o || {}, propertyName)) === null || _a === void 0 ? void 0 : _a.value; }); } const resolvedObjects = []; for (let index = 0; index < objects.length; index++) { resolvedObjects.push(objects[index]); } return resolvedObjects; } getManyProviders(token, options, injectedProvidersStorageItem) { return typeof token === 'string' || typeof token === 'symbol' || String(token).includes('Abstract') || String(token).includes('abstract') ? this._getComponentsByName(token, options, injectedProvidersStorageItem) : this._getComponentsByClass(token, options, injectedProvidersStorageItem); } _getAsyncProviders(token, options, injectedProvidersStorageItem) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { const objects = this.getManyProviders(token, options, injectedProvidersStorageItem); if (Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) { const propertyName = (_a = Object.getOwnPropertyDescriptor(options || {}, 'propertyName')) === null || _a === void 0 ? void 0 : _a.value; const resolvedObjects = []; for (let index = 0; index < objects.length; index++) { let object; if ((0, custom_injector_utils_1.isPromise)(objects[index])) { object = yield objects[index]; } else { object = objects[index]; } resolvedObjects.push(object); } return resolvedObjects .filter((o) => Object.getOwnPropertyDescriptor(o || {}, propertyName)) .map((o) => { var _a; return (_a = Object.getOwnPropertyDescriptor(o || {}, propertyName)) === null || _a === void 0 ? void 0 : _a.value; }); } const resolvedObjects = []; for (let index = 0; index < objects.length; index++) { let object; if ((0, custom_injector_utils_1.isPromise)(objects[index])) { object = yield objects[index]; } else { object = objects[index]; } resolvedObjects.push(object); } return resolvedObjects; }); } _getLastComponentByName( // eslint-disable-next-line @typescript-eslint/no-explicit-any token, options, injectedProvidersStorageItem) { let components; try { components = this._getComponentsByName(token, options, injectedProvidersStorageItem); } catch (err) { components = []; } const defaultProviderValue = options === null || options === void 0 ? void 0 : options.defaultProviderValue; const component = components.length === 0 ? undefined : components[0]; if (component === undefined) { if (defaultProviderValue === undefined) { throw this.errorFactory(token, injectedProvidersStorageItem, options === null || options === void 0 ? void 0 : options.errorFactory); } return defaultProviderValue; } return component; } _getLastComponentsByClass( // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any token, options, injectedProvidersStorageItem) { let components; try { components = this._getComponentsByClass(token, options, injectedProvidersStorageItem); } catch (err) { components = []; } const defaultProviderValue = options === null || options === void 0 ? void 0 : options.defaultProviderValue; const component = components.length === 0 ? undefined : components[0]; if (component === undefined) { if (defaultProviderValue === undefined) { throw this.errorFactory(token, injectedProvidersStorageItem, options === null || options === void 0 ? void 0 : options.errorFactory); } return defaultProviderValue; } return component; } _getComponentsByName( // eslint-disable-next-line @typescript-eslint/no-explicit-any token, options, injectedProvidersStorageItem) { if (!this.discoveryService) { throw new custom_injector_types_1.CustomInjectorError(`this.discoveryService not set`); } let values = this.discoveryService .getProviders() .filter((component) => component.scope !== common_1.Scope.REQUEST && (component.name === token || component.token === token)) .map((component) => this.toDiscoveredClass(component)) .map((component) => (options === null || options === void 0 ? void 0 : options.providerFactory) ? options === null || options === void 0 ? void 0 : options.providerFactory(component) : component); if (values.length === 0 && !Object.getOwnPropertyDescriptor(options, 'providersFactory') && !Object.getOwnPropertyDescriptor(options, 'defaultProvidersValue')) { throw this.errorFactory(token, injectedProvidersStorageItem, options === null || options === void 0 ? void 0 : options.errorFactory); } if (options === null || options === void 0 ? void 0 : options.providersFactory) { values = options.providersFactory(values); } if (options === null || options === void 0 ? void 0 : options.defaultProvidersValue) { values = options.defaultProvidersValue; } return values; } _getComponentsByClass( // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any cls, options, injectedProvidersStorageItem) { if (!this.discoveryService) { throw new custom_injector_types_1.CustomInjectorError(`this.discoveryService not set`); } let values = this.discoveryService .getProviders() .filter((component) => component.scope !== common_1.Scope.REQUEST) .map((component) => this.toDiscoveredClass(component)) .filter((obj) => { try { return obj && obj instanceof cls; } catch (err) { return false; } }) .map((component) => (options === null || options === void 0 ? void 0 : options.providerFactory) ? options === null || options === void 0 ? void 0 : options.providerFactory(component) : component); if (values.length === 0 && !Object.getOwnPropertyDescriptor(options, 'providersFactory') && !Object.getOwnPropertyDescriptor(options, 'defaultProvidersValue')) { throw this.errorFactory(cls, injectedProvidersStorageItem, options === null || options === void 0 ? void 0 : options.errorFactory); } if (options === null || options === void 0 ? void 0 : options.providersFactory) { values = options.providersFactory(values); } if (options === null || options === void 0 ? void 0 : options.defaultProvidersValue) { values = options.defaultProvidersValue; } return values; } errorFactory(token, injectedProvidersStorageItem, errorFactory) { var _a, _b; return errorFactory ? errorFactory(`${((_a = injectedProvidersStorageItem === null || injectedProvidersStorageItem === void 0 ? void 0 : injectedProvidersStorageItem.options) === null || _a === void 0 ? void 0 : _a.multi) ? 'Providers' : 'Provider'} "${token.toString()}" not found!`, injectedProvidersStorageItem) : new custom_injector_types_1.CustomInjectorError(`${((_b = injectedProvidersStorageItem === null || injectedProvidersStorageItem === void 0 ? void 0 : injectedProvidersStorageItem.options) === null || _b === void 0 ? void 0 : _b.multi) ? 'Providers' : 'Provider'} "${token.toString()}" not found!`, injectedProvidersStorageItem); } toDiscoveredClass(wrapper) { const instanceHost = wrapper.getInstanceByContextId(constants_1.STATIC_CONTEXT, wrapper && wrapper.id ? wrapper.id : undefined); return instanceHost.instance; } }; CustomInjectorService._instance = new CustomInjectorService_1(new core_1.DiscoveryService(new core_1.ModulesContainer())); CustomInjectorService = CustomInjectorService_1 = tslib_1.__decorate([ (0, common_1.Injectable)(), tslib_1.__metadata("design:paramtypes", [core_1.DiscoveryService]) ], CustomInjectorService); exports.CustomInjectorService = CustomInjectorService; //# sourceMappingURL=custom-injector.service.js.map