@expressots/core 2.16.2 → 3.0.0-beta.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.
Files changed (185) hide show
  1. package/README.md +2 -2
  2. package/lib/CHANGELOG.md +312 -322
  3. package/lib/README.md +2 -2
  4. package/lib/cjs/application/application-container.js +18 -21
  5. package/lib/cjs/application/application-factory.js +4 -5
  6. package/lib/cjs/{common/server-env.types.js → application/application.types.js} +1 -0
  7. package/lib/cjs/application/index.js +3 -1
  8. package/lib/cjs/console/console.js +8 -20
  9. package/lib/cjs/container-module/container-module.js +10 -18
  10. package/lib/cjs/decorator/scope-binding.js +12 -11
  11. package/lib/cjs/di/annotation/decorator_utils.js +121 -0
  12. package/lib/cjs/di/annotation/inject.js +44 -0
  13. package/lib/cjs/di/annotation/inject_base.js +17 -0
  14. package/lib/cjs/di/annotation/injectable.js +43 -0
  15. package/lib/cjs/di/annotation/lazy_service_identifier.js +12 -0
  16. package/lib/cjs/di/annotation/multi_inject.js +30 -0
  17. package/lib/cjs/di/annotation/named.js +34 -0
  18. package/lib/cjs/di/annotation/optional.js +32 -0
  19. package/lib/cjs/di/annotation/post_construct.js +31 -0
  20. package/lib/cjs/di/annotation/pre_destroy.js +31 -0
  21. package/lib/cjs/di/annotation/property_event_decorator.js +15 -0
  22. package/lib/cjs/di/annotation/tagged.js +9 -0
  23. package/lib/cjs/di/annotation/target_name.js +35 -0
  24. package/lib/cjs/di/annotation/unmanaged.js +35 -0
  25. package/lib/cjs/di/binding-decorator/constants.js +7 -0
  26. package/lib/cjs/di/binding-decorator/decorator/fluent_provide.js +20 -0
  27. package/lib/cjs/di/binding-decorator/decorator/provide.js +37 -0
  28. package/lib/cjs/di/binding-decorator/factory/module_factory.js +17 -0
  29. package/lib/cjs/di/binding-decorator/index.js +14 -0
  30. package/lib/cjs/di/binding-decorator/syntax/provide_done_syntax.js +42 -0
  31. package/lib/cjs/di/binding-decorator/syntax/provide_in_syntax.js +33 -0
  32. package/lib/cjs/di/binding-decorator/syntax/provide_in_when_on_syntax.js +64 -0
  33. package/lib/cjs/di/binding-decorator/syntax/provide_on_syntax.js +22 -0
  34. package/lib/cjs/di/binding-decorator/syntax/provide_when_on_syntax.js +57 -0
  35. package/lib/cjs/di/binding-decorator/syntax/provide_when_syntax.js +89 -0
  36. package/lib/cjs/di/binding-decorator/utils/auto_wire.js +18 -0
  37. package/lib/cjs/di/bindings/binding.js +40 -0
  38. package/lib/cjs/di/bindings/binding_count.js +8 -0
  39. package/lib/cjs/di/constants/error_msgs.js +60 -0
  40. package/lib/cjs/di/constants/literal_types.js +26 -0
  41. package/lib/cjs/di/constants/metadata_keys.js +38 -0
  42. package/lib/cjs/di/container/container.js +521 -0
  43. package/lib/cjs/di/container/container_module.js +18 -0
  44. package/lib/cjs/di/container/container_snapshot.js +15 -0
  45. package/lib/cjs/di/container/lookup.js +132 -0
  46. package/lib/cjs/di/container/module_activation_store.js +49 -0
  47. package/lib/cjs/di/interfaces/interfaces.js +2 -0
  48. package/lib/cjs/di/inversify.js +78 -0
  49. package/lib/cjs/di/planning/context.js +17 -0
  50. package/lib/cjs/di/planning/metadata.js +42 -0
  51. package/lib/cjs/di/planning/metadata_reader.js +45 -0
  52. package/lib/cjs/di/planning/plan.js +10 -0
  53. package/lib/cjs/di/planning/planner.js +186 -0
  54. package/lib/cjs/di/planning/queryable_string.js +27 -0
  55. package/lib/cjs/di/planning/reflection_utils.js +178 -0
  56. package/lib/cjs/di/planning/request.js +23 -0
  57. package/lib/cjs/di/planning/target.js +108 -0
  58. package/lib/cjs/di/resolution/instantiation.js +150 -0
  59. package/lib/cjs/di/resolution/resolver.js +188 -0
  60. package/lib/cjs/di/scope/scope.js +50 -0
  61. package/lib/cjs/di/syntax/binding_in_syntax.js +23 -0
  62. package/lib/cjs/di/syntax/binding_in_when_on_syntax.js +75 -0
  63. package/lib/cjs/di/syntax/binding_on_syntax.js +18 -0
  64. package/lib/cjs/di/syntax/binding_to_syntax.js +111 -0
  65. package/lib/cjs/di/syntax/binding_when_on_syntax.js +64 -0
  66. package/lib/cjs/di/syntax/binding_when_syntax.js +84 -0
  67. package/lib/cjs/di/syntax/constraint_helpers.js +68 -0
  68. package/lib/cjs/di/utils/async.js +15 -0
  69. package/lib/cjs/di/utils/binding_utils.js +77 -0
  70. package/lib/cjs/di/utils/clonable.js +9 -0
  71. package/lib/cjs/di/utils/exceptions.js +46 -0
  72. package/lib/cjs/di/utils/factory_type.js +9 -0
  73. package/lib/cjs/di/utils/id.js +7 -0
  74. package/lib/cjs/di/utils/js.js +15 -0
  75. package/lib/cjs/di/utils/serialization.js +132 -0
  76. package/lib/cjs/error/app-error.js +5 -2
  77. package/lib/cjs/error/report.js +24 -15
  78. package/lib/cjs/index.js +1 -2
  79. package/lib/cjs/middleware/middleware-interface.js +2 -0
  80. package/lib/cjs/middleware/middleware-service.js +9 -24
  81. package/lib/cjs/provider/db-in-memory/base-repo.repository.js +3 -8
  82. package/lib/cjs/provider/db-in-memory/db-in-memory.provider.js +8 -5
  83. package/lib/cjs/provider/dto-validator/dto-validator.provider.js +4 -4
  84. package/lib/cjs/provider/dto-validator/package-resolver.js +56 -0
  85. package/lib/cjs/provider/environment/env-validator.provider.js +14 -12
  86. package/lib/cjs/provider/logger/logger.provider.js +10 -5
  87. package/lib/cjs/provider/provider-manager.js +21 -17
  88. package/lib/cjs/types/application/application-container.d.ts +12 -25
  89. package/lib/cjs/types/application/application-factory.d.ts +10 -7
  90. package/lib/cjs/types/{common/server-env.types.d.ts → application/application.types.d.ts} +1 -0
  91. package/lib/cjs/types/application/index.d.ts +1 -0
  92. package/lib/cjs/types/console/console.d.ts +3 -10
  93. package/lib/cjs/types/console/index.d.ts +2 -1
  94. package/lib/cjs/types/container-module/container-module.d.ts +3 -1
  95. package/lib/cjs/types/decorator/scope-binding.d.ts +9 -9
  96. package/lib/cjs/types/di/annotation/decorator_utils.d.ts +16 -0
  97. package/lib/cjs/types/di/annotation/inject.d.ts +16 -0
  98. package/lib/cjs/types/di/annotation/inject_base.d.ts +3 -0
  99. package/lib/cjs/types/di/annotation/injectable.d.ts +7 -0
  100. package/lib/cjs/types/di/annotation/lazy_service_identifier.d.ts +7 -0
  101. package/lib/cjs/types/di/annotation/multi_inject.d.ts +2 -0
  102. package/lib/cjs/types/di/annotation/named.d.ts +2 -0
  103. package/lib/cjs/types/di/annotation/optional.d.ts +2 -0
  104. package/lib/cjs/types/di/annotation/post_construct.d.ts +4 -0
  105. package/lib/cjs/types/di/annotation/pre_destroy.d.ts +4 -0
  106. package/lib/cjs/types/di/annotation/property_event_decorator.d.ts +4 -0
  107. package/lib/cjs/types/di/annotation/tagged.d.ts +2 -0
  108. package/lib/cjs/types/di/annotation/target_name.d.ts +3 -0
  109. package/lib/cjs/types/di/annotation/unmanaged.d.ts +3 -0
  110. package/lib/cjs/types/di/binding-decorator/constants.d.ts +4 -0
  111. package/lib/cjs/types/di/binding-decorator/decorator/fluent_provide.d.ts +4 -0
  112. package/lib/cjs/types/di/binding-decorator/decorator/provide.d.ts +4 -0
  113. package/lib/cjs/types/di/binding-decorator/factory/module_factory.d.ts +4 -0
  114. package/lib/cjs/types/di/binding-decorator/index.d.ts +8 -0
  115. package/lib/cjs/types/di/binding-decorator/interfaces/interfaces.d.ts +39 -0
  116. package/lib/cjs/types/di/binding-decorator/syntax/provide_done_syntax.d.ts +7 -0
  117. package/lib/cjs/types/di/binding-decorator/syntax/provide_in_syntax.d.ts +11 -0
  118. package/lib/cjs/types/di/binding-decorator/syntax/provide_in_when_on_syntax.d.ts +27 -0
  119. package/lib/cjs/types/di/binding-decorator/syntax/provide_on_syntax.d.ts +10 -0
  120. package/lib/cjs/types/di/binding-decorator/syntax/provide_when_on_syntax.d.ts +24 -0
  121. package/lib/cjs/types/di/binding-decorator/syntax/provide_when_syntax.d.ts +23 -0
  122. package/lib/cjs/types/di/binding-decorator/utils/auto_wire.d.ts +3 -0
  123. package/lib/cjs/types/di/bindings/binding.d.ts +20 -0
  124. package/lib/cjs/types/di/bindings/binding_count.d.ts +5 -0
  125. package/lib/cjs/types/di/constants/error_msgs.d.ts +32 -0
  126. package/lib/cjs/types/di/constants/literal_types.d.ts +5 -0
  127. package/lib/cjs/types/di/constants/metadata_keys.d.ts +13 -0
  128. package/lib/cjs/types/di/container/container.d.ts +73 -0
  129. package/lib/cjs/types/di/container/container_module.d.ts +11 -0
  130. package/lib/cjs/types/di/container/container_snapshot.d.ts +10 -0
  131. package/lib/cjs/types/di/container/lookup.d.ts +16 -0
  132. package/lib/cjs/types/di/container/module_activation_store.d.ts +10 -0
  133. package/lib/cjs/types/di/interfaces/interfaces.d.ts +299 -0
  134. package/lib/cjs/types/di/inversify.d.ts +25 -0
  135. package/lib/cjs/types/di/planning/context.d.ts +11 -0
  136. package/lib/cjs/types/di/planning/metadata.d.ts +8 -0
  137. package/lib/cjs/types/di/planning/metadata_reader.d.ts +6 -0
  138. package/lib/cjs/types/di/planning/plan.d.ts +7 -0
  139. package/lib/cjs/types/di/planning/planner.d.ts +5 -0
  140. package/lib/cjs/types/di/planning/queryable_string.d.ts +11 -0
  141. package/lib/cjs/types/di/planning/reflection_utils.d.ts +5 -0
  142. package/lib/cjs/types/di/planning/request.d.ts +14 -0
  143. package/lib/cjs/types/di/planning/target.d.ts +23 -0
  144. package/lib/cjs/types/di/resolution/instantiation.d.ts +3 -0
  145. package/lib/cjs/types/di/resolution/resolver.d.ts +3 -0
  146. package/lib/cjs/types/di/scope/scope.d.ts +3 -0
  147. package/lib/cjs/types/di/syntax/binding_in_syntax.d.ts +9 -0
  148. package/lib/cjs/types/di/syntax/binding_in_when_on_syntax.d.ts +29 -0
  149. package/lib/cjs/types/di/syntax/binding_on_syntax.d.ts +8 -0
  150. package/lib/cjs/types/di/syntax/binding_to_syntax.d.ts +18 -0
  151. package/lib/cjs/types/di/syntax/binding_when_on_syntax.d.ts +25 -0
  152. package/lib/cjs/types/di/syntax/binding_when_syntax.d.ts +21 -0
  153. package/lib/cjs/types/di/syntax/constraint_helpers.d.ts +6 -0
  154. package/lib/cjs/types/di/utils/async.d.ts +3 -0
  155. package/lib/cjs/types/di/utils/binding_utils.d.ts +4 -0
  156. package/lib/cjs/types/di/utils/clonable.d.ts +3 -0
  157. package/lib/cjs/types/di/utils/exceptions.d.ts +2 -0
  158. package/lib/cjs/types/di/utils/factory_type.d.ts +5 -0
  159. package/lib/cjs/types/di/utils/id.d.ts +2 -0
  160. package/lib/cjs/types/di/utils/js.d.ts +1 -0
  161. package/lib/cjs/types/di/utils/serialization.d.ts +10 -0
  162. package/lib/cjs/types/error/report.d.ts +7 -5
  163. package/lib/cjs/types/index.d.ts +1 -2
  164. package/lib/cjs/types/middleware/index.d.ts +2 -1
  165. package/lib/cjs/types/middleware/middleware-interface.d.ts +185 -0
  166. package/lib/cjs/types/middleware/middleware-service.d.ts +11 -163
  167. package/lib/cjs/types/provider/db-in-memory/db-in-memory.provider.d.ts +4 -0
  168. package/lib/cjs/types/provider/dto-validator/dto-validator.provider.d.ts +2 -3
  169. package/lib/cjs/types/{common → provider/dto-validator}/package-resolver.d.ts +1 -2
  170. package/lib/cjs/types/provider/environment/env-validator.provider.d.ts +7 -3
  171. package/lib/cjs/types/provider/logger/logger.provider.d.ts +5 -0
  172. package/lib/cjs/types/provider/provider-manager.d.ts +22 -2
  173. package/lib/package.json +9 -15
  174. package/package.json +9 -15
  175. package/lib/cjs/common/index.js +0 -5
  176. package/lib/cjs/common/package-resolver.js +0 -34
  177. package/lib/cjs/controller/base-controller.js +0 -63
  178. package/lib/cjs/controller/index.js +0 -5
  179. package/lib/cjs/types/common/index.d.ts +0 -2
  180. package/lib/cjs/types/common/project-config.d.ts +0 -56
  181. package/lib/cjs/types/controller/base-controller.d.ts +0 -32
  182. package/lib/cjs/types/controller/index.d.ts +0 -1
  183. /package/lib/cjs/{common → console}/color-codes.js +0 -0
  184. /package/lib/cjs/{common/project-config.js → di/binding-decorator/interfaces/interfaces.js} +0 -0
  185. /package/lib/cjs/types/{common → console}/color-codes.d.ts +0 -0
@@ -0,0 +1,521 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.Container = void 0;
27
+ const binding_1 = require("../bindings/binding");
28
+ const ERROR_MSGS = __importStar(require("../constants/error_msgs"));
29
+ const literal_types_1 = require("../constants/literal_types");
30
+ const METADATA_KEY = __importStar(require("../constants/metadata_keys"));
31
+ const metadata_reader_1 = require("../planning/metadata_reader");
32
+ const planner_1 = require("../planning/planner");
33
+ const resolver_1 = require("../resolution/resolver");
34
+ const binding_to_syntax_1 = require("../syntax/binding_to_syntax");
35
+ const async_1 = require("../utils/async");
36
+ const id_1 = require("../utils/id");
37
+ const serialization_1 = require("../utils/serialization");
38
+ const container_snapshot_1 = require("./container_snapshot");
39
+ const lookup_1 = require("./lookup");
40
+ const module_activation_store_1 = require("./module_activation_store");
41
+ class Container {
42
+ static merge(container1, container2, ...containers) {
43
+ const container = new Container();
44
+ const targetContainers = [container1, container2, ...containers].map((targetContainer) => (0, planner_1.getBindingDictionary)(targetContainer));
45
+ const bindingDictionary = (0, planner_1.getBindingDictionary)(container);
46
+ function copyDictionary(origin, destination) {
47
+ origin.traverse((_key, value) => {
48
+ value.forEach((binding) => {
49
+ destination.add(binding.serviceIdentifier, binding.clone());
50
+ });
51
+ });
52
+ }
53
+ targetContainers.forEach((targetBindingDictionary) => {
54
+ copyDictionary(targetBindingDictionary, bindingDictionary);
55
+ });
56
+ return container;
57
+ }
58
+ constructor(containerOptions) {
59
+ const options = containerOptions || {};
60
+ if (typeof options !== "object") {
61
+ throw new Error(`${ERROR_MSGS.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT}`);
62
+ }
63
+ if (options.defaultScope === undefined) {
64
+ options.defaultScope = literal_types_1.BindingScopeEnum.Transient;
65
+ }
66
+ else if (options.defaultScope !== literal_types_1.BindingScopeEnum.Singleton &&
67
+ options.defaultScope !== literal_types_1.BindingScopeEnum.Transient &&
68
+ options.defaultScope !== literal_types_1.BindingScopeEnum.Request) {
69
+ throw new Error(`${ERROR_MSGS.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE}`);
70
+ }
71
+ if (options.autoBindInjectable === undefined) {
72
+ options.autoBindInjectable = false;
73
+ }
74
+ else if (typeof options.autoBindInjectable !== "boolean") {
75
+ throw new Error(`${ERROR_MSGS.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE}`);
76
+ }
77
+ if (options.skipBaseClassChecks === undefined) {
78
+ options.skipBaseClassChecks = false;
79
+ }
80
+ else if (typeof options.skipBaseClassChecks !== "boolean") {
81
+ throw new Error(`${ERROR_MSGS.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK}`);
82
+ }
83
+ this.options = {
84
+ autoBindInjectable: options.autoBindInjectable,
85
+ defaultScope: options.defaultScope,
86
+ skipBaseClassChecks: options.skipBaseClassChecks,
87
+ };
88
+ this.id = (0, id_1.id)();
89
+ this._bindingDictionary = new lookup_1.Lookup();
90
+ this._snapshots = [];
91
+ this._middleware = null;
92
+ this._activations = new lookup_1.Lookup();
93
+ this._deactivations = new lookup_1.Lookup();
94
+ this.parent = null;
95
+ this._metadataReader = new metadata_reader_1.MetadataReader();
96
+ this._moduleActivationStore = new module_activation_store_1.ModuleActivationStore();
97
+ }
98
+ load(...modules) {
99
+ const getHelpers = this._getContainerModuleHelpersFactory();
100
+ for (const currentModule of modules) {
101
+ const containerModuleHelpers = getHelpers(currentModule.id);
102
+ currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction, containerModuleHelpers.unbindAsyncFunction, containerModuleHelpers.onActivationFunction, containerModuleHelpers.onDeactivationFunction);
103
+ }
104
+ }
105
+ async loadAsync(...modules) {
106
+ const getHelpers = this._getContainerModuleHelpersFactory();
107
+ for (const currentModule of modules) {
108
+ const containerModuleHelpers = getHelpers(currentModule.id);
109
+ await currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction, containerModuleHelpers.unbindAsyncFunction, containerModuleHelpers.onActivationFunction, containerModuleHelpers.onDeactivationFunction);
110
+ }
111
+ }
112
+ unload(...modules) {
113
+ modules.forEach((module) => {
114
+ const deactivations = this._removeModuleBindings(module.id);
115
+ this._deactivateSingletons(deactivations);
116
+ this._removeModuleHandlers(module.id);
117
+ });
118
+ }
119
+ async unloadAsync(...modules) {
120
+ for (const module of modules) {
121
+ const deactivations = this._removeModuleBindings(module.id);
122
+ await this._deactivateSingletonsAsync(deactivations);
123
+ this._removeModuleHandlers(module.id);
124
+ }
125
+ }
126
+ // Registers a type binding
127
+ bind(serviceIdentifier) {
128
+ const scope = this.options.defaultScope || literal_types_1.BindingScopeEnum.Transient;
129
+ const binding = new binding_1.Binding(serviceIdentifier, scope);
130
+ this._bindingDictionary.add(serviceIdentifier, binding);
131
+ return new binding_to_syntax_1.BindingToSyntax(binding);
132
+ }
133
+ rebind(serviceIdentifier) {
134
+ this.unbind(serviceIdentifier);
135
+ return this.bind(serviceIdentifier);
136
+ }
137
+ async rebindAsync(serviceIdentifier) {
138
+ await this.unbindAsync(serviceIdentifier);
139
+ return this.bind(serviceIdentifier);
140
+ }
141
+ // Removes a type binding from the registry by its key
142
+ unbind(serviceIdentifier) {
143
+ if (this._bindingDictionary.hasKey(serviceIdentifier)) {
144
+ const bindings = this._bindingDictionary.get(serviceIdentifier);
145
+ this._deactivateSingletons(bindings);
146
+ }
147
+ this._removeServiceFromDictionary(serviceIdentifier);
148
+ }
149
+ async unbindAsync(serviceIdentifier) {
150
+ if (this._bindingDictionary.hasKey(serviceIdentifier)) {
151
+ const bindings = this._bindingDictionary.get(serviceIdentifier);
152
+ await this._deactivateSingletonsAsync(bindings);
153
+ }
154
+ this._removeServiceFromDictionary(serviceIdentifier);
155
+ }
156
+ // Removes all the type bindings from the registry
157
+ unbindAll() {
158
+ this._bindingDictionary.traverse((_key, value) => {
159
+ this._deactivateSingletons(value);
160
+ });
161
+ this._bindingDictionary = new lookup_1.Lookup();
162
+ }
163
+ async unbindAllAsync() {
164
+ const promises = [];
165
+ this._bindingDictionary.traverse((_key, value) => {
166
+ promises.push(this._deactivateSingletonsAsync(value));
167
+ });
168
+ await Promise.all(promises);
169
+ this._bindingDictionary = new lookup_1.Lookup();
170
+ }
171
+ onActivation(serviceIdentifier, onActivation) {
172
+ this._activations.add(serviceIdentifier, onActivation);
173
+ }
174
+ onDeactivation(serviceIdentifier, onDeactivation) {
175
+ this._deactivations.add(serviceIdentifier, onDeactivation);
176
+ }
177
+ // Allows to check if there are bindings available for serviceIdentifier
178
+ isBound(serviceIdentifier) {
179
+ let bound = this._bindingDictionary.hasKey(serviceIdentifier);
180
+ if (!bound && this.parent) {
181
+ bound = this.parent.isBound(serviceIdentifier);
182
+ }
183
+ return bound;
184
+ }
185
+ // check binding dependency only in current container
186
+ isCurrentBound(serviceIdentifier) {
187
+ return this._bindingDictionary.hasKey(serviceIdentifier);
188
+ }
189
+ isBoundNamed(serviceIdentifier, named) {
190
+ return this.isBoundTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
191
+ }
192
+ // Check if a binding with a complex constraint is available without throwing a error. Ancestors are also verified.
193
+ isBoundTagged(serviceIdentifier, key, value) {
194
+ let bound = false;
195
+ // verify if there are bindings available for serviceIdentifier on current binding dictionary
196
+ if (this._bindingDictionary.hasKey(serviceIdentifier)) {
197
+ const bindings = this._bindingDictionary.get(serviceIdentifier);
198
+ const request = (0, planner_1.createMockRequest)(this, serviceIdentifier, key, value);
199
+ bound = bindings.some((b) => b.constraint(request));
200
+ }
201
+ // verify if there is a parent container that could solve the request
202
+ if (!bound && this.parent) {
203
+ bound = this.parent.isBoundTagged(serviceIdentifier, key, value);
204
+ }
205
+ return bound;
206
+ }
207
+ snapshot() {
208
+ this._snapshots.push(container_snapshot_1.ContainerSnapshot.of(this._bindingDictionary.clone(), this._middleware, this._activations.clone(), this._deactivations.clone(), this._moduleActivationStore.clone()));
209
+ }
210
+ restore() {
211
+ const snapshot = this._snapshots.pop();
212
+ if (snapshot === undefined) {
213
+ throw new Error(ERROR_MSGS.NO_MORE_SNAPSHOTS_AVAILABLE);
214
+ }
215
+ this._bindingDictionary = snapshot.bindings;
216
+ this._activations = snapshot.activations;
217
+ this._deactivations = snapshot.deactivations;
218
+ this._middleware = snapshot.middleware;
219
+ this._moduleActivationStore = snapshot.moduleActivationStore;
220
+ }
221
+ createChild(containerOptions) {
222
+ const child = new Container(containerOptions || this.options);
223
+ child.parent = this;
224
+ return child;
225
+ }
226
+ applyMiddleware(...middlewares) {
227
+ const initial = this._middleware
228
+ ? this._middleware
229
+ : this._planAndResolve();
230
+ this._middleware = middlewares.reduce((prev, curr) => curr(prev), initial);
231
+ }
232
+ applyCustomMetadataReader(metadataReader) {
233
+ this._metadataReader = metadataReader;
234
+ }
235
+ // Resolves a dependency by its runtime identifier
236
+ // The runtime identifier must be associated with only one binding
237
+ // use getAll when the runtime identifier is associated with multiple bindings
238
+ get(serviceIdentifier) {
239
+ const getArgs = this._getNotAllArgs(serviceIdentifier, false);
240
+ return this._getButThrowIfAsync(getArgs);
241
+ }
242
+ async getAsync(serviceIdentifier) {
243
+ const getArgs = this._getNotAllArgs(serviceIdentifier, false);
244
+ return this._get(getArgs);
245
+ }
246
+ getTagged(serviceIdentifier, key, value) {
247
+ const getArgs = this._getNotAllArgs(serviceIdentifier, false, key, value);
248
+ return this._getButThrowIfAsync(getArgs);
249
+ }
250
+ async getTaggedAsync(serviceIdentifier, key, value) {
251
+ const getArgs = this._getNotAllArgs(serviceIdentifier, false, key, value);
252
+ return this._get(getArgs);
253
+ }
254
+ getNamed(serviceIdentifier, named) {
255
+ return this.getTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
256
+ }
257
+ getNamedAsync(serviceIdentifier, named) {
258
+ return this.getTaggedAsync(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
259
+ }
260
+ // Resolves a dependency by its runtime identifier
261
+ // The runtime identifier can be associated with one or multiple bindings
262
+ getAll(serviceIdentifier) {
263
+ const getArgs = this._getAllArgs(serviceIdentifier);
264
+ return this._getButThrowIfAsync(getArgs);
265
+ }
266
+ getAllAsync(serviceIdentifier) {
267
+ const getArgs = this._getAllArgs(serviceIdentifier);
268
+ return this._getAll(getArgs);
269
+ }
270
+ getAllTagged(serviceIdentifier, key, value) {
271
+ const getArgs = this._getNotAllArgs(serviceIdentifier, true, key, value);
272
+ return this._getButThrowIfAsync(getArgs);
273
+ }
274
+ getAllTaggedAsync(serviceIdentifier, key, value) {
275
+ const getArgs = this._getNotAllArgs(serviceIdentifier, true, key, value);
276
+ return this._getAll(getArgs);
277
+ }
278
+ getAllNamed(serviceIdentifier, named) {
279
+ return this.getAllTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
280
+ }
281
+ getAllNamedAsync(serviceIdentifier, named) {
282
+ return this.getAllTaggedAsync(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
283
+ }
284
+ resolve(constructorFunction) {
285
+ const isBound = this.isBound(constructorFunction);
286
+ if (!isBound) {
287
+ this.bind(constructorFunction).toSelf();
288
+ }
289
+ const resolved = this.get(constructorFunction);
290
+ if (!isBound) {
291
+ this.unbind(constructorFunction);
292
+ }
293
+ return resolved;
294
+ }
295
+ _preDestroy(constructor, instance) {
296
+ if (Reflect.hasMetadata(METADATA_KEY.PRE_DESTROY, constructor)) {
297
+ const data = Reflect.getMetadata(METADATA_KEY.PRE_DESTROY, constructor);
298
+ return instance[data.value]?.();
299
+ }
300
+ }
301
+ _removeModuleHandlers(moduleId) {
302
+ const moduleActivationsHandlers = this._moduleActivationStore.remove(moduleId);
303
+ this._activations.removeIntersection(moduleActivationsHandlers.onActivations);
304
+ this._deactivations.removeIntersection(moduleActivationsHandlers.onDeactivations);
305
+ }
306
+ _removeModuleBindings(moduleId) {
307
+ return this._bindingDictionary.removeByCondition((binding) => binding.moduleId === moduleId);
308
+ }
309
+ _deactivate(binding, instance) {
310
+ const constructor = Object.getPrototypeOf(instance).constructor;
311
+ try {
312
+ if (this._deactivations.hasKey(binding.serviceIdentifier)) {
313
+ const result = this._deactivateContainer(instance, this._deactivations.get(binding.serviceIdentifier).values());
314
+ if ((0, async_1.isPromise)(result)) {
315
+ return this._handleDeactivationError(result.then(() => this._propagateContainerDeactivationThenBindingAndPreDestroyAsync(binding, instance, constructor)), constructor);
316
+ }
317
+ }
318
+ const propagateDeactivationResult = this._propagateContainerDeactivationThenBindingAndPreDestroy(binding, instance, constructor);
319
+ if ((0, async_1.isPromise)(propagateDeactivationResult)) {
320
+ return this._handleDeactivationError(propagateDeactivationResult, constructor);
321
+ }
322
+ }
323
+ catch (ex) {
324
+ if (ex instanceof Error) {
325
+ throw new Error(ERROR_MSGS.ON_DEACTIVATION_ERROR(constructor.name, ex.message));
326
+ }
327
+ }
328
+ }
329
+ async _handleDeactivationError(asyncResult, constructor) {
330
+ try {
331
+ await asyncResult;
332
+ }
333
+ catch (ex) {
334
+ if (ex instanceof Error) {
335
+ throw new Error(ERROR_MSGS.ON_DEACTIVATION_ERROR(constructor.name, ex.message));
336
+ }
337
+ }
338
+ }
339
+ _deactivateContainer(instance, deactivationsIterator) {
340
+ let deactivation = deactivationsIterator.next();
341
+ while (deactivation.value) {
342
+ const result = deactivation.value(instance);
343
+ if ((0, async_1.isPromise)(result)) {
344
+ return result.then(() => this._deactivateContainerAsync(instance, deactivationsIterator));
345
+ }
346
+ deactivation = deactivationsIterator.next();
347
+ }
348
+ }
349
+ async _deactivateContainerAsync(instance, deactivationsIterator) {
350
+ let deactivation = deactivationsIterator.next();
351
+ while (deactivation.value) {
352
+ await deactivation.value(instance);
353
+ deactivation = deactivationsIterator.next();
354
+ }
355
+ }
356
+ _getContainerModuleHelpersFactory() {
357
+ const setModuleId = (bindingToSyntax, moduleId) => {
358
+ // TODO: Implement an internal type `_BindingToSyntax<T>` wherein this member
359
+ // can be public. Let `BindingToSyntax<T>` be the presentational type that
360
+ // depends on it, and does not expose this member as public.
361
+ bindingToSyntax._binding.moduleId = moduleId;
362
+ };
363
+ const getBindFunction = (moduleId) => (serviceIdentifier) => {
364
+ const bindingToSyntax = this.bind(serviceIdentifier);
365
+ setModuleId(bindingToSyntax, moduleId);
366
+ return bindingToSyntax;
367
+ };
368
+ const getUnbindFunction = () => (serviceIdentifier) => {
369
+ return this.unbind(serviceIdentifier);
370
+ };
371
+ const getUnbindAsyncFunction = () => (serviceIdentifier) => {
372
+ return this.unbindAsync(serviceIdentifier);
373
+ };
374
+ const getIsboundFunction = () => (serviceIdentifier) => {
375
+ return this.isBound(serviceIdentifier);
376
+ };
377
+ const getRebindFunction = (moduleId) => (serviceIdentifier) => {
378
+ const bindingToSyntax = this.rebind(serviceIdentifier);
379
+ setModuleId(bindingToSyntax, moduleId);
380
+ return bindingToSyntax;
381
+ };
382
+ const getOnActivationFunction = (moduleId) => (serviceIdentifier, onActivation) => {
383
+ this._moduleActivationStore.addActivation(moduleId, serviceIdentifier, onActivation);
384
+ this.onActivation(serviceIdentifier, onActivation);
385
+ };
386
+ const getOnDeactivationFunction = (moduleId) => (serviceIdentifier, onDeactivation) => {
387
+ this._moduleActivationStore.addDeactivation(moduleId, serviceIdentifier, onDeactivation);
388
+ this.onDeactivation(serviceIdentifier, onDeactivation);
389
+ };
390
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
391
+ return (mId) => ({
392
+ bindFunction: getBindFunction(mId),
393
+ isboundFunction: getIsboundFunction(),
394
+ onActivationFunction: getOnActivationFunction(mId),
395
+ onDeactivationFunction: getOnDeactivationFunction(mId),
396
+ rebindFunction: getRebindFunction(mId),
397
+ unbindFunction: getUnbindFunction(),
398
+ unbindAsyncFunction: getUnbindAsyncFunction(),
399
+ });
400
+ }
401
+ _getAll(getArgs) {
402
+ return Promise.all(this._get(getArgs));
403
+ }
404
+ // Prepares arguments required for resolution and
405
+ // delegates resolution to _middleware if available
406
+ // otherwise it delegates resolution to _planAndResolve
407
+ _get(getArgs) {
408
+ const planAndResolveArgs = {
409
+ ...getArgs,
410
+ contextInterceptor: (context) => context,
411
+ targetType: literal_types_1.TargetTypeEnum.Variable,
412
+ };
413
+ if (this._middleware) {
414
+ const middlewareResult = this._middleware(planAndResolveArgs);
415
+ if (middlewareResult === undefined || middlewareResult === null) {
416
+ throw new Error(ERROR_MSGS.INVALID_MIDDLEWARE_RETURN);
417
+ }
418
+ return middlewareResult;
419
+ }
420
+ return this._planAndResolve()(planAndResolveArgs);
421
+ }
422
+ _getButThrowIfAsync(getArgs) {
423
+ const result = this._get(getArgs);
424
+ if ((0, async_1.isPromiseOrContainsPromise)(result)) {
425
+ throw new Error(ERROR_MSGS.LAZY_IN_SYNC(getArgs.serviceIdentifier));
426
+ }
427
+ return result;
428
+ }
429
+ _getAllArgs(serviceIdentifier) {
430
+ const getAllArgs = {
431
+ avoidConstraints: true,
432
+ isMultiInject: true,
433
+ serviceIdentifier,
434
+ };
435
+ return getAllArgs;
436
+ }
437
+ _getNotAllArgs(serviceIdentifier, isMultiInject, key, value) {
438
+ const getNotAllArgs = {
439
+ avoidConstraints: false,
440
+ isMultiInject,
441
+ serviceIdentifier,
442
+ key,
443
+ value,
444
+ };
445
+ return getNotAllArgs;
446
+ }
447
+ // Planner creates a plan and Resolver resolves a plan
448
+ // one of the jobs of the Container is to links the Planner
449
+ // with the Resolver and that is what this function is about
450
+ _planAndResolve() {
451
+ return (args) => {
452
+ // create a plan
453
+ let context = (0, planner_1.plan)(this._metadataReader, this, args.isMultiInject, args.targetType, args.serviceIdentifier, args.key, args.value, args.avoidConstraints);
454
+ // apply context interceptor
455
+ context = args.contextInterceptor(context);
456
+ // resolve plan
457
+ const result = (0, resolver_1.resolve)(context);
458
+ return result;
459
+ };
460
+ }
461
+ _deactivateIfSingleton(binding) {
462
+ if (!binding.activated) {
463
+ return;
464
+ }
465
+ if ((0, async_1.isPromise)(binding.cache)) {
466
+ return binding.cache.then((resolved) => this._deactivate(binding, resolved));
467
+ }
468
+ return this._deactivate(binding, binding.cache);
469
+ }
470
+ _deactivateSingletons(bindings) {
471
+ for (const binding of bindings) {
472
+ const result = this._deactivateIfSingleton(binding);
473
+ if ((0, async_1.isPromise)(result)) {
474
+ throw new Error(ERROR_MSGS.ASYNC_UNBIND_REQUIRED);
475
+ }
476
+ }
477
+ }
478
+ async _deactivateSingletonsAsync(bindings) {
479
+ await Promise.all(bindings.map((b) => this._deactivateIfSingleton(b)));
480
+ }
481
+ _propagateContainerDeactivationThenBindingAndPreDestroy(binding, instance, constructor) {
482
+ if (this.parent) {
483
+ return this._deactivate.bind(this.parent)(binding, instance);
484
+ }
485
+ else {
486
+ return this._bindingDeactivationAndPreDestroy(binding, instance, constructor);
487
+ }
488
+ }
489
+ async _propagateContainerDeactivationThenBindingAndPreDestroyAsync(binding, instance, constructor) {
490
+ if (this.parent) {
491
+ await this._deactivate.bind(this.parent)(binding, instance);
492
+ }
493
+ else {
494
+ await this._bindingDeactivationAndPreDestroyAsync(binding, instance, constructor);
495
+ }
496
+ }
497
+ _removeServiceFromDictionary(serviceIdentifier) {
498
+ try {
499
+ this._bindingDictionary.remove(serviceIdentifier);
500
+ }
501
+ catch (e) {
502
+ throw new Error(`${ERROR_MSGS.CANNOT_UNBIND} ${(0, serialization_1.getServiceIdentifierAsString)(serviceIdentifier)}`);
503
+ }
504
+ }
505
+ _bindingDeactivationAndPreDestroy(binding, instance, constructor) {
506
+ if (typeof binding.onDeactivation === "function") {
507
+ const result = binding.onDeactivation(instance);
508
+ if ((0, async_1.isPromise)(result)) {
509
+ return result.then(() => this._preDestroy(constructor, instance));
510
+ }
511
+ }
512
+ return this._preDestroy(constructor, instance);
513
+ }
514
+ async _bindingDeactivationAndPreDestroyAsync(binding, instance, constructor) {
515
+ if (typeof binding.onDeactivation === "function") {
516
+ await binding.onDeactivation(instance);
517
+ }
518
+ await this._preDestroy(constructor, instance);
519
+ }
520
+ }
521
+ exports.Container = Container;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AsyncContainerModule = exports.ContainerModule = void 0;
4
+ const id_1 = require("../utils/id");
5
+ class ContainerModule {
6
+ constructor(registry) {
7
+ this.id = (0, id_1.id)();
8
+ this.registry = registry;
9
+ }
10
+ }
11
+ exports.ContainerModule = ContainerModule;
12
+ class AsyncContainerModule {
13
+ constructor(registry) {
14
+ this.id = (0, id_1.id)();
15
+ this.registry = registry;
16
+ }
17
+ }
18
+ exports.AsyncContainerModule = AsyncContainerModule;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContainerSnapshot = void 0;
4
+ class ContainerSnapshot {
5
+ static of(bindings, middleware, activations, deactivations, moduleActivationStore) {
6
+ const snapshot = new ContainerSnapshot();
7
+ snapshot.bindings = bindings;
8
+ snapshot.middleware = middleware;
9
+ snapshot.deactivations = deactivations;
10
+ snapshot.activations = activations;
11
+ snapshot.moduleActivationStore = moduleActivationStore;
12
+ return snapshot;
13
+ }
14
+ }
15
+ exports.ContainerSnapshot = ContainerSnapshot;
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.Lookup = void 0;
27
+ const ERROR_MSGS = __importStar(require("../constants/error_msgs"));
28
+ const clonable_1 = require("../utils/clonable");
29
+ class Lookup {
30
+ constructor() {
31
+ this._map = new Map();
32
+ }
33
+ getMap() {
34
+ return this._map;
35
+ }
36
+ // adds a new entry to _map
37
+ add(serviceIdentifier, value) {
38
+ if (serviceIdentifier === null || serviceIdentifier === undefined) {
39
+ throw new Error(ERROR_MSGS.NULL_ARGUMENT);
40
+ }
41
+ if (value === null || value === undefined) {
42
+ throw new Error(ERROR_MSGS.NULL_ARGUMENT);
43
+ }
44
+ const entry = this._map.get(serviceIdentifier);
45
+ if (entry !== undefined) {
46
+ entry.push(value);
47
+ }
48
+ else {
49
+ this._map.set(serviceIdentifier, [value]);
50
+ }
51
+ }
52
+ // gets the value of a entry by its key (serviceIdentifier)
53
+ get(serviceIdentifier) {
54
+ if (serviceIdentifier === null || serviceIdentifier === undefined) {
55
+ throw new Error(ERROR_MSGS.NULL_ARGUMENT);
56
+ }
57
+ const entry = this._map.get(serviceIdentifier);
58
+ if (entry !== undefined) {
59
+ return entry;
60
+ }
61
+ else {
62
+ throw new Error(ERROR_MSGS.KEY_NOT_FOUND);
63
+ }
64
+ }
65
+ // removes a entry from _map by its key (serviceIdentifier)
66
+ remove(serviceIdentifier) {
67
+ if (serviceIdentifier === null || serviceIdentifier === undefined) {
68
+ throw new Error(ERROR_MSGS.NULL_ARGUMENT);
69
+ }
70
+ if (!this._map.delete(serviceIdentifier)) {
71
+ throw new Error(ERROR_MSGS.KEY_NOT_FOUND);
72
+ }
73
+ }
74
+ removeIntersection(lookup) {
75
+ this.traverse((serviceIdentifier, value) => {
76
+ const lookupActivations = lookup.hasKey(serviceIdentifier)
77
+ ? lookup.get(serviceIdentifier)
78
+ : undefined;
79
+ if (lookupActivations !== undefined) {
80
+ const filteredValues = value.filter((lookupValue) => !lookupActivations.some((moduleActivation) => lookupValue === moduleActivation));
81
+ this._setValue(serviceIdentifier, filteredValues);
82
+ }
83
+ });
84
+ }
85
+ removeByCondition(condition) {
86
+ const removals = [];
87
+ this._map.forEach((entries, key) => {
88
+ const updatedEntries = [];
89
+ for (const entry of entries) {
90
+ const remove = condition(entry);
91
+ if (remove) {
92
+ removals.push(entry);
93
+ }
94
+ else {
95
+ updatedEntries.push(entry);
96
+ }
97
+ }
98
+ this._setValue(key, updatedEntries);
99
+ });
100
+ return removals;
101
+ }
102
+ // returns true if _map contains a key (serviceIdentifier)
103
+ hasKey(serviceIdentifier) {
104
+ if (serviceIdentifier === null || serviceIdentifier === undefined) {
105
+ throw new Error(ERROR_MSGS.NULL_ARGUMENT);
106
+ }
107
+ return this._map.has(serviceIdentifier);
108
+ }
109
+ // returns a new Lookup instance; note: this is not a deep clone, only Lookup related data structure (dictionary) is
110
+ // cloned, content remains the same
111
+ clone() {
112
+ const copy = new Lookup();
113
+ this._map.forEach((value, key) => {
114
+ value.forEach((b) => copy.add(key, (0, clonable_1.isClonable)(b) ? b.clone() : b));
115
+ });
116
+ return copy;
117
+ }
118
+ traverse(func) {
119
+ this._map.forEach((value, key) => {
120
+ func(key, value);
121
+ });
122
+ }
123
+ _setValue(serviceIdentifier, value) {
124
+ if (value.length > 0) {
125
+ this._map.set(serviceIdentifier, value);
126
+ }
127
+ else {
128
+ this._map.delete(serviceIdentifier);
129
+ }
130
+ }
131
+ }
132
+ exports.Lookup = Lookup;