@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.
- package/CHANGELOG.md +50 -0
- package/dist/app/platform.app.d.ts +1 -1
- package/dist/app/platform.app.js +3 -25
- package/dist/app/platform.app.js.map +1 -1
- package/dist/app-metadata/app-metadata.module.js.map +1 -1
- package/dist/app-metadata/exceptions/app-name-validation.exception.js.map +1 -1
- package/dist/config/additional-source/additional-source.initializer.d.ts +6 -2
- package/dist/config/additional-source/additional-source.initializer.js +24 -18
- package/dist/config/additional-source/additional-source.initializer.js.map +1 -1
- package/dist/config/additional-source/additional-source.module.d.ts +1 -1
- package/dist/config/additional-source/additional-source.module.js +3 -1
- package/dist/config/additional-source/additional-source.module.js.map +1 -1
- package/dist/config/config-reload.indicator.d.ts +3 -2
- package/dist/config/config-reload.indicator.js +4 -3
- package/dist/config/config-reload.indicator.js.map +1 -1
- package/dist/config/config.abstract.d.ts +3 -2
- package/dist/config/config.abstract.js +3 -3
- package/dist/config/config.abstract.js.map +1 -1
- package/dist/config/config.module.d.ts +0 -81
- package/dist/config/config.module.js +26 -203
- package/dist/config/config.module.js.map +1 -1
- package/dist/config/context/config.context.d.ts +75 -0
- package/dist/config/context/config.context.js +159 -0
- package/dist/config/context/config.context.js.map +1 -0
- package/dist/config/context/module.d.ts +5 -0
- package/dist/config/context/module.js +26 -0
- package/dist/config/context/module.js.map +1 -0
- package/dist/config/exceptions/config-not-bootstrapped.exception.js.map +1 -1
- package/dist/config/exceptions/property.exception.d.ts +9 -2
- package/dist/config/exceptions/property.exception.js +4 -6
- package/dist/config/exceptions/property.exception.js.map +1 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +3 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/metadata/config-metadata.provider.d.ts +21 -0
- package/dist/config/metadata/config-metadata.provider.js +37 -0
- package/dist/config/metadata/config-metadata.provider.js.map +1 -0
- package/dist/config/metadata/config-metadata.registry.d.ts +1 -9
- package/dist/config/metadata/config-metadata.registry.js +9 -28
- package/dist/config/metadata/config-metadata.registry.js.map +1 -1
- package/dist/config/metadata/constants.d.ts +3 -0
- package/dist/config/metadata/constants.js +7 -0
- package/dist/config/metadata/constants.js.map +1 -0
- package/dist/config/metadata/decorators/declare-property.decorator.js +2 -2
- package/dist/config/metadata/decorators/declare-property.decorator.js.map +1 -1
- package/dist/config/metadata/decorators/inject-property.decorator.d.ts +1 -1
- package/dist/config/metadata/decorators/inject-property.decorator.js +1 -1
- package/dist/config/metadata/exceptions/duplicate-property.exception.js.map +1 -1
- package/dist/config/metadata/exceptions/duplicate-section.exception.js.map +1 -1
- package/dist/config/metadata/exceptions/duplicate-source.exception.js.map +1 -1
- package/dist/config/metadata/types.d.ts +16 -0
- package/dist/config/metadata/types.js +3 -0
- package/dist/config/metadata/types.js.map +1 -0
- package/dist/config/reload/config-reload.events.d.ts +0 -2
- package/dist/config/reload/config-reload.events.js +0 -8
- package/dist/config/reload/config-reload.events.js.map +1 -1
- package/dist/config/sources/base/reloadable-config-source.abstract.d.ts +3 -2
- package/dist/config/sources/base/reloadable-config-source.abstract.js +3 -3
- package/dist/config/sources/base/reloadable-config-source.abstract.js.map +1 -1
- package/dist/config/sources/exceptions/config-source-di.exception.js.map +1 -1
- package/dist/config/sources/implementations/json-file.source.js.map +1 -1
- package/dist/config/sources/implementations/relodable-json-file.source.d.ts +3 -1
- package/dist/config/sources/implementations/relodable-json-file.source.js +6 -3
- package/dist/config/sources/implementations/relodable-json-file.source.js.map +1 -1
- package/dist/config/vars.class.d.ts +1 -1
- package/dist/config/vars.class.js +6 -6
- package/dist/config/vars.class.js.map +1 -1
- package/dist/context.aggregator.d.ts +21 -0
- package/dist/context.aggregator.js +53 -0
- package/dist/context.aggregator.js.map +1 -0
- package/dist/exceptions/base/platform-exception.absract.d.ts +2 -2
- package/dist/exceptions/base/platform-exception.absract.js +4 -1
- package/dist/exceptions/base/platform-exception.absract.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/double-init.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/duplicate-protocol.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/no-http.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/no-init.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/no-matching-transport.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/sequence.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/symbol-key-decoration.exception.js.map +1 -1
- package/dist/exceptions/implementations/bootstrap/unknown-bootstrap.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/authentication.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/conflict.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/duplicate-entity.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/input.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/internal.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/not-allowed.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/not-found.exception.js.map +1 -1
- package/dist/exceptions/implementations/pipeline/timeout.exception.js.map +1 -1
- package/dist/exceptions.handling/global-exceptions.config.js.map +1 -1
- package/dist/exceptions.handling/global-exceptions.filter.js.map +1 -1
- package/dist/exceptions.handling/global-exceptions.module.js.map +1 -1
- package/dist/health/autodoc/heath.autodoc-resolver.d.ts +5 -15
- package/dist/health/autodoc/heath.autodoc-resolver.js +11 -13
- package/dist/health/autodoc/heath.autodoc-resolver.js.map +1 -1
- package/dist/health/exceptions/health-check.exception.js.map +1 -1
- package/dist/health/health.const.d.ts +1 -0
- package/dist/health/health.const.js +2 -1
- package/dist/health/health.const.js.map +1 -1
- package/dist/health/health.module.js.map +1 -1
- package/dist/health/health.service.d.ts +6 -2
- package/dist/health/health.service.js +19 -6
- package/dist/health/health.service.js.map +1 -1
- package/dist/health/metadata/constants.d.ts +1 -0
- package/dist/health/metadata/constants.js +5 -0
- package/dist/health/metadata/constants.js.map +1 -0
- package/dist/health/metadata/indicator.decorator.js +2 -12
- package/dist/health/metadata/indicator.decorator.js.map +1 -1
- package/dist/health/metadata/indicators.registry.d.ts +0 -7
- package/dist/health/metadata/indicators.registry.js +6 -14
- package/dist/health/metadata/indicators.registry.js.map +1 -1
- package/dist/health/metadata/types.d.ts +7 -0
- package/dist/health/metadata/types.js +3 -0
- package/dist/health/metadata/types.js.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +13 -7
- package/dist/index.js.map +1 -1
- package/dist/logging/decorators/inject-logger.decorator.js +5 -3
- package/dist/logging/decorators/inject-logger.decorator.js.map +1 -1
- package/dist/logging/global-logger-provider.generator.d.ts +7 -0
- package/dist/logging/global-logger-provider.generator.js +22 -0
- package/dist/logging/global-logger-provider.generator.js.map +1 -0
- package/dist/logging/index.d.ts +2 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/index.js.map +1 -1
- package/dist/logging/logging.config.js +1 -1
- package/dist/logging/logging.config.js.map +1 -1
- package/dist/logging/logging.module.d.ts +5 -3
- package/dist/logging/logging.module.js +25 -13
- package/dist/logging/logging.module.js.map +1 -1
- package/dist/logging/metadata/constants.d.ts +1 -0
- package/dist/logging/metadata/constants.js +5 -0
- package/dist/logging/metadata/constants.js.map +1 -0
- package/dist/logging/types.d.ts +6 -2
- package/dist/metrics/index.d.ts +1 -1
- package/dist/metrics/index.js +3 -3
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.d.ts +6 -7
- package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.js +8 -11
- package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.js.map +1 -1
- package/dist/metrics/metadata/constants.d.ts +1 -0
- package/dist/metrics/metadata/constants.js +5 -0
- package/dist/metrics/metadata/constants.js.map +1 -0
- package/dist/metrics/metadata/index.d.ts +0 -1
- package/dist/metrics/metadata/index.js +0 -3
- package/dist/metrics/metadata/index.js.map +1 -1
- package/dist/metrics/metadata/metrics.registry.d.ts +0 -3
- package/dist/metrics/metadata/metrics.registry.js +9 -16
- package/dist/metrics/metadata/metrics.registry.js.map +1 -1
- package/dist/metrics/metadata/types.d.ts +2 -4
- package/dist/metrics/metric.storage.d.ts +8 -0
- package/dist/metrics/metric.storage.js +11 -0
- package/dist/metrics/metric.storage.js.map +1 -0
- package/dist/metrics/metrics.config.js.map +1 -1
- package/dist/metrics/metrics.module.d.ts +1 -1
- package/dist/metrics/metrics.module.js +27 -21
- package/dist/metrics/metrics.module.js.map +1 -1
- package/dist/platform.context.d.ts +5 -3
- package/dist/platform.context.js +20 -19
- package/dist/platform.context.js.map +1 -1
- package/dist/platform.module.d.ts +5 -4
- package/dist/platform.module.js +24 -13
- package/dist/platform.module.js.map +1 -1
- package/dist/rsdk-metadata/constants.d.ts +3 -0
- package/dist/rsdk-metadata/constants.js +5 -0
- package/dist/rsdk-metadata/constants.js.map +1 -0
- package/dist/rsdk-metadata/rsdk-metadata.global-module.d.ts +6 -0
- package/dist/rsdk-metadata/rsdk-metadata.global-module.js +31 -0
- package/dist/rsdk-metadata/rsdk-metadata.global-module.js.map +1 -0
- package/dist/tracing/services/instrumentation.service.js.map +1 -1
- package/dist/tracing/services/metadata.scanner.js.map +1 -1
- package/dist/tracing/tracing.config.js.map +1 -1
- package/dist/tracing/tracing.module.js.map +1 -1
- package/dist/transport/transport.module.d.ts +1 -0
- package/dist/transport/transport.module.js +8 -2
- package/dist/transport/transport.module.js.map +1 -1
- package/dist/types/context-aggregated.d.ts +8 -0
- package/dist/types/context-aggregated.js +3 -0
- package/dist/types/context-aggregated.js.map +1 -0
- package/dist/types/options.d.ts +6 -6
- package/dist/types/transports.d.ts +10 -3
- package/dist/types/transports.js.map +1 -1
- package/dist/unhandled-rejection.handler.d.ts +1 -0
- package/dist/unhandled-rejection.handler.js +24 -0
- package/dist/unhandled-rejection.handler.js.map +1 -0
- package/package.json +8 -7
- package/src/app/platform.app.ts +6 -32
- package/src/config/additional-source/additional-source.initializer.ts +34 -25
- package/src/config/additional-source/additional-source.module.ts +5 -2
- package/src/config/config-reload.indicator.ts +3 -3
- package/src/config/config.abstract.ts +2 -3
- package/src/config/config.module.ts +23 -225
- package/src/config/context/config.context.ts +209 -0
- package/src/config/context/module.ts +25 -0
- package/src/config/exceptions/property.exception.ts +11 -6
- package/src/config/index.ts +1 -0
- package/src/config/metadata/config-metadata.provider.ts +79 -0
- package/src/config/metadata/config-metadata.registry.ts +36 -41
- package/src/config/metadata/constants.ts +6 -0
- package/src/config/metadata/decorators/declare-property.decorator.ts +2 -2
- package/src/config/metadata/decorators/inject-property.decorator.ts +1 -1
- package/src/config/metadata/types.ts +22 -0
- package/src/config/reload/config-reload.events.ts +1 -13
- package/src/config/sources/base/reloadable-config-source.abstract.ts +2 -3
- package/src/config/sources/implementations/relodable-json-file.source.ts +6 -2
- package/src/config/vars.class.ts +9 -7
- package/src/context.aggregator.ts +62 -0
- package/src/exceptions/base/platform-exception.absract.ts +8 -3
- package/src/health/autodoc/heath.autodoc-resolver.ts +15 -18
- package/src/health/health.const.ts +2 -0
- package/src/health/health.service.ts +23 -4
- package/src/health/metadata/constants.ts +1 -0
- package/src/health/metadata/indicator.decorator.ts +2 -18
- package/src/health/metadata/indicators.registry.ts +16 -23
- package/src/health/metadata/types.ts +9 -0
- package/src/index.ts +29 -12
- package/src/logging/decorators/inject-logger.decorator.ts +5 -4
- package/src/logging/global-logger-provider.generator.ts +28 -0
- package/src/logging/index.ts +2 -0
- package/src/logging/logging.config.ts +2 -1
- package/src/logging/logging.module.ts +42 -16
- package/src/logging/metadata/constants.ts +1 -0
- package/src/logging/types.ts +6 -2
- package/src/metrics/index.ts +1 -1
- package/src/metrics/metadata/autodoc/metrics.autodoc-resolver.ts +13 -9
- package/src/metrics/metadata/constants.ts +1 -0
- package/src/metrics/metadata/index.ts +0 -1
- package/src/metrics/metadata/metrics.registry.ts +19 -23
- package/src/metrics/metadata/types.ts +2 -5
- package/src/metrics/metric.storage.ts +10 -0
- package/src/metrics/metrics.module.ts +32 -31
- package/src/platform.context.ts +32 -20
- package/src/platform.module.ts +18 -20
- package/src/rsdk-metadata/constants.ts +5 -0
- package/src/rsdk-metadata/rsdk-metadata.global-module.ts +34 -0
- package/src/transport/transport.module.ts +13 -1
- package/src/types/context-aggregated.ts +10 -0
- package/src/types/options.ts +6 -5
- package/src/types/transports.ts +15 -3
- package/src/unhandled-rejection.handler.ts +29 -0
- package/dist/health/index.d.ts +0 -7
- package/dist/health/index.js +0 -26
- package/dist/health/index.js.map +0 -1
- package/dist/health/metadata/index.d.ts +0 -2
- package/dist/health/metadata/index.js +0 -19
- package/dist/health/metadata/index.js.map +0 -1
- package/src/health/index.ts +0 -7
- 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
|
-
|
|
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(
|
|
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:
|
|
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
|
-
|
|
58
|
+
this.logger.info('No additional sources configured');
|
|
55
59
|
return;
|
|
56
60
|
}
|
|
57
|
-
const { sources
|
|
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(
|
|
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
|
|
135
|
-
|
|
139
|
+
const injectables = new Map<unknown, unknown>().set(
|
|
140
|
+
APP_NAME,
|
|
141
|
+
this.context.prefix,
|
|
142
|
+
);
|
|
136
143
|
|
|
137
|
-
const args = sortedMetadata.map((
|
|
138
|
-
if (injectables.has(
|
|
139
|
-
return injectables.get(
|
|
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(
|
|
143
|
-
throw new ConfigSourceDIException(ctor,
|
|
149
|
+
if (!isPropertyToken(metadata.param)) {
|
|
150
|
+
throw new ConfigSourceDIException(ctor, metadata.param);
|
|
144
151
|
}
|
|
145
152
|
|
|
146
|
-
const propMeta =
|
|
153
|
+
const propMeta = this.context.standalonePropertyMetadata.get(
|
|
154
|
+
metadata.param,
|
|
155
|
+
);
|
|
147
156
|
if (!propMeta) {
|
|
148
|
-
throw new ConfigPropertyMetadataNotFound(
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
|
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: [
|
|
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
|
|
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: [
|
|
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
|
-
|
|
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
|
}
|