typedi
Version:
Dependency injection for TypeScript.
694 lines (678 loc) • 34.6 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ClassTransformer = {}));
}(this, (function (exports) { 'use strict';
/**
* Used to create unique typed service identifier.
* Useful when service has only interface, but don't have a class.
*/
var Token = /** @class */ (function () {
/**
* @param name Token name, optional and only used for debugging purposes.
*/
function Token(name) {
this.name = name;
}
return Token;
}());
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* Thrown when requested service was not found.
*/
var ServiceNotFoundError = /** @class */ (function (_super) {
__extends(ServiceNotFoundError, _super);
function ServiceNotFoundError(identifier) {
var _a, _b;
var _this = _super.call(this) || this;
_this.name = 'ServiceNotFoundError';
/** Normalized identifier name used in the error message. */
_this.normalizedIdentifier = '<UNKNOWN_IDENTIFIER>';
if (typeof identifier === 'string') {
_this.normalizedIdentifier = identifier;
}
else if (identifier instanceof Token) {
_this.normalizedIdentifier = "Token<" + (identifier.name || 'UNSET_NAME') + ">";
}
else if (identifier && (identifier.name || ((_a = identifier.prototype) === null || _a === void 0 ? void 0 : _a.name))) {
_this.normalizedIdentifier =
"MaybeConstructable<" + identifier.name + ">" ||
"MaybeConstructable<" + ((_b = identifier.prototype) === null || _b === void 0 ? void 0 : _b.name) + ">";
}
return _this;
}
Object.defineProperty(ServiceNotFoundError.prototype, "message", {
get: function () {
return ("Service with \"" + this.normalizedIdentifier + "\" identifier was not found in the container. " +
"Register it before usage via explicitly calling the \"Container.set\" function or using the \"@Service()\" decorator.");
},
enumerable: false,
configurable: true
});
return ServiceNotFoundError;
}(Error));
var __extends$1 = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* Thrown when DI cannot inject value into property decorated by @Inject decorator.
*/
var CannotInstantiateValueError = /** @class */ (function (_super) {
__extends$1(CannotInstantiateValueError, _super);
function CannotInstantiateValueError(identifier) {
var _a, _b;
var _this = _super.call(this) || this;
_this.name = 'CannotInstantiateValueError';
/** Normalized identifier name used in the error message. */
_this.normalizedIdentifier = '<UNKNOWN_IDENTIFIER>';
// TODO: Extract this to a helper function and share between this and NotFoundError.
if (typeof identifier === 'string') {
_this.normalizedIdentifier = identifier;
}
else if (identifier instanceof Token) {
_this.normalizedIdentifier = "Token<" + (identifier.name || 'UNSET_NAME') + ">";
}
else if (identifier && (identifier.name || ((_a = identifier.prototype) === null || _a === void 0 ? void 0 : _a.name))) {
_this.normalizedIdentifier =
"MaybeConstructable<" + identifier.name + ">" ||
"MaybeConstructable<" + ((_b = identifier.prototype) === null || _b === void 0 ? void 0 : _b.name) + ">";
}
return _this;
}
Object.defineProperty(CannotInstantiateValueError.prototype, "message", {
get: function () {
return ("Cannot instantiate the requested value for the \"" + this.normalizedIdentifier + "\" identifier. " +
"The related metadata doesn't contain a factory or a type to instantiate.");
},
enumerable: false,
configurable: true
});
return CannotInstantiateValueError;
}(Error));
var EMPTY_VALUE = Symbol('EMPTY_VALUE');
var __assign = (undefined && undefined.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArrays = (undefined && undefined.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
/**
* TypeDI can have multiple containers.
* One container is ContainerInstance.
*/
var ContainerInstance = /** @class */ (function () {
function ContainerInstance(id) {
/** All registered services in the container. */
this.services = [];
this.id = id;
}
ContainerInstance.prototype.has = function (identifier) {
return !!this.findService(identifier);
};
ContainerInstance.prototype.get = function (identifier) {
var globalContainer = Container.of(undefined);
var globalService = globalContainer.findService(identifier);
var scopedService = this.findService(identifier);
if (globalService && globalService.global === true)
return this.getServiceValue(globalService);
if (scopedService)
return this.getServiceValue(scopedService);
/** If it's the first time requested in the child container we load it from parent and set it. */
if (globalService && this !== globalContainer) {
var clonedService = __assign({}, globalService);
clonedService.value = EMPTY_VALUE;
/**
* We need to immediately set the empty value from the root container
* to prevent infinite lookup in cyclic dependencies.
*/
this.set(clonedService);
var value = this.getServiceValue(clonedService);
this.set(__assign(__assign({}, clonedService), { value: value }));
return value;
}
if (globalService)
return this.getServiceValue(globalService);
throw new ServiceNotFoundError(identifier);
};
ContainerInstance.prototype.getMany = function (identifier) {
var _this = this;
return this.findAllServices(identifier).map(function (service) { return _this.getServiceValue(service); });
};
ContainerInstance.prototype.set = function (identifierOrServiceMetadata, value) {
var _this = this;
if (identifierOrServiceMetadata instanceof Array) {
identifierOrServiceMetadata.forEach(function (data) { return _this.set(data); });
return this;
}
if (typeof identifierOrServiceMetadata === 'string' || identifierOrServiceMetadata instanceof Token) {
return this.set({
id: identifierOrServiceMetadata,
type: null,
value: value,
factory: undefined,
global: false,
multiple: false,
eager: false,
transient: false,
});
}
if (typeof identifierOrServiceMetadata === 'function') {
return this.set({
id: identifierOrServiceMetadata,
// TODO: remove explicit casting
type: identifierOrServiceMetadata,
value: value,
factory: undefined,
global: false,
multiple: false,
eager: false,
transient: false,
});
}
var newService = __assign({ id: new Token('UNREACHABLE'), type: null, factory: undefined, value: EMPTY_VALUE, global: false, multiple: false, eager: false, transient: false }, identifierOrServiceMetadata);
var service = this.findService(newService.id);
if (service && service.multiple !== true) {
Object.assign(service, newService);
}
else {
this.services.push(newService);
}
if (newService.eager) {
this.get(newService.id);
}
return this;
};
/**
* Removes services with a given service identifiers.
*/
ContainerInstance.prototype.remove = function (identifierOrIdentifierArray) {
var _this = this;
if (Array.isArray(identifierOrIdentifierArray)) {
identifierOrIdentifierArray.forEach(function (id) { return _this.remove(id); });
}
else {
this.services = this.services.filter(function (service) {
if (service.id === identifierOrIdentifierArray) {
_this.destroyServiceInstance(service);
return false;
}
return true;
});
}
return this;
};
/**
* Completely resets the container by removing all previously registered services from it.
*/
ContainerInstance.prototype.reset = function (options) {
var _this = this;
if (options === void 0) { options = { strategy: 'resetValue' }; }
switch (options.strategy) {
case 'resetValue':
this.services.forEach(function (service) { return _this.destroyServiceInstance(service); });
break;
case 'resetServices':
this.services.forEach(function (service) { return _this.destroyServiceInstance(service); });
this.services = [];
break;
default:
throw new Error('Received invalid reset strategy.');
}
return this;
};
/**
* Returns all services registered with the given identifier.
*/
ContainerInstance.prototype.findAllServices = function (identifier) {
return this.services.filter(function (service) { return service.id === identifier; });
};
/**
* Finds registered service in the with a given service identifier.
*/
ContainerInstance.prototype.findService = function (identifier) {
return this.services.find(function (service) { return service.id === identifier; });
};
/**
* Gets the value belonging to `serviceMetadata.id`.
*
* - if `serviceMetadata.value` is already set it is immediately returned
* - otherwise the requested type is resolved to the value saved to `serviceMetadata.value` and returned
*/
ContainerInstance.prototype.getServiceValue = function (serviceMetadata) {
var _a;
var value = EMPTY_VALUE;
/**
* If the service value has been set to anything prior to this call we return that value.
* NOTE: This part builds on the assumption that transient dependencies has no value set ever.
*/
if (serviceMetadata.value !== EMPTY_VALUE) {
return serviceMetadata.value;
}
/** If both factory and type is missing, we cannot resolve the requested ID. */
if (!serviceMetadata.factory && !serviceMetadata.type) {
throw new CannotInstantiateValueError(serviceMetadata.id);
}
/**
* If a factory is defined it takes priority over creating an instance via `new`.
* The return value of the factory is not checked, we believe by design that the user knows what he/she is doing.
*/
if (serviceMetadata.factory) {
/**
* If we received the factory in the [Constructable<Factory>, "functionName"] format, we need to create the
* factory first and then call the specified function on it.
*/
if (serviceMetadata.factory instanceof Array) {
var factoryInstance = void 0;
try {
/** Try to get the factory from TypeDI first, if failed, fall back to simply initiating the class. */
factoryInstance = this.get(serviceMetadata.factory[0]);
}
catch (error) {
if (error instanceof ServiceNotFoundError) {
factoryInstance = new serviceMetadata.factory[0]();
}
else {
throw error;
}
}
value = factoryInstance[serviceMetadata.factory[1]](this, serviceMetadata.id);
}
else {
/** If only a simple function was provided we simply call it. */
value = serviceMetadata.factory(this, serviceMetadata.id);
}
}
/**
* If no factory was provided and only then, we create the instance from the type if it was set.
*/
if (!serviceMetadata.factory && serviceMetadata.type) {
var constructableTargetType = serviceMetadata.type;
// setup constructor parameters for a newly initialized service
var paramTypes = ((_a = Reflect) === null || _a === void 0 ? void 0 : _a.getMetadata('design:paramtypes', constructableTargetType)) || [];
var params = this.initializeParams(constructableTargetType, paramTypes);
// "extra feature" - always pass container instance as the last argument to the service function
// this allows us to support javascript where we don't have decorators and emitted metadata about dependencies
// need to be injected, and user can use provided container to get instances he needs
params.push(this);
value = new (constructableTargetType.bind.apply(constructableTargetType, __spreadArrays([void 0], params)))();
// TODO: Calling this here, leads to infinite loop, because @Inject decorator registerds a handler
// TODO: which calls Container.get, which will check if the requested type has a value set and if not
// TODO: it will start the instantiation process over. So this is currently called outside of the if branch
// TODO: after the current value has been assigned to the serviceMetadata.
// this.applyPropertyHandlers(constructableTargetType, value as Constructable<unknown>);
}
/** If this is not a transient service, and we resolved something, then we set it as the value. */
if (!serviceMetadata.transient && value !== EMPTY_VALUE) {
serviceMetadata.value = value;
}
if (value === EMPTY_VALUE) {
/** This branch should never execute, but better to be safe than sorry. */
throw new CannotInstantiateValueError(serviceMetadata.id);
}
if (serviceMetadata.type) {
this.applyPropertyHandlers(serviceMetadata.type, value);
}
return value;
};
/**
* Initializes all parameter types for a given target service class.
*/
ContainerInstance.prototype.initializeParams = function (target, paramTypes) {
var _this = this;
return paramTypes.map(function (paramType, index) {
var paramHandler = Container.handlers.find(function (handler) {
/**
* @Inject()-ed values are stored as parameter handlers and they reference their target
* when created. So when a class is extended the @Inject()-ed values are not inherited
* because the handler still points to the old object only.
*
* As a quick fix a single level parent lookup is added via `Object.getPrototypeOf(target)`,
* however this should be updated to a more robust solution.
*
* TODO: Add proper inheritance handling: either copy the handlers when a class is registered what
* TODO: has it's parent already registered as dependency or make the lookup search up to the base Object.
*/
return ((handler.object === target || handler.object === Object.getPrototypeOf(target)) && handler.index === index);
});
if (paramHandler)
return paramHandler.value(_this);
if (paramType && paramType.name && !_this.isPrimitiveParamType(paramType.name)) {
return _this.get(paramType);
}
return undefined;
});
};
/**
* Checks if given parameter type is primitive type or not.
*/
ContainerInstance.prototype.isPrimitiveParamType = function (paramTypeName) {
return ['string', 'boolean', 'number', 'object'].includes(paramTypeName.toLowerCase());
};
/**
* Applies all registered handlers on a given target class.
*/
ContainerInstance.prototype.applyPropertyHandlers = function (target, instance) {
var _this = this;
Container.handlers.forEach(function (handler) {
if (typeof handler.index === 'number')
return;
if (handler.object.constructor !== target && !(target.prototype instanceof handler.object.constructor))
return;
if (handler.propertyName) {
instance[handler.propertyName] = handler.value(_this);
}
});
};
/**
* Checks if the given service metadata contains a destroyable service instance and destroys it in place. If the service
* contains a callable function named `destroy` it is called but not awaited and the return value is ignored..
*
* @param serviceMetadata the service metadata containing the instance to destroy
* @param force when true the service will be always destroyed even if it's cannot be re-created
*/
ContainerInstance.prototype.destroyServiceInstance = function (serviceMetadata, force) {
if (force === void 0) { force = false; }
/** We reset value only if we can re-create it (aka type or factory exists). */
var shouldResetValue = force || !!serviceMetadata.type || !!serviceMetadata.factory;
if (shouldResetValue) {
/** If we wound a function named destroy we call it without any params. */
if (typeof (serviceMetadata === null || serviceMetadata === void 0 ? void 0 : serviceMetadata.value)['destroy'] === 'function') {
try {
serviceMetadata.value.destroy();
}
catch (error) {
/** We simply ignore the errors from the destroy function. */
}
}
serviceMetadata.value = EMPTY_VALUE;
}
};
return ContainerInstance;
}());
/**
* Service container.
*/
var Container = /** @class */ (function () {
function Container() {
}
/**
* Gets a separate container instance for the given instance id.
*/
Container.of = function (containerId) {
if (containerId === void 0) { containerId = 'default'; }
if (containerId === 'default')
return this.globalInstance;
var container = this.instances.find(function (instance) { return instance.id === containerId; });
if (!container) {
container = new ContainerInstance(containerId);
this.instances.push(container);
// TODO: Why we are not reseting here? Let's reset here. (I have added the commented code.)
// container.reset();
}
return container;
};
Container.has = function (identifier) {
return this.globalInstance.has(identifier);
};
Container.get = function (identifier) {
return this.globalInstance.get(identifier);
};
Container.getMany = function (id) {
return this.globalInstance.getMany(id);
};
Container.set = function (identifierOrServiceMetadata, value) {
this.globalInstance.set(identifierOrServiceMetadata, value);
return this;
};
/**
* Removes services with a given service identifiers.
*/
Container.remove = function (identifierOrIdentifierArray) {
this.globalInstance.remove(identifierOrIdentifierArray);
return this;
};
/**
* Completely resets the container by removing all previously registered services and handlers from it.
*/
Container.reset = function (containerId) {
if (containerId === void 0) { containerId = 'default'; }
if (containerId == 'default') {
this.globalInstance.reset();
this.instances.forEach(function (instance) { return instance.reset(); });
}
else {
var instance = this.instances.find(function (instance) { return instance.id === containerId; });
if (instance) {
instance.reset();
this.instances.splice(this.instances.indexOf(instance), 1);
}
}
return this;
};
/**
* Registers a new handler.
*/
Container.registerHandler = function (handler) {
this.handlers.push(handler);
return this;
};
/**
* Helper method that imports given services.
*/
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
Container.import = function (services) {
return this;
};
/**
* All registered handlers. The @Inject() decorator uses handlers internally to mark a property for injection.
**/
Container.handlers = [];
/** Global container instance. */
Container.globalInstance = new ContainerInstance('default');
/** Other containers created using Container.of method. */
Container.instances = [];
return Container;
}());
var __extends$2 = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* Thrown when DI cannot inject value into property decorated by @Inject decorator.
*/
var CannotInjectValueError = /** @class */ (function (_super) {
__extends$2(CannotInjectValueError, _super);
function CannotInjectValueError(target, propertyName) {
var _this = _super.call(this) || this;
_this.target = target;
_this.propertyName = propertyName;
_this.name = 'CannotInjectValueError';
return _this;
}
Object.defineProperty(CannotInjectValueError.prototype, "message", {
get: function () {
return ("Cannot inject value into \"" + this.target.constructor.name + "." + this.propertyName + "\". " +
"Please make sure you setup reflect-metadata properly and you don't use interfaces without service tokens as injection value.");
},
enumerable: false,
configurable: true
});
return CannotInjectValueError;
}(Error));
/**
* Helper function used in inject decorators to resolve the received identifier to
* an eager type when possible or to a lazy type when cyclic dependencies are possibly involved.
*
* @param typeOrIdentifier a service identifier or a function returning a type acting as service identifier or nothing
* @param target the class definition of the target of the decorator
* @param propertyName the name of the property in case of a PropertyDecorator
* @param index the index of the parameter in the constructor in case of ParameterDecorator
*/
function resolveToTypeWrapper(typeOrIdentifier, target, propertyName, index) {
/**
* ? We want to error out as soon as possible when looking up services to inject, however
* ? we cannot determine the type at decorator execution when cyclic dependencies are involved
* ? because calling the received `() => MyType` function right away would cause a JS error:
* ? "Cannot access 'MyType' before initialization", so we need to execute the function in the handler,
* ? when the classes are already created. To overcome this, we use a wrapper:
* ? - the lazyType is executed in the handler so we never have a JS error
* ? - the eagerType is checked when decorator is running and an error is raised if an unknown type is encountered
*/
var typeWrapper;
/** If requested type is explicitly set via a string ID or token, we set it explicitly. */
if ((typeOrIdentifier && typeof typeOrIdentifier === 'string') || typeOrIdentifier instanceof Token) {
typeWrapper = { eagerType: typeOrIdentifier, lazyType: function () { return typeOrIdentifier; } };
}
/** If requested type is explicitly set via a () => MyClassType format, we set it explicitly. */
if (typeOrIdentifier && typeof typeOrIdentifier === 'function') {
/** We set eagerType to null, preventing the raising of the CannotInjectValueError in decorators. */
typeWrapper = { eagerType: null, lazyType: function () { return typeOrIdentifier(); } };
}
/** If no explicit type is set and handler registered for a class property, we need to get the property type. */
if (!typeOrIdentifier && propertyName) {
var identifier_1 = Reflect.getMetadata('design:type', target, propertyName);
typeWrapper = { eagerType: identifier_1, lazyType: function () { return identifier_1; } };
}
/** If no explicit type is set and handler registered for a constructor parameter, we need to get the parameter types. */
if (!typeOrIdentifier && typeof index == 'number' && Number.isInteger(index)) {
var paramTypes = Reflect.getMetadata('design:paramtypes', target, propertyName);
/** It's not guaranteed, that we find any types for the constructor. */
var identifier_2 = paramTypes === null || paramTypes === void 0 ? void 0 : paramTypes[index];
typeWrapper = { eagerType: identifier_2, lazyType: function () { return identifier_2; } };
}
return typeWrapper;
}
function InjectMany(typeOrIdentifier) {
return function (target, propertyName, index) {
var typeWrapper = resolveToTypeWrapper(typeOrIdentifier, target, propertyName, index);
/** If no type was inferred, or the general Object type was inferred we throw an error. */
if (typeWrapper === undefined || typeWrapper.eagerType === undefined || typeWrapper.eagerType === Object) {
throw new CannotInjectValueError(target, propertyName);
}
Container.registerHandler({
object: target,
propertyName: propertyName,
index: index,
value: function (containerInstance) {
var evaluatedLazyType = typeWrapper.lazyType();
/** If no type was inferred lazily, or the general Object type was inferred we throw an error. */
if (evaluatedLazyType === undefined || evaluatedLazyType === Object) {
throw new CannotInjectValueError(target, propertyName);
}
return containerInstance.getMany(evaluatedLazyType);
},
});
};
}
function Inject(typeOrIdentifier) {
return function (target, propertyName, index) {
var typeWrapper = resolveToTypeWrapper(typeOrIdentifier, target, propertyName, index);
/** If no type was inferred, or the general Object type was inferred we throw an error. */
if (typeWrapper === undefined || typeWrapper.eagerType === undefined || typeWrapper.eagerType === Object) {
throw new CannotInjectValueError(target, propertyName);
}
Container.registerHandler({
object: target,
propertyName: propertyName,
index: index,
value: function (containerInstance) {
var evaluatedLazyType = typeWrapper.lazyType();
/** If no type was inferred lazily, or the general Object type was inferred we throw an error. */
if (evaluatedLazyType === undefined || evaluatedLazyType === Object) {
throw new CannotInjectValueError(target, propertyName);
}
return containerInstance.get(evaluatedLazyType);
},
});
};
}
function Service(optionsOrServiceIdentifier) {
return function (targetConstructor) {
var serviceMetadata = {
id: targetConstructor,
// TODO: Let's investigate why we receive Function type instead of a constructable.
type: targetConstructor,
factory: undefined,
multiple: false,
global: false,
eager: false,
transient: false,
value: EMPTY_VALUE,
};
if (optionsOrServiceIdentifier instanceof Token || typeof optionsOrServiceIdentifier === 'string') {
/** We received a Token or string ID. */
serviceMetadata.id = optionsOrServiceIdentifier;
}
else if (optionsOrServiceIdentifier) {
/** We received a ServiceOptions object. */
serviceMetadata.id = optionsOrServiceIdentifier.id || targetConstructor;
serviceMetadata.factory = optionsOrServiceIdentifier.factory || undefined;
serviceMetadata.multiple = optionsOrServiceIdentifier.multiple || false;
serviceMetadata.global = optionsOrServiceIdentifier.global || false;
serviceMetadata.eager = optionsOrServiceIdentifier.eager || false;
serviceMetadata.transient = optionsOrServiceIdentifier.transient || false;
}
Container.set(serviceMetadata);
};
}
/**
* We have a hard dependency on reflect-metadata package.
* Without the dependency lookup wont work. So we should warn the users
* when it's not loaded.
*/
exports.CannotInjectValueError = CannotInjectValueError;
exports.CannotInstantiateValueError = CannotInstantiateValueError;
exports.Container = Container;
exports.ContainerInstance = ContainerInstance;
exports.Inject = Inject;
exports.InjectMany = InjectMany;
exports.Service = Service;
exports.ServiceNotFoundError = ServiceNotFoundError;
exports.Token = Token;
exports.default = Container;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=typedi.umd.js.map