@loopback/context 4.0.0-alpha.6 → 4.0.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 (137) 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/dist/json-types.js +7 -0
  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/dist/provider.js +7 -0
  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 -36
  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 -102
  116. package/lib/context.d.ts +0 -14
  117. package/lib/context.js +0 -96
  118. package/lib/index.d.ts +0 -5
  119. package/lib/index.js +0 -13
  120. package/lib/inject.d.ts +0 -24
  121. package/lib/inject.js +0 -43
  122. package/lib/isPromise.d.ts +0 -1
  123. package/lib/isPromise.js +0 -14
  124. package/lib/resolver.d.ts +0 -26
  125. package/lib/resolver.js +0 -72
  126. package/lib6/binding.d.ts +0 -75
  127. package/lib6/binding.js +0 -102
  128. package/lib6/context.d.ts +0 -14
  129. package/lib6/context.js +0 -96
  130. package/lib6/index.d.ts +0 -5
  131. package/lib6/index.js +0 -13
  132. package/lib6/inject.d.ts +0 -24
  133. package/lib6/inject.js +0 -43
  134. package/lib6/isPromise.d.ts +0 -1
  135. package/lib6/isPromise.js +0 -14
  136. package/lib6/resolver.d.ts +0 -26
  137. package/lib6/resolver.js +0 -72
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2019. 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.sortBindingsByPhase = exports.compareByOrder = exports.compareBindingsByTag = void 0;
8
+ /**
9
+ * Creates a binding compare function to sort bindings by tagged phase name.
10
+ *
11
+ * @remarks
12
+ * Two bindings are compared as follows:
13
+ *
14
+ * 1. Get values for the given tag as `phase` for bindings, if the tag is not
15
+ * present, default `phase` to `''`.
16
+ * 2. If both bindings have `phase` value in `orderOfPhases`, honor the order
17
+ * specified by `orderOfPhases`.
18
+ * 3. If a binding's `phase` does not exist in `orderOfPhases`, it comes before
19
+ * the one with `phase` exists in `orderOfPhases`.
20
+ * 4. If both bindings have `phase` value outside of `orderOfPhases`, they are
21
+ * ordered by phase names alphabetically and symbol values come before string
22
+ * values.
23
+ *
24
+ * @param phaseTagName - Name of the binding tag for phase
25
+ * @param orderOfPhases - An array of phase names as the predefined order
26
+ */
27
+ function compareBindingsByTag(phaseTagName = 'phase', orderOfPhases = []) {
28
+ return (a, b) => {
29
+ return compareByOrder(a.tagMap[phaseTagName], b.tagMap[phaseTagName], orderOfPhases);
30
+ };
31
+ }
32
+ exports.compareBindingsByTag = compareBindingsByTag;
33
+ /**
34
+ * Compare two values by the predefined order
35
+ *
36
+ * @remarks
37
+ *
38
+ * The comparison is performed as follows:
39
+ *
40
+ * 1. If both values are included in `order`, they are sorted by their indexes in
41
+ * `order`.
42
+ * 2. The value included in `order` comes after the value not included in `order`.
43
+ * 3. If neither values are included in `order`, they are sorted:
44
+ * - symbol values come before string values
45
+ * - alphabetical order for two symbols or two strings
46
+ *
47
+ * @param a - First value
48
+ * @param b - Second value
49
+ * @param order - An array of values as the predefined order
50
+ */
51
+ function compareByOrder(a, b, order = []) {
52
+ a = a !== null && a !== void 0 ? a : '';
53
+ b = b !== null && b !== void 0 ? b : '';
54
+ const i1 = order.indexOf(a);
55
+ const i2 = order.indexOf(b);
56
+ if (i1 !== -1 || i2 !== -1) {
57
+ // Honor the order
58
+ return i1 - i2;
59
+ }
60
+ else {
61
+ // Neither value is in the pre-defined order
62
+ // symbol comes before string
63
+ if (typeof a === 'symbol' && typeof b === 'string')
64
+ return -1;
65
+ if (typeof a === 'string' && typeof b === 'symbol')
66
+ return 1;
67
+ // both a and b are symbols or both a and b are strings
68
+ if (typeof a === 'symbol')
69
+ a = a.toString();
70
+ if (typeof b === 'symbol')
71
+ b = b.toString();
72
+ return a < b ? -1 : a > b ? 1 : 0;
73
+ }
74
+ }
75
+ exports.compareByOrder = compareByOrder;
76
+ /**
77
+ * Sort bindings by phase names denoted by a tag and the predefined order
78
+ *
79
+ * @param bindings - An array of bindings
80
+ * @param phaseTagName - Tag name for phase, for example, we can use the value
81
+ * `'a'` of tag `order` as the phase name for `binding.tag({order: 'a'})`.
82
+ *
83
+ * @param orderOfPhases - An array of phase names as the predefined order
84
+ */
85
+ function sortBindingsByPhase(bindings, phaseTagName, orderOfPhases) {
86
+ return bindings.sort(compareBindingsByTag(phaseTagName, orderOfPhases));
87
+ }
88
+ exports.sortBindingsByPhase = sortBindingsByPhase;
89
+ //# sourceMappingURL=binding-sorter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-sorter.js","sourceRoot":"","sources":["../src/binding-sorter.ts"],"names":[],"mappings":";AAAA,iDAAiD;AACjD,iCAAiC;AACjC,+CAA+C;AAC/C,gEAAgE;;;AA6BhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,oBAAoB,CAClC,YAAY,GAAG,OAAO,EACtB,gBAAqC,EAAE;IAEvC,OAAO,CAAC,CAA6B,EAAE,CAA6B,EAAE,EAAE;QACtE,OAAO,cAAc,CACnB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EACtB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EACtB,aAAa,CACd,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAXD,oDAWC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,cAAc,CAC5B,CAAqC,EACrC,CAAqC,EACrC,QAA6B,EAAE;IAE/B,CAAC,GAAG,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,CAAC;IACZ,CAAC,GAAG,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,CAAC;IACZ,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE;QAC1B,kBAAkB;QAClB,OAAO,EAAE,GAAG,EAAE,CAAC;KAChB;SAAM;QACL,4CAA4C;QAE5C,6BAA6B;QAC7B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC,CAAC;QAC9D,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;QAE7D,uDAAuD;QACvD,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACnC;AACH,CAAC;AAxBD,wCAwBC;AAED;;;;;;;;GAQG;AACH,SAAgB,mBAAmB,CACjC,QAAgC,EAChC,YAAqB,EACrB,aAAmC;IAEnC,OAAO,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;AAC1E,CAAC;AAND,kDAMC"}
@@ -0,0 +1,577 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import { BindingAddress } from './binding-key';
4
+ import { Context } from './context';
5
+ import { JSONObject } from './json-types';
6
+ import { Provider } from './provider';
7
+ import { ResolutionContext, ResolutionOptions, ResolutionSession } from './resolution-session';
8
+ import { BoundValue, Constructor, MapObject, ValueOrPromise } from './value-promise';
9
+ /**
10
+ * Scope for binding values
11
+ */
12
+ export declare enum BindingScope {
13
+ /**
14
+ * The binding provides a value that is calculated each time. This will be
15
+ * the default scope if not set.
16
+ *
17
+ * For example, with the following context hierarchy:
18
+ *
19
+ * - `app` (with a binding `'b1'` that produces sequential values 0, 1, ...)
20
+ * - req1
21
+ * - req2
22
+ *
23
+ * Now `'b1'` is resolved to a new value each time for `app` and its
24
+ * descendants `req1` and `req2`:
25
+ * - app.get('b1') ==> 0
26
+ * - req1.get('b1') ==> 1
27
+ * - req2.get('b1') ==> 2
28
+ * - req2.get('b1') ==> 3
29
+ * - app.get('b1') ==> 4
30
+ */
31
+ TRANSIENT = "Transient",
32
+ /**
33
+ * @deprecated Finer-grained scopes such as `APPLICATION`, `SERVER`, or
34
+ * `REQUEST` should be used instead to ensure the scope of sharing of resolved
35
+ * binding values.
36
+ *
37
+ * The binding provides a value as a singleton within each local context. The
38
+ * value is calculated only once per context and cached for subsequential
39
+ * uses. Child contexts have their own value and do not share with their
40
+ * ancestors.
41
+ *
42
+ * For example, with the following context hierarchy:
43
+ *
44
+ * - `app` (with a binding `'b1'` that produces sequential values 0, 1, ...)
45
+ * - req1
46
+ * - req2
47
+ *
48
+ * 1. `0` is the resolved value for `'b1'` within the `app` afterward
49
+ * - app.get('b1') ==> 0 (always)
50
+ *
51
+ * 2. `'b1'` is resolved in `app` but not in `req1`, a new value `1` is
52
+ * calculated and used for `req1` afterward
53
+ * - req1.get('b1') ==> 1 (always)
54
+ *
55
+ * 3. `'b1'` is resolved in `app` but not in `req2`, a new value `2` is
56
+ * calculated and used for `req2` afterward
57
+ * - req2.get('b1') ==> 2 (always)
58
+ *
59
+ */
60
+ CONTEXT = "Context",
61
+ /**
62
+ * The binding provides a value as a singleton within the context hierarchy
63
+ * (the owning context and its descendants). The value is calculated only
64
+ * once for the owning context and cached for subsequential uses. Child
65
+ * contexts share the same value as their ancestors.
66
+ *
67
+ * For example, with the following context hierarchy:
68
+ *
69
+ * - `app` (with a binding `'b1'` that produces sequential values 0, 1, ...)
70
+ * - req1
71
+ * - req2
72
+ *
73
+ * 1. `0` is the singleton for `app` afterward
74
+ * - app.get('b1') ==> 0 (always)
75
+ *
76
+ * 2. `'b1'` is resolved in `app`, reuse it for `req1`
77
+ * - req1.get('b1') ==> 0 (always)
78
+ *
79
+ * 3. `'b1'` is resolved in `app`, reuse it for `req2`
80
+ * - req2.get('b1') ==> 0 (always)
81
+ */
82
+ SINGLETON = "Singleton",
83
+ /**
84
+ * Application scope
85
+ *
86
+ * @remarks
87
+ * The binding provides an application-scoped value within the context
88
+ * hierarchy. Resolved value for this binding will be cached and shared for
89
+ * the same application context (denoted by its scope property set to
90
+ * `BindingScope.APPLICATION`).
91
+ *
92
+ */
93
+ APPLICATION = "Application",
94
+ /**
95
+ * Server scope
96
+ *
97
+ * @remarks
98
+ * The binding provides an server-scoped value within the context hierarchy.
99
+ * Resolved value for this binding will be cached and shared for the same
100
+ * server context (denoted by its scope property set to
101
+ * `BindingScope.SERVER`).
102
+ *
103
+ * It's possible that an application has more than one servers configured,
104
+ * such as a `RestServer` and a `GrpcServer`. Both server contexts are created
105
+ * with `scope` set to `BindingScope.SERVER`. Depending on where a binding
106
+ * is resolved:
107
+ * - If the binding is resolved from the RestServer or below, it will be
108
+ * cached using the RestServer context as the key.
109
+ * - If the binding is resolved from the GrpcServer or below, it will be
110
+ * cached using the GrpcServer context as the key.
111
+ *
112
+ * The same binding can resolved/shared/cached for all servers, each of which
113
+ * has its own value for the binding.
114
+ */
115
+ SERVER = "Server",
116
+ /**
117
+ * Request scope
118
+ *
119
+ * @remarks
120
+ * The binding provides an request-scoped value within the context hierarchy.
121
+ * Resolved value for this binding will be cached and shared for the same
122
+ * request context (denoted by its scope property set to
123
+ * `BindingScope.REQUEST`).
124
+ *
125
+ * The `REQUEST` scope is very useful for controllers, services and artifacts
126
+ * that want to have a single instance/value for a given request.
127
+ */
128
+ REQUEST = "Request"
129
+ }
130
+ /**
131
+ * Type of the binding source
132
+ */
133
+ export declare enum BindingType {
134
+ /**
135
+ * A fixed value
136
+ */
137
+ CONSTANT = "Constant",
138
+ /**
139
+ * A function to get the value
140
+ */
141
+ DYNAMIC_VALUE = "DynamicValue",
142
+ /**
143
+ * A class to be instantiated as the value
144
+ */
145
+ CLASS = "Class",
146
+ /**
147
+ * A provider class with `value()` function to get the value
148
+ */
149
+ PROVIDER = "Provider",
150
+ /**
151
+ * A alias to another binding key with optional path
152
+ */
153
+ ALIAS = "Alias"
154
+ }
155
+ /**
156
+ * Binding source for `to`
157
+ */
158
+ export declare type ConstantBindingSource<T> = {
159
+ type: BindingType.CONSTANT;
160
+ value: T;
161
+ };
162
+ /**
163
+ * Binding source for `toDynamicValue`
164
+ */
165
+ export declare type DynamicValueBindingSource<T> = {
166
+ type: BindingType.DYNAMIC_VALUE;
167
+ value: ValueFactory<T> | DynamicValueProviderClass<T>;
168
+ };
169
+ /**
170
+ * Binding source for `toClass`
171
+ */
172
+ export declare type ClassBindingSource<T> = {
173
+ type: BindingType.CLASS;
174
+ value: Constructor<T>;
175
+ };
176
+ /**
177
+ * Binding source for `toProvider`
178
+ */
179
+ export declare type ProviderBindingSource<T> = {
180
+ type: BindingType.PROVIDER;
181
+ value: Constructor<Provider<T>>;
182
+ };
183
+ /**
184
+ * Binding source for `toAlias`
185
+ */
186
+ export declare type AliasBindingSource<T> = {
187
+ type: BindingType.ALIAS;
188
+ value: BindingAddress<T>;
189
+ };
190
+ /**
191
+ * Source for the binding, including the type and value
192
+ */
193
+ export declare type BindingSource<T> = ConstantBindingSource<T> | DynamicValueBindingSource<T> | ClassBindingSource<T> | ProviderBindingSource<T> | AliasBindingSource<T>;
194
+ export declare type TagMap = MapObject<any>;
195
+ /**
196
+ * Binding tag can be a simple name or name/value pairs
197
+ */
198
+ export declare type BindingTag = TagMap | string;
199
+ /**
200
+ * A function as the template to configure bindings
201
+ */
202
+ export declare type BindingTemplate<T = unknown> = (binding: Binding<T>) => void;
203
+ /**
204
+ * Information for a binding event
205
+ */
206
+ export declare type BindingEvent = {
207
+ /**
208
+ * Event type
209
+ */
210
+ type: 'changed' | string;
211
+ /**
212
+ * Source binding that emits the event
213
+ */
214
+ binding: Readonly<Binding<unknown>>;
215
+ /**
216
+ * Operation that triggers the event
217
+ */
218
+ operation: 'tag' | 'scope' | 'value' | string;
219
+ };
220
+ /**
221
+ * Event listeners for binding events
222
+ */
223
+ export declare type BindingEventListener = (
224
+ /**
225
+ * Binding event
226
+ */
227
+ event: BindingEvent) => void;
228
+ /**
229
+ * A factory function for `toDynamicValue`
230
+ */
231
+ export declare type ValueFactory<T = unknown> = (resolutionCtx: ResolutionContext) => ValueOrPromise<T | undefined>;
232
+ /**
233
+ * A class with a static `value` method as the factory function for
234
+ * `toDynamicValue`.
235
+ *
236
+ * @example
237
+ * ```ts
238
+ * import {inject} from '@loopback/context';
239
+ *
240
+ * export class DynamicGreetingProvider {
241
+ * static value(@inject('currentUser') user: string) {
242
+ * return `Hello, ${user}`;
243
+ * }
244
+ * }
245
+ * ```
246
+ */
247
+ export interface DynamicValueProviderClass<T = unknown> extends Constructor<unknown>, Function {
248
+ value: (...args: BoundValue[]) => ValueOrPromise<T>;
249
+ }
250
+ /**
251
+ * Check if the factory is a value factory provider class
252
+ * @param factory - A factory function or a dynamic value provider class
253
+ */
254
+ export declare function isDynamicValueProviderClass<T = unknown>(factory: unknown): factory is DynamicValueProviderClass<T>;
255
+ /**
256
+ * Binding represents an entry in the `Context`. Each binding has a key and a
257
+ * corresponding value getter.
258
+ */
259
+ export declare class Binding<T = BoundValue> extends EventEmitter {
260
+ isLocked: boolean;
261
+ /**
262
+ * Key of the binding
263
+ */
264
+ readonly key: string;
265
+ /**
266
+ * Map for tag name/value pairs
267
+ */
268
+ readonly tagMap: TagMap;
269
+ private _scope?;
270
+ /**
271
+ * Scope of the binding to control how the value is cached/shared
272
+ */
273
+ get scope(): BindingScope;
274
+ /**
275
+ * Type of the binding value getter
276
+ */
277
+ get type(): BindingType | undefined;
278
+ private _cache;
279
+ private _getValue?;
280
+ /**
281
+ * The original source value received from `to`, `toClass`, `toDynamicValue`,
282
+ * `toProvider`, or `toAlias`.
283
+ */
284
+ private _source?;
285
+ get source(): BindingSource<T> | undefined;
286
+ /**
287
+ * For bindings bound via `toClass()`, this property contains the constructor
288
+ * function of the class
289
+ */
290
+ get valueConstructor(): Constructor<T> | undefined;
291
+ /**
292
+ * For bindings bound via `toProvider()`, this property contains the
293
+ * constructor function of the provider class
294
+ */
295
+ get providerConstructor(): Constructor<Provider<T>> | undefined;
296
+ constructor(key: BindingAddress<T>, isLocked?: boolean);
297
+ /**
298
+ * Cache the resolved value by the binding scope
299
+ * @param resolutionCtx - The resolution context
300
+ * @param result - The calculated value for the binding
301
+ */
302
+ private _cacheValue;
303
+ /**
304
+ * Clear the cache
305
+ */
306
+ private _clearCache;
307
+ /**
308
+ * Invalidate the binding cache so that its value will be reloaded next time.
309
+ * This is useful to force reloading a cached value when its configuration or
310
+ * dependencies are changed.
311
+ * **WARNING**: The state held in the cached value will be gone.
312
+ *
313
+ * @param ctx - Context object
314
+ */
315
+ refresh(ctx: Context): void;
316
+ /**
317
+ * This is an internal function optimized for performance.
318
+ * Users should use `@inject(key)` or `ctx.get(key)` instead.
319
+ *
320
+ * Get the value bound to this key. Depending on `isSync`, this
321
+ * function returns either:
322
+ * - the bound value
323
+ * - a promise of the bound value
324
+ *
325
+ * Consumers wishing to consume sync values directly should use `isPromiseLike`
326
+ * to check the type of the returned value to decide how to handle it.
327
+ *
328
+ * @example
329
+ * ```
330
+ * const result = binding.getValue(ctx);
331
+ * if (isPromiseLike(result)) {
332
+ * result.then(doSomething)
333
+ * } else {
334
+ * doSomething(result);
335
+ * }
336
+ * ```
337
+ *
338
+ * @param ctx - Context for the resolution
339
+ * @param session - Optional session for binding and dependency resolution
340
+ */
341
+ getValue(ctx: Context, session?: ResolutionSession): ValueOrPromise<T>;
342
+ /**
343
+ * Returns a value or promise for this binding in the given context. The
344
+ * resolved value can be `undefined` if `optional` is set to `true` in
345
+ * `options`.
346
+ * @param ctx - Context for the resolution
347
+ * @param options - Optional options for binding and dependency resolution
348
+ */
349
+ getValue(ctx: Context, options?: ResolutionOptions): ValueOrPromise<T | undefined>;
350
+ private getValueOrProxy;
351
+ /**
352
+ * Locate and validate the resolution context
353
+ * @param ctx - Current context
354
+ * @param options - Resolution options
355
+ */
356
+ private getResolutionContext;
357
+ /**
358
+ * Lock the binding so that it cannot be rebound
359
+ */
360
+ lock(): this;
361
+ /**
362
+ * Emit a `changed` event
363
+ * @param operation - Operation that makes changes
364
+ */
365
+ private emitChangedEvent;
366
+ /**
367
+ * Tag the binding with names or name/value objects. A tag has a name and
368
+ * an optional value. If not supplied, the tag name is used as the value.
369
+ *
370
+ * @param tags - A list of names or name/value objects. Each
371
+ * parameter can be in one of the following forms:
372
+ * - string: A tag name without value
373
+ * - string[]: An array of tag names
374
+ * - TagMap: A map of tag name/value pairs
375
+ *
376
+ * @example
377
+ * ```ts
378
+ * // Add a named tag `controller`
379
+ * binding.tag('controller');
380
+ *
381
+ * // Add two named tags: `controller` and `rest`
382
+ * binding.tag('controller', 'rest');
383
+ *
384
+ * // Add two tags
385
+ * // - `controller` (name = 'controller')
386
+ * // `{name: 'my-controller'}` (name = 'name', value = 'my-controller')
387
+ * binding.tag('controller', {name: 'my-controller'});
388
+ *
389
+ * ```
390
+ */
391
+ tag(...tags: BindingTag[]): this;
392
+ /**
393
+ * Get an array of tag names
394
+ */
395
+ get tagNames(): string[];
396
+ /**
397
+ * Set the binding scope
398
+ * @param scope - Binding scope
399
+ */
400
+ inScope(scope: BindingScope): this;
401
+ /**
402
+ * Apply default scope to the binding. It only changes the scope if it's not
403
+ * set yet
404
+ * @param scope - Default binding scope
405
+ */
406
+ applyDefaultScope(scope: BindingScope): this;
407
+ /**
408
+ * Set the `_getValue` function
409
+ * @param getValue - getValue function
410
+ */
411
+ private _setValueGetter;
412
+ /**
413
+ * Bind the key to a constant value. The value must be already available
414
+ * at binding time, it is not allowed to pass a Promise instance.
415
+ *
416
+ * @param value - The bound value.
417
+ *
418
+ * @example
419
+ *
420
+ * ```ts
421
+ * ctx.bind('appName').to('CodeHub');
422
+ * ```
423
+ */
424
+ to(value: T): this;
425
+ /**
426
+ * Bind the key to a computed (dynamic) value.
427
+ *
428
+ * @param factoryFn - The factory function creating the value.
429
+ * Both sync and async functions are supported.
430
+ *
431
+ * @example
432
+ *
433
+ * ```ts
434
+ * // synchronous
435
+ * ctx.bind('now').toDynamicValue(() => Date.now());
436
+ *
437
+ * // asynchronous
438
+ * ctx.bind('something').toDynamicValue(
439
+ * async () => Promise.delay(10).then(doSomething)
440
+ * );
441
+ * ```
442
+ */
443
+ toDynamicValue(factory: ValueFactory<T> | DynamicValueProviderClass<T>): this;
444
+ private static valueOrProxy;
445
+ /**
446
+ * Bind the key to a value computed by a Provider.
447
+ *
448
+ * * @example
449
+ *
450
+ * ```ts
451
+ * export class DateProvider implements Provider<Date> {
452
+ * constructor(@inject('stringDate') private param: String){}
453
+ * value(): Date {
454
+ * return new Date(param);
455
+ * }
456
+ * }
457
+ * ```
458
+ *
459
+ * @param provider - The value provider to use.
460
+ */
461
+ toProvider(providerClass: Constructor<Provider<T>>): this;
462
+ /**
463
+ * Bind the key to an instance of the given class.
464
+ *
465
+ * @param ctor - The class constructor to call. Any constructor
466
+ * arguments must be annotated with `@inject` so that
467
+ * we can resolve them from the context.
468
+ */
469
+ toClass(ctor: Constructor<T>): this;
470
+ /**
471
+ * Bind to a class optionally decorated with `@injectable`. Based on the
472
+ * introspection of the class, it calls `toClass/toProvider/toDynamicValue`
473
+ * internally. The current binding key will be preserved (not being overridden
474
+ * by the key inferred from the class or options).
475
+ *
476
+ * This is similar to {@link createBindingFromClass} but applies to an
477
+ * existing binding.
478
+ *
479
+ * @example
480
+ *
481
+ * ```ts
482
+ * @injectable({scope: BindingScope.SINGLETON, tags: {service: 'MyService}})
483
+ * class MyService {
484
+ * // ...
485
+ * }
486
+ *
487
+ * const ctx = new Context();
488
+ * ctx.bind('services.MyService').toInjectable(MyService);
489
+ * ```
490
+ *
491
+ * @param ctor - A class decorated with `@injectable`.
492
+ */
493
+ toInjectable(ctor: DynamicValueProviderClass<T> | Constructor<T | Provider<T>>): this;
494
+ /**
495
+ * Bind the key to an alias of another binding
496
+ * @param keyWithPath - Target binding key with optional path,
497
+ * such as `servers.RestServer.options#apiExplorer`
498
+ */
499
+ toAlias(keyWithPath: BindingAddress<T>): this;
500
+ /**
501
+ * Unlock the binding
502
+ */
503
+ unlock(): this;
504
+ /**
505
+ * Apply one or more template functions to set up the binding with scope,
506
+ * tags, and other attributes as a group.
507
+ *
508
+ * @example
509
+ * ```ts
510
+ * const serverTemplate = (binding: Binding) =>
511
+ * binding.inScope(BindingScope.SINGLETON).tag('server');
512
+ *
513
+ * const serverBinding = new Binding<RestServer>('servers.RestServer1');
514
+ * serverBinding.apply(serverTemplate);
515
+ * ```
516
+ * @param templateFns - One or more functions to configure the binding
517
+ */
518
+ apply(...templateFns: BindingTemplate<T>[]): this;
519
+ /**
520
+ * Convert to a plain JSON object
521
+ */
522
+ toJSON(): JSONObject;
523
+ /**
524
+ * Inspect the binding to return a json representation of the binding information
525
+ * @param options - Options to control what information should be included
526
+ */
527
+ inspect(options?: BindingInspectOptions): JSONObject;
528
+ /**
529
+ * A static method to create a binding so that we can do
530
+ * `Binding.bind('foo').to('bar');` as `new Binding('foo').to('bar')` is not
531
+ * easy to read.
532
+ * @param key - Binding key
533
+ */
534
+ static bind<V = unknown>(key: BindingAddress<V>): Binding<V>;
535
+ /**
536
+ * Create a configuration binding for the given key
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * const configBinding = Binding.configure('servers.RestServer.server1')
541
+ * .to({port: 3000});
542
+ * ```
543
+ *
544
+ * @typeParam V Generic type for the configuration value (not the binding to
545
+ * be configured)
546
+ *
547
+ * @param key - Key for the binding to be configured
548
+ */
549
+ static configure<V = unknown>(key: BindingAddress): Binding<V>;
550
+ /**
551
+ * The "changed" event is emitted by methods such as `tag`, `inScope`, `to`,
552
+ * and `toClass`.
553
+ *
554
+ * @param eventName The name of the event - always `changed`.
555
+ * @param listener The listener function to call when the event is emitted.
556
+ */
557
+ on(eventName: 'changed', listener: BindingEventListener): this;
558
+ on(event: string | symbol, listener: (...args: any[]) => void): this;
559
+ /**
560
+ * The "changed" event is emitted by methods such as `tag`, `inScope`, `to`,
561
+ * and `toClass`.
562
+ *
563
+ * @param eventName The name of the event - always `changed`.
564
+ * @param listener The listener function to call when the event is emitted.
565
+ */
566
+ once(eventName: 'changed', listener: BindingEventListener): this;
567
+ once(event: string | symbol, listener: (...args: any[]) => void): this;
568
+ }
569
+ /**
570
+ * Options for binding.inspect()
571
+ */
572
+ export interface BindingInspectOptions {
573
+ /**
574
+ * The flag to control if injections should be inspected
575
+ */
576
+ includeInjections?: boolean;
577
+ }