UNPKG

3.61 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.$injector = void 0;
4var index_1 = require("../common/index");
5// globally available injectables
6var globals = {};
7var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
8var ARGUMENT_NAMES = /([^\s,]+)/g;
9/**
10 * A basic angular1-like injector api
11 *
12 * This object implements four methods similar to the
13 * [angular 1 dependency injector](https://docs.angularjs.org/api/auto/service/$injector)
14 *
15 * UI-Router evolved from an angular 1 library to a framework agnostic library.
16 * However, some of the `@uirouter/core` code uses these ng1 style APIs to support ng1 style dependency injection.
17 *
18 * This object provides a naive implementation of a globally scoped dependency injection system.
19 * It supports the following DI approaches:
20 *
21 * ### Function parameter names
22 *
23 * A function's `.toString()` is called, and the parameter names are parsed.
24 * This only works when the parameter names aren't "mangled" by a minifier such as UglifyJS.
25 *
26 * ```js
27 * function injectedFunction(FooService, BarService) {
28 * // FooService and BarService are injected
29 * }
30 * ```
31 *
32 * ### Function annotation
33 *
34 * A function may be annotated with an array of dependency names as the `$inject` property.
35 *
36 * ```js
37 * injectedFunction.$inject = [ 'FooService', 'BarService' ];
38 * function injectedFunction(fs, bs) {
39 * // FooService and BarService are injected as fs and bs parameters
40 * }
41 * ```
42 *
43 * ### Array notation
44 *
45 * An array provides the names of the dependencies to inject (as strings).
46 * The function is the last element of the array.
47 *
48 * ```js
49 * [ 'FooService', 'BarService', function (fs, bs) {
50 * // FooService and BarService are injected as fs and bs parameters
51 * }]
52 * ```
53 *
54 * @type {$InjectorLike}
55 */
56exports.$injector = {
57 /** Gets an object from DI based on a string token */
58 get: function (name) { return globals[name]; },
59 /** Returns true if an object named `name` exists in global DI */
60 has: function (name) { return exports.$injector.get(name) != null; },
61 /**
62 * Injects a function
63 *
64 * @param fn the function to inject
65 * @param context the function's `this` binding
66 * @param locals An object with additional DI tokens and values, such as `{ someToken: { foo: 1 } }`
67 */
68 invoke: function (fn, context, locals) {
69 var all = index_1.extend({}, globals, locals || {});
70 var params = exports.$injector.annotate(fn);
71 var ensureExist = index_1.assertPredicate(function (key) { return all.hasOwnProperty(key); }, function (key) { return "DI can't find injectable: '" + key + "'"; });
72 var args = params.filter(ensureExist).map(function (x) { return all[x]; });
73 if (index_1.isFunction(fn))
74 return fn.apply(context, args);
75 else
76 return fn.slice(-1)[0].apply(context, args);
77 },
78 /**
79 * Returns a function's dependencies
80 *
81 * Analyzes a function (or array) and returns an array of DI tokens that the function requires.
82 * @return an array of `string`s
83 */
84 annotate: function (fn) {
85 if (!index_1.isInjectable(fn))
86 throw new Error("Not an injectable function: " + fn);
87 if (fn && fn.$inject)
88 return fn.$inject;
89 if (index_1.isArray(fn))
90 return fn.slice(0, -1);
91 var fnStr = fn.toString().replace(STRIP_COMMENTS, '');
92 var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
93 return result || [];
94 },
95};
96//# sourceMappingURL=injector.js.map
\No newline at end of file