injection-js
Version:
Dependency Injection library for JavaScript and TypeScript
1,310 lines (1,293 loc) • 70.5 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('tslib')) :
typeof define === 'function' && define.amd ? define(['exports', 'tslib'], factory) :
(global = global || self, factory(global['injection-js'] = {}, global.tslib));
}(this, (function (exports, tslib) { 'use strict';
var globalScope;
if (typeof window === 'undefined') {
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
// TODO: Replace any with WorkerGlobalScope from lib.webworker.d.ts #3492
globalScope = self;
}
else {
globalScope = global;
}
}
else {
globalScope = window;
}
// Need to declare a new variable for global here since TypeScript
// exports the original value of the symbol.
var _global = globalScope;
function stringify(token) {
if (typeof token === 'string') {
return token;
}
if (token == null) {
return '' + token;
}
if (token.overriddenName) {
return "" + token.overriddenName;
}
if (token.name) {
return "" + token.name;
}
var res = token.toString();
var newLineIndex = res.indexOf('\n');
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _nextClassId = 0;
var Reflect = _global['Reflect'];
function extractAnnotation(annotation) {
if (typeof annotation === 'function' && annotation.hasOwnProperty('annotation')) {
// it is a decorator, extract annotation
annotation = annotation.annotation;
}
return annotation;
}
function applyParams(fnOrArray, key) {
if (fnOrArray === Object || fnOrArray === String || fnOrArray === Function || fnOrArray === Number || fnOrArray === Array) {
throw new Error("Can not use native " + stringify(fnOrArray) + " as constructor");
}
if (typeof fnOrArray === 'function') {
return fnOrArray;
}
if (Array.isArray(fnOrArray)) {
var annotations = fnOrArray;
var annoLength = annotations.length - 1;
var fn = fnOrArray[annoLength];
if (typeof fn !== 'function') {
throw new Error("Last position of Class method array must be Function in key " + key + " was '" + stringify(fn) + "'");
}
if (annoLength !== fn.length) {
throw new Error("Number of annotations (" + annoLength + ") does not match number of arguments (" + fn.length + ") in the function: " + stringify(fn));
}
var paramsAnnotations = [];
for (var i = 0, ii = annotations.length - 1; i < ii; i++) {
var paramAnnotations = [];
paramsAnnotations.push(paramAnnotations);
var annotation = annotations[i];
if (Array.isArray(annotation)) {
for (var j = 0; j < annotation.length; j++) {
paramAnnotations.push(extractAnnotation(annotation[j]));
}
}
else if (typeof annotation === 'function') {
paramAnnotations.push(extractAnnotation(annotation));
}
else {
paramAnnotations.push(annotation);
}
}
Reflect.defineMetadata('parameters', paramsAnnotations, fn);
return fn;
}
throw new Error("Only Function or Array is supported in Class definition for key '" + key + "' is '" + stringify(fnOrArray) + "'");
}
/**
* Provides a way for expressing ES6 classes with parameter annotations in ES5.
*
* ## Basic Example
*
* ```
* var Greeter = ng.Class({
* constructor: function(name) {
* this.name = name;
* },
*
* greet: function() {
* alert('Hello ' + this.name + '!');
* }
* });
* ```
*
* is equivalent to ES6:
*
* ```
* class Greeter {
* constructor(name) {
* this.name = name;
* }
*
* greet() {
* alert('Hello ' + this.name + '!');
* }
* }
* ```
*
* or equivalent to ES5:
*
* ```
* var Greeter = function (name) {
* this.name = name;
* }
*
* Greeter.prototype.greet = function () {
* alert('Hello ' + this.name + '!');
* }
* ```
*
* ### Example with parameter annotations
*
* ```
* var MyService = ng.Class({
* constructor: [String, [new Optional(), Service], function(name, myService) {
* ...
* }]
* });
* ```
*
* is equivalent to ES6:
*
* ```
* class MyService {
* constructor(name: string, @Optional() myService: Service) {
* ...
* }
* }
* ```
*
* ### Example with inheritance
*
* ```
* var Shape = ng.Class({
* constructor: (color) {
* this.color = color;
* }
* });
*
* var Square = ng.Class({
* extends: Shape,
* constructor: function(color, size) {
* Shape.call(this, color);
* this.size = size;
* }
* });
* ```
* @suppress {globalThis}
* @stable
*/
function Class(clsDef) {
var constructor = applyParams(clsDef.hasOwnProperty('constructor') ? clsDef.constructor : undefined, 'constructor');
var proto = constructor.prototype;
if (clsDef.hasOwnProperty('extends')) {
if (typeof clsDef.extends === 'function') {
constructor.prototype = proto = Object.create(clsDef.extends.prototype);
}
else {
throw new Error("Class definition 'extends' property must be a constructor function was: " + stringify(clsDef.extends));
}
}
for (var key in clsDef) {
if (key !== 'extends' && key !== 'prototype' && clsDef.hasOwnProperty(key)) {
proto[key] = applyParams(clsDef[key], key);
}
}
if (this && this.annotations instanceof Array) {
Reflect.defineMetadata('annotations', this.annotations, constructor);
}
var constructorName = constructor['name'];
if (!constructorName || constructorName === 'constructor') {
constructor['overriddenName'] = "class" + _nextClassId++;
}
return constructor;
}
/**
* @suppress {globalThis}
*/
function makeDecorator(name, props, parentClass, chainFn) {
var metaCtor = makeMetadataCtor([props]);
function DecoratorFactory(objOrType) {
if (!(Reflect && Reflect.getOwnMetadata)) {
throw 'reflect-metadata shim is required when using class decorators';
}
if (this instanceof DecoratorFactory) {
metaCtor.call(this, objOrType);
return this;
}
var annotationInstance = new DecoratorFactory(objOrType);
var chainAnnotation = typeof this === 'function' && Array.isArray(this.annotations) ? this.annotations : [];
chainAnnotation.push(annotationInstance);
var TypeDecorator = function TypeDecorator(cls) {
var annotations = Reflect.getOwnMetadata('annotations', cls) || [];
annotations.push(annotationInstance);
Reflect.defineMetadata('annotations', annotations, cls);
return cls;
};
TypeDecorator.annotations = chainAnnotation;
TypeDecorator.Class = Class;
if (chainFn)
chainFn(TypeDecorator);
return TypeDecorator;
}
if (parentClass) {
DecoratorFactory.prototype = Object.create(parentClass.prototype);
}
DecoratorFactory.prototype.toString = function () { return "@" + name; };
DecoratorFactory.annotationCls = DecoratorFactory;
return DecoratorFactory;
}
function makeMetadataCtor(props) {
return function ctor() {
var _this = this;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
props.forEach(function (prop, i) {
var argVal = args[i];
if (Array.isArray(prop)) {
// plain parameter
_this[prop[0]] = argVal === undefined ? prop[1] : argVal;
}
else {
for (var propName in prop) {
_this[propName] = argVal && argVal.hasOwnProperty(propName) ? argVal[propName] : prop[propName];
}
}
});
};
}
function makeParamDecorator(name, props, parentClass) {
var metaCtor = makeMetadataCtor(props);
function ParamDecoratorFactory() {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this instanceof ParamDecoratorFactory) {
metaCtor.apply(this, args);
return this;
}
var annotationInstance = new ((_a = ParamDecoratorFactory).bind.apply(_a, tslib.__spreadArrays([void 0], args)))();
ParamDecorator.annotation = annotationInstance;
return ParamDecorator;
function ParamDecorator(cls, unusedKey, index) {
var parameters = Reflect.getOwnMetadata('parameters', cls) || [];
// there might be gaps if some in between parameters do not have annotations.
// we pad with nulls.
while (parameters.length <= index) {
parameters.push(null);
}
parameters[index] = parameters[index] || [];
parameters[index].push(annotationInstance);
Reflect.defineMetadata('parameters', parameters, cls);
return cls;
}
}
if (parentClass) {
ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
ParamDecoratorFactory.prototype.toString = function () { return "@" + name; };
ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
return ParamDecoratorFactory;
}
function makePropDecorator(name, props, parentClass) {
var metaCtor = makeMetadataCtor(props);
function PropDecoratorFactory() {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this instanceof PropDecoratorFactory) {
metaCtor.apply(this, args);
return this;
}
var decoratorInstance = new ((_a = PropDecoratorFactory).bind.apply(_a, tslib.__spreadArrays([void 0], args)))();
return function PropDecorator(target, name) {
var meta = Reflect.getOwnMetadata('propMetadata', target.constructor) || {};
meta[name] = (meta.hasOwnProperty(name) && meta[name]) || [];
meta[name].unshift(decoratorInstance);
Reflect.defineMetadata('propMetadata', meta, target.constructor);
};
}
if (parentClass) {
PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
PropDecoratorFactory.prototype.toString = function () { return "@" + name; };
PropDecoratorFactory.annotationCls = PropDecoratorFactory;
return PropDecoratorFactory;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Inject decorator and metadata.
*
* @stable
* @Annotation
*/
var Inject = makeParamDecorator('Inject', [['token', undefined]]);
/**
* Optional decorator and metadata.
*
* @stable
* @Annotation
*/
var Optional = makeParamDecorator('Optional', []);
/**
* Injectable decorator and metadata.
*
* @stable
* @Annotation
*/
var Injectable = makeDecorator('Injectable', []);
/**
* Self decorator and metadata.
*
* @stable
* @Annotation
*/
var Self = makeParamDecorator('Self', []);
/**
* SkipSelf decorator and metadata.
*
* @stable
* @Annotation
*/
var SkipSelf = makeParamDecorator('SkipSelf', []);
/**
* Host decorator and metadata.
*
* @stable
* @Annotation
*/
var Host = makeParamDecorator('Host', []);
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Allows to refer to references which are not yet defined.
*
* For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
* DI is declared,
* but not yet defined. It is also used when the `token` which we use when creating a query is not
* yet defined.
*
* ### Example
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
* @experimental
*/
function forwardRef(forwardRefFn) {
forwardRefFn.__forward_ref__ = forwardRef;
forwardRefFn.toString = function () {
return stringify(this());
};
return forwardRefFn;
}
/**
* Lazily retrieves the reference value from a forwardRef.
*
* Acts as the identity function when given a non-forward-ref value.
*
* ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
*
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
*
* See: {@link forwardRef}
* @experimental
*/
function resolveForwardRef(type) {
if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') && type.__forward_ref__ === forwardRef) {
return type();
}
else {
return type;
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _THROW_IF_NOT_FOUND = new Object();
var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
// tslint:disable-next-line:class-name no-use-before-declare
var _NullInjector = /** @class */ (function () {
function _NullInjector() {
}
_NullInjector.prototype.get = function (token, notFoundValue) {
if (notFoundValue === void 0) { notFoundValue = _THROW_IF_NOT_FOUND; }
if (notFoundValue === _THROW_IF_NOT_FOUND) {
throw new Error("No provider for " + stringify(token) + "!");
}
return notFoundValue;
};
return _NullInjector;
}());
/**
* @whatItDoes Injector interface
* @howToUse
* ```
* const injector: Injector = ...;
* injector.get(...);
* ```
*
* @description
* For more details, see the {@linkDocs guide/dependency-injection "Dependency Injection Guide"}.
*
* ### Example
*
* {@example core/di/ts/injector_spec.ts region='Injector'}
*
* `Injector` returns itself when given `Injector` as a token:
* {@example core/di/ts/injector_spec.ts region='injectInjector'}
*
* @stable
*/
var Injector = /** @class */ (function () {
function Injector() {
}
Injector.THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
Injector.NULL = new _NullInjector();
return Injector;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
function getOriginalError(error) {
return error[ERROR_ORIGINAL_ERROR];
}
function wrappedError(message, originalError) {
var msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
var error = Error(msg);
error[ERROR_ORIGINAL_ERROR] = originalError;
return error;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function findFirstClosedCycle(keys) {
var res = [];
for (var i = 0; i < keys.length; ++i) {
if (res.indexOf(keys[i]) > -1) {
res.push(keys[i]);
return res;
}
res.push(keys[i]);
}
return res;
}
function constructResolvingPath(keys) {
if (keys.length > 1) {
var reversed = findFirstClosedCycle(keys.slice().reverse());
var tokenStrs = reversed.map(function (k) { return stringify(k.token); });
return ' (' + tokenStrs.join(' -> ') + ')';
}
return '';
}
function injectionError(injector, key, constructResolvingMessage, originalError) {
var error = (originalError ? wrappedError('', originalError) : Error());
error.addKey = addKey;
error.keys = [key];
error.injectors = [injector];
error.constructResolvingMessage = constructResolvingMessage;
error.message = error.constructResolvingMessage();
error[ERROR_ORIGINAL_ERROR] = originalError;
return error;
}
function addKey(injector, key) {
this.injectors.push(injector);
this.keys.push(key);
this.message = this.constructResolvingMessage();
}
/**
* Thrown when trying to retrieve a dependency by key from {@link Injector}, but the
* {@link Injector} does not have a {@link Provider} for the given key.
*
* ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
*
* ```typescript
* class A {
* constructor(b:B) {}
* }
*
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
*/
function noProviderError(injector, key) {
return injectionError(injector, key, function () {
var first = stringify(this.keys[0].token);
return "No provider for " + first + "!" + constructResolvingPath(this.keys);
});
}
/**
* Thrown when dependencies form a cycle.
*
* ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
* {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
* ]);
*
* expect(() => injector.get("one")).toThrowError();
* ```
*
* Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
*/
function cyclicDependencyError(injector, key) {
return injectionError(injector, key, function () {
return "Cannot instantiate cyclic dependency!" + constructResolvingPath(this.keys);
});
}
/**
* Thrown when a constructing type returns with an Error.
*
* The `InstantiationError` class contains the original error plus the dependency graph which caused
* this object to be instantiated.
*
* ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
*
* ```typescript
* class A {
* constructor() {
* throw new Error('message');
* }
* }
*
* var injector = Injector.resolveAndCreate([A]);
* try {
* injector.get(A);
* } catch (e) {
* expect(e instanceof InstantiationError).toBe(true);
* expect(e.originalException.message).toEqual("message");
* expect(e.originalStack).toBeDefined();
* }
* ```
*/
function instantiationError(injector, originalException, originalStack, key) {
return injectionError(injector, key, function () {
var first = stringify(this.keys[0].token);
return getOriginalError(this).message + ": Error during instantiation of " + first + "!" + constructResolvingPath(this.keys) + ".";
}, originalException);
}
/**
* Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
* creation.
*
* ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
*
* ```typescript
* expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
* ```
*/
function invalidProviderError(provider) {
return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
}
/**
* Thrown when the class has no annotation information.
*
* Lack of annotation information prevents the {@link Injector} from determining which dependencies
* need to be injected into the constructor.
*
* ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
*
* ```typescript
* class A {
* constructor(b) {}
* }
*
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
*
* This error is also thrown when the class not marked with {@link Injectable} has parameter types.
*
* ```typescript
* class B {}
*
* class A {
* constructor(b:B) {} // no information about the parameter types of A is available at runtime.
* }
*
* expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
* ```
* @stable
*/
function noAnnotationError(typeOrFunc, params) {
var signature = [];
for (var i = 0, ii = params.length; i < ii; i++) {
var parameter = params[i];
if (!parameter || parameter.length === 0) {
signature.push('?');
}
else {
signature.push(parameter.map(stringify).join(' '));
}
}
return Error("Cannot resolve all parameters for '" +
stringify(typeOrFunc) +
"'(" +
signature.join(', ') +
'). ' +
"Make sure that all the parameters are decorated with Inject or have valid type annotations and that '" +
stringify(typeOrFunc) +
"' is decorated with Injectable.");
}
/**
* Thrown when getting an object by index.
*
* ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
*
* ```typescript
* class A {}
*
* var injector = Injector.resolveAndCreate([A]);
*
* expect(() => injector.getAt(100)).toThrowError();
* ```
* @stable
*/
function outOfBoundsError(index) {
return Error("Index " + index + " is out-of-bounds.");
}
// TODO: add a working example after alpha38 is released
/**
* Thrown when a multi provider and a regular provider are bound to the same token.
*
* ### Example
*
* ```typescript
* expect(() => Injector.resolveAndCreate([
* { provide: "Strings", useValue: "string1", multi: true},
* { provide: "Strings", useValue: "string2", multi: false}
* ])).toThrowError();
* ```
*/
function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A unique object used for retrieving items from the {@link ReflectiveInjector}.
*
* Keys have:
* - a system-wide unique `id`.
* - a `token`.
*
* `Key` is used internally by {@link ReflectiveInjector} because its system-wide unique `id` allows
* the
* injector to store created objects in a more efficient way.
*
* `Key` should not be created directly. {@link ReflectiveInjector} creates keys automatically when
* resolving
* providers.
* @experimental
*/
var ReflectiveKey = /** @class */ (function () {
/**
* Private
*/
function ReflectiveKey(token, id) {
this.token = token;
this.id = id;
if (!token) {
throw new Error('Token must be defined!');
}
}
Object.defineProperty(ReflectiveKey.prototype, "displayName", {
/**
* Returns a stringified token.
*/
get: function () {
return stringify(this.token);
},
enumerable: false,
configurable: true
});
/**
* Retrieves a `Key` for a token.
*/
ReflectiveKey.get = function (token) {
// tslint:disable-next-line:no-use-before-declare
return _globalKeyRegistry.get(resolveForwardRef(token));
};
Object.defineProperty(ReflectiveKey, "numberOfKeys", {
/**
* @returns the number of keys registered in the system.
*/
get: function () {
// tslint:disable-next-line:no-use-before-declare
return _globalKeyRegistry.numberOfKeys;
},
enumerable: false,
configurable: true
});
return ReflectiveKey;
}());
/**
* @internal
*/
var KeyRegistry = /** @class */ (function () {
function KeyRegistry() {
this._allKeys = new Map();
}
KeyRegistry.prototype.get = function (token) {
if (token instanceof ReflectiveKey)
return token;
if (this._allKeys.has(token)) {
return this._allKeys.get(token);
}
var newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
this._allKeys.set(token, newKey);
return newKey;
};
Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
get: function () {
return this._allKeys.size;
},
enumerable: false,
configurable: true
});
return KeyRegistry;
}());
var _globalKeyRegistry = new KeyRegistry();
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @whatItDoes Represents a type that a Component or other object is instances of.
*
* @description
*
* An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
* the `MyCustomComponent` constructor function.
*
* @stable
*/
var Type = Function;
function isType(v) {
return typeof v === 'function';
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Attention: This regex has to hold even if the code is minified!
*/
var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
var ReflectionCapabilities = /** @class */ (function () {
function ReflectionCapabilities(reflect) {
this._reflect = reflect || _global['Reflect'];
}
ReflectionCapabilities.prototype.isReflectionEnabled = function () {
return true;
};
ReflectionCapabilities.prototype.factory = function (t) {
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return new (t.bind.apply(t, tslib.__spreadArrays([void 0], args)))();
};
};
/** @internal */
ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
var result;
if (typeof paramTypes === 'undefined') {
result = new Array(paramAnnotations.length);
}
else {
result = new Array(paramTypes.length);
}
for (var i = 0; i < result.length; i++) {
// TS outputs Object for parameters without types, while Traceur omits
// the annotations. For now we preserve the Traceur behavior to aid
// migration, but this can be revisited.
if (typeof paramTypes === 'undefined') {
result[i] = [];
// tslint:disable-next-line:triple-equals
}
else if (paramTypes[i] != Object) {
result[i] = [paramTypes[i]];
}
else {
result[i] = [];
}
if (paramAnnotations && paramAnnotations[i] != null) {
result[i] = result[i].concat(paramAnnotations[i]);
}
}
return result;
};
ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
// If we have no decorators, we only have function.length as metadata.
// In that case, to detect whether a child class declared an own constructor or not,
// we need to look inside of that constructor to check whether it is
// just calling the parent.
// This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
// that sets 'design:paramtypes' to []
// if a class inherits from another class but has no ctor declared itself.
if (DELEGATE_CTOR.exec(type.toString())) {
return null;
}
// Prefer the direct API.
if (type.parameters && type.parameters !== parentCtor.parameters) {
return type.parameters;
}
// API of tsickle for lowering decorators to properties on the class.
var tsickleCtorParams = type.ctorParameters;
if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
// Newer tsickle uses a function closure
// Retain the non-function case for compatibility with older tsickle
var ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
var paramTypes = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
var paramAnnotations = ctorParameters.map(function (ctorParam) { return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators); });
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
}
// API for metadata created by invoking the decorators.
if (this._reflect != null && this._reflect.getOwnMetadata != null) {
var paramAnnotations = this._reflect.getOwnMetadata('parameters', type);
var paramTypes = this._reflect.getOwnMetadata('design:paramtypes', type);
if (paramTypes || paramAnnotations) {
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
}
}
// If a class has no decorators, at least create metadata
// based on function.length.
// Note: We know that this is a real constructor as we checked
// the content of the constructor above.
return new Array(type.length).fill(undefined);
};
ReflectionCapabilities.prototype.parameters = function (type) {
// Note: only report metadata if we have at least one class decorator
// to stay in sync with the static reflector.
if (!isType(type)) {
return [];
}
var parentCtor = getParentCtor(type);
var parameters = this._ownParameters(type, parentCtor);
if (!parameters && parentCtor !== Object) {
parameters = this.parameters(parentCtor);
}
return parameters || [];
};
ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
// Prefer the direct API.
if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
var annotations = typeOrFunc.annotations;
if (typeof annotations === 'function' && annotations.annotations) {
annotations = annotations.annotations;
}
return annotations;
}
// API of tsickle for lowering decorators to properties on the class.
if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
}
// API for metadata created by invoking the decorators.
if (this._reflect && this._reflect.getOwnMetadata) {
return this._reflect.getOwnMetadata('annotations', typeOrFunc);
}
return null;
};
ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
if (!isType(typeOrFunc)) {
return [];
}
var parentCtor = getParentCtor(typeOrFunc);
var ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
var parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
return parentAnnotations.concat(ownAnnotations);
};
ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
// Prefer the direct API.
if (typeOrFunc.propMetadata && typeOrFunc.propMetadata !== parentCtor.propMetadata) {
var propMetadata = typeOrFunc.propMetadata;
if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
propMetadata = propMetadata.propMetadata;
}
return propMetadata;
}
// API of tsickle for lowering decorators to properties on the class.
if (typeOrFunc.propDecorators && typeOrFunc.propDecorators !== parentCtor.propDecorators) {
var propDecorators_1 = typeOrFunc.propDecorators;
var propMetadata_1 = {};
Object.keys(propDecorators_1).forEach(function (prop) {
propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
});
return propMetadata_1;
}
// API for metadata created by invoking the decorators.
if (this._reflect && this._reflect.getOwnMetadata) {
return this._reflect.getOwnMetadata('propMetadata', typeOrFunc);
}
return null;
};
ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
if (!isType(typeOrFunc)) {
return {};
}
var parentCtor = getParentCtor(typeOrFunc);
var propMetadata = {};
if (parentCtor !== Object) {
var parentPropMetadata_1 = this.propMetadata(parentCtor);
Object.keys(parentPropMetadata_1).forEach(function (propName) {
propMetadata[propName] = parentPropMetadata_1[propName];
});
}
var ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
if (ownPropMetadata) {
Object.keys(ownPropMetadata).forEach(function (propName) {
var decorators = [];
if (propMetadata.hasOwnProperty(propName)) {
decorators.push.apply(decorators, propMetadata[propName]);
}
decorators.push.apply(decorators, ownPropMetadata[propName]);
propMetadata[propName] = decorators;
});
}
return propMetadata;
};
ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
return type instanceof Type && lcProperty in type.prototype;
};
ReflectionCapabilities.prototype.getter = function (name) {
return new Function('o', 'return o.' + name + ';');
};
ReflectionCapabilities.prototype.setter = function (name) {
return new Function('o', 'v', 'return o.' + name + ' = v;');
};
ReflectionCapabilities.prototype.method = function (name) {
var functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n return o." + name + ".apply(o, args);";
return new Function('o', 'args', functionBody);
};
// There is not a concept of import uri in Js, but this is useful in developing Dart applications.
ReflectionCapabilities.prototype.importUri = function (type) {
// StaticSymbol
if (typeof type === 'object' && type['filePath']) {
return type['filePath'];
}
// Runtime type
return "./" + stringify(type);
};
ReflectionCapabilities.prototype.resourceUri = function (type) {
return "./" + stringify(type);
};
ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
return runtime;
};
ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) {
return enumIdentifier[name];
};
return ReflectionCapabilities;
}());
function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
if (!decoratorInvocations) {
return [];
}
return decoratorInvocations.map(function (decoratorInvocation) {
var decoratorType = decoratorInvocation.type;
var annotationCls = decoratorType.annotationCls;
var annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
return new (annotationCls.bind.apply(annotationCls, tslib.__spreadArrays([void 0], annotationArgs)))();
});
}
function getParentCtor(ctor) {
if (!ctor.prototype) {
return Object;
}
var parentProto = Object.getPrototypeOf(ctor.prototype);
var parentCtor = parentProto ? parentProto.constructor : null;
// Note: We always use `Object` as the null value
// to simplify checking later on.
return parentCtor || Object;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Provides read-only access to reflection data about symbols. Used internally by Angular
* to power dependency injection and compilation.
*/
var ReflectorReader = /** @class */ (function () {
function ReflectorReader() {
}
return ReflectorReader;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Provides access to reflection data about symbols. Used internally by Angular
* to power dependency injection and compilation.
*/
var Reflector = /** @class */ (function (_super) {
tslib.__extends(Reflector, _super);
function Reflector(reflectionCapabilities) {
var _this = _super.call(this) || this;
_this.reflectionCapabilities = reflectionCapabilities;
return _this;
}
Reflector.prototype.updateCapabilities = function (caps) {
this.reflectionCapabilities = caps;
};
Reflector.prototype.factory = function (type) {
return this.reflectionCapabilities.factory(type);
};
Reflector.prototype.parameters = function (typeOrFunc) {
return this.reflectionCapabilities.parameters(typeOrFunc);
};
Reflector.prototype.annotations = function (typeOrFunc) {
return this.reflectionCapabilities.annotations(typeOrFunc);
};
Reflector.prototype.propMetadata = function (typeOrFunc) {
return this.reflectionCapabilities.propMetadata(typeOrFunc);
};
Reflector.prototype.hasLifecycleHook = function (type, lcProperty) {
return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
};
Reflector.prototype.getter = function (name) {
return this.reflectionCapabilities.getter(name);
};
Reflector.prototype.setter = function (name) {
return this.reflectionCapabilities.setter(name);
};
Reflector.prototype.method = function (name) {
return this.reflectionCapabilities.method(name);
};
Reflector.prototype.importUri = function (type) {
return this.reflectionCapabilities.importUri(type);
};
Reflector.prototype.resourceUri = function (type) {
return this.reflectionCapabilities.resourceUri(type);
};
Reflector.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
};
Reflector.prototype.resolveEnum = function (identifier, name) {
return this.reflectionCapabilities.resolveEnum(identifier, name);
};
return Reflector;
}(ReflectorReader));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* The {@link Reflector} used internally in Angular to access metadata
* about symbols.
*/
var reflector = new Reflector(new ReflectionCapabilities());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Creates a token that can be used in a DI Provider.
*
* ### Example ([live demo](http://plnkr.co/edit/Ys9ezXpj2Mnoy3Uc8KBp?p=preview))
*
* ```typescript
* var t = new OpaqueToken("value");
*
* var injector = Injector.resolveAndCreate([
* {provide: t, useValue: "bindingValue"}
* ]);
*
* expect(injector.get(t)).toEqual("bindingValue");
* ```
*
* Using an `OpaqueToken` is preferable to using strings as tokens because of possible collisions
* caused by multiple providers using the same string as two different tokens.
*
* Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
* error messages.
* @deprecated since v4.0.0 because it does not support type information, use `InjectionToken<?>`
* instead.
*/
var OpaqueToken = /** @class */ (function () {
function OpaqueToken(_desc) {
this._desc = _desc;
}
OpaqueToken.prototype.toString = function () {
return "Token " + this._desc;
};
return OpaqueToken;
}());
/**
* Creates a token that can be used in a DI Provider.
*
* Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
* runtime representation) such as when injecting an interface, callable type, array or
* parametrized type.
*
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
* the `Injector`. This provides additional level of type safety.
*
* ```
* interface MyInterface {...}
* var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
* // myInterface is inferred to be MyInterface.
* ```
*
* ### Example
*
* {@example core/di/ts/injector_spec.ts region='InjectionToken'}
*
* @stable
*/
var InjectionToken = /** @class */ (function (_super) {
tslib.__extends(InjectionToken, _super);
function InjectionToken(desc) {
return _super.call(this, desc) || this;
}
InjectionToken.prototype.toString = function () {
return "InjectionToken " + this._desc;
};
return InjectionToken;
}(OpaqueToken));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* `Dependency` is used by the framework to extend DI.
* This is internal to Angular and should not be used directly.
*/
var ReflectiveDependency = /** @class */ (function () {
function ReflectiveDependency(key, optional, visibility) {
this.key = key;
this.optional = optional;
this.visibility = visibility;
}
ReflectiveDependency.fromKey = function (key) {
return new ReflectiveDependency(key, false, null);
};
return ReflectiveDependency;
}());
var _EMPTY_LIST = [];
// tslint:disable-next-line:class-name
var ResolvedReflectiveProvider_ = /** @class */ (function () {
function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
this.key = key;
this.resolvedFactories = resolvedFactories;
this.multiProvider = multiProvider;
}
Object.defineProperty(ResolvedReflectiveProvider_.prototype, "resolvedFactory", {
get: function () {
return this.resolvedFactories[0];
},
enumerable: false,
configurable: true
});
return ResolvedReflectiveProvider_;
}());
/**
* An internal resolved representation of a factory function created by resolving {@link
* Provider}.
* @experimental
*/
var ResolvedReflectiveFactory = /** @class */ (function () {
function ResolvedReflectiveFactory(
/**
* Factory function which can return an instance of an object represented by a key.
*/
factory,
/**
* Arguments (dependencies) to the `factory` function.
*/
dependencies) {
this.factory = factory;
this.dependencies = dependencies;
}
return ResolvedReflectiveFactory;
}());
/**
* Resolve a single provider.
*/
function resolveReflectiveFactory(provider) {
var factoryFn;
var resolvedDeps;
if (provider.useClass) {
var useClass = resolveForwardRef(provider.useClass);
factoryFn = reflector.factory(useClass);
resolvedDeps = _dependenciesFor(useClass);
}
else if (provider.useExisting) {
factoryFn = function (aliasInstance) { return aliasInstance; };
resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
}
else if (provider.useFactory) {
factoryFn = provider.useFactory;
resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
}
else {
factoryFn = function () { return provider.useValue; };
resolvedDeps = _EMPTY_LIST;
}
return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
}
/**
* Converts the {@link Provider} into {@link ResolvedProvider}.
*
* {@link Injector} internally only uses {@link ResolvedProvider}, {@link Provider} contains
* convenience provider syntax.
*/
function resolveReflectiveProvider(provider) {
return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
}
/**
* Resolve a list of Providers.
*/