@rsdk/core 1.0.12 → 2.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 (248) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/app/platform.app.d.ts +1 -1
  3. package/dist/app/platform.app.js +3 -25
  4. package/dist/app/platform.app.js.map +1 -1
  5. package/dist/app-metadata/app-metadata.module.js.map +1 -1
  6. package/dist/app-metadata/exceptions/app-name-validation.exception.js.map +1 -1
  7. package/dist/config/additional-source/additional-source.initializer.d.ts +6 -2
  8. package/dist/config/additional-source/additional-source.initializer.js +24 -18
  9. package/dist/config/additional-source/additional-source.initializer.js.map +1 -1
  10. package/dist/config/additional-source/additional-source.module.d.ts +1 -1
  11. package/dist/config/additional-source/additional-source.module.js +3 -1
  12. package/dist/config/additional-source/additional-source.module.js.map +1 -1
  13. package/dist/config/config-reload.indicator.d.ts +3 -2
  14. package/dist/config/config-reload.indicator.js +4 -3
  15. package/dist/config/config-reload.indicator.js.map +1 -1
  16. package/dist/config/config.abstract.d.ts +3 -2
  17. package/dist/config/config.abstract.js +3 -3
  18. package/dist/config/config.abstract.js.map +1 -1
  19. package/dist/config/config.module.d.ts +0 -81
  20. package/dist/config/config.module.js +26 -203
  21. package/dist/config/config.module.js.map +1 -1
  22. package/dist/config/context/config.context.d.ts +75 -0
  23. package/dist/config/context/config.context.js +159 -0
  24. package/dist/config/context/config.context.js.map +1 -0
  25. package/dist/config/context/module.d.ts +5 -0
  26. package/dist/config/context/module.js +26 -0
  27. package/dist/config/context/module.js.map +1 -0
  28. package/dist/config/exceptions/config-not-bootstrapped.exception.js.map +1 -1
  29. package/dist/config/exceptions/property.exception.d.ts +9 -2
  30. package/dist/config/exceptions/property.exception.js +4 -6
  31. package/dist/config/exceptions/property.exception.js.map +1 -1
  32. package/dist/config/index.d.ts +1 -0
  33. package/dist/config/index.js +3 -1
  34. package/dist/config/index.js.map +1 -1
  35. package/dist/config/metadata/config-metadata.provider.d.ts +21 -0
  36. package/dist/config/metadata/config-metadata.provider.js +37 -0
  37. package/dist/config/metadata/config-metadata.provider.js.map +1 -0
  38. package/dist/config/metadata/config-metadata.registry.d.ts +1 -9
  39. package/dist/config/metadata/config-metadata.registry.js +9 -28
  40. package/dist/config/metadata/config-metadata.registry.js.map +1 -1
  41. package/dist/config/metadata/constants.d.ts +3 -0
  42. package/dist/config/metadata/constants.js +7 -0
  43. package/dist/config/metadata/constants.js.map +1 -0
  44. package/dist/config/metadata/decorators/declare-property.decorator.js +2 -2
  45. package/dist/config/metadata/decorators/declare-property.decorator.js.map +1 -1
  46. package/dist/config/metadata/decorators/inject-property.decorator.d.ts +1 -1
  47. package/dist/config/metadata/decorators/inject-property.decorator.js +1 -1
  48. package/dist/config/metadata/exceptions/duplicate-property.exception.js.map +1 -1
  49. package/dist/config/metadata/exceptions/duplicate-section.exception.js.map +1 -1
  50. package/dist/config/metadata/exceptions/duplicate-source.exception.js.map +1 -1
  51. package/dist/config/metadata/types.d.ts +16 -0
  52. package/dist/config/metadata/types.js +3 -0
  53. package/dist/config/metadata/types.js.map +1 -0
  54. package/dist/config/reload/config-reload.events.d.ts +0 -2
  55. package/dist/config/reload/config-reload.events.js +0 -8
  56. package/dist/config/reload/config-reload.events.js.map +1 -1
  57. package/dist/config/sources/base/reloadable-config-source.abstract.d.ts +3 -2
  58. package/dist/config/sources/base/reloadable-config-source.abstract.js +3 -3
  59. package/dist/config/sources/base/reloadable-config-source.abstract.js.map +1 -1
  60. package/dist/config/sources/exceptions/config-source-di.exception.js.map +1 -1
  61. package/dist/config/sources/implementations/json-file.source.js.map +1 -1
  62. package/dist/config/sources/implementations/relodable-json-file.source.d.ts +3 -1
  63. package/dist/config/sources/implementations/relodable-json-file.source.js +6 -3
  64. package/dist/config/sources/implementations/relodable-json-file.source.js.map +1 -1
  65. package/dist/config/vars.class.d.ts +1 -1
  66. package/dist/config/vars.class.js +6 -6
  67. package/dist/config/vars.class.js.map +1 -1
  68. package/dist/context.aggregator.d.ts +21 -0
  69. package/dist/context.aggregator.js +53 -0
  70. package/dist/context.aggregator.js.map +1 -0
  71. package/dist/exceptions/base/platform-exception.absract.d.ts +2 -2
  72. package/dist/exceptions/base/platform-exception.absract.js +4 -1
  73. package/dist/exceptions/base/platform-exception.absract.js.map +1 -1
  74. package/dist/exceptions/implementations/bootstrap/double-init.exception.js.map +1 -1
  75. package/dist/exceptions/implementations/bootstrap/duplicate-protocol.exception.js.map +1 -1
  76. package/dist/exceptions/implementations/bootstrap/no-http.exception.js.map +1 -1
  77. package/dist/exceptions/implementations/bootstrap/no-init.exception.js.map +1 -1
  78. package/dist/exceptions/implementations/bootstrap/no-matching-transport.exception.js.map +1 -1
  79. package/dist/exceptions/implementations/bootstrap/sequence.exception.js.map +1 -1
  80. package/dist/exceptions/implementations/bootstrap/symbol-key-decoration.exception.js.map +1 -1
  81. package/dist/exceptions/implementations/bootstrap/unknown-bootstrap.exception.js.map +1 -1
  82. package/dist/exceptions/implementations/pipeline/authentication.exception.js.map +1 -1
  83. package/dist/exceptions/implementations/pipeline/conflict.exception.js.map +1 -1
  84. package/dist/exceptions/implementations/pipeline/duplicate-entity.exception.js.map +1 -1
  85. package/dist/exceptions/implementations/pipeline/input.exception.js.map +1 -1
  86. package/dist/exceptions/implementations/pipeline/internal.exception.js.map +1 -1
  87. package/dist/exceptions/implementations/pipeline/not-allowed.exception.js.map +1 -1
  88. package/dist/exceptions/implementations/pipeline/not-found.exception.js.map +1 -1
  89. package/dist/exceptions/implementations/pipeline/timeout.exception.js.map +1 -1
  90. package/dist/exceptions.handling/global-exceptions.config.js.map +1 -1
  91. package/dist/exceptions.handling/global-exceptions.filter.js.map +1 -1
  92. package/dist/exceptions.handling/global-exceptions.module.js.map +1 -1
  93. package/dist/health/autodoc/heath.autodoc-resolver.d.ts +5 -15
  94. package/dist/health/autodoc/heath.autodoc-resolver.js +11 -13
  95. package/dist/health/autodoc/heath.autodoc-resolver.js.map +1 -1
  96. package/dist/health/exceptions/health-check.exception.js.map +1 -1
  97. package/dist/health/health.const.d.ts +1 -0
  98. package/dist/health/health.const.js +2 -1
  99. package/dist/health/health.const.js.map +1 -1
  100. package/dist/health/health.module.js.map +1 -1
  101. package/dist/health/health.service.d.ts +6 -2
  102. package/dist/health/health.service.js +19 -6
  103. package/dist/health/health.service.js.map +1 -1
  104. package/dist/health/metadata/constants.d.ts +1 -0
  105. package/dist/health/metadata/constants.js +5 -0
  106. package/dist/health/metadata/constants.js.map +1 -0
  107. package/dist/health/metadata/indicator.decorator.js +2 -12
  108. package/dist/health/metadata/indicator.decorator.js.map +1 -1
  109. package/dist/health/metadata/indicators.registry.d.ts +0 -7
  110. package/dist/health/metadata/indicators.registry.js +6 -14
  111. package/dist/health/metadata/indicators.registry.js.map +1 -1
  112. package/dist/health/metadata/types.d.ts +7 -0
  113. package/dist/health/metadata/types.js +3 -0
  114. package/dist/health/metadata/types.js.map +1 -0
  115. package/dist/index.d.ts +8 -1
  116. package/dist/index.js +13 -7
  117. package/dist/index.js.map +1 -1
  118. package/dist/logging/decorators/inject-logger.decorator.js +5 -3
  119. package/dist/logging/decorators/inject-logger.decorator.js.map +1 -1
  120. package/dist/logging/global-logger-provider.generator.d.ts +7 -0
  121. package/dist/logging/global-logger-provider.generator.js +22 -0
  122. package/dist/logging/global-logger-provider.generator.js.map +1 -0
  123. package/dist/logging/index.d.ts +2 -0
  124. package/dist/logging/index.js +3 -0
  125. package/dist/logging/index.js.map +1 -1
  126. package/dist/logging/logging.config.js +1 -1
  127. package/dist/logging/logging.config.js.map +1 -1
  128. package/dist/logging/logging.module.d.ts +5 -3
  129. package/dist/logging/logging.module.js +25 -13
  130. package/dist/logging/logging.module.js.map +1 -1
  131. package/dist/logging/metadata/constants.d.ts +1 -0
  132. package/dist/logging/metadata/constants.js +5 -0
  133. package/dist/logging/metadata/constants.js.map +1 -0
  134. package/dist/logging/types.d.ts +6 -2
  135. package/dist/metrics/index.d.ts +1 -1
  136. package/dist/metrics/index.js +3 -3
  137. package/dist/metrics/index.js.map +1 -1
  138. package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.d.ts +6 -7
  139. package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.js +8 -11
  140. package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.js.map +1 -1
  141. package/dist/metrics/metadata/constants.d.ts +1 -0
  142. package/dist/metrics/metadata/constants.js +5 -0
  143. package/dist/metrics/metadata/constants.js.map +1 -0
  144. package/dist/metrics/metadata/index.d.ts +0 -1
  145. package/dist/metrics/metadata/index.js +0 -3
  146. package/dist/metrics/metadata/index.js.map +1 -1
  147. package/dist/metrics/metadata/metrics.registry.d.ts +0 -3
  148. package/dist/metrics/metadata/metrics.registry.js +9 -16
  149. package/dist/metrics/metadata/metrics.registry.js.map +1 -1
  150. package/dist/metrics/metadata/types.d.ts +2 -4
  151. package/dist/metrics/metric.storage.d.ts +8 -0
  152. package/dist/metrics/metric.storage.js +11 -0
  153. package/dist/metrics/metric.storage.js.map +1 -0
  154. package/dist/metrics/metrics.config.js.map +1 -1
  155. package/dist/metrics/metrics.module.d.ts +1 -1
  156. package/dist/metrics/metrics.module.js +27 -21
  157. package/dist/metrics/metrics.module.js.map +1 -1
  158. package/dist/platform.context.d.ts +5 -3
  159. package/dist/platform.context.js +20 -19
  160. package/dist/platform.context.js.map +1 -1
  161. package/dist/platform.module.d.ts +5 -4
  162. package/dist/platform.module.js +24 -13
  163. package/dist/platform.module.js.map +1 -1
  164. package/dist/rsdk-metadata/constants.d.ts +3 -0
  165. package/dist/rsdk-metadata/constants.js +5 -0
  166. package/dist/rsdk-metadata/constants.js.map +1 -0
  167. package/dist/rsdk-metadata/rsdk-metadata.global-module.d.ts +6 -0
  168. package/dist/rsdk-metadata/rsdk-metadata.global-module.js +31 -0
  169. package/dist/rsdk-metadata/rsdk-metadata.global-module.js.map +1 -0
  170. package/dist/tracing/services/instrumentation.service.js.map +1 -1
  171. package/dist/tracing/services/metadata.scanner.js.map +1 -1
  172. package/dist/tracing/tracing.config.js.map +1 -1
  173. package/dist/tracing/tracing.module.js.map +1 -1
  174. package/dist/transport/transport.module.d.ts +1 -0
  175. package/dist/transport/transport.module.js +8 -2
  176. package/dist/transport/transport.module.js.map +1 -1
  177. package/dist/types/context-aggregated.d.ts +8 -0
  178. package/dist/types/context-aggregated.js +3 -0
  179. package/dist/types/context-aggregated.js.map +1 -0
  180. package/dist/types/options.d.ts +6 -6
  181. package/dist/types/transports.d.ts +10 -3
  182. package/dist/types/transports.js.map +1 -1
  183. package/dist/unhandled-rejection.handler.d.ts +1 -0
  184. package/dist/unhandled-rejection.handler.js +24 -0
  185. package/dist/unhandled-rejection.handler.js.map +1 -0
  186. package/package.json +8 -7
  187. package/src/app/platform.app.ts +6 -32
  188. package/src/config/additional-source/additional-source.initializer.ts +34 -25
  189. package/src/config/additional-source/additional-source.module.ts +5 -2
  190. package/src/config/config-reload.indicator.ts +3 -3
  191. package/src/config/config.abstract.ts +2 -3
  192. package/src/config/config.module.ts +23 -225
  193. package/src/config/context/config.context.ts +209 -0
  194. package/src/config/context/module.ts +25 -0
  195. package/src/config/exceptions/property.exception.ts +11 -6
  196. package/src/config/index.ts +1 -0
  197. package/src/config/metadata/config-metadata.provider.ts +79 -0
  198. package/src/config/metadata/config-metadata.registry.ts +36 -41
  199. package/src/config/metadata/constants.ts +6 -0
  200. package/src/config/metadata/decorators/declare-property.decorator.ts +2 -2
  201. package/src/config/metadata/decorators/inject-property.decorator.ts +1 -1
  202. package/src/config/metadata/types.ts +22 -0
  203. package/src/config/reload/config-reload.events.ts +1 -13
  204. package/src/config/sources/base/reloadable-config-source.abstract.ts +2 -3
  205. package/src/config/sources/implementations/relodable-json-file.source.ts +6 -2
  206. package/src/config/vars.class.ts +9 -7
  207. package/src/context.aggregator.ts +62 -0
  208. package/src/exceptions/base/platform-exception.absract.ts +8 -3
  209. package/src/health/autodoc/heath.autodoc-resolver.ts +15 -18
  210. package/src/health/health.const.ts +2 -0
  211. package/src/health/health.service.ts +23 -4
  212. package/src/health/metadata/constants.ts +1 -0
  213. package/src/health/metadata/indicator.decorator.ts +2 -18
  214. package/src/health/metadata/indicators.registry.ts +16 -23
  215. package/src/health/metadata/types.ts +9 -0
  216. package/src/index.ts +29 -12
  217. package/src/logging/decorators/inject-logger.decorator.ts +5 -4
  218. package/src/logging/global-logger-provider.generator.ts +28 -0
  219. package/src/logging/index.ts +2 -0
  220. package/src/logging/logging.config.ts +2 -1
  221. package/src/logging/logging.module.ts +42 -16
  222. package/src/logging/metadata/constants.ts +1 -0
  223. package/src/logging/types.ts +6 -2
  224. package/src/metrics/index.ts +1 -1
  225. package/src/metrics/metadata/autodoc/metrics.autodoc-resolver.ts +13 -9
  226. package/src/metrics/metadata/constants.ts +1 -0
  227. package/src/metrics/metadata/index.ts +0 -1
  228. package/src/metrics/metadata/metrics.registry.ts +19 -23
  229. package/src/metrics/metadata/types.ts +2 -5
  230. package/src/metrics/metric.storage.ts +10 -0
  231. package/src/metrics/metrics.module.ts +32 -31
  232. package/src/platform.context.ts +32 -20
  233. package/src/platform.module.ts +18 -20
  234. package/src/rsdk-metadata/constants.ts +5 -0
  235. package/src/rsdk-metadata/rsdk-metadata.global-module.ts +34 -0
  236. package/src/transport/transport.module.ts +13 -1
  237. package/src/types/context-aggregated.ts +10 -0
  238. package/src/types/options.ts +6 -5
  239. package/src/types/transports.ts +15 -3
  240. package/src/unhandled-rejection.handler.ts +29 -0
  241. package/dist/health/index.d.ts +0 -7
  242. package/dist/health/index.js +0 -26
  243. package/dist/health/index.js.map +0 -1
  244. package/dist/health/metadata/index.d.ts +0 -2
  245. package/dist/health/metadata/index.js +0 -19
  246. package/dist/health/metadata/index.js.map +0 -1
  247. package/src/health/index.ts +0 -7
  248. package/src/health/metadata/index.ts +0 -2
@@ -1,16 +1,16 @@
1
1
  import { SELF_DECLARED_DEPS_METADATA } from '@nestjs/common/constants';
2
2
  import type { Constructor } from '@rsdk/common';
3
+ import { LoggerFactory } from '@rsdk/logging';
3
4
 
4
5
  import { APP_NAME } from '../../app-metadata/app-metadata.const';
5
6
  import { NoInitException } from '../../exceptions';
7
+ import type { ConfigContext } from '../context/config.context';
6
8
  import { ConfigPropertyMetadataNotFound } from '../exceptions';
7
9
  import { isPropertyToken } from '../metadata';
8
10
  import type { ConfigSource } from '../sources';
9
11
  import { ConfigSourceDIException, isReloadable } from '../sources';
10
12
  import type { RawValues } from '../types';
11
13
 
12
- import type { AdditionalSourceOptions } from './additional-source.module';
13
-
14
14
  /**
15
15
  * Содержит логику инициализации дополнительных источников конфигурации
16
16
  */
@@ -21,7 +21,12 @@ export class AdditionalSourceInitializer {
21
21
  */
22
22
  private initializePromise: Promise<void> | undefined;
23
23
 
24
- constructor(private options: AdditionalSourceOptions) {}
24
+ private logger = LoggerFactory.create(AdditionalSourceInitializer);
25
+
26
+ constructor(
27
+ private context: ConfigContext,
28
+ private options: Constructor<ConfigSource>[],
29
+ ) {}
25
30
 
26
31
  /**
27
32
  * Инициализирует дополнительные источники конфигурации
@@ -37,7 +42,7 @@ export class AdditionalSourceInitializer {
37
42
  if (this.initializePromise) {
38
43
  return this.initializePromise;
39
44
  }
40
- this.initializePromise = this.initializeAdditionalSources(this.options);
45
+ this.initializePromise = this.initializeAdditionalSources();
41
46
  return this.initializePromise;
42
47
  }
43
48
 
@@ -47,20 +52,23 @@ export class AdditionalSourceInitializer {
47
52
  * NOTE: standalone properties from env can be used to
48
53
  * configure additional sources
49
54
  */
50
- private async initializeAdditionalSources(
51
- options: AdditionalSourceOptions,
52
- ): Promise<void> {
55
+ private async initializeAdditionalSources(): Promise<void> {
56
+ const options = { sources: this.options };
53
57
  if (!options.sources || options.sources.length === 0) {
54
- options.logger.info('No additional sources configured');
58
+ this.logger.info('No additional sources configured');
55
59
  return;
56
60
  }
57
- const { sources, events, logger, vars } = options;
61
+ const { sources } = options;
62
+
63
+ const { events, vars } = this.context;
64
+
65
+ const logger = this.logger;
58
66
 
59
67
  logger.info('Initializing additional configuration sources');
60
68
 
61
69
  for (const ctor of sources) {
62
70
  // We should restore the order to initialize for our ctor init later
63
- const args = this.getConfigSourceArguments(options, ctor);
71
+ const args = this.getConfigSourceArguments(ctor);
64
72
 
65
73
  const source = new ctor(...args);
66
74
 
@@ -114,10 +122,7 @@ export class AdditionalSourceInitializer {
114
122
  * @param ctor
115
123
  * @private
116
124
  */
117
- private getConfigSourceArguments(
118
- options: AdditionalSourceOptions,
119
- ctor: Constructor<ConfigSource>,
120
- ): unknown[] {
125
+ private getConfigSourceArguments(ctor: Constructor<ConfigSource>): unknown[] {
121
126
  // Injectable config properties!
122
127
  const metadata = Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, ctor) as {
123
128
  index: number;
@@ -131,28 +136,32 @@ export class AdditionalSourceInitializer {
131
136
 
132
137
  const sortedMetadata = [...metadata].sort((a, b) => a.index - b.index);
133
138
 
134
- const { prefix, propertyMetadata, vars } = options;
135
- const injectables = new Map<unknown, unknown>().set(APP_NAME, prefix);
139
+ const injectables = new Map<unknown, unknown>().set(
140
+ APP_NAME,
141
+ this.context.prefix,
142
+ );
136
143
 
137
- const args = sortedMetadata.map((x) => {
138
- if (injectables.has(x.param)) {
139
- return injectables.get(x.param);
144
+ const args = sortedMetadata.map((metadata) => {
145
+ if (injectables.has(metadata.param)) {
146
+ return injectables.get(metadata.param);
140
147
  }
141
148
 
142
- if (!isPropertyToken(x.param)) {
143
- throw new ConfigSourceDIException(ctor, x.param);
149
+ if (!isPropertyToken(metadata.param)) {
150
+ throw new ConfigSourceDIException(ctor, metadata.param);
144
151
  }
145
152
 
146
- const propMeta = propertyMetadata.get(x.param);
153
+ const propMeta = this.context.standalonePropertyMetadata.get(
154
+ metadata.param,
155
+ );
147
156
  if (!propMeta) {
148
- throw new ConfigPropertyMetadataNotFound(x.param);
157
+ throw new ConfigPropertyMetadataNotFound(metadata.param);
149
158
  }
150
159
 
151
- const property = vars.extract(propMeta);
160
+ const property = this.context.vars.extract(propMeta);
152
161
  if (!property) {
153
162
  throw new NoInitException(
154
163
  'Config property',
155
- x.param as string,
164
+ metadata.param as string,
156
165
  'You probably should add @DeclareProperty decorator to source class.',
157
166
  );
158
167
  }
@@ -3,6 +3,7 @@ import type { Constructor } from '@rsdk/common';
3
3
  import type { ILogger } from '@rsdk/logging';
4
4
 
5
5
  import { ConfigReloadIndicator } from '../config-reload.indicator';
6
+ import { ConfigContext } from '../context/config.context';
6
7
  import type { PropertyToken } from '../metadata';
7
8
  import type { ReloadEvents } from '../reload';
8
9
  import type { ConfigSource } from '../sources';
@@ -16,7 +17,7 @@ import { AdditionalSourceInitializer } from './additional-source.initializer';
16
17
  * Инициализирует все `source` в хуке `onModuleInit`
17
18
  */
18
19
  export class AdditionalSourceModule {
19
- static forRoot(options: AdditionalSourceOptions): DynamicModule {
20
+ static forRoot(options: Constructor<ConfigSource>[]): DynamicModule {
20
21
  return {
21
22
  imports: [
22
23
  {
@@ -24,8 +25,10 @@ export class AdditionalSourceModule {
24
25
  module: AdditionalSourceModule,
25
26
  providers: [
26
27
  {
28
+ inject: [ConfigContext],
27
29
  provide: AdditionalSourceInitializer,
28
- useValue: new AdditionalSourceInitializer(options),
30
+ useFactory: (configContext: ConfigContext) =>
31
+ new AdditionalSourceInitializer(configContext, options),
29
32
  },
30
33
  ],
31
34
  exports: [AdditionalSourceInitializer],
@@ -1,7 +1,8 @@
1
1
  import { Injectable } from '@nestjs/common';
2
2
 
3
- import type { CheckDetails, HealthIndicator } from '../health';
3
+ import type { CheckDetails } from '../health/helpers';
4
4
  import { CheckResult } from '../health/helpers';
5
+ import type { HealthIndicator } from '../health/types';
5
6
 
6
7
  import type { Config } from './config.abstract';
7
8
  import { ReloadEvents } from './reload';
@@ -9,10 +10,9 @@ import type { ConfigSource } from './sources';
9
10
 
10
11
  @Injectable()
11
12
  export class ConfigReloadIndicator implements HealthIndicator {
12
- private events = ReloadEvents.getInstance();
13
13
  private errors = new Map<ConfigSource | Config, Error>();
14
14
 
15
- constructor() {
15
+ constructor(private events: ReloadEvents) {
16
16
  this.events
17
17
  .on('reload_failure', (source, err) => this.errors.set(source, err))
18
18
  .on('update_failure', (config, err) => this.errors.set(config, err))
@@ -3,7 +3,7 @@ import { intersection, isEqual } from 'lodash';
3
3
  import 'reflect-metadata';
4
4
 
5
5
  import { CONFIG_METADATA_KEY } from './metadata';
6
- import { ReloadEvents } from './reload';
6
+ import type { ReloadEvents } from './reload';
7
7
  import type { PropertyMetadata, SectionMetadata } from './types';
8
8
  import type { Vars } from './vars.class';
9
9
 
@@ -18,10 +18,9 @@ export class Config {
18
18
  * Keys are prefixed and sources are added.
19
19
  */
20
20
  private readonly propertiesMetadata: Record<string, PropertyMetadata>;
21
- private readonly events: ReloadEvents = ReloadEvents.getInstance();
22
21
 
23
22
  // TODO: why not to pass this.vars and event emitter?
24
- constructor() {
23
+ constructor(private readonly events: ReloadEvents) {
25
24
  const metadata = Reflect.getMetadata(
26
25
  CONFIG_METADATA_KEY,
27
26
  this.constructor,
@@ -1,25 +1,15 @@
1
1
  import type { DynamicModule, FactoryProvider, Provider } from '@nestjs/common';
2
- import { Module } from '@nestjs/common';
3
2
  import type { Constructor } from '@rsdk/common';
4
- import { dotenv } from '@rsdk/common';
5
- import { LoggerFactory } from '@rsdk/logging';
6
3
 
7
- import { SequenceException } from '../exceptions';
8
4
  import type { PlatformOptions } from '../types';
9
5
 
10
6
  import { AdditionalSourceInitializer } from './additional-source/additional-source.initializer';
11
7
  import { AdditionalSourceModule } from './additional-source/additional-source.module';
8
+ import { ConfigContext } from './context/config.context';
12
9
  import type { Config } from './config.abstract';
13
- import {
14
- ConfigNotBootstrappedException,
15
- ConfigPropertyMetadataNotFound,
16
- } from './exceptions';
17
- import type { PropertyToken } from './metadata';
18
- import { ConfigMetadataRegistry, getPropertyToken } from './metadata';
19
- import { ReloadEvents } from './reload';
10
+ import { getPropertyToken } from './metadata';
20
11
  import type { ConfigSource } from './sources';
21
- import type { ConfigValue, PropertyMetadata } from './types';
22
- import { Vars } from './vars.class';
12
+ import type { ConfigValue } from './types';
23
13
 
24
14
  export interface ConfigModuleOptions {
25
15
  /**
@@ -35,108 +25,7 @@ export interface ConfigModuleOptions {
35
25
  sources?: Constructor<ConfigSource>[];
36
26
  }
37
27
 
38
- /**
39
- * Configuration is loaded in predictable order. You should take
40
- * into account chat all repeating keys will be overwritten on each step:
41
- *
42
- * 1. .env file if there is any
43
- * 2. process environment
44
- * 3. динамические source'ы (если сделать последовательно - то в порядке указания)
45
- */
46
-
47
- @Module({})
48
28
  export class PlatformConfigModule {
49
- private static isBootstrapped = false;
50
- private static events = ReloadEvents.getInstance();
51
- private static vars: Vars;
52
- private static prefix: string;
53
- /**
54
- * Проинициализированные секции конфигов
55
- * @private
56
- */
57
- private static initializedConfigs = new Map<Constructor<Config>, Config>();
58
- /**
59
- * undefined является валидным значением по умолчанию (`defaultValue`)
60
- * @private
61
- */
62
- private static properties = new Map<PropertyToken, ConfigValue | undefined>();
63
-
64
- /**
65
- * We don't use class as context here because it is undefined if
66
- * tsc target is ES2022
67
- */
68
- private static logger = LoggerFactory.create('PlatformConfigModule');
69
-
70
- /**
71
- * Метадата о необходимых приложению значениях конфигурации
72
- * Зачем храним?
73
- * Потому что пайплайн такой:
74
- * 1. Собираем данные о том какие поля нам нужны
75
- * 2. Приложение запрашивает поле из конфигурации
76
- * 3. Ищем метаданные
77
- * 4. По метаданным вытягиваем значение
78
- * 5. Отдаём значение
79
- *
80
- * Это важно так как позволяет прозрачным образом контролировать этот процесс и инициализировать поля в тот момент когда они потребуются
81
- * А не в тот момент когда их объявили
82
- * Основной кейс, где это применяется - тесты
83
- * @private
84
- */
85
- private static propertyMetadata = new Map<string, PropertyMetadata>();
86
-
87
- /**
88
- * This method should be invoked BEFORE bootstrapping nest application.
89
- *
90
- * It takes 2 main actions:
91
- * - load environment variables
92
- *
93
- * - instantiates all configuration initializedConfig (classes marked with
94
- * @ConfigSection() decorator) and adds them into internal storage
95
- *
96
- * If any of these actions fails - application should exit.
97
- *
98
- * NOTE: This method should be invoked before any other interaction
99
- * with ConfigurationModule
100
- *
101
- * ATTENTION: not load values from additional source
102
- */
103
- static bootstrap(options?: ConfigModuleOptions): void {
104
- if (this.isBootstrapped) {
105
- throw new SequenceException("Can't bootstrap ConfigurationModule twice");
106
- }
107
-
108
- this.prefix = options?.appName ?? '';
109
-
110
- if (this.prefix) {
111
- this.logger.info('Setting configuration keys prefix', {
112
- prefix: this.prefix,
113
- });
114
- }
115
-
116
- this.vars = new Vars(this.prefix);
117
-
118
- this.readEnvironment();
119
-
120
- /**
121
- * Reading and validating standalone properties from env.
122
- *
123
- * NOTE: Splitting extraction if standalone properties into 2 phases
124
- * is necessary, some configuration sources can need something
125
- * from env to be instatiated.
126
- */
127
- const { properties } = ConfigMetadataRegistry.getMetadata();
128
-
129
- this.extractStandaloneProperties(properties, 'expectedInEnv');
130
-
131
- /**
132
- * NOTE: That properties from .env already loaded.
133
- * Now loading ones from other sources
134
- */
135
- this.extractStandaloneProperties(properties, 'others');
136
-
137
- this.isBootstrapped = true;
138
- }
139
-
140
29
  /**
141
30
  * Use this method to imports specific configuration property
142
31
  * into given module
@@ -171,20 +60,29 @@ export class PlatformConfigModule {
171
60
  * forFeature() is executed Config instances don't yet exist
172
61
  */
173
62
  const provider: FactoryProvider = {
174
- inject: [{ optional: true, token: AdditionalSourceInitializer }],
63
+ inject: [
64
+ ConfigContext,
65
+ { optional: true, token: AdditionalSourceInitializer },
66
+ ],
175
67
  provide: ctor,
176
68
  useFactory: async (
69
+ configContext: ConfigContext,
177
70
  additionalSourceModuleInitializer?: AdditionalSourceInitializer,
178
71
  ) => {
179
72
  /**
180
73
  * Да, каждый раз вызываем метод `initialize` более подробно почему так - смотри в `JSDoc` метода
181
74
  */
182
75
  await additionalSourceModuleInitializer?.initialize();
183
- return this.resolve(ctor);
76
+ return configContext.resolve(ctor);
184
77
  },
185
78
  };
186
79
 
187
80
  return {
81
+ /**
82
+ * Если использовать существующий PlatformConfigModule,
83
+ * то появляются коллизии при резолве зависимостей, а сам Nest падает
84
+ * TODO [@nestjs/core@>9.4]: проверить работоспособность, может быть исправлено
85
+ */
188
86
  module: PlatformConfigModule,
189
87
  providers: [provider],
190
88
 
@@ -197,134 +95,34 @@ export class PlatformConfigModule {
197
95
  const imports: (Promise<DynamicModule> | DynamicModule)[] = [];
198
96
 
199
97
  if (options.config?.sources) {
200
- imports.push(
201
- // TODO: Эти опции в идеале добавить в сам контейнер и использовать их везде
202
- AdditionalSourceModule.forRoot({
203
- sources: options.config?.sources,
204
- logger: this.logger,
205
- properties: this.properties,
206
- vars: this.vars,
207
- events: this.events,
208
- prefix: this.prefix,
209
- propertyMetadata: this.propertyMetadata,
210
- }),
211
- );
98
+ imports.push(AdditionalSourceModule.forRoot(options.config?.sources));
212
99
  }
213
100
 
214
101
  return {
102
+ global: true,
215
103
  imports,
216
104
  module: PlatformConfigModule,
217
105
  providers,
106
+ exports: providers,
218
107
  };
219
108
  }
220
109
 
221
- /**
222
- * Extracting specific instance of configuration section by
223
- * its class reference. Throws error if called before .bootstrap()
224
- *
225
- * ATTENTION: Конфиг будет разрешен с доступными на данный момент переменными,
226
- * то есть если дополнительные источники конфигурации ещё не были проинициализированы,
227
- * они не будут учтены в разрешении конфигурации.
228
- *
229
- * @param ctor Pass constructor of configuration section class
230
- * @returns T
231
- */
232
- static resolve<T extends Config>(ctor: Constructor<T>): T {
233
- /**
234
- * Автор уверен, что здесь не стоит делать bootstrap так как это разные зоны ответственности
235
- */
236
- if (!this.isBootstrapped) {
237
- throw new ConfigNotBootstrappedException();
238
- }
239
-
240
- const instance = this.initializedConfigs.get(ctor);
241
- if (!instance) {
242
- const instantiateSection = this.instantiateSection(ctor);
243
-
244
- this.initializedConfigs.set(ctor, instantiateSection);
245
- return instantiateSection;
246
- }
247
-
248
- // We know exactly it is T
249
- return instance as T;
250
- }
251
-
252
110
  private static getPropertyProvider(
253
111
  token: `STANDALONE_CONFIG_PROPERTY_${string}`,
254
112
  ): FactoryProvider<ConfigValue | undefined> {
255
113
  return {
256
- inject: [{ optional: true, token: AdditionalSourceInitializer }],
114
+ inject: [
115
+ ConfigContext,
116
+ { optional: true, token: AdditionalSourceInitializer },
117
+ ],
257
118
  provide: token,
258
119
  useFactory: async (
120
+ configContext: ConfigContext,
259
121
  additionalSourceModuleInitializer?: AdditionalSourceInitializer,
260
122
  ): Promise<ConfigValue | undefined> => {
261
123
  await additionalSourceModuleInitializer?.initialize();
262
- if (this.properties.has(token)) {
263
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
264
- return this.properties.get(token)!;
265
- }
266
- const propMeta = this.propertyMetadata.get(token);
267
- if (!propMeta) {
268
- throw new ConfigPropertyMetadataNotFound(token);
269
- }
270
- const value = this.vars.extract(propMeta);
271
-
272
- this.properties.set(token, value);
273
- return value;
124
+ return configContext.resolveProperty(token);
274
125
  },
275
126
  };
276
127
  }
277
-
278
- private static readEnvironment(): void {
279
- this.logger.info('Loading variables from .env file if exists');
280
- dotenv.config();
281
-
282
- this.logger.info('Initializing raw parameters storage');
283
-
284
- /**
285
- * Copying parameters from process.env, skipping entries
286
- * for which value is undefined (not sure it's possible,
287
- * but @types/node says it is).
288
- */
289
-
290
- for (const [key, value] of Object.entries(process.env)) {
291
- if (value !== undefined) {
292
- this.vars.set(key, value);
293
- }
294
- }
295
- }
296
-
297
- private static extractStandaloneProperties(
298
- properties: Map<string, PropertyMetadata>,
299
- subset: 'expectedInEnv' | 'others',
300
- ): void {
301
- for (const [alias, metadata] of properties.entries()) {
302
- if (subset === 'expectedInEnv' && !metadata.expectedInEnv) {
303
- continue;
304
- }
305
-
306
- this.propertyMetadata.set(getPropertyToken(alias), metadata);
307
- }
308
- }
309
-
310
- /**
311
- * Инициализирует инстанс секции конфига
312
- * ATTENTION: не проверяет есть ли ещё проинициализированные, будьте внимательны во избежание неожиданного поведение
313
- * @param ctor
314
- * @private
315
- */
316
- private static instantiateSection<T extends Config>(ctor: Constructor<T>): T {
317
- const instance = new ctor();
318
-
319
- this.logger.debug('Initializing configuration section instance', {
320
- ctor: ctor.name,
321
- });
322
-
323
- this.events.on('merge', () => {
324
- instance.tryUpdate(this.vars);
325
- });
326
-
327
- instance.read(this.vars);
328
- return instance;
329
- }
330
128
  }