@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
@@ -0,0 +1,136 @@
1
+ // Copyright IBM Corp. 2018,2020. All Rights Reserved.
2
+ // Node module: @loopback/context
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import {generateUniqueId} from './unique-id';
7
+
8
+ export type BindingAddress<T = unknown> = string | BindingKey<T>;
9
+
10
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
+ export class BindingKey<ValueType> {
12
+ static readonly PROPERTY_SEPARATOR = '#';
13
+
14
+ /**
15
+ * Create a new key for a binding bound to a value of type `ValueType`.
16
+ *
17
+ * @example
18
+ *
19
+ * ```ts
20
+ * BindingKey.create<string>('application.name');
21
+ * BindingKey.create<number>('config', 'rest.port);
22
+ * BindingKey.create<number>('config#rest.port');
23
+ * ```
24
+ *
25
+ * @param key - The binding key. When propertyPath is not provided, the key
26
+ * is allowed to contain propertyPath as encoded via `BindingKey#toString()`
27
+ * @param propertyPath - Optional path to a deep property of the bound value.
28
+ */
29
+ public static create<V>(key: string, propertyPath?: string): BindingKey<V> {
30
+ // TODO(bajtos) allow chaining of propertyPaths, e.g.
31
+ // BindingKey.create('config#rest', 'port')
32
+ // should create {key: 'config', path: 'rest.port'}
33
+ if (propertyPath) {
34
+ BindingKey.validate(key);
35
+ return new BindingKey<V>(key, propertyPath);
36
+ }
37
+
38
+ return BindingKey.parseKeyWithPath(key);
39
+ }
40
+
41
+ private constructor(
42
+ public readonly key: string,
43
+ public readonly propertyPath?: string,
44
+ ) {}
45
+
46
+ toString() {
47
+ return this.propertyPath
48
+ ? `${this.key}${BindingKey.PROPERTY_SEPARATOR}${this.propertyPath}`
49
+ : this.key;
50
+ }
51
+
52
+ /**
53
+ * Get a binding address for retrieving a deep property of the object
54
+ * bound to the current binding key.
55
+ *
56
+ * @param propertyPath - A dot-separated path to a (deep) property, e.g. "server.port".
57
+ */
58
+ deepProperty<PropertyValueType>(propertyPath: string) {
59
+ // TODO(bajtos) allow chaining of propertyPaths, e.g.
60
+ // BindingKey.create('config', 'rest').deepProperty('port')
61
+ // should create {key: 'config', path: 'rest.port'}
62
+ return BindingKey.create<PropertyValueType>(this.key, propertyPath);
63
+ }
64
+
65
+ /**
66
+ * Validate the binding key format. Please note that `#` is reserved.
67
+ * Returns a string representation of the binding key.
68
+ *
69
+ * @param key - Binding key, such as `a`, `a.b`, `a:b`, or `a/b`
70
+ */
71
+ static validate<T>(key: BindingAddress<T>): string {
72
+ if (!key) throw new Error('Binding key must be provided.');
73
+ key = key.toString();
74
+ if (key.includes(BindingKey.PROPERTY_SEPARATOR)) {
75
+ throw new Error(
76
+ `Binding key ${key} cannot contain` +
77
+ ` '${BindingKey.PROPERTY_SEPARATOR}'.`,
78
+ );
79
+ }
80
+ return key;
81
+ }
82
+
83
+ /**
84
+ * Parse a string containing both the binding key and the path to the deeply
85
+ * nested property to retrieve.
86
+ *
87
+ * @param keyWithPath - The key with an optional path,
88
+ * e.g. "application.instance" or "config#rest.port".
89
+ */
90
+ static parseKeyWithPath<T>(keyWithPath: BindingAddress<T>): BindingKey<T> {
91
+ if (typeof keyWithPath !== 'string') {
92
+ return BindingKey.create<T>(keyWithPath.key, keyWithPath.propertyPath);
93
+ }
94
+
95
+ const index = keyWithPath.indexOf(BindingKey.PROPERTY_SEPARATOR);
96
+ if (index === -1) {
97
+ return new BindingKey<T>(keyWithPath);
98
+ }
99
+
100
+ return BindingKey.create<T>(
101
+ keyWithPath.substr(0, index).trim(),
102
+ keyWithPath.substr(index + 1),
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Name space for configuration binding keys
108
+ */
109
+ static CONFIG_NAMESPACE = '$config';
110
+
111
+ /**
112
+ * Build a binding key for the configuration of the given binding.
113
+ * The format is `<key>:$config`
114
+ *
115
+ * @param key - Key of the target binding to be configured
116
+ */
117
+ static buildKeyForConfig<T>(key: BindingAddress = ''): BindingAddress<T> {
118
+ const suffix = BindingKey.CONFIG_NAMESPACE;
119
+ const bindingKey = key ? `${key}:${suffix}` : suffix;
120
+ return bindingKey;
121
+ }
122
+
123
+ /**
124
+ * Generate a universally unique binding key.
125
+ *
126
+ * Please note the format of they generated key is not specified, you must
127
+ * not rely on any specific formatting (e.g. UUID style).
128
+ *
129
+ * @param namespace - Namespace for the binding
130
+ */
131
+ static generate<T>(namespace = ''): BindingKey<T> {
132
+ const prefix = namespace ? `${namespace}.` : '';
133
+ const name = generateUniqueId();
134
+ return BindingKey.create(`${prefix}${name}`);
135
+ }
136
+ }
@@ -0,0 +1,124 @@
1
+ // Copyright IBM Corp. 2019. All Rights Reserved.
2
+ // Node module: @loopback/context
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import {Binding} from './binding';
7
+
8
+ /**
9
+ * Compare function to sort an array of bindings.
10
+ * It is used by `Array.prototype.sort()`.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const compareByKey: BindingComparator = (a, b) => a.key.localeCompare(b.key);
15
+ * ```
16
+ */
17
+ export interface BindingComparator {
18
+ /**
19
+ * Compare two bindings
20
+ * @param bindingA - First binding
21
+ * @param bindingB - Second binding
22
+ * @returns A number to determine order of bindingA and bindingB
23
+ * - 0 leaves bindingA and bindingB unchanged
24
+ * - <0 bindingA comes before bindingB
25
+ * - >0 bindingA comes after bindingB
26
+ */
27
+ (
28
+ bindingA: Readonly<Binding<unknown>>,
29
+ bindingB: Readonly<Binding<unknown>>,
30
+ ): number;
31
+ }
32
+
33
+ /**
34
+ * Creates a binding compare function to sort bindings by tagged phase name.
35
+ *
36
+ * @remarks
37
+ * Two bindings are compared as follows:
38
+ *
39
+ * 1. Get values for the given tag as `phase` for bindings, if the tag is not
40
+ * present, default `phase` to `''`.
41
+ * 2. If both bindings have `phase` value in `orderOfPhases`, honor the order
42
+ * specified by `orderOfPhases`.
43
+ * 3. If a binding's `phase` does not exist in `orderOfPhases`, it comes before
44
+ * the one with `phase` exists in `orderOfPhases`.
45
+ * 4. If both bindings have `phase` value outside of `orderOfPhases`, they are
46
+ * ordered by phase names alphabetically and symbol values come before string
47
+ * values.
48
+ *
49
+ * @param phaseTagName - Name of the binding tag for phase
50
+ * @param orderOfPhases - An array of phase names as the predefined order
51
+ */
52
+ export function compareBindingsByTag(
53
+ phaseTagName = 'phase',
54
+ orderOfPhases: (string | symbol)[] = [],
55
+ ): BindingComparator {
56
+ return (a: Readonly<Binding<unknown>>, b: Readonly<Binding<unknown>>) => {
57
+ return compareByOrder(
58
+ a.tagMap[phaseTagName],
59
+ b.tagMap[phaseTagName],
60
+ orderOfPhases,
61
+ );
62
+ };
63
+ }
64
+
65
+ /**
66
+ * Compare two values by the predefined order
67
+ *
68
+ * @remarks
69
+ *
70
+ * The comparison is performed as follows:
71
+ *
72
+ * 1. If both values are included in `order`, they are sorted by their indexes in
73
+ * `order`.
74
+ * 2. The value included in `order` comes after the value not included in `order`.
75
+ * 3. If neither values are included in `order`, they are sorted:
76
+ * - symbol values come before string values
77
+ * - alphabetical order for two symbols or two strings
78
+ *
79
+ * @param a - First value
80
+ * @param b - Second value
81
+ * @param order - An array of values as the predefined order
82
+ */
83
+ export function compareByOrder(
84
+ a: string | symbol | undefined | null,
85
+ b: string | symbol | undefined | null,
86
+ order: (string | symbol)[] = [],
87
+ ) {
88
+ a = a ?? '';
89
+ b = b ?? '';
90
+ const i1 = order.indexOf(a);
91
+ const i2 = order.indexOf(b);
92
+ if (i1 !== -1 || i2 !== -1) {
93
+ // Honor the order
94
+ return i1 - i2;
95
+ } else {
96
+ // Neither value is in the pre-defined order
97
+
98
+ // symbol comes before string
99
+ if (typeof a === 'symbol' && typeof b === 'string') return -1;
100
+ if (typeof a === 'string' && typeof b === 'symbol') return 1;
101
+
102
+ // both a and b are symbols or both a and b are strings
103
+ if (typeof a === 'symbol') a = a.toString();
104
+ if (typeof b === 'symbol') b = b.toString();
105
+ return a < b ? -1 : a > b ? 1 : 0;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Sort bindings by phase names denoted by a tag and the predefined order
111
+ *
112
+ * @param bindings - An array of bindings
113
+ * @param phaseTagName - Tag name for phase, for example, we can use the value
114
+ * `'a'` of tag `order` as the phase name for `binding.tag({order: 'a'})`.
115
+ *
116
+ * @param orderOfPhases - An array of phase names as the predefined order
117
+ */
118
+ export function sortBindingsByPhase<T = unknown>(
119
+ bindings: Readonly<Binding<T>>[],
120
+ phaseTagName?: string,
121
+ orderOfPhases?: (string | symbol)[],
122
+ ) {
123
+ return bindings.sort(compareBindingsByTag(phaseTagName, orderOfPhases));
124
+ }