@loopback/context 4.0.0-alpha.8 → 4.1.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.
Files changed (201) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +116 -0
  3. package/dist/binding-config.d.ts +40 -0
  4. package/dist/binding-config.js +33 -0
  5. package/dist/binding-config.js.map +1 -0
  6. package/dist/binding-decorator.d.ts +45 -0
  7. package/dist/binding-decorator.js +118 -0
  8. package/dist/binding-decorator.js.map +1 -0
  9. package/dist/binding-filter.d.ts +108 -0
  10. package/dist/binding-filter.js +162 -0
  11. package/dist/binding-filter.js.map +1 -0
  12. package/dist/binding-inspector.d.ts +150 -0
  13. package/dist/binding-inspector.js +249 -0
  14. package/dist/binding-inspector.js.map +1 -0
  15. package/dist/binding-key.d.ts +66 -0
  16. package/dist/binding-key.js +121 -0
  17. package/dist/binding-key.js.map +1 -0
  18. package/dist/binding-sorter.d.ts +71 -0
  19. package/dist/binding-sorter.js +89 -0
  20. package/dist/binding-sorter.js.map +1 -0
  21. package/dist/binding.d.ts +577 -0
  22. package/dist/binding.js +788 -0
  23. package/dist/binding.js.map +1 -0
  24. package/dist/context-event.d.ts +23 -0
  25. package/dist/context-event.js +7 -0
  26. package/dist/context-event.js.map +1 -0
  27. package/dist/context-observer.d.ts +36 -0
  28. package/dist/context-observer.js +7 -0
  29. package/dist/context-observer.js.map +1 -0
  30. package/dist/context-subscription.d.ts +147 -0
  31. package/dist/context-subscription.js +317 -0
  32. package/dist/context-subscription.js.map +1 -0
  33. package/dist/context-tag-indexer.d.ts +42 -0
  34. package/dist/context-tag-indexer.js +135 -0
  35. package/dist/context-tag-indexer.js.map +1 -0
  36. package/dist/context-view.d.ts +209 -0
  37. package/dist/context-view.js +240 -0
  38. package/dist/context-view.js.map +1 -0
  39. package/dist/context.d.ts +513 -0
  40. package/dist/context.js +717 -0
  41. package/dist/context.js.map +1 -0
  42. package/dist/index.d.ts +52 -0
  43. package/dist/index.js +60 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/inject-config.d.ts +67 -0
  46. package/dist/inject-config.js +181 -0
  47. package/dist/inject-config.js.map +1 -0
  48. package/dist/inject.d.ts +250 -0
  49. package/dist/inject.js +535 -0
  50. package/dist/inject.js.map +1 -0
  51. package/dist/interception-proxy.d.ts +76 -0
  52. package/dist/interception-proxy.js +67 -0
  53. package/dist/interception-proxy.js.map +1 -0
  54. package/dist/interceptor-chain.d.ts +121 -0
  55. package/dist/interceptor-chain.js +148 -0
  56. package/dist/interceptor-chain.js.map +1 -0
  57. package/dist/interceptor.d.ts +138 -0
  58. package/dist/interceptor.js +299 -0
  59. package/dist/interceptor.js.map +1 -0
  60. package/dist/invocation.d.ts +101 -0
  61. package/dist/invocation.js +163 -0
  62. package/dist/invocation.js.map +1 -0
  63. package/dist/json-types.d.ts +28 -0
  64. package/{lib/src/provider.js → dist/json-types.js} +3 -3
  65. package/dist/json-types.js.map +1 -0
  66. package/dist/keys.d.ts +65 -0
  67. package/dist/keys.js +74 -0
  68. package/dist/keys.js.map +1 -0
  69. package/dist/provider.d.ts +31 -0
  70. package/{lib6/src → dist}/provider.js +2 -2
  71. package/dist/provider.js.map +1 -0
  72. package/dist/resolution-session.d.ts +180 -0
  73. package/dist/resolution-session.js +274 -0
  74. package/dist/resolution-session.js.map +1 -0
  75. package/dist/resolver.d.ts +46 -0
  76. package/dist/resolver.js +203 -0
  77. package/dist/resolver.js.map +1 -0
  78. package/dist/unique-id.d.ts +14 -0
  79. package/dist/unique-id.js +26 -0
  80. package/dist/unique-id.js.map +1 -0
  81. package/dist/value-promise.d.ts +134 -0
  82. package/dist/value-promise.js +277 -0
  83. package/dist/value-promise.js.map +1 -0
  84. package/package.json +49 -34
  85. package/src/binding-config.ts +73 -0
  86. package/src/binding-decorator.ts +136 -0
  87. package/src/binding-filter.ts +250 -0
  88. package/src/binding-inspector.ts +371 -0
  89. package/src/binding-key.ts +136 -0
  90. package/src/binding-sorter.ts +124 -0
  91. package/src/binding.ts +1107 -0
  92. package/src/context-event.ts +30 -0
  93. package/src/context-observer.ts +50 -0
  94. package/src/context-subscription.ts +402 -0
  95. package/src/context-tag-indexer.ts +147 -0
  96. package/src/context-view.ts +440 -0
  97. package/src/context.ts +1079 -0
  98. package/src/index.ts +58 -0
  99. package/src/inject-config.ts +239 -0
  100. package/src/inject.ts +796 -0
  101. package/src/interception-proxy.ts +127 -0
  102. package/src/interceptor-chain.ts +268 -0
  103. package/src/interceptor.ts +430 -0
  104. package/src/invocation.ts +269 -0
  105. package/src/json-types.ts +35 -0
  106. package/src/keys.ts +85 -0
  107. package/src/provider.ts +37 -0
  108. package/src/resolution-session.ts +414 -0
  109. package/src/resolver.ts +282 -0
  110. package/src/unique-id.ts +24 -0
  111. package/src/value-promise.ts +318 -0
  112. package/index.d.ts +0 -6
  113. package/index.js +0 -9
  114. package/lib/binding.d.ts +0 -75
  115. package/lib/binding.js +0 -103
  116. package/lib/binding.js.map +0 -1
  117. package/lib/context.d.ts +0 -14
  118. package/lib/context.js +0 -97
  119. package/lib/context.js.map +0 -1
  120. package/lib/index.d.ts +0 -1
  121. package/lib/index.js +0 -12
  122. package/lib/index.js.map +0 -1
  123. package/lib/inject.d.ts +0 -46
  124. package/lib/inject.js +0 -74
  125. package/lib/inject.js.map +0 -1
  126. package/lib/isPromise.d.ts +0 -1
  127. package/lib/isPromise.js +0 -15
  128. package/lib/isPromise.js.map +0 -1
  129. package/lib/reflect.d.ts +0 -39
  130. package/lib/reflect.js +0 -20
  131. package/lib/reflect.js.map +0 -1
  132. package/lib/resolver.d.ts +0 -30
  133. package/lib/resolver.js +0 -129
  134. package/lib/resolver.js.map +0 -1
  135. package/lib/src/binding.d.ts +0 -85
  136. package/lib/src/binding.js +0 -123
  137. package/lib/src/binding.js.map +0 -1
  138. package/lib/src/context.d.ts +0 -14
  139. package/lib/src/context.js +0 -97
  140. package/lib/src/context.js.map +0 -1
  141. package/lib/src/index.d.ts +0 -10
  142. package/lib/src/index.js +0 -27
  143. package/lib/src/index.js.map +0 -1
  144. package/lib/src/inject.d.ts +0 -46
  145. package/lib/src/inject.js +0 -74
  146. package/lib/src/inject.js.map +0 -1
  147. package/lib/src/isPromise.d.ts +0 -1
  148. package/lib/src/isPromise.js +0 -15
  149. package/lib/src/isPromise.js.map +0 -1
  150. package/lib/src/provider.d.ts +0 -29
  151. package/lib/src/provider.js.map +0 -1
  152. package/lib/src/reflect.d.ts +0 -38
  153. package/lib/src/reflect.js +0 -143
  154. package/lib/src/reflect.js.map +0 -1
  155. package/lib/src/resolver.d.ts +0 -34
  156. package/lib/src/resolver.js +0 -144
  157. package/lib/src/resolver.js.map +0 -1
  158. package/lib6/binding.d.ts +0 -75
  159. package/lib6/binding.js +0 -103
  160. package/lib6/binding.js.map +0 -1
  161. package/lib6/context.d.ts +0 -14
  162. package/lib6/context.js +0 -97
  163. package/lib6/context.js.map +0 -1
  164. package/lib6/index.d.ts +0 -1
  165. package/lib6/index.js +0 -12
  166. package/lib6/index.js.map +0 -1
  167. package/lib6/inject.d.ts +0 -46
  168. package/lib6/inject.js +0 -74
  169. package/lib6/inject.js.map +0 -1
  170. package/lib6/isPromise.d.ts +0 -1
  171. package/lib6/isPromise.js +0 -15
  172. package/lib6/isPromise.js.map +0 -1
  173. package/lib6/reflect.d.ts +0 -39
  174. package/lib6/reflect.js +0 -20
  175. package/lib6/reflect.js.map +0 -1
  176. package/lib6/resolver.d.ts +0 -30
  177. package/lib6/resolver.js +0 -129
  178. package/lib6/resolver.js.map +0 -1
  179. package/lib6/src/binding.d.ts +0 -85
  180. package/lib6/src/binding.js +0 -133
  181. package/lib6/src/binding.js.map +0 -1
  182. package/lib6/src/context.d.ts +0 -14
  183. package/lib6/src/context.js +0 -97
  184. package/lib6/src/context.js.map +0 -1
  185. package/lib6/src/index.d.ts +0 -10
  186. package/lib6/src/index.js +0 -27
  187. package/lib6/src/index.js.map +0 -1
  188. package/lib6/src/inject.d.ts +0 -46
  189. package/lib6/src/inject.js +0 -74
  190. package/lib6/src/inject.js.map +0 -1
  191. package/lib6/src/isPromise.d.ts +0 -1
  192. package/lib6/src/isPromise.js +0 -15
  193. package/lib6/src/isPromise.js.map +0 -1
  194. package/lib6/src/provider.d.ts +0 -29
  195. package/lib6/src/provider.js.map +0 -1
  196. package/lib6/src/reflect.d.ts +0 -38
  197. package/lib6/src/reflect.js +0 -143
  198. package/lib6/src/reflect.js.map +0 -1
  199. package/lib6/src/resolver.d.ts +0 -34
  200. package/lib6/src/resolver.js +0 -154
  201. package/lib6/src/resolver.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) IBM Corp. 2017,2019.
2
+ Node module: @loopback/context
3
+ This project is licensed under the MIT License, full text below.
4
+
5
+ --------
6
+
7
+ MIT license
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in
17
+ all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1 +1,117 @@
1
1
  # @loopback/context
2
+
3
+ This module provides facilities to manage artifacts and their dependencies using
4
+ `Context` in your Node.js applications. It can be used independent of the
5
+ LoopBack framework.
6
+
7
+ ## Overview
8
+
9
+ The `@loopback/context` package exposes TypeScript/JavaScript APIs and
10
+ decorators to register artifacts, declare dependencies, and resolve artifacts by
11
+ keys. The `Context` also serves as an
12
+ [IoC container](https://en.wikipedia.org/wiki/Inversion_of_control) to support
13
+ [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection).
14
+
15
+ `Context` and `Binding` are the two core concepts. A context is a registry of
16
+ bindings and each binding represents a resolvable artifact by the key.
17
+
18
+ - Bindings can be fulfilled by a constant, a factory function, a class, or a
19
+ provider.
20
+ - Bindings can be grouped by tags and searched by tags.
21
+ - Binding scopes can be used to control how a resolved binding value is shared.
22
+ - Bindings can be resolved synchronously or asynchronously.
23
+ - Provide `@inject` and other variants of decorators to express dependencies.
24
+ - Support Constructor, property, and method injections.
25
+ - Allow contexts to form a hierarchy to share or override bindings.
26
+ - Track bindings and injections during resolution to detect circular
27
+ dependencies.
28
+
29
+ ## Installation
30
+
31
+ ```sh
32
+ npm install --save @loopback/context
33
+ ```
34
+
35
+ ## Basic use
36
+
37
+ ### Locate an artifact by key
38
+
39
+ ```js
40
+ const Context = require('@loopback/context').Context;
41
+ const ctx = new Context();
42
+ ctx.bind('hello').to('world'); // BindingKey='hello', BindingValue='world'
43
+ const helloVal = ctx.getSync('hello');
44
+ console.log(helloVal); // => 'world'
45
+ ```
46
+
47
+ The binding can also be located asynchronously:
48
+
49
+ ```ts
50
+ const helloVal = await ctx.get('hello');
51
+ console.log(helloVal); // => 'world'
52
+ ```
53
+
54
+ ### Dependency injection using context
55
+
56
+ ```ts
57
+ import {Context, inject} from '@loopback/context';
58
+ const ctx = new Context();
59
+
60
+ // bind 'greeting' to 'Hello' as the constant value
61
+ ctx.bind('greeting').to('Hello');
62
+
63
+ class HelloController {
64
+ constructor(
65
+ // injecting the value bound to `greeting` using context
66
+ @inject('greeting') private greeting: string,
67
+ ) {}
68
+
69
+ greet(name) {
70
+ return `${this.greeting}, ${name}`;
71
+ }
72
+ }
73
+
74
+ // Bind 'HelloController' to class HelloController
75
+ ctx.bind('HelloController').toClass(HelloController);
76
+
77
+ async function hello() {
78
+ // Get an instance of HelloController
79
+ const helloController = await ctx.get<HelloController>('HelloController');
80
+ // helloController now has the `greeting` property injected with `Hello`
81
+ console.log(helloController.greet('John')); // => Hello, John
82
+ }
83
+
84
+ hello();
85
+ ```
86
+
87
+ For additional information, please refer to the
88
+ [Context page](http://loopback.io/doc/en/lb4/Context.html).
89
+
90
+ ## Examples
91
+
92
+ To learn more about advanced features, check out standalone examples at
93
+ [`@loopback/example-context`](https://github.com/loopbackio/loopback-next/tree/master/examples/context).
94
+
95
+ Use the following command to download the example project to try out:
96
+
97
+ ```sh
98
+ lb4 example context
99
+ ```
100
+
101
+ ## Contributions
102
+
103
+ - [Guidelines](https://github.com/loopbackio/loopback-next/blob/master/docs/CONTRIBUTING.md)
104
+ - [Join the team](https://github.com/loopbackio/loopback-next/issues/110)
105
+
106
+ ## Tests
107
+
108
+ Run `npm test` from the root folder.
109
+
110
+ ## Contributors
111
+
112
+ See
113
+ [all contributors](https://github.com/loopbackio/loopback-next/graphs/contributors).
114
+
115
+ ## License
116
+
117
+ MIT
@@ -0,0 +1,40 @@
1
+ import { BindingAddress, BindingKey } from './binding-key';
2
+ import { Context } from './context';
3
+ import { ResolutionOptions } from './resolution-session';
4
+ import { ValueOrPromise } from './value-promise';
5
+ /**
6
+ * Resolver for configuration of bindings. It's responsible for finding
7
+ * corresponding configuration for a given binding key.
8
+ *
9
+ * By default, `undefined` is expected if no configuration is provided. The
10
+ * behavior can be overridden by setting `optional` to `false` in resolution
11
+ * options.
12
+ */
13
+ export interface ConfigurationResolver {
14
+ /**
15
+ * Resolve config for the binding key
16
+ *
17
+ * @param key - Binding key
18
+ * @param propertyPath - Property path for the option. For example, `x.y`
19
+ * requests for `<config>.x.y`. If not set, the `config` object will be
20
+ * returned.
21
+ * @param resolutionOptions - Options for the resolution.
22
+ * - optional: if not set or set to `true`, `undefined` will be returned if
23
+ * no corresponding value is found. Otherwise, an error will be thrown.
24
+ */
25
+ getConfigAsValueOrPromise<ConfigValueType>(key: BindingAddress<unknown>, propertyPath?: string, resolutionOptions?: ResolutionOptions): ValueOrPromise<ConfigValueType | undefined>;
26
+ }
27
+ /**
28
+ * Resolver for configurations of bindings
29
+ */
30
+ export declare class DefaultConfigurationResolver implements ConfigurationResolver {
31
+ readonly context: Context;
32
+ constructor(context: Context);
33
+ getConfigAsValueOrPromise<ConfigValueType>(key: BindingAddress<unknown>, propertyPath?: string, resolutionOptions?: ResolutionOptions): ValueOrPromise<ConfigValueType | undefined>;
34
+ }
35
+ /**
36
+ * Create binding key for configuration of the binding
37
+ * @param key - Binding key for the target binding
38
+ * @param propertyPath - Property path for the configuration
39
+ */
40
+ export declare function configBindingKeyFor<ConfigValueType = unknown>(key: BindingAddress, propertyPath?: string): BindingKey<ConfigValueType>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2019,2020. All Rights Reserved.
3
+ // Node module: @loopback/context
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.configBindingKeyFor = exports.DefaultConfigurationResolver = void 0;
8
+ const binding_key_1 = require("./binding-key");
9
+ /**
10
+ * Resolver for configurations of bindings
11
+ */
12
+ class DefaultConfigurationResolver {
13
+ constructor(context) {
14
+ this.context = context;
15
+ }
16
+ getConfigAsValueOrPromise(key, propertyPath, resolutionOptions) {
17
+ propertyPath = propertyPath !== null && propertyPath !== void 0 ? propertyPath : '';
18
+ const configKey = configBindingKeyFor(key, propertyPath);
19
+ const options = Object.assign({ optional: true }, resolutionOptions);
20
+ return this.context.getValueOrPromise(configKey, options);
21
+ }
22
+ }
23
+ exports.DefaultConfigurationResolver = DefaultConfigurationResolver;
24
+ /**
25
+ * Create binding key for configuration of the binding
26
+ * @param key - Binding key for the target binding
27
+ * @param propertyPath - Property path for the configuration
28
+ */
29
+ function configBindingKeyFor(key, propertyPath) {
30
+ return binding_key_1.BindingKey.create(binding_key_1.BindingKey.buildKeyForConfig(key).toString(), propertyPath);
31
+ }
32
+ exports.configBindingKeyFor = configBindingKeyFor;
33
+ //# sourceMappingURL=binding-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-config.js","sourceRoot":"","sources":["../src/binding-config.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,iCAAiC;AACjC,+CAA+C;AAC/C,gEAAgE;;;AAEhE,+CAAyD;AAgCzD;;GAEG;AACH,MAAa,4BAA4B;IACvC,YAA4B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;IAEhD,yBAAyB,CACvB,GAA4B,EAC5B,YAAqB,EACrB,iBAAqC;QAErC,YAAY,GAAG,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAEzD,MAAM,OAAO,GAAsB,MAAM,CAAC,MAAM,CAC9C,EAAC,QAAQ,EAAE,IAAI,EAAC,EAChB,iBAAiB,CAClB,CAAC;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAkB,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;CACF;AAjBD,oEAiBC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CACjC,GAAmB,EACnB,YAAqB;IAErB,OAAO,wBAAU,CAAC,MAAM,CACtB,wBAAU,CAAC,iBAAiB,CAAkB,GAAG,CAAC,CAAC,QAAQ,EAAE,EAC7D,YAAY,CACb,CAAC;AACJ,CAAC;AARD,kDAQC"}
@@ -0,0 +1,45 @@
1
+ import { BindingSpec } from './binding-inspector';
2
+ import { Constructor } from './value-promise';
3
+ /**
4
+ * Decorate a class with binding configuration
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * @injectable((binding) => {binding.inScope(BindingScope.SINGLETON).tag('controller')}
9
+ * )
10
+ * @injectable({scope: BindingScope.SINGLETON})
11
+ * export class MyController {
12
+ * }
13
+ * ```
14
+ *
15
+ * @param specs - A list of binding scope/tags or template functions to
16
+ * configure the binding
17
+ */
18
+ export declare function injectable(...specs: BindingSpec[]): ClassDecorator;
19
+ /**
20
+ * A namespace to host shortcuts for `@injectable`
21
+ */
22
+ export declare namespace injectable {
23
+ /**
24
+ * `@injectable.provider` to denote a provider class
25
+ *
26
+ * A list of binding scope/tags or template functions to configure the binding
27
+ */
28
+ function provider(...specs: BindingSpec[]): (target: Constructor<unknown>) => void;
29
+ }
30
+ /**
31
+ * `@bind` is now an alias to {@link injectable} for backward compatibility
32
+ * {@inheritDoc injectable}
33
+ */
34
+ export declare function bind(...specs: BindingSpec[]): ClassDecorator;
35
+ /**
36
+ * Alias namespace `bind` to `injectable` for backward compatibility
37
+ *
38
+ * It should have the same members as `bind`.
39
+ */
40
+ export declare namespace bind {
41
+ /**
42
+ * {@inheritDoc injectable.provider}
43
+ */
44
+ const provider: typeof injectable.provider;
45
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2018,2020. All Rights Reserved.
3
+ // Node module: @loopback/context
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.bind = exports.injectable = void 0;
8
+ const metadata_1 = require("@loopback/metadata");
9
+ const binding_inspector_1 = require("./binding-inspector");
10
+ /**
11
+ * Decorator factory for `@injectable`
12
+ */
13
+ class InjectableDecoratorFactory extends metadata_1.ClassDecoratorFactory {
14
+ mergeWithInherited(inherited, target) {
15
+ if (inherited) {
16
+ return {
17
+ templates: [
18
+ ...inherited.templates,
19
+ binding_inspector_1.removeNameAndKeyTags,
20
+ ...this.spec.templates,
21
+ ],
22
+ target: this.spec.target,
23
+ };
24
+ }
25
+ else {
26
+ this.withTarget(this.spec, target);
27
+ return this.spec;
28
+ }
29
+ }
30
+ mergeWithOwn(ownMetadata) {
31
+ return {
32
+ templates: [...ownMetadata.templates, ...this.spec.templates],
33
+ target: this.spec.target,
34
+ };
35
+ }
36
+ withTarget(spec, target) {
37
+ spec.target = target;
38
+ return spec;
39
+ }
40
+ }
41
+ /**
42
+ * Decorate a class with binding configuration
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * @injectable((binding) => {binding.inScope(BindingScope.SINGLETON).tag('controller')}
47
+ * )
48
+ * @injectable({scope: BindingScope.SINGLETON})
49
+ * export class MyController {
50
+ * }
51
+ * ```
52
+ *
53
+ * @param specs - A list of binding scope/tags or template functions to
54
+ * configure the binding
55
+ */
56
+ function injectable(...specs) {
57
+ const templateFunctions = specs.map(t => {
58
+ if (typeof t === 'function') {
59
+ return t;
60
+ }
61
+ else {
62
+ return (0, binding_inspector_1.asBindingTemplate)(t);
63
+ }
64
+ });
65
+ return (target) => {
66
+ const cls = target;
67
+ const spec = {
68
+ templates: [(0, binding_inspector_1.asClassOrProvider)(cls), ...templateFunctions],
69
+ target: cls,
70
+ };
71
+ const decorator = InjectableDecoratorFactory.createDecorator(binding_inspector_1.BINDING_METADATA_KEY, spec, { decoratorName: '@injectable' });
72
+ decorator(target);
73
+ };
74
+ }
75
+ exports.injectable = injectable;
76
+ /**
77
+ * A namespace to host shortcuts for `@injectable`
78
+ */
79
+ (function (injectable) {
80
+ /**
81
+ * `@injectable.provider` to denote a provider class
82
+ *
83
+ * A list of binding scope/tags or template functions to configure the binding
84
+ */
85
+ function provider(...specs) {
86
+ return (target) => {
87
+ if (!(0, binding_inspector_1.isProviderClass)(target)) {
88
+ throw new Error(`Target ${target} is not a Provider`);
89
+ }
90
+ injectable(
91
+ // Set up the default for providers
92
+ (0, binding_inspector_1.asProvider)(target),
93
+ // Call other template functions
94
+ ...specs)(target);
95
+ };
96
+ }
97
+ injectable.provider = provider;
98
+ })(injectable = exports.injectable || (exports.injectable = {}));
99
+ /**
100
+ * `@bind` is now an alias to {@link injectable} for backward compatibility
101
+ * {@inheritDoc injectable}
102
+ */
103
+ function bind(...specs) {
104
+ return injectable(...specs);
105
+ }
106
+ exports.bind = bind;
107
+ /**
108
+ * Alias namespace `bind` to `injectable` for backward compatibility
109
+ *
110
+ * It should have the same members as `bind`.
111
+ */
112
+ (function (bind) {
113
+ /**
114
+ * {@inheritDoc injectable.provider}
115
+ */
116
+ bind.provider = injectable.provider;
117
+ })(bind = exports.bind || (exports.bind = {}));
118
+ //# sourceMappingURL=binding-decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-decorator.js","sourceRoot":"","sources":["../src/binding-decorator.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,iCAAiC;AACjC,+CAA+C;AAC/C,gEAAgE;;;AAEhE,iDAAyD;AACzD,2DAS6B;AAG7B;;GAEG;AACH,MAAM,0BAA2B,SAAQ,gCAAsC;IAC7E,kBAAkB,CAAC,SAA0B,EAAE,MAAgB;QAC7D,IAAI,SAAS,EAAE;YACb,OAAO;gBACL,SAAS,EAAE;oBACT,GAAG,SAAS,CAAC,SAAS;oBACtB,wCAAoB;oBACpB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS;iBACvB;gBACD,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;aACzB,CAAC;SACH;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,IAAI,CAAC;SAClB;IACH,CAAC;IAED,YAAY,CAAC,WAA4B;QACvC,OAAO;YACL,SAAS,EAAE,CAAC,GAAG,WAAW,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;YAC7D,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;SACzB,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,IAAqB,EAAE,MAAgB;QAChD,IAAI,CAAC,MAAM,GAAG,MAA8B,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,UAAU,CAAC,GAAG,KAAoB;IAChD,MAAM,iBAAiB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACtC,IAAI,OAAO,CAAC,KAAK,UAAU,EAAE;YAC3B,OAAO,CAAC,CAAC;SACV;aAAM;YACL,OAAO,IAAA,qCAAiB,EAAC,CAAC,CAAC,CAAC;SAC7B;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,MAAgB,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,MAA8B,CAAC;QAC3C,MAAM,IAAI,GAAoB;YAC5B,SAAS,EAAE,CAAC,IAAA,qCAAiB,EAAC,GAAG,CAAC,EAAE,GAAG,iBAAiB,CAAC;YACzD,MAAM,EAAE,GAAG;SACZ,CAAC;QAEF,MAAM,SAAS,GAAG,0BAA0B,CAAC,eAAe,CAC1D,wCAAoB,EACpB,IAAI,EACJ,EAAC,aAAa,EAAE,aAAa,EAAC,CAC/B,CAAC;QACF,SAAS,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAvBD,gCAuBC;AAED;;GAEG;AACH,WAAiB,UAAU;IACzB;;;;OAIG;IACH,SAAgB,QAAQ,CACtB,GAAG,KAAoB;QAEvB,OAAO,CAAC,MAA4B,EAAE,EAAE;YACtC,IAAI,CAAC,IAAA,mCAAe,EAAC,MAAM,CAAC,EAAE;gBAC5B,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,oBAAoB,CAAC,CAAC;aACvD;YACD,UAAU;YACR,mCAAmC;YACnC,IAAA,8BAAU,EAAC,MAAM,CAAC;YAClB,gCAAgC;YAChC,GAAG,KAAK,CACT,CAAC,MAAM,CAAC,CAAC;QACZ,CAAC,CAAC;IACJ,CAAC;IAde,mBAAQ,WAcvB,CAAA;AACH,CAAC,EArBgB,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAqB1B;AAED;;;GAGG;AACH,SAAgB,IAAI,CAAC,GAAG,KAAoB;IAC1C,OAAO,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC;AAC9B,CAAC;AAFD,oBAEC;AAED;;;;GAIG;AACH,WAAiB,IAAI;IACnB;;OAEG;IACU,aAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;AAC9C,CAAC,EALgB,IAAI,GAAJ,YAAI,KAAJ,YAAI,QAKpB"}
@@ -0,0 +1,108 @@
1
+ import { Binding, BindingTag } from './binding';
2
+ import { BindingAddress } from './binding-key';
3
+ import { MapObject } from './value-promise';
4
+ /**
5
+ * A function that filters bindings. It returns `true` to select a given
6
+ * binding.
7
+ *
8
+ * @remarks
9
+ * Originally, we allowed filters to be tied with a single value type.
10
+ * This actually does not make much sense - the filter function is typically
11
+ * invoked on all bindings to find those ones matching the given criteria.
12
+ * Filters must be prepared to handle bindings of any value type. We learned
13
+ * about this problem after enabling TypeScript's `strictFunctionTypes` check.
14
+ * This aspect is resolved by typing the input argument as `Binding<unknown>`.
15
+ *
16
+ * Ideally, `BindingFilter` should be declared as a type guard as follows:
17
+ * ```ts
18
+ * export type BindingFilterGuard<ValueType = unknown> = (
19
+ * binding: Readonly<Binding<unknown>>,
20
+ * ) => binding is Readonly<Binding<ValueType>>;
21
+ * ```
22
+ *
23
+ * But TypeScript treats the following types as incompatible and does not accept
24
+ * type 1 for type 2.
25
+ *
26
+ * 1. `(binding: Readonly<Binding<unknown>>) => boolean`
27
+ * 2. `(binding: Readonly<Binding<unknown>>) => binding is Readonly<Binding<ValueType>>`
28
+ *
29
+ * If we described BindingFilter as a type-guard, then all filter implementations
30
+ * would have to be explicitly typed as type-guards too, which would make it
31
+ * tedious to write quick filter functions like `b => b.key.startsWith('services')`.
32
+ *
33
+ * To keep things simple and easy to use, we use `boolean` as the return type
34
+ * of a binding filter function.
35
+ */
36
+ export interface BindingFilter {
37
+ (binding: Readonly<Binding<unknown>>): boolean;
38
+ }
39
+ /**
40
+ * Select binding(s) by key or a filter function
41
+ */
42
+ export declare type BindingSelector<ValueType = unknown> = BindingAddress<ValueType> | BindingFilter;
43
+ /**
44
+ * Type guard for binding address
45
+ * @param bindingSelector - Binding key or filter function
46
+ */
47
+ export declare function isBindingAddress(bindingSelector: BindingSelector): bindingSelector is BindingAddress;
48
+ /**
49
+ * Binding filter function that holds a binding tag pattern. `Context.find()`
50
+ * uses the `bindingTagPattern` to optimize the matching of bindings by tag to
51
+ * avoid expensive check for all bindings.
52
+ */
53
+ export interface BindingTagFilter extends BindingFilter {
54
+ /**
55
+ * A special property on the filter function to provide access to the binding
56
+ * tag pattern which can be utilized to optimize the matching of bindings by
57
+ * tag in a context.
58
+ */
59
+ bindingTagPattern: BindingTag | RegExp;
60
+ }
61
+ /**
62
+ * Type guard for BindingTagFilter
63
+ * @param filter - A BindingFilter function
64
+ */
65
+ export declare function isBindingTagFilter(filter?: BindingFilter): filter is BindingTagFilter;
66
+ /**
67
+ * A function to check if a given tag value is matched for `filterByTag`
68
+ */
69
+ export interface TagValueMatcher {
70
+ /**
71
+ * Check if the given tag value matches the search criteria
72
+ * @param tagValue - Tag value from the binding
73
+ * @param tagName - Tag name
74
+ * @param tagMap - Tag map from the binding
75
+ */
76
+ (tagValue: unknown, tagName: string, tagMap: MapObject<unknown>): boolean;
77
+ }
78
+ /**
79
+ * A symbol that can be used to match binding tags by name regardless of the
80
+ * value.
81
+ *
82
+ * @example
83
+ *
84
+ * The following code matches bindings with tag `{controller: 'A'}` or
85
+ * `{controller: 'controller'}`. But if the tag name 'controller' does not
86
+ * exist for a binding, the binding will NOT be included.
87
+ *
88
+ * ```ts
89
+ * ctx.findByTag({controller: ANY_TAG_VALUE})
90
+ * ```
91
+ */
92
+ export declare const ANY_TAG_VALUE: TagValueMatcher;
93
+ /**
94
+ * Create a tag value matcher function that returns `true` if the target tag
95
+ * value equals to the item value or is an array that includes the item value.
96
+ * @param itemValues - A list of tag item value
97
+ */
98
+ export declare function includesTagValue(...itemValues: unknown[]): TagValueMatcher;
99
+ /**
100
+ * Create a binding filter for the tag pattern
101
+ * @param tagPattern - Binding tag name, regexp, or object
102
+ */
103
+ export declare function filterByTag(tagPattern: BindingTag | RegExp): BindingTagFilter;
104
+ /**
105
+ * Create a binding filter from key pattern
106
+ * @param keyPattern - Binding key/wildcard, regexp, or a filter function
107
+ */
108
+ export declare function filterByKey(keyPattern?: string | RegExp | BindingFilter): BindingFilter;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2019,2020. All Rights Reserved.
3
+ // Node module: @loopback/context
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.filterByKey = exports.filterByTag = exports.includesTagValue = exports.ANY_TAG_VALUE = exports.isBindingTagFilter = exports.isBindingAddress = void 0;
8
+ /**
9
+ * Check if an object is a `BindingKey` by duck typing
10
+ * @param selector Binding selector
11
+ */
12
+ function isBindingKey(selector) {
13
+ if (selector == null || typeof selector !== 'object')
14
+ return false;
15
+ return (typeof selector.key === 'string' &&
16
+ typeof selector.deepProperty === 'function');
17
+ }
18
+ /**
19
+ * Type guard for binding address
20
+ * @param bindingSelector - Binding key or filter function
21
+ */
22
+ function isBindingAddress(bindingSelector) {
23
+ return (typeof bindingSelector !== 'function' &&
24
+ (typeof bindingSelector === 'string' ||
25
+ // See https://github.com/loopbackio/loopback-next/issues/4570
26
+ // `bindingSelector instanceof BindingKey` is not always reliable as the
27
+ // `@loopback/context` module might be loaded from multiple locations if
28
+ // `npm install` does not dedupe or there are mixed versions in the tree
29
+ isBindingKey(bindingSelector)));
30
+ }
31
+ exports.isBindingAddress = isBindingAddress;
32
+ /**
33
+ * Type guard for BindingTagFilter
34
+ * @param filter - A BindingFilter function
35
+ */
36
+ function isBindingTagFilter(filter) {
37
+ if (filter == null || !('bindingTagPattern' in filter))
38
+ return false;
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ const tagPattern = filter.bindingTagPattern;
41
+ return (tagPattern instanceof RegExp ||
42
+ typeof tagPattern === 'string' ||
43
+ typeof tagPattern === 'object');
44
+ }
45
+ exports.isBindingTagFilter = isBindingTagFilter;
46
+ /**
47
+ * A symbol that can be used to match binding tags by name regardless of the
48
+ * value.
49
+ *
50
+ * @example
51
+ *
52
+ * The following code matches bindings with tag `{controller: 'A'}` or
53
+ * `{controller: 'controller'}`. But if the tag name 'controller' does not
54
+ * exist for a binding, the binding will NOT be included.
55
+ *
56
+ * ```ts
57
+ * ctx.findByTag({controller: ANY_TAG_VALUE})
58
+ * ```
59
+ */
60
+ const ANY_TAG_VALUE = (tagValue, tagName, tagMap) => tagName in tagMap;
61
+ exports.ANY_TAG_VALUE = ANY_TAG_VALUE;
62
+ /**
63
+ * Create a tag value matcher function that returns `true` if the target tag
64
+ * value equals to the item value or is an array that includes the item value.
65
+ * @param itemValues - A list of tag item value
66
+ */
67
+ function includesTagValue(...itemValues) {
68
+ return tagValue => {
69
+ return itemValues.some(itemValue =>
70
+ // The tag value equals the item value
71
+ tagValue === itemValue ||
72
+ // The tag value contains the item value
73
+ (Array.isArray(tagValue) && tagValue.includes(itemValue)));
74
+ };
75
+ }
76
+ exports.includesTagValue = includesTagValue;
77
+ /**
78
+ * Create a binding filter for the tag pattern
79
+ * @param tagPattern - Binding tag name, regexp, or object
80
+ */
81
+ function filterByTag(tagPattern) {
82
+ let filter;
83
+ let regex = undefined;
84
+ if (tagPattern instanceof RegExp) {
85
+ // RegExp for tag names
86
+ regex = tagPattern;
87
+ }
88
+ if (typeof tagPattern === 'string' &&
89
+ (tagPattern.includes('*') || tagPattern.includes('?'))) {
90
+ // Wildcard tag name
91
+ regex = wildcardToRegExp(tagPattern);
92
+ }
93
+ if (regex != null) {
94
+ // RegExp or wildcard match
95
+ filter = b => b.tagNames.some(t => regex.test(t));
96
+ }
97
+ else if (typeof tagPattern === 'string') {
98
+ // Plain tag string match
99
+ filter = b => b.tagNames.includes(tagPattern);
100
+ }
101
+ else {
102
+ // Match tag name/value pairs
103
+ const tagMap = tagPattern;
104
+ filter = b => {
105
+ for (const t in tagMap) {
106
+ if (!matchTagValue(tagMap[t], t, b.tagMap))
107
+ return false;
108
+ }
109
+ // All tag name/value pairs match
110
+ return true;
111
+ };
112
+ }
113
+ // Set up binding tag for the filter
114
+ const tagFilter = filter;
115
+ tagFilter.bindingTagPattern = regex !== null && regex !== void 0 ? regex : tagPattern;
116
+ return tagFilter;
117
+ }
118
+ exports.filterByTag = filterByTag;
119
+ function matchTagValue(tagValueOrMatcher, tagName, tagMap) {
120
+ const tagValue = tagMap[tagName];
121
+ if (tagValue === tagValueOrMatcher)
122
+ return true;
123
+ if (typeof tagValueOrMatcher === 'function') {
124
+ return tagValueOrMatcher(tagValue, tagName, tagMap);
125
+ }
126
+ return false;
127
+ }
128
+ /**
129
+ * Create a binding filter from key pattern
130
+ * @param keyPattern - Binding key/wildcard, regexp, or a filter function
131
+ */
132
+ function filterByKey(keyPattern) {
133
+ if (typeof keyPattern === 'string') {
134
+ const regex = wildcardToRegExp(keyPattern);
135
+ return binding => regex.test(binding.key);
136
+ }
137
+ else if (keyPattern instanceof RegExp) {
138
+ return binding => keyPattern.test(binding.key);
139
+ }
140
+ else if (typeof keyPattern === 'function') {
141
+ return keyPattern;
142
+ }
143
+ return () => true;
144
+ }
145
+ exports.filterByKey = filterByKey;
146
+ /**
147
+ * Convert a wildcard pattern to RegExp
148
+ * @param pattern - A wildcard string with `*` and `?` as special characters.
149
+ * - `*` matches zero or more characters except `.` and `:`
150
+ * - `?` matches exactly one character except `.` and `:`
151
+ */
152
+ function wildcardToRegExp(pattern) {
153
+ // Escape reserved chars for RegExp:
154
+ // `- \ ^ $ + . ( ) | { } [ ] :`
155
+ let regexp = pattern.replace(/[\-\[\]\/\{\}\(\)\+\.\\\^\$\|\:]/g, '\\$&');
156
+ // Replace wildcard chars `*` and `?`
157
+ // `*` matches zero or more characters except `.` and `:`
158
+ // `?` matches one character except `.` and `:`
159
+ regexp = regexp.replace(/\*/g, '[^.:]*').replace(/\?/g, '[^.:]');
160
+ return new RegExp(`^${regexp}$`);
161
+ }
162
+ //# sourceMappingURL=binding-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-filter.js","sourceRoot":"","sources":["../src/binding-filter.ts"],"names":[],"mappings":"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"}