static-injector 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/import/commonjs/index.js +403 -211
- package/import/{es2015 → es2022}/di/create_injector.js +5 -3
- package/import/{es2015 → es2022}/di/forward_ref.js +32 -5
- package/import/{es2015 → es2022}/di/injection_token.js +20 -11
- package/import/{es2015 → es2022}/di/injector.js +15 -16
- package/import/{es2015 → es2022}/di/injector_compatibility.js +27 -13
- package/import/{es2015 → es2022}/di/injector_token.js +3 -3
- package/import/{es2015 → es2022}/di/interface/defs.js +22 -27
- package/import/{es2015 → es2022}/di/interface/injector.js +1 -1
- package/import/{es2015 → es2022}/di/interface/provider.js +3 -1
- package/import/{es2015 → es2022}/di/null_injector.js +3 -3
- package/import/es2022/di/provider_collection.js +104 -0
- package/import/{es2015 → es2022}/di/r3_injector.js +71 -37
- package/import/es2022/error_details_base_url.js +19 -0
- package/import/es2022/errors.js +44 -0
- package/import/es2022/interface/type.js +21 -0
- package/import/{es2015 → es2022}/render3/definition_factory.js +2 -3
- package/import/{es2015 → es2022}/render3/error_code.js +1 -0
- package/import/{es2015 → es2022}/render3/errors_di.js +2 -3
- package/import/es2022/render3/fields.js +22 -0
- package/import/{es2015 → es2022}/render3/instructions/di.js +0 -7
- package/import/{es2015 → es2022}/render3/util/stringify_utils.js +5 -5
- package/import/{es2015 → es2022}/util/array_utils.js +0 -7
- package/import/es2022/util/decorators.js +53 -0
- package/import/{es2015 → es2022}/util/empty.js +4 -0
- package/import/{es2015 → es2022}/util/stringify.js +5 -5
- package/import/{fesm2015 → fesm2022}/index.js +399 -209
- package/import/typings/di/create_injector.d.ts +3 -5
- package/import/typings/di/forward_ref.d.ts +30 -3
- package/import/typings/di/inject_switch.d.ts +1 -1
- package/import/typings/di/injectable.d.ts +4 -3
- package/import/typings/di/injection_token.d.ts +21 -6
- package/import/typings/di/injector.d.ts +19 -3
- package/import/typings/di/injector_compatibility.d.ts +12 -5
- package/import/typings/di/injector_token.d.ts +2 -2
- package/import/typings/di/interface/defs.d.ts +17 -9
- package/import/typings/di/interface/injector.d.ts +2 -2
- package/import/typings/di/interface/provider.d.ts +64 -4
- package/import/typings/di/metadata.d.ts +4 -4
- package/import/typings/di/null_injector.d.ts +1 -1
- package/import/typings/di/provider_collection.d.ts +53 -11
- package/import/typings/di/provider_token.d.ts +2 -2
- package/import/typings/di/r3_injector.d.ts +11 -14
- package/import/typings/di/scope.d.ts +1 -1
- package/import/typings/error_details_base_url.d.ts +19 -0
- package/import/typings/errors.d.ts +114 -0
- package/import/typings/interface/type.d.ts +45 -0
- package/import/typings/render3/errors_di.d.ts +7 -0
- package/import/typings/render3/fields.d.ts +9 -0
- package/import/typings/render3/instructions/di.d.ts +0 -7
- package/import/typings/util/array_utils.d.ts +15 -7
- package/import/typings/util/decorators.d.ts +3 -1
- package/import/typings/util/empty.d.ts +1 -0
- package/package.json +7 -7
- package/readme.md +4 -1
- package/transform/compiler/src/injectable_compiler_2.d.ts +0 -1
- package/transform/compiler/src/injectable_compiler_2.js +31 -16
- package/transform/compiler/src/output/output_ast.d.ts +53 -10
- package/transform/compiler/src/output/output_ast.js +211 -12
- package/transform/compiler/src/parse_util.js +10 -0
- package/transform/compiler/src/render3/partial/api.js +1 -1
- package/transform/compiler/src/render3/r3_factory.d.ts +0 -8
- package/transform/compiler/src/render3/r3_factory.js +5 -4
- package/transform/compiler/src/render3/r3_identifiers.js +37 -37
- package/transform/compiler/src/render3/view/util.js +1 -3
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +2 -4
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/factory.js +1 -0
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.d.ts +1 -1
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +5 -9
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +2 -1
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +12 -8
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.d.ts +2 -2
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.js +8 -4
- package/transform/compiler-cli/src/ngtsc/diagnostics/error_code.js +1 -1
- package/transform/compiler-cli/src/ngtsc/imports/src/default.js +1 -2
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +24 -173
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +2 -51
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +5 -3
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +5 -10
- package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +5 -23
- package/transform/compiler-cli/src/ngtsc/transform/src/api.js +0 -21
- package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +1 -2
- package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +7 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/context.js +1 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +4 -2
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +1 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +10 -4
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +2 -1
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +20 -16
- package/transform/injectable-transform.d.ts +2 -2
- package/transform/injectable-transform.js +32 -6
- package/import/es2015/di/provider_collection.js +0 -49
- package/import/es2015/interface/type.js +0 -8
- package/import/es2015/render3/fields.js +0 -11
- package/import/es2015/util/decorators.js +0 -30
- /package/import/{es2015 → es2022}/di/initializer_token.js +0 -0
- /package/import/{es2015 → es2022}/di/inject_switch.js +0 -0
- /package/import/{es2015 → es2022}/di/injectable.js +0 -0
- /package/import/{es2015 → es2022}/di/injector_marker.js +0 -0
- /package/import/{es2015 → es2022}/di/internal_tokens.js +0 -0
- /package/import/{es2015 → es2022}/di/metadata.js +0 -0
- /package/import/{es2015 → es2022}/di/provider_token.js +0 -0
- /package/import/{es2015 → es2022}/di/scope.js +0 -0
- /package/import/{es2015 → es2022}/index.js +0 -0
- /package/import/{es2015 → es2022}/interface/lifecycle_hooks.js +0 -0
- /package/import/{es2015 → es2022}/render3/di.js +0 -0
- /package/import/{es2015 → es2022}/util/closure.js +0 -0
- /package/import/{es2015 → es2022}/util/property.js +0 -0
package/import/commonjs/index.js
CHANGED
|
@@ -42,6 +42,7 @@ function noSideEffects(fn) {
|
|
|
42
42
|
* Use of this source code is governed by an MIT-style license that can be
|
|
43
43
|
* found in the LICENSE file at https://angular.io/license
|
|
44
44
|
*/
|
|
45
|
+
const PARAMETERS = '__parameters__';
|
|
45
46
|
function makeMetadataCtor(props) {
|
|
46
47
|
return function ctor(...args) {
|
|
47
48
|
if (props) {
|
|
@@ -52,7 +53,7 @@ function makeMetadataCtor(props) {
|
|
|
52
53
|
}
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
|
-
function makeParamDecorator(name, props) {
|
|
56
|
+
function makeParamDecorator(name, props, parentClass) {
|
|
56
57
|
return noSideEffects(() => {
|
|
57
58
|
const metaCtor = makeMetadataCtor(props);
|
|
58
59
|
function ParamDecoratorFactory(...args) {
|
|
@@ -60,7 +61,29 @@ function makeParamDecorator(name, props) {
|
|
|
60
61
|
metaCtor.apply(this, args);
|
|
61
62
|
return this;
|
|
62
63
|
}
|
|
64
|
+
const annotationInstance = new ParamDecoratorFactory(...args);
|
|
65
|
+
ParamDecorator.annotation = annotationInstance;
|
|
66
|
+
return ParamDecorator;
|
|
67
|
+
function ParamDecorator(cls, unusedKey, index) {
|
|
68
|
+
// Use of Object.defineProperty is important since it creates non-enumerable property which
|
|
69
|
+
// prevents the property is copied during subclassing.
|
|
70
|
+
const parameters = cls.hasOwnProperty(PARAMETERS)
|
|
71
|
+
? cls[PARAMETERS]
|
|
72
|
+
: Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
|
|
73
|
+
// there might be gaps if some in between parameters do not have annotations.
|
|
74
|
+
// we pad with nulls.
|
|
75
|
+
while (parameters.length <= index) {
|
|
76
|
+
parameters.push(null);
|
|
77
|
+
}
|
|
78
|
+
(parameters[index] = parameters[index] || []).push(annotationInstance);
|
|
79
|
+
return cls;
|
|
80
|
+
}
|
|
63
81
|
}
|
|
82
|
+
if (parentClass) {
|
|
83
|
+
ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
|
|
84
|
+
}
|
|
85
|
+
ParamDecoratorFactory.prototype.ngMetadataName = name;
|
|
86
|
+
ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
|
|
64
87
|
return ParamDecoratorFactory;
|
|
65
88
|
});
|
|
66
89
|
}
|
|
@@ -72,13 +95,42 @@ function makeParamDecorator(name, props) {
|
|
|
72
95
|
* Use of this source code is governed by an MIT-style license that can be
|
|
73
96
|
* found in the LICENSE file at https://angular.io/license
|
|
74
97
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Class that represents a runtime error.
|
|
100
|
+
* Formats and outputs the error message in a consistent way.
|
|
101
|
+
*
|
|
102
|
+
* Example:
|
|
103
|
+
* ```
|
|
104
|
+
* throw new RuntimeError(
|
|
105
|
+
* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
|
|
106
|
+
* ngDevMode && 'Injector has already been destroyed.');
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* Note: the `message` argument contains a descriptive error message as a string in development
|
|
110
|
+
* mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
|
|
111
|
+
* `message` argument becomes `false`, thus we account for it in the typings and the runtime
|
|
112
|
+
* logic.
|
|
113
|
+
*/
|
|
114
|
+
class RuntimeError extends Error {
|
|
115
|
+
code;
|
|
116
|
+
constructor(code, message) {
|
|
117
|
+
super(formatRuntimeError(code, message));
|
|
118
|
+
this.code = code;
|
|
80
119
|
}
|
|
81
|
-
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Called to format a runtime error.
|
|
123
|
+
* See additional info on the `message` argument type in the `RuntimeError` class description.
|
|
124
|
+
*/
|
|
125
|
+
function formatRuntimeError(code, message) {
|
|
126
|
+
// Error code might be a negative number, which is a special marker that instructs the logic to
|
|
127
|
+
// generate a link to the error details page on angular.io.
|
|
128
|
+
// We also prepend `0` to non-compile-time errors.
|
|
129
|
+
const fullCode = `NG0${Math.abs(code)}`;
|
|
130
|
+
let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
|
|
131
|
+
if (false) {
|
|
132
|
+
}
|
|
133
|
+
return errorMessage;
|
|
82
134
|
}
|
|
83
135
|
|
|
84
136
|
/**
|
|
@@ -89,14 +141,14 @@ function getClosureSafeProperty(objWithPropertyToExtract) {
|
|
|
89
141
|
* found in the LICENSE file at https://angular.io/license
|
|
90
142
|
*/
|
|
91
143
|
function stringify(token) {
|
|
92
|
-
if (typeof token ===
|
|
144
|
+
if (typeof token === 'string') {
|
|
93
145
|
return token;
|
|
94
146
|
}
|
|
95
147
|
if (Array.isArray(token)) {
|
|
96
|
-
return
|
|
148
|
+
return '[' + token.map(stringify).join(', ') + ']';
|
|
97
149
|
}
|
|
98
150
|
if (token == null) {
|
|
99
|
-
return
|
|
151
|
+
return '' + token;
|
|
100
152
|
}
|
|
101
153
|
if (token.overriddenName) {
|
|
102
154
|
return `${token.overriddenName}`;
|
|
@@ -106,12 +158,28 @@ function stringify(token) {
|
|
|
106
158
|
}
|
|
107
159
|
const res = token.toString();
|
|
108
160
|
if (res == null) {
|
|
109
|
-
return
|
|
161
|
+
return '' + res;
|
|
110
162
|
}
|
|
111
|
-
const newLineIndex = res.indexOf(
|
|
163
|
+
const newLineIndex = res.indexOf('\n');
|
|
112
164
|
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
|
|
113
165
|
}
|
|
114
166
|
|
|
167
|
+
/**
|
|
168
|
+
* @license
|
|
169
|
+
* Copyright Google LLC All Rights Reserved.
|
|
170
|
+
*
|
|
171
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
172
|
+
* found in the LICENSE file at https://angular.io/license
|
|
173
|
+
*/
|
|
174
|
+
function getClosureSafeProperty(objWithPropertyToExtract) {
|
|
175
|
+
for (let key in objWithPropertyToExtract) {
|
|
176
|
+
if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
|
|
177
|
+
return key;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
throw Error('Could not find renamed property on target object.');
|
|
181
|
+
}
|
|
182
|
+
|
|
115
183
|
/**
|
|
116
184
|
* @license
|
|
117
185
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -129,9 +197,36 @@ const __forward_ref__ = getClosureSafeProperty({
|
|
|
129
197
|
* DI is declared, but not yet defined. It is also used when the `token` which we use when creating
|
|
130
198
|
* a query is not yet defined.
|
|
131
199
|
*
|
|
200
|
+
* `forwardRef` is also used to break circularities in standalone components imports.
|
|
201
|
+
*
|
|
132
202
|
* @usageNotes
|
|
133
|
-
* ###
|
|
203
|
+
* ### Circular dependency example
|
|
134
204
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
|
|
205
|
+
*
|
|
206
|
+
* ### Circular standalone reference import example
|
|
207
|
+
* ```ts
|
|
208
|
+
* @Component({
|
|
209
|
+
* standalone: true,
|
|
210
|
+
* imports: [ChildComponent],
|
|
211
|
+
* selector: 'app-parent',
|
|
212
|
+
* template: `<app-child [hideParent]="hideParent"></app-child>`,
|
|
213
|
+
* })
|
|
214
|
+
* export class ParentComponent {
|
|
215
|
+
* @Input() hideParent: boolean;
|
|
216
|
+
* }
|
|
217
|
+
*
|
|
218
|
+
*
|
|
219
|
+
* @Component({
|
|
220
|
+
* standalone: true,
|
|
221
|
+
* imports: [CommonModule, forwardRef(() => ParentComponent)],
|
|
222
|
+
* selector: 'app-child',
|
|
223
|
+
* template: `<app-parent *ngIf="!hideParent"></app-parent>`,
|
|
224
|
+
* })
|
|
225
|
+
* export class ChildComponent {
|
|
226
|
+
* @Input() hideParent: boolean;
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*
|
|
135
230
|
* @publicApi
|
|
136
231
|
*/
|
|
137
232
|
function forwardRef(forwardRefFn) {
|
|
@@ -151,7 +246,7 @@ function forwardRef(forwardRefFn) {
|
|
|
151
246
|
*
|
|
152
247
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
|
|
153
248
|
*
|
|
154
|
-
* @see
|
|
249
|
+
* @see {@link forwardRef}
|
|
155
250
|
* @publicApi
|
|
156
251
|
*/
|
|
157
252
|
function resolveForwardRef(type) {
|
|
@@ -159,79 +254,11 @@ function resolveForwardRef(type) {
|
|
|
159
254
|
}
|
|
160
255
|
/** Checks whether a function is wrapped by a `forwardRef`. */
|
|
161
256
|
function isForwardRef(fn) {
|
|
162
|
-
return (typeof fn ===
|
|
257
|
+
return (typeof fn === 'function' &&
|
|
163
258
|
fn.hasOwnProperty(__forward_ref__) &&
|
|
164
259
|
fn.__forward_ref__ === forwardRef);
|
|
165
260
|
}
|
|
166
261
|
|
|
167
|
-
/**
|
|
168
|
-
* @license
|
|
169
|
-
* Copyright Google LLC All Rights Reserved.
|
|
170
|
-
*
|
|
171
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
172
|
-
* found in the LICENSE file at https://angular.io/license
|
|
173
|
-
*/
|
|
174
|
-
class RuntimeError extends Error {
|
|
175
|
-
constructor(code, message) {
|
|
176
|
-
super(formatRuntimeError(code, message));
|
|
177
|
-
this.code = code;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/* tslint:enable:no-toplevel-property-access */
|
|
181
|
-
/** Called to format a runtime error */
|
|
182
|
-
function formatRuntimeError(code, message) {
|
|
183
|
-
const fullCode = code ? `NG0${code}: ` : '';
|
|
184
|
-
let errorMessage = `${fullCode}${message}`;
|
|
185
|
-
// Some runtime errors are still thrown without `ngDevMode` (for example
|
|
186
|
-
// `throwProviderNotFoundError`), so we add `ngDevMode` check here to avoid pulling
|
|
187
|
-
// `RUNTIME_ERRORS_WITH_GUIDES` symbol into prod bundles.
|
|
188
|
-
// TODO: revisit all instances where `RuntimeError` is thrown and see if `ngDevMode` can be added
|
|
189
|
-
// there instead to tree-shake more devmode-only code (and eventually remove `ngDevMode` check
|
|
190
|
-
// from this code).
|
|
191
|
-
// if (ngDevMode && RUNTIME_ERRORS_WITH_GUIDES.has(code)) {
|
|
192
|
-
// errorMessage = `${errorMessage}. Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/NG0${code}`;
|
|
193
|
-
// }
|
|
194
|
-
return errorMessage;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* @license
|
|
199
|
-
* Copyright Google LLC All Rights Reserved.
|
|
200
|
-
*
|
|
201
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
202
|
-
* found in the LICENSE file at https://angular.io/license
|
|
203
|
-
*/
|
|
204
|
-
/**
|
|
205
|
-
* Used for stringify render output in Ivy.
|
|
206
|
-
* Important! This function is very performance-sensitive and we should
|
|
207
|
-
* be extra careful not to introduce megamorphic reads in it.
|
|
208
|
-
* Check `core/test/render3/perf/render_stringify` for benchmarks and alternate implementations.
|
|
209
|
-
*/
|
|
210
|
-
function renderStringify(value) {
|
|
211
|
-
if (typeof value === "string")
|
|
212
|
-
return value;
|
|
213
|
-
if (value == null)
|
|
214
|
-
return "";
|
|
215
|
-
// Use `String` so that it invokes the `toString` method of the value. Note that this
|
|
216
|
-
// appears to be faster than calling `value.toString` (see `render_stringify` benchmark).
|
|
217
|
-
return String(value);
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Used to stringify a value so that it can be displayed in an error message.
|
|
221
|
-
* Important! This function contains a megamorphic read and should only be
|
|
222
|
-
* used for error messages.
|
|
223
|
-
*/
|
|
224
|
-
function stringifyForError(value) {
|
|
225
|
-
if (typeof value === "function")
|
|
226
|
-
return value.name || value.toString();
|
|
227
|
-
if (typeof value === "object" &&
|
|
228
|
-
value != null &&
|
|
229
|
-
typeof value.type === "function") {
|
|
230
|
-
return value.type.name || value.type.toString();
|
|
231
|
-
}
|
|
232
|
-
return renderStringify(value);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
262
|
/**
|
|
236
263
|
* @license
|
|
237
264
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -242,7 +269,7 @@ function stringifyForError(value) {
|
|
|
242
269
|
/** Throws an error when a token is not found in DI. */
|
|
243
270
|
function throwProviderNotFoundError(token, injectorName) {
|
|
244
271
|
const injectorDetails = injectorName ? ` in ${injectorName}` : '';
|
|
245
|
-
throw new RuntimeError(
|
|
272
|
+
throw new RuntimeError(-201 /* RuntimeErrorCode.PROVIDER_NOT_FOUND */, null);
|
|
246
273
|
}
|
|
247
274
|
|
|
248
275
|
/**
|
|
@@ -264,7 +291,8 @@ function throwProviderNotFoundError(token, injectorName) {
|
|
|
264
291
|
* with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
|
|
265
292
|
* provided in the `'root'` injector, which will be the application-level injector in most apps.
|
|
266
293
|
* * `factory` gives the zero argument function which will create an instance of the injectable.
|
|
267
|
-
* The factory can call `inject` to access the `Injector` and request injection
|
|
294
|
+
* The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection
|
|
295
|
+
* of dependencies.
|
|
268
296
|
*
|
|
269
297
|
* @codeGenApi
|
|
270
298
|
* @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
|
|
@@ -304,7 +332,10 @@ function ɵɵdefineInjector(options) {
|
|
|
304
332
|
* @param type A type which may have its own (non-inherited) `ɵprov`.
|
|
305
333
|
*/
|
|
306
334
|
function getInjectableDef(type) {
|
|
307
|
-
return getOwnDefinition(type, NG_PROV_DEF);
|
|
335
|
+
return getOwnDefinition(type, NG_PROV_DEF) || null;
|
|
336
|
+
}
|
|
337
|
+
function isInjectable(type) {
|
|
338
|
+
return getInjectableDef(type) !== null;
|
|
308
339
|
}
|
|
309
340
|
/**
|
|
310
341
|
* Return definition only if it is defined directly on `type` and is not inherited from a base
|
|
@@ -313,9 +344,6 @@ function getInjectableDef(type) {
|
|
|
313
344
|
function getOwnDefinition(type, field) {
|
|
314
345
|
return type.hasOwnProperty(field) ? type[field] : null;
|
|
315
346
|
}
|
|
316
|
-
const NG_PROV_DEF = getClosureSafeProperty({
|
|
317
|
-
ɵprov: getClosureSafeProperty,
|
|
318
|
-
});
|
|
319
347
|
/**
|
|
320
348
|
* Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
|
|
321
349
|
*
|
|
@@ -325,36 +353,30 @@ const NG_PROV_DEF = getClosureSafeProperty({
|
|
|
325
353
|
* scenario if we find the `ɵprov` on an ancestor only.
|
|
326
354
|
*/
|
|
327
355
|
function getInheritedInjectableDef(type) {
|
|
328
|
-
const def = type && (type[NG_PROV_DEF] ||
|
|
356
|
+
const def = type && (type[NG_PROV_DEF] || null);
|
|
329
357
|
if (def) {
|
|
330
|
-
const typeName = getTypeName(type);
|
|
331
|
-
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
|
332
|
-
// ngDevMode &&
|
|
333
|
-
console.warn(`DEPRECATED: DI is instantiating a token "${typeName}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
|
334
|
-
`This will become an error in a future version of Angular. Please add @Injectable() to the "${typeName}" class.`);
|
|
335
358
|
return def;
|
|
336
359
|
}
|
|
337
360
|
else {
|
|
338
361
|
return null;
|
|
339
362
|
}
|
|
340
363
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
// browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
|
|
351
|
-
// the issue by converting the function to a string and parsing its name out that way via a regex.
|
|
352
|
-
if (type.hasOwnProperty('name')) {
|
|
353
|
-
return type.name;
|
|
354
|
-
}
|
|
355
|
-
const match = ('' + type).match(/^function\s*([^\s(]+)/);
|
|
356
|
-
return match === null ? '' : match[1];
|
|
364
|
+
/**
|
|
365
|
+
* Read the injector def type in a way which is immune to accidentally reading inherited value.
|
|
366
|
+
*
|
|
367
|
+
* @param type type which may have an injector def (`ɵinj`)
|
|
368
|
+
*/
|
|
369
|
+
function getInjectorDef(type) {
|
|
370
|
+
return type && (type.hasOwnProperty(NG_INJ_DEF) || false)
|
|
371
|
+
? type[NG_INJ_DEF]
|
|
372
|
+
: null;
|
|
357
373
|
}
|
|
374
|
+
const NG_PROV_DEF = getClosureSafeProperty({
|
|
375
|
+
ɵprov: getClosureSafeProperty,
|
|
376
|
+
});
|
|
377
|
+
const NG_INJ_DEF = getClosureSafeProperty({
|
|
378
|
+
ɵinj: getClosureSafeProperty,
|
|
379
|
+
});
|
|
358
380
|
|
|
359
381
|
/**
|
|
360
382
|
* @license
|
|
@@ -367,7 +389,7 @@ function getTypeName(type) {
|
|
|
367
389
|
* Injection flags for DI.
|
|
368
390
|
*
|
|
369
391
|
* @publicApi
|
|
370
|
-
* @deprecated use an options object for `inject` instead.
|
|
392
|
+
* @deprecated use an options object for [`inject`](api/core/inject) instead.
|
|
371
393
|
*/
|
|
372
394
|
exports.InjectFlags = void 0;
|
|
373
395
|
(function (InjectFlags) {
|
|
@@ -452,10 +474,6 @@ const NG_TOKEN_PATH = 'ngTokenPath';
|
|
|
452
474
|
const NEW_LINE = /\n/gm;
|
|
453
475
|
const NO_NEW_LINE = 'ɵ';
|
|
454
476
|
const SOURCE = '__source';
|
|
455
|
-
const USE_VALUE = getClosureSafeProperty({
|
|
456
|
-
provide: String,
|
|
457
|
-
useValue: getClosureSafeProperty,
|
|
458
|
-
});
|
|
459
477
|
/**
|
|
460
478
|
* Current injector value used by `inject`.
|
|
461
479
|
* - `undefined`: it is an error to call `inject`
|
|
@@ -463,6 +481,9 @@ const USE_VALUE = getClosureSafeProperty({
|
|
|
463
481
|
* - Injector instance: Use the injector for resolution.
|
|
464
482
|
*/
|
|
465
483
|
let _currentInjector = undefined;
|
|
484
|
+
function getCurrentInjector() {
|
|
485
|
+
return _currentInjector;
|
|
486
|
+
}
|
|
466
487
|
function setCurrentInjector(injector) {
|
|
467
488
|
const former = _currentInjector;
|
|
468
489
|
_currentInjector = injector;
|
|
@@ -470,32 +491,46 @@ function setCurrentInjector(injector) {
|
|
|
470
491
|
}
|
|
471
492
|
function injectInjectorOnly(token, flags = exports.InjectFlags.Default) {
|
|
472
493
|
if (_currentInjector === undefined) {
|
|
473
|
-
throw new
|
|
494
|
+
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, null);
|
|
474
495
|
}
|
|
475
496
|
else if (_currentInjector === null) {
|
|
476
497
|
return injectRootLimpMode(token, undefined, flags);
|
|
477
498
|
}
|
|
478
499
|
else {
|
|
479
|
-
|
|
500
|
+
const value = _currentInjector.get(token, flags & exports.InjectFlags.Optional ? null : undefined, flags);
|
|
501
|
+
return value;
|
|
480
502
|
}
|
|
481
503
|
}
|
|
482
504
|
function ɵɵinject(token, flags = exports.InjectFlags.Default) {
|
|
483
|
-
return injectInjectorOnly(resolveForwardRef(token), flags);
|
|
505
|
+
return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
509
|
+
* particular class.
|
|
510
|
+
*
|
|
511
|
+
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
512
|
+
* and thus in the stack trace.
|
|
513
|
+
*
|
|
514
|
+
* @codeGenApi
|
|
515
|
+
*/
|
|
516
|
+
function ɵɵinvalidFactoryDep(index) {
|
|
517
|
+
throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, null);
|
|
484
518
|
}
|
|
485
519
|
/**
|
|
486
520
|
* Injects a token from the currently active injector.
|
|
487
|
-
* `inject` is only supported
|
|
488
|
-
* during:
|
|
521
|
+
* `inject` is only supported in an [injection context](/guide/dependency-injection-context). It can
|
|
522
|
+
* be used during:
|
|
489
523
|
* - Construction (via the `constructor`) of a class being instantiated by the DI system, such
|
|
490
524
|
* as an `@Injectable` or `@Component`.
|
|
491
525
|
* - In the initializer for fields of such classes.
|
|
492
526
|
* - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
|
|
493
527
|
* - In the `factory` function specified for an `InjectionToken`.
|
|
528
|
+
* - In a stackframe of a function call in a DI context
|
|
494
529
|
*
|
|
495
530
|
* @param token A token that represents a dependency that should be injected.
|
|
496
531
|
* @param flags Optional flags that control how injection is executed.
|
|
497
532
|
* The flags correspond to injection strategies that can be specified with
|
|
498
|
-
* parameter decorators `@Host`, `@Self`, `@
|
|
533
|
+
* parameter decorators `@Host`, `@Self`, `@SkipSelf`, and `@Optional`.
|
|
499
534
|
* @returns the injected value if operation is successful, `null` otherwise.
|
|
500
535
|
* @throws if called outside of a supported context.
|
|
501
536
|
*
|
|
@@ -559,6 +594,7 @@ function convertToBitFlags(flags) {
|
|
|
559
594
|
// `InjectOptions` to `InjectFlags`.
|
|
560
595
|
return (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
|
|
561
596
|
(flags.optional && 8 /* InternalInjectFlags.Optional */) |
|
|
597
|
+
0 |
|
|
562
598
|
(flags.self && 2 /* InternalInjectFlags.Self */) |
|
|
563
599
|
(flags.skipSelf &&
|
|
564
600
|
4 /* InternalInjectFlags.SkipSelf */));
|
|
@@ -569,7 +605,7 @@ function injectArgs(types) {
|
|
|
569
605
|
const arg = resolveForwardRef(types[i]);
|
|
570
606
|
if (Array.isArray(arg)) {
|
|
571
607
|
if (arg.length === 0) {
|
|
572
|
-
throw new
|
|
608
|
+
throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, null);
|
|
573
609
|
}
|
|
574
610
|
let type = undefined;
|
|
575
611
|
let flags = exports.InjectFlags.Default;
|
|
@@ -714,6 +750,17 @@ attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* InternalInjectFlags.SkipSe
|
|
|
714
750
|
const NG_FACTORY_DEF = getClosureSafeProperty({
|
|
715
751
|
ɵfac: getClosureSafeProperty,
|
|
716
752
|
});
|
|
753
|
+
/**
|
|
754
|
+
* The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
|
|
755
|
+
* getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
|
|
756
|
+
* strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
|
|
757
|
+
*
|
|
758
|
+
* This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
|
|
759
|
+
* improve tree-shaking.
|
|
760
|
+
*/
|
|
761
|
+
const NG_ENV_ID = getClosureSafeProperty({
|
|
762
|
+
__NG_ENV_ID__: getClosureSafeProperty,
|
|
763
|
+
});
|
|
717
764
|
|
|
718
765
|
/**
|
|
719
766
|
* @license
|
|
@@ -724,19 +771,11 @@ const NG_FACTORY_DEF = getClosureSafeProperty({
|
|
|
724
771
|
*/
|
|
725
772
|
function getFactoryDef(type, throwNotFound) {
|
|
726
773
|
const hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
// }
|
|
774
|
+
if (false) {
|
|
775
|
+
}
|
|
730
776
|
return hasFactoryDef ? type[NG_FACTORY_DEF] : null;
|
|
731
777
|
}
|
|
732
778
|
|
|
733
|
-
/**
|
|
734
|
-
* @license
|
|
735
|
-
* Copyright Google LLC All Rights Reserved.
|
|
736
|
-
*
|
|
737
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
738
|
-
* found in the LICENSE file at https://angular.io/license
|
|
739
|
-
*/
|
|
740
779
|
function deepForEach(input, fn) {
|
|
741
780
|
input.forEach((value) => Array.isArray(value) ? deepForEach(value, fn) : fn(value));
|
|
742
781
|
}
|
|
@@ -761,7 +800,11 @@ function newArray(size, value) {
|
|
|
761
800
|
* allows for identity checks against these values to be consistently used by the framework
|
|
762
801
|
* code.
|
|
763
802
|
*/
|
|
803
|
+
const EMPTY_OBJ = {};
|
|
764
804
|
const EMPTY_ARRAY = [];
|
|
805
|
+
// freezing the values prevents any code from accidentally inserting new values in
|
|
806
|
+
if (false) {
|
|
807
|
+
}
|
|
765
808
|
|
|
766
809
|
/**
|
|
767
810
|
* @license
|
|
@@ -778,11 +821,11 @@ const EMPTY_ARRAY = [];
|
|
|
778
821
|
* parameterized type.
|
|
779
822
|
*
|
|
780
823
|
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
|
|
781
|
-
* the `Injector`. This provides additional level of type safety.
|
|
824
|
+
* the `Injector`. This provides an additional level of type safety.
|
|
782
825
|
*
|
|
783
826
|
* ```
|
|
784
827
|
* interface MyInterface {...}
|
|
785
|
-
*
|
|
828
|
+
* const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
|
|
786
829
|
* // myInterface is inferred to be MyInterface.
|
|
787
830
|
* ```
|
|
788
831
|
*
|
|
@@ -790,14 +833,18 @@ const EMPTY_ARRAY = [];
|
|
|
790
833
|
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
|
|
791
834
|
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
|
|
792
835
|
* application's root injector. If the factory function, which takes zero arguments, needs to inject
|
|
793
|
-
* dependencies, it can do so using the `inject` function.
|
|
836
|
+
* dependencies, it can do so using the [`inject`](api/core/inject) function.
|
|
837
|
+
* As you can see in the Tree-shakable InjectionToken example below.
|
|
794
838
|
*
|
|
795
839
|
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
|
|
796
|
-
* overrides the above behavior and marks the token as belonging to a particular `@NgModule
|
|
797
|
-
* mentioned above, `'root'` is the default value for
|
|
840
|
+
* overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note:
|
|
841
|
+
* this option is now deprecated). As mentioned above, `'root'` is the default value for
|
|
842
|
+
* `providedIn`.
|
|
843
|
+
*
|
|
844
|
+
* The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated.
|
|
798
845
|
*
|
|
799
846
|
* @usageNotes
|
|
800
|
-
* ### Basic
|
|
847
|
+
* ### Basic Examples
|
|
801
848
|
*
|
|
802
849
|
* ### Plain InjectionToken
|
|
803
850
|
*
|
|
@@ -811,15 +858,20 @@ const EMPTY_ARRAY = [];
|
|
|
811
858
|
* @publicApi
|
|
812
859
|
*/
|
|
813
860
|
class InjectionToken {
|
|
861
|
+
_desc;
|
|
862
|
+
/** @internal */
|
|
863
|
+
ngMetadataName = 'InjectionToken';
|
|
864
|
+
ɵprov;
|
|
865
|
+
/**
|
|
866
|
+
* @param _desc Description for the token,
|
|
867
|
+
* used only for debugging purposes,
|
|
868
|
+
* it should but does not need to be unique
|
|
869
|
+
* @param options Options for the token's usage, as described above
|
|
870
|
+
*/
|
|
814
871
|
constructor(_desc, options) {
|
|
815
872
|
this._desc = _desc;
|
|
816
873
|
this.ɵprov = undefined;
|
|
817
874
|
if (typeof options == 'number') {
|
|
818
|
-
// (typeof ngDevMode === "undefined" || ngDevMode) &&
|
|
819
|
-
// assertLessThan(options, 0, "Only negative numbers are supported here");
|
|
820
|
-
// // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
|
|
821
|
-
// // See `InjectorMarkers`
|
|
822
|
-
// (this as any).__NG_ELEMENT_ID__ = options;
|
|
823
875
|
}
|
|
824
876
|
else if (options !== undefined) {
|
|
825
877
|
this.ɵprov = ɵɵdefineInjectable({
|
|
@@ -870,12 +922,23 @@ const ENVIRONMENT_INITIALIZER = new InjectionToken('ENVIRONMENT_INITIALIZER');
|
|
|
870
922
|
*
|
|
871
923
|
* @publicApi
|
|
872
924
|
*/
|
|
873
|
-
const INJECTOR = new InjectionToken(
|
|
874
|
-
//
|
|
925
|
+
const INJECTOR = new InjectionToken('INJECTOR',
|
|
926
|
+
// Disable tslint because this is const enum which gets inlined not top level prop access.
|
|
875
927
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
876
928
|
-1 /* InjectorMarkers.Injector */ // Special value used by Ivy to identify `Injector`.
|
|
877
929
|
);
|
|
878
930
|
|
|
931
|
+
/**
|
|
932
|
+
* @license
|
|
933
|
+
* Copyright Google LLC All Rights Reserved.
|
|
934
|
+
*
|
|
935
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
936
|
+
* found in the LICENSE file at https://angular.io/license
|
|
937
|
+
*/
|
|
938
|
+
function isEnvironmentProviders(value) {
|
|
939
|
+
return value && !!value.ɵproviders;
|
|
940
|
+
}
|
|
941
|
+
|
|
879
942
|
/**
|
|
880
943
|
* @license
|
|
881
944
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -896,13 +959,117 @@ class NullInjector {
|
|
|
896
959
|
get(token, notFoundValue = THROW_IF_NOT_FOUND) {
|
|
897
960
|
if (notFoundValue === THROW_IF_NOT_FOUND) {
|
|
898
961
|
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
|
|
899
|
-
error.name =
|
|
962
|
+
error.name = 'NullInjectorError';
|
|
900
963
|
throw error;
|
|
901
964
|
}
|
|
902
965
|
return notFoundValue;
|
|
903
966
|
}
|
|
904
967
|
}
|
|
905
968
|
|
|
969
|
+
/**
|
|
970
|
+
* @license
|
|
971
|
+
* Copyright Google LLC All Rights Reserved.
|
|
972
|
+
*
|
|
973
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
974
|
+
* found in the LICENSE file at https://angular.io/license
|
|
975
|
+
*/
|
|
976
|
+
/**
|
|
977
|
+
* Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally
|
|
978
|
+
* referenced in `@Component` in a component injector.
|
|
979
|
+
*/
|
|
980
|
+
function makeEnvironmentProviders(providers) {
|
|
981
|
+
return {
|
|
982
|
+
ɵproviders: providers,
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Collects providers from all NgModules and standalone components, including transitively imported
|
|
987
|
+
* ones.
|
|
988
|
+
*
|
|
989
|
+
* Providers extracted via `importProvidersFrom` are only usable in an application injector or
|
|
990
|
+
* another environment injector (such as a route injector). They should not be used in component
|
|
991
|
+
* providers.
|
|
992
|
+
*
|
|
993
|
+
* More information about standalone components can be found in [this
|
|
994
|
+
* guide](guide/standalone-components).
|
|
995
|
+
*
|
|
996
|
+
* @usageNotes
|
|
997
|
+
* The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:
|
|
998
|
+
*
|
|
999
|
+
* ```typescript
|
|
1000
|
+
* await bootstrapApplication(RootComponent, {
|
|
1001
|
+
* providers: [
|
|
1002
|
+
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
1003
|
+
* ]
|
|
1004
|
+
* });
|
|
1005
|
+
* ```
|
|
1006
|
+
*
|
|
1007
|
+
* You can also use the `importProvidersFrom` results in the `providers` field of a route, when a
|
|
1008
|
+
* standalone component is used:
|
|
1009
|
+
*
|
|
1010
|
+
* ```typescript
|
|
1011
|
+
* export const ROUTES: Route[] = [
|
|
1012
|
+
* {
|
|
1013
|
+
* path: 'foo',
|
|
1014
|
+
* providers: [
|
|
1015
|
+
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
1016
|
+
* ],
|
|
1017
|
+
* component: YourStandaloneComponent
|
|
1018
|
+
* }
|
|
1019
|
+
* ];
|
|
1020
|
+
* ```
|
|
1021
|
+
*
|
|
1022
|
+
* @returns Collected providers from the specified list of types.
|
|
1023
|
+
* @publicApi
|
|
1024
|
+
*/
|
|
1025
|
+
function importProvidersFrom(...sources) {
|
|
1026
|
+
return {
|
|
1027
|
+
ɵproviders: internalImportProvidersFrom(true, sources),
|
|
1028
|
+
ɵfromNgModule: true,
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
1032
|
+
const providersOut = [];
|
|
1033
|
+
const dedup = new Set(); // already seen types
|
|
1034
|
+
let injectorTypesWithProviders;
|
|
1035
|
+
const collectProviders = (provider) => {
|
|
1036
|
+
providersOut.push(provider);
|
|
1037
|
+
};
|
|
1038
|
+
// Collect all providers from `ModuleWithProviders` types.
|
|
1039
|
+
if (injectorTypesWithProviders !== undefined) {
|
|
1040
|
+
processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
|
|
1041
|
+
}
|
|
1042
|
+
return providersOut;
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
|
|
1046
|
+
* array.
|
|
1047
|
+
*/
|
|
1048
|
+
function processInjectorTypesWithProviders(typesWithProviders, visitor) {
|
|
1049
|
+
for (let i = 0; i < typesWithProviders.length; i++) {
|
|
1050
|
+
const { ngModule, providers } = typesWithProviders[i];
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
const USE_VALUE = getClosureSafeProperty({
|
|
1054
|
+
provide: String,
|
|
1055
|
+
useValue: getClosureSafeProperty,
|
|
1056
|
+
});
|
|
1057
|
+
function isValueProvider(value) {
|
|
1058
|
+
return value !== null && typeof value == 'object' && USE_VALUE in value;
|
|
1059
|
+
}
|
|
1060
|
+
function isExistingProvider(value) {
|
|
1061
|
+
return !!(value && value.useExisting);
|
|
1062
|
+
}
|
|
1063
|
+
function isFactoryProvider(value) {
|
|
1064
|
+
return !!(value && value.useFactory);
|
|
1065
|
+
}
|
|
1066
|
+
function isTypeProvider(value) {
|
|
1067
|
+
return typeof value === 'function';
|
|
1068
|
+
}
|
|
1069
|
+
function isClassProvider(value) {
|
|
1070
|
+
return !!value.useClass;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
906
1073
|
/**
|
|
907
1074
|
* @license
|
|
908
1075
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -953,29 +1120,33 @@ function getNullInjector() {
|
|
|
953
1120
|
class EnvironmentInjector {
|
|
954
1121
|
}
|
|
955
1122
|
class R3Injector extends EnvironmentInjector {
|
|
1123
|
+
parent;
|
|
1124
|
+
source;
|
|
1125
|
+
scopes;
|
|
1126
|
+
/**
|
|
1127
|
+
* Map of tokens to records which contain the instances of those tokens.
|
|
1128
|
+
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
1129
|
+
* to prevent further searches.
|
|
1130
|
+
*/
|
|
1131
|
+
records = new Map();
|
|
1132
|
+
/**
|
|
1133
|
+
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
1134
|
+
*/
|
|
1135
|
+
_ngOnDestroyHooks = new Set();
|
|
1136
|
+
_onDestroyHooks = [];
|
|
956
1137
|
/**
|
|
957
1138
|
* Flag indicating that this injector was previously destroyed.
|
|
958
1139
|
*/
|
|
959
1140
|
get destroyed() {
|
|
960
1141
|
return this._destroyed;
|
|
961
1142
|
}
|
|
1143
|
+
_destroyed = false;
|
|
1144
|
+
injectorDefTypes;
|
|
962
1145
|
constructor(providers, parent, source, scopes) {
|
|
963
1146
|
super();
|
|
964
1147
|
this.parent = parent;
|
|
965
1148
|
this.source = source;
|
|
966
1149
|
this.scopes = scopes;
|
|
967
|
-
/**
|
|
968
|
-
* Map of tokens to records which contain the instances of those tokens.
|
|
969
|
-
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
970
|
-
* to prevent further searches.
|
|
971
|
-
*/
|
|
972
|
-
this.records = new Map();
|
|
973
|
-
/**
|
|
974
|
-
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
975
|
-
*/
|
|
976
|
-
this._ngOnDestroyHooks = new Set();
|
|
977
|
-
this._onDestroyHooks = [];
|
|
978
|
-
this._destroyed = false;
|
|
979
1150
|
// Start off by creating Records for every provider.
|
|
980
1151
|
forEachSingleProvider(providers, (provider) => this.processProvider(provider));
|
|
981
1152
|
// Make sure the INJECTOR token provides this injector.
|
|
@@ -1007,7 +1178,11 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1007
1178
|
for (const service of this._ngOnDestroyHooks) {
|
|
1008
1179
|
service.ngOnDestroy();
|
|
1009
1180
|
}
|
|
1010
|
-
|
|
1181
|
+
const onDestroyHooks = this._onDestroyHooks;
|
|
1182
|
+
// Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
|
|
1183
|
+
// themselves from mutating the array during iteration.
|
|
1184
|
+
this._onDestroyHooks = [];
|
|
1185
|
+
for (const hook of onDestroyHooks) {
|
|
1011
1186
|
hook();
|
|
1012
1187
|
}
|
|
1013
1188
|
}
|
|
@@ -1016,16 +1191,19 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1016
1191
|
this.records.clear();
|
|
1017
1192
|
this._ngOnDestroyHooks.clear();
|
|
1018
1193
|
this.injectorDefTypes.clear();
|
|
1019
|
-
this._onDestroyHooks.length = 0;
|
|
1020
1194
|
}
|
|
1021
1195
|
}
|
|
1022
1196
|
onDestroy(callback) {
|
|
1197
|
+
this.assertNotDestroyed();
|
|
1023
1198
|
this._onDestroyHooks.push(callback);
|
|
1199
|
+
return () => this.removeOnDestroy(callback);
|
|
1024
1200
|
}
|
|
1025
1201
|
runInContext(fn) {
|
|
1026
1202
|
this.assertNotDestroyed();
|
|
1027
1203
|
const previousInjector = setCurrentInjector(this);
|
|
1028
1204
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1205
|
+
if (false) {
|
|
1206
|
+
}
|
|
1029
1207
|
try {
|
|
1030
1208
|
return fn();
|
|
1031
1209
|
}
|
|
@@ -1036,8 +1214,13 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1036
1214
|
}
|
|
1037
1215
|
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = exports.InjectFlags.Default) {
|
|
1038
1216
|
this.assertNotDestroyed();
|
|
1217
|
+
if (token.hasOwnProperty(NG_ENV_ID)) {
|
|
1218
|
+
return token[NG_ENV_ID](this);
|
|
1219
|
+
}
|
|
1039
1220
|
flags = convertToBitFlags(flags);
|
|
1040
1221
|
// Set the injection context.
|
|
1222
|
+
if (false) {
|
|
1223
|
+
}
|
|
1041
1224
|
const previousInjector = setCurrentInjector(this);
|
|
1042
1225
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1043
1226
|
try {
|
|
@@ -1105,8 +1288,12 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1105
1288
|
resolveInjectorInitializers() {
|
|
1106
1289
|
const previousInjector = setCurrentInjector(this);
|
|
1107
1290
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1291
|
+
if (false) {
|
|
1292
|
+
}
|
|
1108
1293
|
try {
|
|
1109
1294
|
const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, exports.InjectFlags.Self);
|
|
1295
|
+
if (false) {
|
|
1296
|
+
}
|
|
1110
1297
|
for (const initializer of initializers) {
|
|
1111
1298
|
initializer();
|
|
1112
1299
|
}
|
|
@@ -1126,7 +1313,7 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1126
1313
|
}
|
|
1127
1314
|
assertNotDestroyed() {
|
|
1128
1315
|
if (this._destroyed) {
|
|
1129
|
-
throw new
|
|
1316
|
+
throw new RuntimeError(205 /* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED */, null);
|
|
1130
1317
|
}
|
|
1131
1318
|
}
|
|
1132
1319
|
/**
|
|
@@ -1141,12 +1328,16 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1141
1328
|
: resolveForwardRef(provider && provider.provide);
|
|
1142
1329
|
// Construct a `Record` for the provider.
|
|
1143
1330
|
const record = providerToRecord(provider);
|
|
1331
|
+
if (false) {
|
|
1332
|
+
}
|
|
1144
1333
|
if (!isTypeProvider(provider) && provider.multi === true) {
|
|
1145
1334
|
// If the provider indicates that it's a multi-provider, process it specially.
|
|
1146
1335
|
// First check whether it's been defined already.
|
|
1147
1336
|
let multiRecord = this.records.get(token);
|
|
1148
1337
|
if (multiRecord) {
|
|
1149
1338
|
// It has. Throw a nice error if
|
|
1339
|
+
if (false) {
|
|
1340
|
+
}
|
|
1150
1341
|
}
|
|
1151
1342
|
else {
|
|
1152
1343
|
multiRecord = makeRecord(undefined, NOT_YET, true);
|
|
@@ -1158,13 +1349,21 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1158
1349
|
}
|
|
1159
1350
|
else {
|
|
1160
1351
|
const existing = this.records.get(token);
|
|
1352
|
+
if (false) {
|
|
1353
|
+
}
|
|
1161
1354
|
}
|
|
1162
1355
|
this.records.set(token, record);
|
|
1163
1356
|
}
|
|
1164
1357
|
hydrate(token, record) {
|
|
1165
|
-
if (
|
|
1358
|
+
if (false) {
|
|
1359
|
+
}
|
|
1360
|
+
else if (record.value === NOT_YET) {
|
|
1166
1361
|
record.value = CIRCULAR;
|
|
1167
|
-
|
|
1362
|
+
if (false) {
|
|
1363
|
+
}
|
|
1364
|
+
else {
|
|
1365
|
+
record.value = record.factory();
|
|
1366
|
+
}
|
|
1168
1367
|
}
|
|
1169
1368
|
if (typeof record.value === 'object' &&
|
|
1170
1369
|
record.value &&
|
|
@@ -1185,6 +1384,12 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1185
1384
|
return this.injectorDefTypes.has(providedIn);
|
|
1186
1385
|
}
|
|
1187
1386
|
}
|
|
1387
|
+
removeOnDestroy(callback) {
|
|
1388
|
+
const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
|
|
1389
|
+
if (destroyCBIdx !== -1) {
|
|
1390
|
+
this._onDestroyHooks.splice(destroyCBIdx, 1);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1188
1393
|
}
|
|
1189
1394
|
function injectableDefOrInjectorDefFactory(token) {
|
|
1190
1395
|
// Most tokens will have an injectable def directly on them, which specifies a factory directly.
|
|
@@ -1196,21 +1401,21 @@ function injectableDefOrInjectorDefFactory(token) {
|
|
|
1196
1401
|
// InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
|
|
1197
1402
|
// If it's missing that, it's an error.
|
|
1198
1403
|
if (token instanceof InjectionToken) {
|
|
1199
|
-
throw new
|
|
1404
|
+
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1200
1405
|
}
|
|
1201
1406
|
// Undecorated types can sometimes be created if they have no constructor arguments.
|
|
1202
1407
|
if (token instanceof Function) {
|
|
1203
1408
|
return getUndecoratedInjectableFactory(token);
|
|
1204
1409
|
}
|
|
1205
1410
|
// There was no way to resolve a factory for this token.
|
|
1206
|
-
throw new
|
|
1411
|
+
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1207
1412
|
}
|
|
1208
1413
|
function getUndecoratedInjectableFactory(token) {
|
|
1209
1414
|
// If the token has parameters then it has dependencies that we cannot resolve implicitly.
|
|
1210
1415
|
const paramLength = token.length;
|
|
1211
1416
|
if (paramLength > 0) {
|
|
1212
1417
|
const args = newArray(paramLength, '?');
|
|
1213
|
-
throw new
|
|
1418
|
+
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1214
1419
|
}
|
|
1215
1420
|
// The constructor function appears to have no parameters.
|
|
1216
1421
|
// This might be because it inherits from a super-class. In which case, use an injectable
|
|
@@ -1241,6 +1446,8 @@ function providerToRecord(provider) {
|
|
|
1241
1446
|
*/
|
|
1242
1447
|
function providerToFactory(provider, ngModuleType, providers) {
|
|
1243
1448
|
let factory = undefined;
|
|
1449
|
+
if (false) {
|
|
1450
|
+
}
|
|
1244
1451
|
if (isTypeProvider(provider)) {
|
|
1245
1452
|
const unwrappedProvider = resolveForwardRef(provider);
|
|
1246
1453
|
return (getFactoryDef(unwrappedProvider) ||
|
|
@@ -1260,9 +1467,8 @@ function providerToFactory(provider, ngModuleType, providers) {
|
|
|
1260
1467
|
const classRef = resolveForwardRef(provider &&
|
|
1261
1468
|
(provider.useClass ||
|
|
1262
1469
|
provider.provide));
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
// }
|
|
1470
|
+
if (false) {
|
|
1471
|
+
}
|
|
1266
1472
|
if (hasDeps(provider)) {
|
|
1267
1473
|
factory = () => new classRef(...injectArgs(provider.deps));
|
|
1268
1474
|
}
|
|
@@ -1280,18 +1486,6 @@ function makeRecord(factory, value, multi = false) {
|
|
|
1280
1486
|
multi: multi ? [] : undefined,
|
|
1281
1487
|
};
|
|
1282
1488
|
}
|
|
1283
|
-
function isValueProvider(value) {
|
|
1284
|
-
return value !== null && typeof value == 'object' && USE_VALUE in value;
|
|
1285
|
-
}
|
|
1286
|
-
function isExistingProvider(value) {
|
|
1287
|
-
return !!(value && value.useExisting);
|
|
1288
|
-
}
|
|
1289
|
-
function isFactoryProvider(value) {
|
|
1290
|
-
return !!(value && value.useFactory);
|
|
1291
|
-
}
|
|
1292
|
-
function isTypeProvider(value) {
|
|
1293
|
-
return typeof value === 'function';
|
|
1294
|
-
}
|
|
1295
1489
|
function hasDeps(value) {
|
|
1296
1490
|
return !!value.deps;
|
|
1297
1491
|
}
|
|
@@ -1309,6 +1503,9 @@ function forEachSingleProvider(providers, fn) {
|
|
|
1309
1503
|
if (Array.isArray(provider)) {
|
|
1310
1504
|
forEachSingleProvider(provider, fn);
|
|
1311
1505
|
}
|
|
1506
|
+
else if (provider && isEnvironmentProviders(provider)) {
|
|
1507
|
+
forEachSingleProvider(provider.ɵproviders, fn);
|
|
1508
|
+
}
|
|
1312
1509
|
else {
|
|
1313
1510
|
fn(provider);
|
|
1314
1511
|
}
|
|
@@ -1324,8 +1521,6 @@ function forEachSingleProvider(providers, fn) {
|
|
|
1324
1521
|
*/
|
|
1325
1522
|
/**
|
|
1326
1523
|
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
1327
|
-
*
|
|
1328
|
-
* @publicApi
|
|
1329
1524
|
*/
|
|
1330
1525
|
function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
1331
1526
|
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
@@ -1338,7 +1533,10 @@ function createInjector(defType, parent = null, additionalProviders = null, name
|
|
|
1338
1533
|
* should be resolved at a later point by calling `_resolveInjectorDefTypes`.
|
|
1339
1534
|
*/
|
|
1340
1535
|
function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
|
|
1341
|
-
const providers = [
|
|
1536
|
+
const providers = [
|
|
1537
|
+
additionalProviders || EMPTY_ARRAY,
|
|
1538
|
+
importProvidersFrom(defType),
|
|
1539
|
+
];
|
|
1342
1540
|
name = name || (typeof defType === 'object' ? undefined : stringify(defType));
|
|
1343
1541
|
return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
|
|
1344
1542
|
}
|
|
@@ -1356,7 +1554,7 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
|
|
|
1356
1554
|
* dependencies of various types with [injection tokens](guide/glossary#di-token).
|
|
1357
1555
|
*
|
|
1358
1556
|
* @see ["DI Providers"](guide/dependency-injection-providers).
|
|
1359
|
-
* @see
|
|
1557
|
+
* @see {@link StaticProvider}
|
|
1360
1558
|
*
|
|
1361
1559
|
* @usageNotes
|
|
1362
1560
|
*
|
|
@@ -1375,38 +1573,30 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
|
|
|
1375
1573
|
* @publicApi
|
|
1376
1574
|
*/
|
|
1377
1575
|
class Injector {
|
|
1576
|
+
static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1577
|
+
static NULL = new NullInjector();
|
|
1378
1578
|
static create(options, parent) {
|
|
1379
|
-
var _a;
|
|
1380
1579
|
if (Array.isArray(options)) {
|
|
1381
1580
|
return createInjector({ name: '' }, parent, options, '');
|
|
1382
1581
|
}
|
|
1383
1582
|
else {
|
|
1384
|
-
const name =
|
|
1583
|
+
const name = options.name ?? '';
|
|
1385
1584
|
return createInjector({ name }, options.parent, options.providers, name);
|
|
1386
1585
|
}
|
|
1387
1586
|
}
|
|
1587
|
+
/** @nocollapse */
|
|
1588
|
+
static ɵprov = /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
|
|
1589
|
+
token: Injector,
|
|
1590
|
+
providedIn: 'any',
|
|
1591
|
+
factory: () => ɵɵinject(INJECTOR),
|
|
1592
|
+
});
|
|
1593
|
+
/**
|
|
1594
|
+
* @internal
|
|
1595
|
+
* @nocollapse
|
|
1596
|
+
*/
|
|
1597
|
+
static __NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1388
1598
|
}
|
|
1389
|
-
Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1390
|
-
Injector.NULL = new NullInjector();
|
|
1391
|
-
/** @nocollapse */
|
|
1392
|
-
Injector.ɵprov = ɵɵdefineInjectable({
|
|
1393
|
-
token: Injector,
|
|
1394
|
-
providedIn: 'any',
|
|
1395
|
-
factory: () => ɵɵinject(INJECTOR),
|
|
1396
|
-
});
|
|
1397
|
-
/**
|
|
1398
|
-
* @internal
|
|
1399
|
-
* @nocollapse
|
|
1400
|
-
*/
|
|
1401
|
-
Injector.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1402
1599
|
|
|
1403
|
-
/**
|
|
1404
|
-
* @license
|
|
1405
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1406
|
-
*
|
|
1407
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1408
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1409
|
-
*/
|
|
1410
1600
|
/**
|
|
1411
1601
|
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
1412
1602
|
* particular class.
|
|
@@ -1476,7 +1666,7 @@ exports.Inject = Inject;
|
|
|
1476
1666
|
exports.Injectable = Injectable;
|
|
1477
1667
|
exports.InjectionToken = InjectionToken;
|
|
1478
1668
|
exports.Injector = Injector;
|
|
1479
|
-
exports.
|
|
1669
|
+
exports.NG_INJ_DEF = NG_INJ_DEF;
|
|
1480
1670
|
exports.NG_PROV_DEF = NG_PROV_DEF;
|
|
1481
1671
|
exports.NG_TEMP_TOKEN_PATH = NG_TEMP_TOKEN_PATH;
|
|
1482
1672
|
exports.NullInjector = NullInjector;
|
|
@@ -1486,19 +1676,20 @@ exports.SOURCE = SOURCE;
|
|
|
1486
1676
|
exports.Self = Self;
|
|
1487
1677
|
exports.SkipSelf = SkipSelf;
|
|
1488
1678
|
exports.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1489
|
-
exports.USE_VALUE = USE_VALUE;
|
|
1490
1679
|
exports.attachInjectFlag = attachInjectFlag;
|
|
1491
1680
|
exports.catchInjectorError = catchInjectorError;
|
|
1492
1681
|
exports.convertToBitFlags = convertToBitFlags;
|
|
1493
1682
|
exports.formatError = formatError;
|
|
1683
|
+
exports.getCurrentInjector = getCurrentInjector;
|
|
1494
1684
|
exports.getInheritedInjectableDef = getInheritedInjectableDef;
|
|
1495
1685
|
exports.getInjectFlag = getInjectFlag;
|
|
1496
1686
|
exports.getInjectableDef = getInjectableDef;
|
|
1687
|
+
exports.getInjectorDef = getInjectorDef;
|
|
1497
1688
|
exports.getNullInjector = getNullInjector;
|
|
1498
1689
|
exports.inject = inject;
|
|
1499
1690
|
exports.injectArgs = injectArgs;
|
|
1500
1691
|
exports.injectInjectorOnly = injectInjectorOnly;
|
|
1501
|
-
exports.
|
|
1692
|
+
exports.isInjectable = isInjectable;
|
|
1502
1693
|
exports.providerToFactory = providerToFactory;
|
|
1503
1694
|
exports.setCurrentInjector = setCurrentInjector;
|
|
1504
1695
|
exports["ɵɵdefineInjectable"] = ɵɵdefineInjectable;
|
|
@@ -1506,3 +1697,4 @@ exports["ɵɵdefineInjector"] = ɵɵdefineInjector;
|
|
|
1506
1697
|
exports["ɵɵgetInheritedFactory"] = ɵɵgetInheritedFactory;
|
|
1507
1698
|
exports["ɵɵinject"] = ɵɵinject;
|
|
1508
1699
|
exports["ɵɵinvalidFactory"] = ɵɵinvalidFactory;
|
|
1700
|
+
exports["ɵɵinvalidFactoryDep"] = ɵɵinvalidFactoryDep;
|