static-injector 5.0.2 → 6.0.1
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/change_detection/scheduling/zoneless_scheduling.d.ts +37 -0
- package/import/change_detection/scheduling/zoneless_scheduling_impl.d.ts +16 -0
- package/import/core_reactivity_export_internal.d.ts +17 -0
- package/import/di/contextual.d.ts +36 -0
- package/{typings → import}/di/create_injector.d.ts +1 -1
- package/{typings → import}/di/forward_ref.d.ts +2 -2
- package/import/di/index.d.ts +3 -0
- package/{typings → import}/di/initializer_token.d.ts +8 -1
- package/{typings → import}/di/inject_switch.d.ts +2 -2
- package/{typings → import}/di/injectable.d.ts +2 -2
- package/{typings → import}/di/injection_token.d.ts +3 -4
- package/{typings → import}/di/injector.d.ts +1 -1
- package/{typings → import}/di/injector_compatibility.d.ts +1 -1
- package/{typings → import}/di/injector_marker.d.ts +1 -1
- package/{typings → import}/di/injector_token.d.ts +1 -1
- package/{typings → import}/di/interface/defs.d.ts +1 -1
- package/{typings → import}/di/interface/injector.d.ts +1 -1
- package/{typings → import}/di/interface/provider.d.ts +1 -1
- package/{typings → import}/di/internal_tokens.d.ts +1 -1
- package/{typings → import}/di/metadata.d.ts +5 -9
- package/{typings → import}/di/null_injector.d.ts +1 -1
- package/{typings → import}/di/provider_collection.d.ts +31 -3
- package/{typings → import}/di/provider_token.d.ts +1 -1
- package/{typings → import}/di/r3_injector.d.ts +2 -2
- package/{typings → import}/di/scope.d.ts +1 -1
- package/{typings → import}/di.d.ts +1 -1
- package/import/error_handler.d.ts +45 -0
- package/{typings → import}/errors.d.ts +9 -7
- package/import/index.d.ts +37 -0
- package/{typings → import}/interface/lifecycle_hooks.d.ts +1 -1
- package/{typings → import}/interface/type.d.ts +4 -9
- package/import/linker/destroy_ref.d.ts +44 -0
- package/import/pending_tasks.d.ts +78 -0
- package/{typings → import}/render3/definition_factory.d.ts +1 -1
- package/{typings → import}/render3/errors_di.d.ts +1 -1
- package/{typings → import}/render3/fields.d.ts +1 -1
- package/{typings → import}/render3/instructions/di.d.ts +1 -1
- package/import/render3/reactivity/api.d.ts +27 -0
- package/import/render3/reactivity/asserts.d.ts +16 -0
- package/import/render3/reactivity/computed.d.ts +25 -0
- package/import/render3/reactivity/effect.d.ts +121 -0
- package/import/render3/reactivity/linked_signal.d.ts +33 -0
- package/import/render3/reactivity/microtask_effect.d.ts +21 -0
- package/import/render3/reactivity/patch.d.ts +11 -0
- package/import/render3/reactivity/root_effect_scheduler.d.ts +54 -0
- package/import/render3/reactivity/signal.d.ts +61 -0
- package/import/render3/reactivity/untracked.d.ts +12 -0
- package/import/resource/api.d.ts +219 -0
- package/{es2022/di/injectable.js → import/resource/index.d.ts} +3 -2
- package/import/resource/resource.d.ts +89 -0
- package/import/util/callback_scheduler.d.ts +35 -0
- package/{typings → import}/util/closure.d.ts +1 -1
- package/{typings → import}/util/decorators.d.ts +3 -3
- package/{typings → import}/util/empty.d.ts +1 -1
- package/{es2022/di/provider_token.js → import/util/noop.d.ts} +2 -2
- package/{typings → import}/util/property.d.ts +1 -1
- package/{typings → import}/util/stringify.d.ts +1 -1
- package/index.js +2349 -0
- package/index.js.map +7 -0
- package/index.mjs +2258 -0
- package/index.mjs.map +7 -0
- package/package.json +22 -11
- package/primitives/signals/index.d.ts +15 -0
- package/primitives/signals/src/computed.d.ts +55 -0
- package/primitives/signals/src/equality.d.ts +15 -0
- package/primitives/signals/src/errors.d.ts +10 -0
- package/primitives/signals/src/graph.d.ts +182 -0
- package/primitives/signals/src/linked_signal.d.ts +72 -0
- package/primitives/signals/src/signal.d.ts +29 -0
- package/primitives/signals/src/watch.d.ts +43 -0
- package/{es2022/di/injector_marker.js → primitives/signals/src/weak_ref.d.ts} +2 -2
- package/readme.md +19 -15
- package/commonjs/index.js +0 -1586
- package/es2022/di/create_injector.js +0 -32
- package/es2022/di/forward_ref.js +0 -80
- package/es2022/di/index.js +0 -1
- package/es2022/di/initializer_token.js +0 -15
- package/es2022/di/inject_switch.js +0 -51
- package/es2022/di/injection_token.js +0 -93
- package/es2022/di/injector.js +0 -60
- package/es2022/di/injector_compatibility.js +0 -265
- package/es2022/di/injector_token.js +0 -20
- package/es2022/di/interface/defs.js +0 -110
- package/es2022/di/interface/injector.js +0 -26
- package/es2022/di/interface/provider.js +0 -10
- package/es2022/di/internal_tokens.js +0 -9
- package/es2022/di/metadata.js +0 -48
- package/es2022/di/null_injector.js +0 -19
- package/es2022/di/provider_collection.js +0 -104
- package/es2022/di/r3_injector.js +0 -449
- package/es2022/di/scope.js +0 -14
- package/es2022/di.js +0 -24
- package/es2022/errors.js +0 -44
- package/es2022/index.js +0 -19
- package/es2022/interface/lifecycle_hooks.js +0 -8
- package/es2022/interface/type.js +0 -21
- package/es2022/render3/definition_factory.js +0 -10
- package/es2022/render3/errors_di.js +0 -13
- package/es2022/render3/fields.js +0 -22
- package/es2022/render3/instructions/di.js +0 -23
- package/es2022/render3/util/stringify_utils.js +0 -38
- package/es2022/util/closure.js +0 -19
- package/es2022/util/decorators.js +0 -31
- package/es2022/util/empty.js +0 -18
- package/es2022/util/property.js +0 -15
- package/es2022/util/stringify.js +0 -45
- package/fesm2022/index.js +0 -1547
- package/typings/di/index.d.ts +0 -1
- package/typings/index.d.ts +0 -18
- package/typings/render3/util/stringify_utils.d.ts +0 -21
package/fesm2022/index.js
DELETED
|
@@ -1,1547 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Convince closure compiler that the wrapped function has no side-effects.
|
|
10
|
-
*
|
|
11
|
-
* Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
|
|
12
|
-
* allow us to execute a function but have closure compiler mark the call as no-side-effects.
|
|
13
|
-
* It is important that the return value for the `noSideEffects` function be assigned
|
|
14
|
-
* to something which is retained otherwise the call to `noSideEffects` will be removed by closure
|
|
15
|
-
* compiler.
|
|
16
|
-
*/
|
|
17
|
-
function noSideEffects(fn) {
|
|
18
|
-
return { toString: fn }.toString();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @license
|
|
23
|
-
* Copyright Google LLC All Rights Reserved.
|
|
24
|
-
*
|
|
25
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
26
|
-
* found in the LICENSE file at https://angular.io/license
|
|
27
|
-
*/
|
|
28
|
-
function makeMetadataCtor(props) {
|
|
29
|
-
return function ctor(...args) {
|
|
30
|
-
if (props) {
|
|
31
|
-
const values = props(...args);
|
|
32
|
-
for (const propName in values) {
|
|
33
|
-
this[propName] = values[propName];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function makeParamDecorator(name, props, parentClass) {
|
|
39
|
-
return noSideEffects(() => {
|
|
40
|
-
const metaCtor = makeMetadataCtor(props);
|
|
41
|
-
function ParamDecoratorFactory(...args) {
|
|
42
|
-
metaCtor.apply(this, args);
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
return ParamDecoratorFactory;
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @license
|
|
51
|
-
* Copyright Google LLC All Rights Reserved.
|
|
52
|
-
*
|
|
53
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
54
|
-
* found in the LICENSE file at https://angular.io/license
|
|
55
|
-
*/
|
|
56
|
-
/**
|
|
57
|
-
* Class that represents a runtime error.
|
|
58
|
-
* Formats and outputs the error message in a consistent way.
|
|
59
|
-
*
|
|
60
|
-
* Example:
|
|
61
|
-
* ```
|
|
62
|
-
* throw new RuntimeError(
|
|
63
|
-
* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
|
|
64
|
-
* ngDevMode && 'Injector has already been destroyed.');
|
|
65
|
-
* ```
|
|
66
|
-
*
|
|
67
|
-
* Note: the `message` argument contains a descriptive error message as a string in development
|
|
68
|
-
* mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
|
|
69
|
-
* `message` argument becomes `false`, thus we account for it in the typings and the runtime
|
|
70
|
-
* logic.
|
|
71
|
-
*/
|
|
72
|
-
class RuntimeError extends Error {
|
|
73
|
-
code;
|
|
74
|
-
constructor(code, message) {
|
|
75
|
-
super(formatRuntimeError(code, message));
|
|
76
|
-
this.code = code;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Called to format a runtime error.
|
|
81
|
-
* See additional info on the `message` argument type in the `RuntimeError` class description.
|
|
82
|
-
*/
|
|
83
|
-
function formatRuntimeError(code, message) {
|
|
84
|
-
// Error code might be a negative number, which is a special marker that instructs the logic to
|
|
85
|
-
// generate a link to the error details page on angular.io.
|
|
86
|
-
// We also prepend `0` to non-compile-time errors.
|
|
87
|
-
const fullCode = `NG0${Math.abs(code)}`;
|
|
88
|
-
let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
|
|
89
|
-
return errorMessage;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @license
|
|
94
|
-
* Copyright Google LLC All Rights Reserved.
|
|
95
|
-
*
|
|
96
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
97
|
-
* found in the LICENSE file at https://angular.io/license
|
|
98
|
-
*/
|
|
99
|
-
function stringify(token) {
|
|
100
|
-
if (typeof token === 'string') {
|
|
101
|
-
return token;
|
|
102
|
-
}
|
|
103
|
-
if (Array.isArray(token)) {
|
|
104
|
-
return '[' + token.map(stringify).join(', ') + ']';
|
|
105
|
-
}
|
|
106
|
-
if (token == null) {
|
|
107
|
-
return '' + token;
|
|
108
|
-
}
|
|
109
|
-
if (token.overriddenName) {
|
|
110
|
-
return `${token.overriddenName}`;
|
|
111
|
-
}
|
|
112
|
-
if (token.name) {
|
|
113
|
-
return `${token.name}`;
|
|
114
|
-
}
|
|
115
|
-
const res = token.toString();
|
|
116
|
-
if (res == null) {
|
|
117
|
-
return '' + res;
|
|
118
|
-
}
|
|
119
|
-
const newLineIndex = res.indexOf('\n');
|
|
120
|
-
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* @license
|
|
125
|
-
* Copyright Google LLC All Rights Reserved.
|
|
126
|
-
*
|
|
127
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
128
|
-
* found in the LICENSE file at https://angular.io/license
|
|
129
|
-
*/
|
|
130
|
-
function getClosureSafeProperty(objWithPropertyToExtract) {
|
|
131
|
-
for (let key in objWithPropertyToExtract) {
|
|
132
|
-
if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
|
|
133
|
-
return key;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
throw Error('Could not find renamed property on target object.');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* @license
|
|
141
|
-
* Copyright Google LLC All Rights Reserved.
|
|
142
|
-
*
|
|
143
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
144
|
-
* found in the LICENSE file at https://angular.io/license
|
|
145
|
-
*/
|
|
146
|
-
const __forward_ref__ = getClosureSafeProperty({
|
|
147
|
-
__forward_ref__: getClosureSafeProperty,
|
|
148
|
-
});
|
|
149
|
-
/**
|
|
150
|
-
* Allows to refer to references which are not yet defined.
|
|
151
|
-
*
|
|
152
|
-
* For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
|
|
153
|
-
* DI is declared, but not yet defined. It is also used when the `token` which we use when creating
|
|
154
|
-
* a query is not yet defined.
|
|
155
|
-
*
|
|
156
|
-
* `forwardRef` is also used to break circularities in standalone components imports.
|
|
157
|
-
*
|
|
158
|
-
* @usageNotes
|
|
159
|
-
* ### Circular dependency example
|
|
160
|
-
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
|
|
161
|
-
*
|
|
162
|
-
* ### Circular standalone reference import example
|
|
163
|
-
* ```ts
|
|
164
|
-
* @Component({
|
|
165
|
-
* standalone: true,
|
|
166
|
-
* imports: [ChildComponent],
|
|
167
|
-
* selector: 'app-parent',
|
|
168
|
-
* template: `<app-child [hideParent]="hideParent"></app-child>`,
|
|
169
|
-
* })
|
|
170
|
-
* export class ParentComponent {
|
|
171
|
-
* @Input() hideParent: boolean;
|
|
172
|
-
* }
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* @Component({
|
|
176
|
-
* standalone: true,
|
|
177
|
-
* imports: [CommonModule, forwardRef(() => ParentComponent)],
|
|
178
|
-
* selector: 'app-child',
|
|
179
|
-
* template: `<app-parent *ngIf="!hideParent"></app-parent>`,
|
|
180
|
-
* })
|
|
181
|
-
* export class ChildComponent {
|
|
182
|
-
* @Input() hideParent: boolean;
|
|
183
|
-
* }
|
|
184
|
-
* ```
|
|
185
|
-
*
|
|
186
|
-
* @publicApi
|
|
187
|
-
*/
|
|
188
|
-
function forwardRef(forwardRefFn) {
|
|
189
|
-
forwardRefFn.__forward_ref__ = forwardRef;
|
|
190
|
-
forwardRefFn.toString = function () {
|
|
191
|
-
return stringify(this());
|
|
192
|
-
};
|
|
193
|
-
return forwardRefFn;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Lazily retrieves the reference value from a forwardRef.
|
|
197
|
-
*
|
|
198
|
-
* Acts as the identity function when given a non-forward-ref value.
|
|
199
|
-
*
|
|
200
|
-
* @usageNotes
|
|
201
|
-
* ### Example
|
|
202
|
-
*
|
|
203
|
-
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
|
|
204
|
-
*
|
|
205
|
-
* @see {@link forwardRef}
|
|
206
|
-
* @publicApi
|
|
207
|
-
*/
|
|
208
|
-
function resolveForwardRef(type) {
|
|
209
|
-
return isForwardRef(type) ? type() : type;
|
|
210
|
-
}
|
|
211
|
-
/** Checks whether a function is wrapped by a `forwardRef`. */
|
|
212
|
-
function isForwardRef(fn) {
|
|
213
|
-
return (typeof fn === 'function' &&
|
|
214
|
-
fn.hasOwnProperty(__forward_ref__) &&
|
|
215
|
-
fn.__forward_ref__ === forwardRef);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* @license
|
|
220
|
-
* Copyright Google LLC All Rights Reserved.
|
|
221
|
-
*
|
|
222
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
223
|
-
* found in the LICENSE file at https://angular.io/license
|
|
224
|
-
*/
|
|
225
|
-
/** Throws an error when a token is not found in DI. */
|
|
226
|
-
function throwProviderNotFoundError(token, injectorName) {
|
|
227
|
-
const errorMessage = null;
|
|
228
|
-
throw new RuntimeError(-201 /* RuntimeErrorCode.PROVIDER_NOT_FOUND */, errorMessage);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* @license
|
|
233
|
-
* Copyright Google LLC All Rights Reserved.
|
|
234
|
-
*
|
|
235
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
236
|
-
* found in the LICENSE file at https://angular.io/license
|
|
237
|
-
*/
|
|
238
|
-
/**
|
|
239
|
-
* Construct an injectable definition which defines how a token will be constructed by the DI
|
|
240
|
-
* system, and in which injectors (if any) it will be available.
|
|
241
|
-
*
|
|
242
|
-
* This should be assigned to a static `ɵprov` field on a type, which will then be an
|
|
243
|
-
* `InjectableType`.
|
|
244
|
-
*
|
|
245
|
-
* Options:
|
|
246
|
-
* * `providedIn` determines which injectors will include the injectable, by either associating it
|
|
247
|
-
* with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
|
|
248
|
-
* provided in the `'root'` injector, which will be the application-level injector in most apps.
|
|
249
|
-
* * `factory` gives the zero argument function which will create an instance of the injectable.
|
|
250
|
-
* The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection
|
|
251
|
-
* of dependencies.
|
|
252
|
-
*
|
|
253
|
-
* @codeGenApi
|
|
254
|
-
* @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
|
|
255
|
-
*/
|
|
256
|
-
function ɵɵdefineInjectable(opts) {
|
|
257
|
-
return {
|
|
258
|
-
token: opts.token,
|
|
259
|
-
providedIn: opts.providedIn || null,
|
|
260
|
-
factory: opts.factory,
|
|
261
|
-
value: undefined,
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Construct an `InjectorDef` which configures an injector.
|
|
266
|
-
*
|
|
267
|
-
* This should be assigned to a static injector def (`ɵinj`) field on a type, which will then be an
|
|
268
|
-
* `InjectorType`.
|
|
269
|
-
*
|
|
270
|
-
* Options:
|
|
271
|
-
*
|
|
272
|
-
* * `providers`: an optional array of providers to add to the injector. Each provider must
|
|
273
|
-
* either have a factory or point to a type which has a `ɵprov` static property (the
|
|
274
|
-
* type must be an `InjectableType`).
|
|
275
|
-
* * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
|
|
276
|
-
* whose providers will also be added to the injector. Locally provided types will override
|
|
277
|
-
* providers from imports.
|
|
278
|
-
*
|
|
279
|
-
* @codeGenApi
|
|
280
|
-
*/
|
|
281
|
-
function ɵɵdefineInjector(options) {
|
|
282
|
-
return { providers: options.providers || [], imports: options.imports || [] };
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Read the injectable def (`ɵprov`) for `type` in a way which is immune to accidentally reading
|
|
286
|
-
* inherited value.
|
|
287
|
-
*
|
|
288
|
-
* @param type A type which may have its own (non-inherited) `ɵprov`.
|
|
289
|
-
*/
|
|
290
|
-
function getInjectableDef(type) {
|
|
291
|
-
return (getOwnDefinition(type, NG_PROV_DEF) || {
|
|
292
|
-
token: type,
|
|
293
|
-
factory: () => new type(),
|
|
294
|
-
...type.injectOptions,
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
function isInjectable(type) {
|
|
298
|
-
return getInjectableDef(type) !== null;
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Return definition only if it is defined directly on `type` and is not inherited from a base
|
|
302
|
-
* class of `type`.
|
|
303
|
-
*/
|
|
304
|
-
function getOwnDefinition(type, field) {
|
|
305
|
-
return type.hasOwnProperty(field) ? type[field] : null;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
|
|
309
|
-
*
|
|
310
|
-
* @param type A type which may have `ɵprov`, via inheritance.
|
|
311
|
-
*
|
|
312
|
-
* @deprecated Will be removed in a future version of Angular, where an error will occur in the
|
|
313
|
-
* scenario if we find the `ɵprov` on an ancestor only.
|
|
314
|
-
*/
|
|
315
|
-
function getInheritedInjectableDef(type) {
|
|
316
|
-
const def = type && (type[NG_PROV_DEF] || null);
|
|
317
|
-
if (def) {
|
|
318
|
-
return def;
|
|
319
|
-
}
|
|
320
|
-
else {
|
|
321
|
-
return null;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Read the injector def type in a way which is immune to accidentally reading inherited value.
|
|
326
|
-
*
|
|
327
|
-
* @param type type which may have an injector def (`ɵinj`)
|
|
328
|
-
*/
|
|
329
|
-
function getInjectorDef(type) {
|
|
330
|
-
return type && (type.hasOwnProperty(NG_INJ_DEF) || false)
|
|
331
|
-
? type[NG_INJ_DEF]
|
|
332
|
-
: null;
|
|
333
|
-
}
|
|
334
|
-
const NG_PROV_DEF = getClosureSafeProperty({
|
|
335
|
-
ɵprov: getClosureSafeProperty,
|
|
336
|
-
});
|
|
337
|
-
const NG_INJ_DEF = getClosureSafeProperty({
|
|
338
|
-
ɵinj: getClosureSafeProperty,
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* @license
|
|
343
|
-
* Copyright Google LLC All Rights Reserved.
|
|
344
|
-
*
|
|
345
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
346
|
-
* found in the LICENSE file at https://angular.io/license
|
|
347
|
-
*/
|
|
348
|
-
/**
|
|
349
|
-
* Injection flags for DI.
|
|
350
|
-
*
|
|
351
|
-
* @publicApi
|
|
352
|
-
* @deprecated use an options object for [`inject`](api/core/inject) instead.
|
|
353
|
-
*/
|
|
354
|
-
var InjectFlags;
|
|
355
|
-
(function (InjectFlags) {
|
|
356
|
-
// TODO(alxhub): make this 'const' (and remove `InternalInjectFlags` enum) when ngc no longer
|
|
357
|
-
// writes exports of it into ngfactory files.
|
|
358
|
-
/** Check self and check parent injector if needed */
|
|
359
|
-
InjectFlags[InjectFlags["Default"] = 0] = "Default";
|
|
360
|
-
/** Don't ascend to ancestors of the node requesting injection. */
|
|
361
|
-
InjectFlags[InjectFlags["Self"] = 2] = "Self";
|
|
362
|
-
/** Skip the node that is requesting injection. */
|
|
363
|
-
InjectFlags[InjectFlags["SkipSelf"] = 4] = "SkipSelf";
|
|
364
|
-
/** Inject `defaultValue` instead if token not found. */
|
|
365
|
-
InjectFlags[InjectFlags["Optional"] = 8] = "Optional";
|
|
366
|
-
})(InjectFlags || (InjectFlags = {}));
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* @license
|
|
370
|
-
* Copyright Google LLC All Rights Reserved.
|
|
371
|
-
*
|
|
372
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
373
|
-
* found in the LICENSE file at https://angular.io/license
|
|
374
|
-
*/
|
|
375
|
-
/**
|
|
376
|
-
* Current implementation of inject.
|
|
377
|
-
*
|
|
378
|
-
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
|
|
379
|
-
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
|
|
380
|
-
* way for two reasons:
|
|
381
|
-
* 1. `Injector` should not depend on ivy logic.
|
|
382
|
-
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
|
|
383
|
-
*/
|
|
384
|
-
let _injectImplementation;
|
|
385
|
-
function getInjectImplementation() {
|
|
386
|
-
return _injectImplementation;
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Sets the current inject implementation.
|
|
390
|
-
*/
|
|
391
|
-
function setInjectImplementation(impl) {
|
|
392
|
-
const previous = _injectImplementation;
|
|
393
|
-
_injectImplementation = impl;
|
|
394
|
-
return previous;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Injects `root` tokens in limp mode.
|
|
398
|
-
*
|
|
399
|
-
* If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
|
|
400
|
-
* `"root"`. This is known as the limp mode injection. In such case the value is stored in the
|
|
401
|
-
* injectable definition.
|
|
402
|
-
*/
|
|
403
|
-
function injectRootLimpMode(token, notFoundValue, flags) {
|
|
404
|
-
const injectableDef = getInjectableDef(token);
|
|
405
|
-
if (injectableDef && injectableDef.providedIn == 'root') {
|
|
406
|
-
return injectableDef.value === undefined
|
|
407
|
-
? (injectableDef.value = injectableDef.factory())
|
|
408
|
-
: injectableDef.value;
|
|
409
|
-
}
|
|
410
|
-
if (flags & InjectFlags.Optional)
|
|
411
|
-
return null;
|
|
412
|
-
throwProviderNotFoundError();
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* @license
|
|
417
|
-
* Copyright Google LLC All Rights Reserved.
|
|
418
|
-
*
|
|
419
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
420
|
-
* found in the LICENSE file at https://angular.io/license
|
|
421
|
-
*/
|
|
422
|
-
const _THROW_IF_NOT_FOUND = {};
|
|
423
|
-
const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
|
424
|
-
/*
|
|
425
|
-
* Name of a property (that we patch onto DI decorator), which is used as an annotation of which
|
|
426
|
-
* InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators
|
|
427
|
-
* in the code, thus making them tree-shakable.
|
|
428
|
-
*/
|
|
429
|
-
const DI_DECORATOR_FLAG = '__NG_DI_FLAG__';
|
|
430
|
-
const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
|
|
431
|
-
const NG_TOKEN_PATH = 'ngTokenPath';
|
|
432
|
-
const NEW_LINE = /\n/gm;
|
|
433
|
-
const NO_NEW_LINE = 'ɵ';
|
|
434
|
-
const SOURCE = '__source';
|
|
435
|
-
/**
|
|
436
|
-
* Current injector value used by `inject`.
|
|
437
|
-
* - `undefined`: it is an error to call `inject`
|
|
438
|
-
* - `null`: `inject` can be called but there is no injector (limp-mode).
|
|
439
|
-
* - Injector instance: Use the injector for resolution.
|
|
440
|
-
*/
|
|
441
|
-
let _currentInjector = undefined;
|
|
442
|
-
function getCurrentInjector() {
|
|
443
|
-
return _currentInjector;
|
|
444
|
-
}
|
|
445
|
-
function setCurrentInjector(injector) {
|
|
446
|
-
const former = _currentInjector;
|
|
447
|
-
_currentInjector = injector;
|
|
448
|
-
return former;
|
|
449
|
-
}
|
|
450
|
-
function injectInjectorOnly(token, flags = InjectFlags.Default) {
|
|
451
|
-
if (_currentInjector === undefined) {
|
|
452
|
-
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, null);
|
|
453
|
-
}
|
|
454
|
-
else if (_currentInjector === null) {
|
|
455
|
-
return injectRootLimpMode(token, undefined, flags);
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
const value = _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
|
|
459
|
-
return value;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
function ɵɵinject(token, flags = InjectFlags.Default) {
|
|
463
|
-
return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
467
|
-
* particular class.
|
|
468
|
-
*
|
|
469
|
-
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
470
|
-
* and thus in the stack trace.
|
|
471
|
-
*
|
|
472
|
-
* @codeGenApi
|
|
473
|
-
*/
|
|
474
|
-
function ɵɵinvalidFactoryDep(index) {
|
|
475
|
-
throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, null);
|
|
476
|
-
}
|
|
477
|
-
/**
|
|
478
|
-
* @param token A token that represents a static attribute on the host node that should be injected.
|
|
479
|
-
* @returns Value of the attribute if it exists.
|
|
480
|
-
* @throws If called outside of a supported context or the attribute does not exist.
|
|
481
|
-
*
|
|
482
|
-
* @publicApi
|
|
483
|
-
*/
|
|
484
|
-
/**
|
|
485
|
-
* @param token A token that represents a static attribute on the host node that should be injected.
|
|
486
|
-
* @returns Value of the attribute if it exists, otherwise `null`.
|
|
487
|
-
* @throws If called outside of a supported context.
|
|
488
|
-
*
|
|
489
|
-
* @publicApi
|
|
490
|
-
*/
|
|
491
|
-
/**
|
|
492
|
-
* @param token A token that represents a static attribute on the host node that should be injected.
|
|
493
|
-
* @returns Value of the attribute if it exists.
|
|
494
|
-
* @throws If called outside of a supported context or the attribute does not exist.
|
|
495
|
-
*
|
|
496
|
-
* @publicApi
|
|
497
|
-
*/
|
|
498
|
-
/**
|
|
499
|
-
* Injects a token from the currently active injector.
|
|
500
|
-
* `inject` is only supported in an [injection context](guide/di/dependency-injection-context). It
|
|
501
|
-
* can be used during:
|
|
502
|
-
* - Construction (via the `constructor`) of a class being instantiated by the DI system, such
|
|
503
|
-
* as an `@Injectable` or `@Component`.
|
|
504
|
-
* - In the initializer for fields of such classes.
|
|
505
|
-
* - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
|
|
506
|
-
* - In the `factory` function specified for an `InjectionToken`.
|
|
507
|
-
* - In a stackframe of a function call in a DI context
|
|
508
|
-
*
|
|
509
|
-
* @param token A token that represents a dependency that should be injected.
|
|
510
|
-
* @param flags Optional flags that control how injection is executed.
|
|
511
|
-
* The flags correspond to injection strategies that can be specified with
|
|
512
|
-
* parameter decorators `@Host`, `@Self`, `@SkipSelf`, and `@Optional`.
|
|
513
|
-
* @returns the injected value if operation is successful, `null` otherwise.
|
|
514
|
-
* @throws if called outside of a supported context.
|
|
515
|
-
*
|
|
516
|
-
* @usageNotes
|
|
517
|
-
* In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
|
|
518
|
-
* field initializer:
|
|
519
|
-
*
|
|
520
|
-
* ```typescript
|
|
521
|
-
* @Injectable({providedIn: 'root'})
|
|
522
|
-
* export class Car {
|
|
523
|
-
* radio: Radio|undefined;
|
|
524
|
-
* // OK: field initializer
|
|
525
|
-
* spareTyre = inject(Tyre);
|
|
526
|
-
*
|
|
527
|
-
* constructor() {
|
|
528
|
-
* // OK: constructor body
|
|
529
|
-
* this.radio = inject(Radio);
|
|
530
|
-
* }
|
|
531
|
-
* }
|
|
532
|
-
* ```
|
|
533
|
-
*
|
|
534
|
-
* It is also legal to call `inject` from a provider's factory:
|
|
535
|
-
*
|
|
536
|
-
* ```typescript
|
|
537
|
-
* providers: [
|
|
538
|
-
* {provide: Car, useFactory: () => {
|
|
539
|
-
* // OK: a class factory
|
|
540
|
-
* const engine = inject(Engine);
|
|
541
|
-
* return new Car(engine);
|
|
542
|
-
* }}
|
|
543
|
-
* ]
|
|
544
|
-
* ```
|
|
545
|
-
*
|
|
546
|
-
* Calls to the `inject()` function outside of the class creation context will result in error. Most
|
|
547
|
-
* notably, calls to `inject()` are disallowed after a class instance was created, in methods
|
|
548
|
-
* (including lifecycle hooks):
|
|
549
|
-
*
|
|
550
|
-
* ```typescript
|
|
551
|
-
* @Component({ ... })
|
|
552
|
-
* export class CarComponent {
|
|
553
|
-
* ngOnInit() {
|
|
554
|
-
* // ERROR: too late, the component instance was already created
|
|
555
|
-
* const engine = inject(Engine);
|
|
556
|
-
* engine.start();
|
|
557
|
-
* }
|
|
558
|
-
* }
|
|
559
|
-
* ```
|
|
560
|
-
*
|
|
561
|
-
* @publicApi
|
|
562
|
-
*/
|
|
563
|
-
function inject(token, flags = InjectFlags.Default) {
|
|
564
|
-
// The `as any` here _shouldn't_ be necessary, but without it JSCompiler
|
|
565
|
-
// throws a disambiguation error due to the multiple signatures.
|
|
566
|
-
return ɵɵinject(token, convertToBitFlags(flags));
|
|
567
|
-
}
|
|
568
|
-
// Converts object-based DI flags (`InjectOptions`) to bit flags (`InjectFlags`).
|
|
569
|
-
function convertToBitFlags(flags) {
|
|
570
|
-
if (typeof flags === 'undefined' || typeof flags === 'number') {
|
|
571
|
-
return flags;
|
|
572
|
-
}
|
|
573
|
-
// While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
|
|
574
|
-
// JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
|
|
575
|
-
// `InjectOptions` to `InjectFlags`.
|
|
576
|
-
return (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
|
|
577
|
-
(flags.optional && 8 /* InternalInjectFlags.Optional */) |
|
|
578
|
-
0 |
|
|
579
|
-
(flags.self && 2 /* InternalInjectFlags.Self */) |
|
|
580
|
-
(flags.skipSelf &&
|
|
581
|
-
4 /* InternalInjectFlags.SkipSelf */));
|
|
582
|
-
}
|
|
583
|
-
function injectArgs(types) {
|
|
584
|
-
const args = [];
|
|
585
|
-
for (let i = 0; i < types.length; i++) {
|
|
586
|
-
const arg = resolveForwardRef(types[i]);
|
|
587
|
-
if (Array.isArray(arg)) {
|
|
588
|
-
if (arg.length === 0) {
|
|
589
|
-
throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, null);
|
|
590
|
-
}
|
|
591
|
-
let type = undefined;
|
|
592
|
-
let flags = InjectFlags.Default;
|
|
593
|
-
for (let j = 0; j < arg.length; j++) {
|
|
594
|
-
const meta = arg[j];
|
|
595
|
-
const flag = getInjectFlag(meta);
|
|
596
|
-
if (typeof flag === 'number') {
|
|
597
|
-
// Special case when we handle @Inject decorator.
|
|
598
|
-
if (flag === -1 /* DecoratorFlags.Inject */) {
|
|
599
|
-
type = meta.token;
|
|
600
|
-
}
|
|
601
|
-
else {
|
|
602
|
-
flags |= flag;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
else {
|
|
606
|
-
type = meta;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
args.push(ɵɵinject(type, flags));
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
args.push(ɵɵinject(arg));
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
return args;
|
|
616
|
-
}
|
|
617
|
-
/**
|
|
618
|
-
* Attaches a given InjectFlag to a given decorator using monkey-patching.
|
|
619
|
-
* Since DI decorators can be used in providers `deps` array (when provider is configured using
|
|
620
|
-
* `useFactory`) without initialization (e.g. `Host`) and as an instance (e.g. `new Host()`), we
|
|
621
|
-
* attach the flag to make it available both as a static property and as a field on decorator
|
|
622
|
-
* instance.
|
|
623
|
-
*
|
|
624
|
-
* @param decorator Provided DI decorator.
|
|
625
|
-
* @param flag InjectFlag that should be applied.
|
|
626
|
-
*/
|
|
627
|
-
function attachInjectFlag(decorator, flag) {
|
|
628
|
-
decorator[DI_DECORATOR_FLAG] = flag;
|
|
629
|
-
decorator.prototype[DI_DECORATOR_FLAG] = flag;
|
|
630
|
-
return decorator;
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* Reads monkey-patched property that contains InjectFlag attached to a decorator.
|
|
634
|
-
*
|
|
635
|
-
* @param token Token that may contain monkey-patched DI flags property.
|
|
636
|
-
*/
|
|
637
|
-
function getInjectFlag(token) {
|
|
638
|
-
return token[DI_DECORATOR_FLAG];
|
|
639
|
-
}
|
|
640
|
-
function catchInjectorError(e, token, injectorErrorName, source) {
|
|
641
|
-
const tokenPath = e[NG_TEMP_TOKEN_PATH];
|
|
642
|
-
if (token[SOURCE]) {
|
|
643
|
-
tokenPath.unshift(token[SOURCE]);
|
|
644
|
-
}
|
|
645
|
-
e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
|
|
646
|
-
e[NG_TOKEN_PATH] = tokenPath;
|
|
647
|
-
e[NG_TEMP_TOKEN_PATH] = null;
|
|
648
|
-
throw e;
|
|
649
|
-
}
|
|
650
|
-
function formatError(text, obj, injectorErrorName, source = null) {
|
|
651
|
-
text =
|
|
652
|
-
text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE
|
|
653
|
-
? text.slice(2)
|
|
654
|
-
: text;
|
|
655
|
-
let context = stringify(obj);
|
|
656
|
-
if (Array.isArray(obj)) {
|
|
657
|
-
context = obj.map(stringify).join(' -> ');
|
|
658
|
-
}
|
|
659
|
-
else if (typeof obj === 'object') {
|
|
660
|
-
let parts = [];
|
|
661
|
-
for (let key in obj) {
|
|
662
|
-
if (obj.hasOwnProperty(key)) {
|
|
663
|
-
let value = obj[key];
|
|
664
|
-
parts.push(key +
|
|
665
|
-
':' +
|
|
666
|
-
(typeof value === 'string'
|
|
667
|
-
? JSON.stringify(value)
|
|
668
|
-
: stringify(value)));
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
context = `{${parts.join(', ')}}`;
|
|
672
|
-
}
|
|
673
|
-
return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* @license
|
|
678
|
-
* Copyright Google LLC All Rights Reserved.
|
|
679
|
-
*
|
|
680
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
681
|
-
* found in the LICENSE file at https://angular.io/license
|
|
682
|
-
*/
|
|
683
|
-
/**
|
|
684
|
-
* Inject decorator and metadata.
|
|
685
|
-
*
|
|
686
|
-
* @Annotation
|
|
687
|
-
* @publicApi
|
|
688
|
-
*/
|
|
689
|
-
const Inject = attachInjectFlag(
|
|
690
|
-
// Disable tslint because `DecoratorFlags` is a const enum which gets inlined.
|
|
691
|
-
makeParamDecorator('Inject', (token) => ({ token })), -1 /* DecoratorFlags.Inject */);
|
|
692
|
-
/**
|
|
693
|
-
* Optional decorator and metadata.
|
|
694
|
-
*
|
|
695
|
-
* @Annotation
|
|
696
|
-
* @publicApi
|
|
697
|
-
*/
|
|
698
|
-
const Optional =
|
|
699
|
-
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
|
|
700
|
-
// tslint:disable-next-line: no-toplevel-property-access
|
|
701
|
-
attachInjectFlag(makeParamDecorator(), 8 /* InternalInjectFlags.Optional */);
|
|
702
|
-
/**
|
|
703
|
-
* Self decorator and metadata.
|
|
704
|
-
*
|
|
705
|
-
* @Annotation
|
|
706
|
-
* @publicApi
|
|
707
|
-
*/
|
|
708
|
-
const Self =
|
|
709
|
-
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
|
|
710
|
-
// tslint:disable-next-line: no-toplevel-property-access
|
|
711
|
-
attachInjectFlag(makeParamDecorator(), 2 /* InternalInjectFlags.Self */);
|
|
712
|
-
/**
|
|
713
|
-
* `SkipSelf` decorator and metadata.
|
|
714
|
-
*
|
|
715
|
-
* @Annotation
|
|
716
|
-
* @publicApi
|
|
717
|
-
*/
|
|
718
|
-
const SkipSelf =
|
|
719
|
-
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
|
|
720
|
-
// tslint:disable-next-line: no-toplevel-property-access
|
|
721
|
-
attachInjectFlag(makeParamDecorator(), 4 /* InternalInjectFlags.SkipSelf */);
|
|
722
|
-
|
|
723
|
-
/**
|
|
724
|
-
* @license
|
|
725
|
-
* Copyright Google LLC All Rights Reserved.
|
|
726
|
-
*
|
|
727
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
728
|
-
* found in the LICENSE file at https://angular.io/license
|
|
729
|
-
*/
|
|
730
|
-
function getFactoryDef(type, throwNotFound) {
|
|
731
|
-
return () => new type();
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
/**
|
|
735
|
-
* @license
|
|
736
|
-
* Copyright Google LLC All Rights Reserved.
|
|
737
|
-
*
|
|
738
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
739
|
-
* found in the LICENSE file at https://angular.io/license
|
|
740
|
-
*/
|
|
741
|
-
getClosureSafeProperty({
|
|
742
|
-
ɵfac: getClosureSafeProperty,
|
|
743
|
-
});
|
|
744
|
-
/**
|
|
745
|
-
* The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
|
|
746
|
-
* getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
|
|
747
|
-
* strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
|
|
748
|
-
*
|
|
749
|
-
* This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
|
|
750
|
-
* improve tree-shaking.
|
|
751
|
-
*/
|
|
752
|
-
const NG_ENV_ID = getClosureSafeProperty({
|
|
753
|
-
__NG_ENV_ID__: getClosureSafeProperty,
|
|
754
|
-
});
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* @license
|
|
758
|
-
* Copyright Google LLC All Rights Reserved.
|
|
759
|
-
*
|
|
760
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
761
|
-
* found in the LICENSE file at https://angular.io/license
|
|
762
|
-
*/
|
|
763
|
-
/**
|
|
764
|
-
* This file contains reuseable "empty" symbols that can be used as default return values
|
|
765
|
-
* in different parts of the rendering code. Because the same symbols are returned, this
|
|
766
|
-
* allows for identity checks against these values to be consistently used by the framework
|
|
767
|
-
* code.
|
|
768
|
-
*/
|
|
769
|
-
const EMPTY_ARRAY = [];
|
|
770
|
-
|
|
771
|
-
/**
|
|
772
|
-
* @license
|
|
773
|
-
* Copyright Google LLC All Rights Reserved.
|
|
774
|
-
*
|
|
775
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
776
|
-
* found in the LICENSE file at https://angular.io/license
|
|
777
|
-
*/
|
|
778
|
-
/**
|
|
779
|
-
* Creates a token that can be used in a DI Provider.
|
|
780
|
-
*
|
|
781
|
-
* Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
|
|
782
|
-
* runtime representation) such as when injecting an interface, callable type, array or
|
|
783
|
-
* parameterized type.
|
|
784
|
-
*
|
|
785
|
-
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
|
|
786
|
-
* the `Injector`. This provides an additional level of type safety.
|
|
787
|
-
*
|
|
788
|
-
* <div class="alert is-helpful">
|
|
789
|
-
*
|
|
790
|
-
* **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the
|
|
791
|
-
* provider and the injection call. Creating a new instance of `InjectionToken` in different places,
|
|
792
|
-
* even with the same description, will be treated as different tokens by Angular's DI system,
|
|
793
|
-
* leading to a `NullInjectorError`.
|
|
794
|
-
*
|
|
795
|
-
* </div>
|
|
796
|
-
*
|
|
797
|
-
* <code-example format="typescript" language="typescript" path="injection-token/src/main.ts"
|
|
798
|
-
* region="InjectionToken"></code-example>
|
|
799
|
-
*
|
|
800
|
-
* When creating an `InjectionToken`, you can optionally specify a factory function which returns
|
|
801
|
-
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
|
|
802
|
-
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
|
|
803
|
-
* application's root injector. If the factory function, which takes zero arguments, needs to inject
|
|
804
|
-
* dependencies, it can do so using the [`inject`](api/core/inject) function.
|
|
805
|
-
* As you can see in the Tree-shakable InjectionToken example below.
|
|
806
|
-
*
|
|
807
|
-
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
|
|
808
|
-
* overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note:
|
|
809
|
-
* this option is now deprecated). As mentioned above, `'root'` is the default value for
|
|
810
|
-
* `providedIn`.
|
|
811
|
-
*
|
|
812
|
-
* The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated.
|
|
813
|
-
*
|
|
814
|
-
* @usageNotes
|
|
815
|
-
* ### Basic Examples
|
|
816
|
-
*
|
|
817
|
-
* ### Plain InjectionToken
|
|
818
|
-
*
|
|
819
|
-
* {@example core/di/ts/injector_spec.ts region='InjectionToken'}
|
|
820
|
-
*
|
|
821
|
-
* ### Tree-shakable InjectionToken
|
|
822
|
-
*
|
|
823
|
-
* {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
|
|
824
|
-
*
|
|
825
|
-
* @publicApi
|
|
826
|
-
*/
|
|
827
|
-
class InjectionToken {
|
|
828
|
-
_desc;
|
|
829
|
-
/** @internal */
|
|
830
|
-
ngMetadataName = 'InjectionToken';
|
|
831
|
-
ɵprov;
|
|
832
|
-
/**
|
|
833
|
-
* @param _desc Description for the token,
|
|
834
|
-
* used only for debugging purposes,
|
|
835
|
-
* it should but does not need to be unique
|
|
836
|
-
* @param options Options for the token's usage, as described above
|
|
837
|
-
*/
|
|
838
|
-
constructor(_desc, options) {
|
|
839
|
-
this._desc = _desc;
|
|
840
|
-
this.ɵprov = undefined;
|
|
841
|
-
if (typeof options == 'number') ;
|
|
842
|
-
else if (options !== undefined) {
|
|
843
|
-
this.ɵprov = ɵɵdefineInjectable({
|
|
844
|
-
token: this,
|
|
845
|
-
providedIn: options.providedIn || 'root',
|
|
846
|
-
factory: options.factory,
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* @internal
|
|
852
|
-
*/
|
|
853
|
-
get multi() {
|
|
854
|
-
return this;
|
|
855
|
-
}
|
|
856
|
-
toString() {
|
|
857
|
-
return `InjectionToken ${this._desc}`;
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
/**
|
|
862
|
-
* @license
|
|
863
|
-
* Copyright Google LLC All Rights Reserved.
|
|
864
|
-
*
|
|
865
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
866
|
-
* found in the LICENSE file at https://angular.io/license
|
|
867
|
-
*/
|
|
868
|
-
/**
|
|
869
|
-
* A multi-provider token for initialization functions that will run upon construction of an
|
|
870
|
-
* environment injector.
|
|
871
|
-
*
|
|
872
|
-
* @publicApi
|
|
873
|
-
*/
|
|
874
|
-
const ENVIRONMENT_INITIALIZER = new InjectionToken('');
|
|
875
|
-
|
|
876
|
-
/**
|
|
877
|
-
* @license
|
|
878
|
-
* Copyright Google LLC All Rights Reserved.
|
|
879
|
-
*
|
|
880
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
881
|
-
* found in the LICENSE file at https://angular.io/license
|
|
882
|
-
*/
|
|
883
|
-
/**
|
|
884
|
-
* An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
|
|
885
|
-
*
|
|
886
|
-
* Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
|
|
887
|
-
* project.
|
|
888
|
-
*
|
|
889
|
-
* @publicApi
|
|
890
|
-
*/
|
|
891
|
-
const INJECTOR = new InjectionToken('',
|
|
892
|
-
// Disable tslint because this is const enum which gets inlined not top level prop access.
|
|
893
|
-
// tslint:disable-next-line: no-toplevel-property-access
|
|
894
|
-
-1 /* InjectorMarkers.Injector */);
|
|
895
|
-
|
|
896
|
-
/**
|
|
897
|
-
* @license
|
|
898
|
-
* Copyright Google LLC All Rights Reserved.
|
|
899
|
-
*
|
|
900
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
901
|
-
* found in the LICENSE file at https://angular.io/license
|
|
902
|
-
*/
|
|
903
|
-
function isEnvironmentProviders(value) {
|
|
904
|
-
return value && !!value.ɵproviders;
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
/**
|
|
908
|
-
* @license
|
|
909
|
-
* Copyright Google LLC All Rights Reserved.
|
|
910
|
-
*
|
|
911
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
912
|
-
* found in the LICENSE file at https://angular.io/license
|
|
913
|
-
*/
|
|
914
|
-
const INJECTOR_DEF_TYPES = new InjectionToken('');
|
|
915
|
-
|
|
916
|
-
/**
|
|
917
|
-
* @license
|
|
918
|
-
* Copyright Google LLC All Rights Reserved.
|
|
919
|
-
*
|
|
920
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
921
|
-
* found in the LICENSE file at https://angular.io/license
|
|
922
|
-
*/
|
|
923
|
-
class NullInjector {
|
|
924
|
-
get(token, notFoundValue = THROW_IF_NOT_FOUND) {
|
|
925
|
-
if (notFoundValue === THROW_IF_NOT_FOUND) {
|
|
926
|
-
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
|
|
927
|
-
error.name = 'NullInjectorError';
|
|
928
|
-
throw error;
|
|
929
|
-
}
|
|
930
|
-
return notFoundValue;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
/**
|
|
935
|
-
* @license
|
|
936
|
-
* Copyright Google LLC All Rights Reserved.
|
|
937
|
-
*
|
|
938
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
939
|
-
* found in the LICENSE file at https://angular.io/license
|
|
940
|
-
*/
|
|
941
|
-
/**
|
|
942
|
-
* Collects providers from all NgModules and standalone components, including transitively imported
|
|
943
|
-
* ones.
|
|
944
|
-
*
|
|
945
|
-
* Providers extracted via `importProvidersFrom` are only usable in an application injector or
|
|
946
|
-
* another environment injector (such as a route injector). They should not be used in component
|
|
947
|
-
* providers.
|
|
948
|
-
*
|
|
949
|
-
* More information about standalone components can be found in [this
|
|
950
|
-
* guide](guide/components/importing).
|
|
951
|
-
*
|
|
952
|
-
* @usageNotes
|
|
953
|
-
* The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:
|
|
954
|
-
*
|
|
955
|
-
* ```typescript
|
|
956
|
-
* await bootstrapApplication(RootComponent, {
|
|
957
|
-
* providers: [
|
|
958
|
-
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
959
|
-
* ]
|
|
960
|
-
* });
|
|
961
|
-
* ```
|
|
962
|
-
*
|
|
963
|
-
* You can also use the `importProvidersFrom` results in the `providers` field of a route, when a
|
|
964
|
-
* standalone component is used:
|
|
965
|
-
*
|
|
966
|
-
* ```typescript
|
|
967
|
-
* export const ROUTES: Route[] = [
|
|
968
|
-
* {
|
|
969
|
-
* path: 'foo',
|
|
970
|
-
* providers: [
|
|
971
|
-
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
972
|
-
* ],
|
|
973
|
-
* component: YourStandaloneComponent
|
|
974
|
-
* }
|
|
975
|
-
* ];
|
|
976
|
-
* ```
|
|
977
|
-
*
|
|
978
|
-
* @returns Collected providers from the specified list of types.
|
|
979
|
-
* @publicApi
|
|
980
|
-
*/
|
|
981
|
-
function importProvidersFrom(...sources) {
|
|
982
|
-
return {
|
|
983
|
-
ɵproviders: internalImportProvidersFrom(true, sources),
|
|
984
|
-
ɵfromNgModule: true,
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
|
-
function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
988
|
-
const providersOut = [];
|
|
989
|
-
return providersOut;
|
|
990
|
-
}
|
|
991
|
-
const USE_VALUE = getClosureSafeProperty({
|
|
992
|
-
provide: String,
|
|
993
|
-
useValue: getClosureSafeProperty,
|
|
994
|
-
});
|
|
995
|
-
function isValueProvider(value) {
|
|
996
|
-
return value !== null && typeof value == 'object' && USE_VALUE in value;
|
|
997
|
-
}
|
|
998
|
-
function isExistingProvider(value) {
|
|
999
|
-
return !!(value && value.useExisting);
|
|
1000
|
-
}
|
|
1001
|
-
function isFactoryProvider(value) {
|
|
1002
|
-
return !!(value && value.useFactory);
|
|
1003
|
-
}
|
|
1004
|
-
function isTypeProvider(value) {
|
|
1005
|
-
return typeof value === 'function';
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
/**
|
|
1009
|
-
* @license
|
|
1010
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1011
|
-
*
|
|
1012
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1013
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1014
|
-
*/
|
|
1015
|
-
/**
|
|
1016
|
-
* An internal token whose presence in an injector indicates that the injector should treat itself
|
|
1017
|
-
* as a root scoped injector when processing requests for unknown tokens which may indicate
|
|
1018
|
-
* they are provided in the root scope.
|
|
1019
|
-
*/
|
|
1020
|
-
const INJECTOR_SCOPE = new InjectionToken('');
|
|
1021
|
-
|
|
1022
|
-
/**
|
|
1023
|
-
* @license
|
|
1024
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1025
|
-
*
|
|
1026
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1027
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1028
|
-
*/
|
|
1029
|
-
/**
|
|
1030
|
-
* Marker which indicates that a value has not yet been created from the factory function.
|
|
1031
|
-
*/
|
|
1032
|
-
const NOT_YET = {};
|
|
1033
|
-
/**
|
|
1034
|
-
* Marker which indicates that the factory function for a token is in the process of being called.
|
|
1035
|
-
*
|
|
1036
|
-
* If the injector is asked to inject a token with its value set to CIRCULAR, that indicates
|
|
1037
|
-
* injection of a dependency has recursively attempted to inject the original token, and there is
|
|
1038
|
-
* a circular dependency among the providers.
|
|
1039
|
-
*/
|
|
1040
|
-
const CIRCULAR = {};
|
|
1041
|
-
/**
|
|
1042
|
-
* A lazily initialized NullInjector.
|
|
1043
|
-
*/
|
|
1044
|
-
let NULL_INJECTOR = undefined;
|
|
1045
|
-
function getNullInjector() {
|
|
1046
|
-
if (NULL_INJECTOR === undefined) {
|
|
1047
|
-
NULL_INJECTOR = new NullInjector();
|
|
1048
|
-
}
|
|
1049
|
-
return NULL_INJECTOR;
|
|
1050
|
-
}
|
|
1051
|
-
/**
|
|
1052
|
-
* An `Injector` that's part of the environment injector hierarchy, which exists outside of the
|
|
1053
|
-
* component tree.
|
|
1054
|
-
*/
|
|
1055
|
-
class EnvironmentInjector {
|
|
1056
|
-
}
|
|
1057
|
-
class R3Injector extends EnvironmentInjector {
|
|
1058
|
-
parent;
|
|
1059
|
-
source;
|
|
1060
|
-
scopes;
|
|
1061
|
-
/**
|
|
1062
|
-
* Map of tokens to records which contain the instances of those tokens.
|
|
1063
|
-
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
1064
|
-
* to prevent further searches.
|
|
1065
|
-
*/
|
|
1066
|
-
records = new Map();
|
|
1067
|
-
/**
|
|
1068
|
-
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
1069
|
-
*/
|
|
1070
|
-
_ngOnDestroyHooks = new Set();
|
|
1071
|
-
_onDestroyHooks = [];
|
|
1072
|
-
/**
|
|
1073
|
-
* Flag indicating that this injector was previously destroyed.
|
|
1074
|
-
*/
|
|
1075
|
-
get destroyed() {
|
|
1076
|
-
return this._destroyed;
|
|
1077
|
-
}
|
|
1078
|
-
_destroyed = false;
|
|
1079
|
-
injectorDefTypes;
|
|
1080
|
-
constructor(providers, parent, source, scopes) {
|
|
1081
|
-
super();
|
|
1082
|
-
this.parent = parent;
|
|
1083
|
-
this.source = source;
|
|
1084
|
-
this.scopes = scopes;
|
|
1085
|
-
// Start off by creating Records for every provider.
|
|
1086
|
-
forEachSingleProvider(providers, (provider) => this.processProvider(provider));
|
|
1087
|
-
// Make sure the INJECTOR token provides this injector.
|
|
1088
|
-
this.records.set(INJECTOR, makeRecord(undefined, this));
|
|
1089
|
-
// And `EnvironmentInjector` if the current injector is supposed to be env-scoped.
|
|
1090
|
-
if (scopes.has('environment')) {
|
|
1091
|
-
this.records.set(EnvironmentInjector, makeRecord(undefined, this));
|
|
1092
|
-
}
|
|
1093
|
-
// Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
|
|
1094
|
-
// any injectable scoped to APP_ROOT_SCOPE.
|
|
1095
|
-
const record = this.records.get(INJECTOR_SCOPE);
|
|
1096
|
-
if (record != null && typeof record.value === 'string') {
|
|
1097
|
-
this.scopes.add(record.value);
|
|
1098
|
-
}
|
|
1099
|
-
this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES, EMPTY_ARRAY, InjectFlags.Self));
|
|
1100
|
-
}
|
|
1101
|
-
/**
|
|
1102
|
-
* Destroy the injector and release references to every instance or provider associated with it.
|
|
1103
|
-
*
|
|
1104
|
-
* Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a
|
|
1105
|
-
* hook was found.
|
|
1106
|
-
*/
|
|
1107
|
-
destroy() {
|
|
1108
|
-
this.assertNotDestroyed();
|
|
1109
|
-
// Set destroyed = true first, in case lifecycle hooks re-enter destroy().
|
|
1110
|
-
this._destroyed = true;
|
|
1111
|
-
try {
|
|
1112
|
-
// Call all the lifecycle hooks.
|
|
1113
|
-
for (const service of this._ngOnDestroyHooks) {
|
|
1114
|
-
service.ngOnDestroy();
|
|
1115
|
-
}
|
|
1116
|
-
const onDestroyHooks = this._onDestroyHooks;
|
|
1117
|
-
// Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
|
|
1118
|
-
// themselves from mutating the array during iteration.
|
|
1119
|
-
this._onDestroyHooks = [];
|
|
1120
|
-
for (const hook of onDestroyHooks) {
|
|
1121
|
-
hook();
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
finally {
|
|
1125
|
-
// Release all references.
|
|
1126
|
-
this.records.clear();
|
|
1127
|
-
this._ngOnDestroyHooks.clear();
|
|
1128
|
-
this.injectorDefTypes.clear();
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
onDestroy(callback) {
|
|
1132
|
-
this.assertNotDestroyed();
|
|
1133
|
-
this._onDestroyHooks.push(callback);
|
|
1134
|
-
return () => this.removeOnDestroy(callback);
|
|
1135
|
-
}
|
|
1136
|
-
runInContext(fn) {
|
|
1137
|
-
this.assertNotDestroyed();
|
|
1138
|
-
const previousInjector = setCurrentInjector(this);
|
|
1139
|
-
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1140
|
-
try {
|
|
1141
|
-
return fn();
|
|
1142
|
-
}
|
|
1143
|
-
finally {
|
|
1144
|
-
setCurrentInjector(previousInjector);
|
|
1145
|
-
setInjectImplementation(previousInjectImplementation);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
|
|
1149
|
-
this.assertNotDestroyed();
|
|
1150
|
-
if (token.hasOwnProperty(NG_ENV_ID)) {
|
|
1151
|
-
return token[NG_ENV_ID](this);
|
|
1152
|
-
}
|
|
1153
|
-
flags = convertToBitFlags(flags);
|
|
1154
|
-
const previousInjector = setCurrentInjector(this);
|
|
1155
|
-
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1156
|
-
try {
|
|
1157
|
-
// Check for the SkipSelf flag.
|
|
1158
|
-
if (!(flags & InjectFlags.SkipSelf)) {
|
|
1159
|
-
// SkipSelf isn't set, check if the record belongs to this injector.
|
|
1160
|
-
let record = this.records.get(token);
|
|
1161
|
-
if (record === undefined) {
|
|
1162
|
-
// No record, but maybe the token is scoped to this injector. Look for an injectable
|
|
1163
|
-
// def with a scope matching this injector.
|
|
1164
|
-
const def = couldBeInjectableType(token) && getInjectableDef(token);
|
|
1165
|
-
if (def && this.injectableDefInScope(def)) {
|
|
1166
|
-
// Found an injectable def and it's scoped to this injector. Pretend as if it was here
|
|
1167
|
-
// all along.
|
|
1168
|
-
if (false) ;
|
|
1169
|
-
record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
|
|
1170
|
-
}
|
|
1171
|
-
else {
|
|
1172
|
-
record = null;
|
|
1173
|
-
}
|
|
1174
|
-
this.records.set(token, record);
|
|
1175
|
-
}
|
|
1176
|
-
// If a record was found, get the instance for it and return it.
|
|
1177
|
-
if (record != null /* NOT null || undefined */) {
|
|
1178
|
-
return this.hydrate(token, record);
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
// Select the next injector based on the Self flag - if self is set, the next injector is
|
|
1182
|
-
// the NullInjector, otherwise it's the parent.
|
|
1183
|
-
const nextInjector = !(flags & InjectFlags.Self)
|
|
1184
|
-
? this.parent
|
|
1185
|
-
: getNullInjector();
|
|
1186
|
-
// Set the notFoundValue based on the Optional flag - if optional is set and notFoundValue
|
|
1187
|
-
// is undefined, the value is null, otherwise it's the notFoundValue.
|
|
1188
|
-
notFoundValue =
|
|
1189
|
-
flags & InjectFlags.Optional && notFoundValue === THROW_IF_NOT_FOUND
|
|
1190
|
-
? null
|
|
1191
|
-
: notFoundValue;
|
|
1192
|
-
return nextInjector.get(token, notFoundValue);
|
|
1193
|
-
}
|
|
1194
|
-
catch (e) {
|
|
1195
|
-
if (e.name === 'NullInjectorError') {
|
|
1196
|
-
const path = (e[NG_TEMP_TOKEN_PATH] =
|
|
1197
|
-
e[NG_TEMP_TOKEN_PATH] || []);
|
|
1198
|
-
path.unshift(stringify(token));
|
|
1199
|
-
if (previousInjector) {
|
|
1200
|
-
// We still have a parent injector, keep throwing
|
|
1201
|
-
throw e;
|
|
1202
|
-
}
|
|
1203
|
-
else {
|
|
1204
|
-
// Format & throw the final error message when we don't have any previous injector
|
|
1205
|
-
return catchInjectorError(e, token, 'R3InjectorError', this.source);
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
else {
|
|
1209
|
-
throw e;
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
finally {
|
|
1213
|
-
// Lastly, restore the previous injection context.
|
|
1214
|
-
setInjectImplementation(previousInjectImplementation);
|
|
1215
|
-
setCurrentInjector(previousInjector);
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
/** @internal */
|
|
1219
|
-
resolveInjectorInitializers() {
|
|
1220
|
-
const previousInjector = setCurrentInjector(this);
|
|
1221
|
-
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1222
|
-
try {
|
|
1223
|
-
const initializers = this.get(ENVIRONMENT_INITIALIZER, EMPTY_ARRAY, InjectFlags.Self);
|
|
1224
|
-
if (false) ;
|
|
1225
|
-
for (const initializer of initializers) {
|
|
1226
|
-
initializer();
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1229
|
-
finally {
|
|
1230
|
-
setCurrentInjector(previousInjector);
|
|
1231
|
-
setInjectImplementation(previousInjectImplementation);
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
toString() {
|
|
1235
|
-
const tokens = [];
|
|
1236
|
-
const records = this.records;
|
|
1237
|
-
for (const token of records.keys()) {
|
|
1238
|
-
tokens.push(stringify(token));
|
|
1239
|
-
}
|
|
1240
|
-
return `R3Injector[${tokens.join(', ')}]`;
|
|
1241
|
-
}
|
|
1242
|
-
assertNotDestroyed() {
|
|
1243
|
-
if (this._destroyed) {
|
|
1244
|
-
throw new RuntimeError(205 /* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED */, null);
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
/**
|
|
1248
|
-
* Process a `SingleProvider` and add it.
|
|
1249
|
-
*/
|
|
1250
|
-
processProvider(provider) {
|
|
1251
|
-
// Determine the token from the provider. Either it's its own token, or has a {provide: ...}
|
|
1252
|
-
// property.
|
|
1253
|
-
provider = resolveForwardRef(provider);
|
|
1254
|
-
let token = isTypeProvider(provider)
|
|
1255
|
-
? provider
|
|
1256
|
-
: resolveForwardRef(provider && provider.provide);
|
|
1257
|
-
// Construct a `Record` for the provider.
|
|
1258
|
-
const record = providerToRecord(provider);
|
|
1259
|
-
if (!isTypeProvider(provider) && provider.multi === true) {
|
|
1260
|
-
// If the provider indicates that it's a multi-provider, process it specially.
|
|
1261
|
-
// First check whether it's been defined already.
|
|
1262
|
-
let multiRecord = this.records.get(token);
|
|
1263
|
-
if (multiRecord) ;
|
|
1264
|
-
else {
|
|
1265
|
-
multiRecord = makeRecord(undefined, NOT_YET, true);
|
|
1266
|
-
multiRecord.factory = () => injectArgs(multiRecord.multi);
|
|
1267
|
-
this.records.set(token, multiRecord);
|
|
1268
|
-
}
|
|
1269
|
-
token = provider;
|
|
1270
|
-
multiRecord.multi.push(provider);
|
|
1271
|
-
}
|
|
1272
|
-
this.records.set(token, record);
|
|
1273
|
-
}
|
|
1274
|
-
hydrate(token, record) {
|
|
1275
|
-
try {
|
|
1276
|
-
if (false) ;
|
|
1277
|
-
else if (record.value === NOT_YET) {
|
|
1278
|
-
record.value = CIRCULAR;
|
|
1279
|
-
if (false) ;
|
|
1280
|
-
else {
|
|
1281
|
-
record.value = record.factory();
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
if (typeof record.value === 'object' &&
|
|
1285
|
-
record.value &&
|
|
1286
|
-
hasOnDestroy(record.value)) {
|
|
1287
|
-
this._ngOnDestroyHooks.add(record.value);
|
|
1288
|
-
}
|
|
1289
|
-
return record.value;
|
|
1290
|
-
}
|
|
1291
|
-
finally {
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
injectableDefInScope(def) {
|
|
1295
|
-
if (!def.providedIn) {
|
|
1296
|
-
return false;
|
|
1297
|
-
}
|
|
1298
|
-
const providedIn = resolveForwardRef(def.providedIn);
|
|
1299
|
-
if (typeof providedIn === 'string') {
|
|
1300
|
-
return providedIn === 'any' || this.scopes.has(providedIn);
|
|
1301
|
-
}
|
|
1302
|
-
else {
|
|
1303
|
-
return this.injectorDefTypes.has(providedIn);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
removeOnDestroy(callback) {
|
|
1307
|
-
const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
|
|
1308
|
-
if (destroyCBIdx !== -1) {
|
|
1309
|
-
this._onDestroyHooks.splice(destroyCBIdx, 1);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
function injectableDefOrInjectorDefFactory(token) {
|
|
1314
|
-
// Most tokens will have an injectable def directly on them, which specifies a factory directly.
|
|
1315
|
-
const injectableDef = getInjectableDef(token);
|
|
1316
|
-
const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);
|
|
1317
|
-
if (factory !== null) {
|
|
1318
|
-
return factory;
|
|
1319
|
-
}
|
|
1320
|
-
// InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
|
|
1321
|
-
// If it's missing that, it's an error.
|
|
1322
|
-
if (token instanceof InjectionToken) {
|
|
1323
|
-
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1324
|
-
}
|
|
1325
|
-
// Undecorated types can sometimes be created if they have no constructor arguments.
|
|
1326
|
-
if (token instanceof Function) {
|
|
1327
|
-
return getUndecoratedInjectableFactory(token);
|
|
1328
|
-
}
|
|
1329
|
-
// There was no way to resolve a factory for this token.
|
|
1330
|
-
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1331
|
-
}
|
|
1332
|
-
function getUndecoratedInjectableFactory(token) {
|
|
1333
|
-
// If the token has parameters then it has dependencies that we cannot resolve implicitly.
|
|
1334
|
-
const paramLength = token.length;
|
|
1335
|
-
if (paramLength > 0) {
|
|
1336
|
-
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1337
|
-
}
|
|
1338
|
-
// The constructor function appears to have no parameters.
|
|
1339
|
-
// This might be because it inherits from a super-class. In which case, use an injectable
|
|
1340
|
-
// def from an ancestor if there is one.
|
|
1341
|
-
// Otherwise this really is a simple class with no dependencies, so return a factory that
|
|
1342
|
-
// just instantiates the zero-arg constructor.
|
|
1343
|
-
const inheritedInjectableDef = getInheritedInjectableDef(token);
|
|
1344
|
-
if (inheritedInjectableDef !== null) {
|
|
1345
|
-
return () => inheritedInjectableDef.factory(token);
|
|
1346
|
-
}
|
|
1347
|
-
else {
|
|
1348
|
-
return () => new token();
|
|
1349
|
-
}
|
|
1350
|
-
}
|
|
1351
|
-
function providerToRecord(provider) {
|
|
1352
|
-
if (isValueProvider(provider)) {
|
|
1353
|
-
return makeRecord(undefined, provider.useValue);
|
|
1354
|
-
}
|
|
1355
|
-
else {
|
|
1356
|
-
const factory = providerToFactory(provider);
|
|
1357
|
-
return makeRecord(factory, NOT_YET);
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
/**
|
|
1361
|
-
* Converts a `SingleProvider` into a factory function.
|
|
1362
|
-
*
|
|
1363
|
-
* @param provider provider to convert to factory
|
|
1364
|
-
*/
|
|
1365
|
-
function providerToFactory(provider, ngModuleType, providers) {
|
|
1366
|
-
let factory = undefined;
|
|
1367
|
-
if (isTypeProvider(provider)) {
|
|
1368
|
-
const unwrappedProvider = resolveForwardRef(provider);
|
|
1369
|
-
return (getFactoryDef(unwrappedProvider) ||
|
|
1370
|
-
injectableDefOrInjectorDefFactory(unwrappedProvider));
|
|
1371
|
-
}
|
|
1372
|
-
else {
|
|
1373
|
-
if (isValueProvider(provider)) {
|
|
1374
|
-
factory = () => resolveForwardRef(provider.useValue);
|
|
1375
|
-
}
|
|
1376
|
-
else if (isFactoryProvider(provider)) {
|
|
1377
|
-
factory = () => provider.useFactory(...injectArgs(provider.deps || []));
|
|
1378
|
-
}
|
|
1379
|
-
else if (isExistingProvider(provider)) {
|
|
1380
|
-
factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));
|
|
1381
|
-
}
|
|
1382
|
-
else {
|
|
1383
|
-
const classRef = resolveForwardRef(provider &&
|
|
1384
|
-
(provider.useClass ||
|
|
1385
|
-
provider.provide));
|
|
1386
|
-
if (hasDeps(provider)) {
|
|
1387
|
-
factory = () => new classRef(...injectArgs(provider.deps));
|
|
1388
|
-
}
|
|
1389
|
-
else {
|
|
1390
|
-
return (getFactoryDef(classRef) || injectableDefOrInjectorDefFactory(classRef));
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
return factory;
|
|
1395
|
-
}
|
|
1396
|
-
function makeRecord(factory, value, multi = false) {
|
|
1397
|
-
return {
|
|
1398
|
-
factory: factory,
|
|
1399
|
-
value: value,
|
|
1400
|
-
multi: multi ? [] : undefined,
|
|
1401
|
-
};
|
|
1402
|
-
}
|
|
1403
|
-
function hasDeps(value) {
|
|
1404
|
-
return !!value.deps;
|
|
1405
|
-
}
|
|
1406
|
-
function hasOnDestroy(value) {
|
|
1407
|
-
return (value !== null &&
|
|
1408
|
-
typeof value === 'object' &&
|
|
1409
|
-
typeof value.ngOnDestroy === 'function');
|
|
1410
|
-
}
|
|
1411
|
-
function couldBeInjectableType(value) {
|
|
1412
|
-
return (typeof value === 'function' ||
|
|
1413
|
-
(typeof value === 'object' && value instanceof InjectionToken));
|
|
1414
|
-
}
|
|
1415
|
-
function forEachSingleProvider(providers, fn) {
|
|
1416
|
-
for (const provider of providers) {
|
|
1417
|
-
if (Array.isArray(provider)) {
|
|
1418
|
-
forEachSingleProvider(provider, fn);
|
|
1419
|
-
}
|
|
1420
|
-
else if (provider && isEnvironmentProviders(provider)) {
|
|
1421
|
-
forEachSingleProvider(provider.ɵproviders, fn);
|
|
1422
|
-
}
|
|
1423
|
-
else {
|
|
1424
|
-
fn(provider);
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
/**
|
|
1430
|
-
* @license
|
|
1431
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1432
|
-
*
|
|
1433
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1434
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1435
|
-
*/
|
|
1436
|
-
/**
|
|
1437
|
-
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
1438
|
-
*/
|
|
1439
|
-
function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
1440
|
-
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
1441
|
-
injector.resolveInjectorInitializers();
|
|
1442
|
-
return injector;
|
|
1443
|
-
}
|
|
1444
|
-
/**
|
|
1445
|
-
* Creates a new injector without eagerly resolving its injector types. Can be used in places
|
|
1446
|
-
* where resolving the injector types immediately can lead to an infinite loop. The injector types
|
|
1447
|
-
* should be resolved at a later point by calling `_resolveInjectorDefTypes`.
|
|
1448
|
-
*/
|
|
1449
|
-
function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
|
|
1450
|
-
const providers = [
|
|
1451
|
-
additionalProviders || EMPTY_ARRAY,
|
|
1452
|
-
importProvidersFrom(defType),
|
|
1453
|
-
];
|
|
1454
|
-
name = name || (typeof defType === 'object' ? undefined : stringify(defType));
|
|
1455
|
-
return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
/**
|
|
1459
|
-
* @license
|
|
1460
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1461
|
-
*
|
|
1462
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1463
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1464
|
-
*/
|
|
1465
|
-
/**
|
|
1466
|
-
* Concrete injectors implement this interface. Injectors are configured
|
|
1467
|
-
* with [providers](guide/di/dependency-injection-providers) that associate
|
|
1468
|
-
* dependencies of various types with [injection tokens](guide/di/dependency-injection-providers).
|
|
1469
|
-
*
|
|
1470
|
-
* @see [DI Providers](guide/di/dependency-injection-providers).
|
|
1471
|
-
* @see {@link StaticProvider}
|
|
1472
|
-
*
|
|
1473
|
-
* @usageNotes
|
|
1474
|
-
*
|
|
1475
|
-
* The following example creates a service injector instance.
|
|
1476
|
-
*
|
|
1477
|
-
* {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
|
|
1478
|
-
*
|
|
1479
|
-
* ### Usage example
|
|
1480
|
-
*
|
|
1481
|
-
* {@example core/di/ts/injector_spec.ts region='Injector'}
|
|
1482
|
-
*
|
|
1483
|
-
* `Injector` returns itself when given `Injector` as a token:
|
|
1484
|
-
*
|
|
1485
|
-
* {@example core/di/ts/injector_spec.ts region='injectInjector'}
|
|
1486
|
-
*
|
|
1487
|
-
* @publicApi
|
|
1488
|
-
*/
|
|
1489
|
-
class Injector {
|
|
1490
|
-
static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1491
|
-
static NULL = new NullInjector();
|
|
1492
|
-
static create(options, parent) {
|
|
1493
|
-
if (Array.isArray(options)) {
|
|
1494
|
-
return createInjector({ name: '' }, parent, options, '');
|
|
1495
|
-
}
|
|
1496
|
-
else {
|
|
1497
|
-
const name = options.name ?? '';
|
|
1498
|
-
return createInjector({ name }, options.parent, options.providers, name);
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
/** @nocollapse */
|
|
1502
|
-
static ɵprov = /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
|
|
1503
|
-
token: Injector,
|
|
1504
|
-
providedIn: 'any',
|
|
1505
|
-
factory: () => ɵɵinject(INJECTOR),
|
|
1506
|
-
});
|
|
1507
|
-
/**
|
|
1508
|
-
* @internal
|
|
1509
|
-
* @nocollapse
|
|
1510
|
-
*/
|
|
1511
|
-
static __NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
/**
|
|
1515
|
-
* @license
|
|
1516
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1517
|
-
*
|
|
1518
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1519
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1520
|
-
*/
|
|
1521
|
-
/**
|
|
1522
|
-
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
1523
|
-
* particular class.
|
|
1524
|
-
*
|
|
1525
|
-
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
1526
|
-
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
1527
|
-
*
|
|
1528
|
-
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
1529
|
-
* and thus in the stack trace.
|
|
1530
|
-
*
|
|
1531
|
-
* @codeGenApi
|
|
1532
|
-
*/
|
|
1533
|
-
function ɵɵinvalidFactory() {
|
|
1534
|
-
const msg = 'invalid';
|
|
1535
|
-
throw new Error(msg);
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
class StaticInjectOptions {
|
|
1539
|
-
static injectOptions;
|
|
1540
|
-
}
|
|
1541
|
-
class RootStaticInjectOptions {
|
|
1542
|
-
static injectOptions = {
|
|
1543
|
-
providedIn: 'root',
|
|
1544
|
-
};
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
export { EnvironmentInjector, INJECTOR_SCOPE, Inject, InjectFlags, InjectionToken, Injector, NG_INJ_DEF, NG_PROV_DEF, NG_TEMP_TOKEN_PATH, NullInjector, Optional, R3Injector, RootStaticInjectOptions, SOURCE, Self, SkipSelf, StaticInjectOptions, THROW_IF_NOT_FOUND, attachInjectFlag, catchInjectorError, convertToBitFlags, formatError, getCurrentInjector, getInheritedInjectableDef, getInjectFlag, getInjectableDef, getInjectorDef, getNullInjector, inject, injectArgs, injectInjectorOnly, isInjectable, providerToFactory, setCurrentInjector, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵinject, ɵɵinvalidFactory, ɵɵinvalidFactoryDep };
|