@rsdk/core 4.0.0-next.14 → 4.0.0-next.15
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 +85 -40
- package/dist/app-metadata/app-name.validator.js.map +1 -1
- package/dist/config/additional-source/additional-source.initializer.js.map +1 -1
- package/dist/config/config-reload.indicator.js.map +1 -1
- package/dist/config/config.abstract.js.map +1 -1
- package/dist/config/config.module.js.map +1 -1
- package/dist/config/context/config.context.js.map +1 -1
- package/dist/config/metadata/config-metadata.registry.js.map +1 -1
- package/dist/config/metadata/decorators/config-section.decorator.js.map +1 -1
- package/dist/config/parsers/array.parser.js.map +1 -1
- package/dist/config/parsers/path/fspath.parser.js.map +1 -1
- package/dist/config/parsers/url/url.parser.js.map +1 -1
- package/dist/config/sources/base/config-source.abstract.js.map +1 -1
- package/dist/config/sources/base/reloadable-config-source.abstract.js.map +1 -1
- package/dist/config/sources/implementations/relodable-json-file.source.js.map +1 -1
- package/dist/config/strategy/app-name-strategy.validator.js.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/config/vars.class.js.map +1 -1
- package/dist/context.aggregator.js.map +1 -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/no-init.exception.js.map +1 -1
- package/dist/exceptions/metadata/exceptions.registry.js.map +1 -1
- package/dist/exceptions.handling/global-exceptions.filter.d.ts +3 -1
- package/dist/exceptions.handling/global-exceptions.filter.js +10 -4
- package/dist/exceptions.handling/global-exceptions.filter.js.map +1 -1
- package/dist/exceptions.handling/types.d.ts +4 -11
- package/dist/health/autodoc/heath.autodoc-resolver.js.map +1 -1
- package/dist/health/health.service.js.map +1 -1
- package/dist/health/indicators.abstract/fs-access.indicator.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/metadata/autodoc/metrics.autodoc-resolver.js.map +1 -1
- package/dist/metrics/metrics.module.js.map +1 -1
- package/dist/platform.context.js.map +1 -1
- package/dist/platform.module.js +0 -1
- package/dist/platform.module.js.map +1 -1
- package/dist/plugin/plugin.module.js.map +1 -1
- package/dist/rsdk-metadata/config-metadata.extractor.js.map +1 -1
- package/dist/tracing/decorators/span.decorator.js.map +1 -1
- package/dist/tracing/services/active-span.storage.js.map +1 -1
- package/dist/tracing/services/request-metadata.injector.js.map +1 -1
- package/dist/tracing/services/request-metadata.storage.js.map +1 -1
- package/dist/tracing/services/trace.injector.js.map +1 -1
- package/dist/tracing/tracing.module.js.map +1 -1
- package/dist/tracing/utils/save-async-hooks-context.js +19 -21
- package/dist/tracing/utils/save-async-hooks-context.js.map +1 -1
- package/dist/transport/get-transport-id.d.ts +5 -0
- package/dist/transport/get-transport-id.js +14 -0
- package/dist/transport/get-transport-id.js.map +1 -0
- package/dist/transport/protocol.detector.d.ts +7 -0
- package/dist/transport/protocol.detector.js +41 -0
- package/dist/transport/protocol.detector.js.map +1 -0
- package/dist/transport/transport.module.js +9 -0
- package/dist/transport/transport.module.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/metadata.js.map +1 -1
- package/dist/types/transports.d.ts +12 -0
- package/dist/types/transports.js.map +1 -1
- package/dist/unhandled-rejection.handler.js.map +1 -1
- package/package.json +12 -12
- package/src/config/reload/config-reload.events.ts +9 -0
- package/src/config/sources/base/config-source.abstract.ts +2 -0
- package/src/config/types.ts +3 -0
- package/src/exceptions.handling/global-exceptions.filter.ts +6 -2
- package/src/exceptions.handling/types.ts +4 -11
- package/src/index.ts +3 -0
- package/src/platform.module.ts +1 -2
- package/src/tracing/utils/save-async-hooks-context.ts +23 -24
- package/src/transport/get-transport-id.ts +20 -0
- package/src/transport/protocol.detector.ts +38 -0
- package/src/transport/transport.module.ts +10 -0
- package/src/types/index.ts +2 -0
- package/src/types/transports.ts +15 -0
- package/tsconfig.json +12 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ArgumentsHost } from '@nestjs/common';
|
|
1
2
|
import type { Controller, INestApplication } from '@nestjs/common/interfaces';
|
|
2
3
|
import type { AbstractHttpAdapter } from '@nestjs/core';
|
|
3
4
|
import type { MicroserviceOptions } from '@nestjs/microservices';
|
|
@@ -13,6 +14,17 @@ export interface ITransport {
|
|
|
13
14
|
* @returns protocol in text format
|
|
14
15
|
*/
|
|
15
16
|
getProtocol(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Detect is it context of this transport
|
|
19
|
+
* !!! Do NOT check on getType() === 'rpc', this type corresponds to all microservices
|
|
20
|
+
*
|
|
21
|
+
* @param {ArgumentsHost} ctx
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
* @example
|
|
24
|
+
* return ctx.getType() === 'http'
|
|
25
|
+
* return ctx.getArgByIndex(1) instanceof MyTransportContext
|
|
26
|
+
*/
|
|
27
|
+
matchByContext(ctx: ArgumentsHost): boolean;
|
|
16
28
|
/**
|
|
17
29
|
* @returns error formatting algorithm
|
|
18
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transports.js","sourceRoot":"","sources":["../../src/types/transports.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"transports.js","sourceRoot":"","sources":["../../src/types/transports.ts"],"names":[],"mappings":";;;AA6HO,MAAM,kBAAkB,GAAG,CAAC,CAAa,EAA0B,EAAE,CAC1E,OAAQ,CAAuB,CAAC,mBAAmB,KAAK,UAAU;IAClE,OAAQ,CAAuB,CAAC,oBAAoB,KAAK,UAAU,CAAC;AAFzD,QAAA,kBAAkB,sBAEuC;AAE/D,MAAM,eAAe,GAAG,CAAC,CAAa,EAAuB,EAAE,CACpE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;AADhB,QAAA,eAAe,mBACC;AAEtB,MAAM,uBAAuB,GAAG,CACrC,CAAa,EACgB,EAAE,CAC/B,OAAQ,CAA4B,CAAC,yBAAyB,KAAK,UAAU,CAAC;AAHnE,QAAA,uBAAuB,2BAG4C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unhandled-rejection.handler.js","sourceRoot":"","sources":["../src/unhandled-rejection.handler.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AACpC,2CAA8C;AAE9C,MAAM,MAAM,GAAG,uBAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEvD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE;
|
|
1
|
+
{"version":3,"file":"unhandled-rejection.handler.js","sourceRoot":"","sources":["../src/unhandled-rejection.handler.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AACpC,2CAA8C;AAE9C,MAAM,MAAM,GAAG,uBAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEvD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC/B,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;AAC7D,CAAC;AAED,2DAA2D;AAC3D,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAW,EAAE,OAAO,EAAE,EAAE;IACxD,MAAM,CAAC,KAAK,CACV,IAAA,aAAI,EAAA;;;;OAID,EACH,EAAE,OAAO,EAAE,MAAM,EAAE,CACpB,CAAC;IAEF;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE;QACzC,OAAO;QACP,MAAM;KACP,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsdk/core",
|
|
3
|
-
"version": "4.0.0-next.
|
|
3
|
+
"version": "4.0.0-next.15",
|
|
4
4
|
"description": "Nestjs based microservice chassis",
|
|
5
5
|
"license": "Apache License 2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"@opentelemetry/exporter-trace-otlp-http": "0.39.1",
|
|
21
21
|
"@opentelemetry/propagator-b3": "1.13.0",
|
|
22
22
|
"@opentelemetry/resources": "1.13.0",
|
|
23
|
-
"@opentelemetry/sdk-node": "
|
|
23
|
+
"@opentelemetry/sdk-node": "0.39.1",
|
|
24
24
|
"@opentelemetry/sdk-trace-base": "1.13.0",
|
|
25
|
-
"@opentelemetry/semantic-conventions": "1.
|
|
25
|
+
"@opentelemetry/semantic-conventions": "1.18.1",
|
|
26
26
|
"dotenv": "^16.3.1",
|
|
27
27
|
"lodash": "^4.17.21",
|
|
28
28
|
"prom-client": "^14.2.0"
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"@nestjs/common": "^10.0.0",
|
|
32
32
|
"@nestjs/core": "^10.0.0",
|
|
33
33
|
"@nestjs/microservices": "^10.0.0",
|
|
34
|
-
"@rsdk/autodoc.protocol": "^4.0.0-next.
|
|
35
|
-
"@rsdk/common": "^4.0.0-next.
|
|
36
|
-
"@rsdk/common.nestjs": "^4.0.0-next.
|
|
37
|
-
"@rsdk/common.node": "^4.0.0-next.
|
|
38
|
-
"@rsdk/decorators": "^4.0.0-next.
|
|
39
|
-
"@rsdk/logging": "^4.0.0-next.
|
|
40
|
-
"@rsdk/metadata": "^4.0.0-next.
|
|
41
|
-
"@rsdk/nest-tools": "^4.0.0-next.
|
|
34
|
+
"@rsdk/autodoc.protocol": "^4.0.0-next.15",
|
|
35
|
+
"@rsdk/common": "^4.0.0-next.15",
|
|
36
|
+
"@rsdk/common.nestjs": "^4.0.0-next.15",
|
|
37
|
+
"@rsdk/common.node": "^4.0.0-next.15",
|
|
38
|
+
"@rsdk/decorators": "^4.0.0-next.15",
|
|
39
|
+
"@rsdk/logging": "^4.0.0-next.15",
|
|
40
|
+
"@rsdk/metadata": "^4.0.0-next.15",
|
|
41
|
+
"@rsdk/nest-tools": "^4.0.0-next.15",
|
|
42
42
|
"axios": "^1.1.3",
|
|
43
43
|
"pino": "^8.16.1",
|
|
44
44
|
"reflect-metadata": "^0.1.13",
|
|
45
45
|
"rxjs": "^7.0.0"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "8abd89d7800375749b024410dc3465ff40389277"
|
|
48
48
|
}
|
|
@@ -11,23 +11,32 @@ export class ReloadEvents extends EventEmitter {}
|
|
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
12
12
|
export declare interface ReloadEvents {
|
|
13
13
|
on(e: 'reload', fn: (source: ConfigSource, values: RawValues) => void): this;
|
|
14
|
+
|
|
14
15
|
on(
|
|
15
16
|
e: 'reload_failure',
|
|
16
17
|
fn: (source: ConfigSource, err: ConfigSourceException) => void,
|
|
17
18
|
): this;
|
|
19
|
+
|
|
18
20
|
on(e: 'merge', fn: (source: ConfigSource, changes: Changes) => void): this;
|
|
21
|
+
|
|
19
22
|
on(e: 'update', fn: (section: Config, keys: string[]) => void): this;
|
|
23
|
+
|
|
20
24
|
on(
|
|
21
25
|
e: 'update_failure',
|
|
22
26
|
fn: (section: Config, err: PropertyException) => void,
|
|
23
27
|
): this;
|
|
28
|
+
|
|
24
29
|
emit(e: 'reload', source: ConfigSource, values: RawValues): boolean;
|
|
30
|
+
|
|
25
31
|
emit(
|
|
26
32
|
e: 'reload_failure',
|
|
27
33
|
source: ConfigSource,
|
|
28
34
|
err: ConfigSourceException,
|
|
29
35
|
): boolean;
|
|
36
|
+
|
|
30
37
|
emit(e: 'merge', source: ConfigSource, changes: Changes): boolean;
|
|
38
|
+
|
|
31
39
|
emit(e: 'update', section: Config, keys: string[]): boolean;
|
|
40
|
+
|
|
32
41
|
emit(e: 'update_failure', section: Config, err: PropertyException): boolean;
|
|
33
42
|
}
|
package/src/config/types.ts
CHANGED
|
@@ -70,7 +70,9 @@ export interface ParserMetadata {
|
|
|
70
70
|
*/
|
|
71
71
|
export interface PropertyParser<T = any> {
|
|
72
72
|
type(): string;
|
|
73
|
+
|
|
73
74
|
description(): string;
|
|
75
|
+
|
|
74
76
|
parse(value: unknown): T;
|
|
75
77
|
}
|
|
76
78
|
|
|
@@ -83,5 +85,6 @@ export enum AppNameStrategyType {
|
|
|
83
85
|
|
|
84
86
|
export interface AppNameStrategy {
|
|
85
87
|
type: AppNameStrategyType;
|
|
88
|
+
|
|
86
89
|
transform(appName: string): string;
|
|
87
90
|
}
|
|
@@ -7,6 +7,7 @@ import { throwError } from 'rxjs';
|
|
|
7
7
|
|
|
8
8
|
import { InternalException, PipelineException } from '../exceptions';
|
|
9
9
|
import { InjectLogger } from '../logging';
|
|
10
|
+
import { ProtocolDetector } from '../transport/protocol.detector';
|
|
10
11
|
|
|
11
12
|
import { FORMATTERS, SENDERS, TRANSFORMERS } from './constants';
|
|
12
13
|
import { GlobalExceptionsConfig } from './global-exceptions.config';
|
|
@@ -25,6 +26,7 @@ export class GlobalExceptionsFilter implements ExceptionFilter {
|
|
|
25
26
|
@InjectLogger(GlobalExceptionsFilter)
|
|
26
27
|
private readonly logger: ILogger,
|
|
27
28
|
private readonly config: GlobalExceptionsConfig,
|
|
29
|
+
private detector: ProtocolDetector,
|
|
28
30
|
) {}
|
|
29
31
|
|
|
30
32
|
catch(ex: any, host: ArgumentsHost): Observable<any> {
|
|
@@ -53,7 +55,8 @@ export class GlobalExceptionsFilter implements ExceptionFilter {
|
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
private format(host: ArgumentsHost, ex: unknown): unknown {
|
|
56
|
-
const
|
|
58
|
+
const protocol = this.detector.getProtocol(host);
|
|
59
|
+
const formatter = this.formatters.find((x) => x.protocol === protocol);
|
|
57
60
|
if (formatter) {
|
|
58
61
|
this.logger.trace(`Found formatter: ${formatter.constructor.name}`);
|
|
59
62
|
|
|
@@ -74,7 +77,8 @@ export class GlobalExceptionsFilter implements ExceptionFilter {
|
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
private send(host: ArgumentsHost, ex: any): Observable<unknown> {
|
|
77
|
-
const
|
|
80
|
+
const protocol = this.detector.getProtocol(host);
|
|
81
|
+
const sender = this.senders.find((x) => x.protocol === protocol);
|
|
78
82
|
|
|
79
83
|
return sender?.send(host, ex) ?? throwError(() => ex);
|
|
80
84
|
}
|
|
@@ -13,13 +13,9 @@ import type { PipelineException } from '../exceptions/base';
|
|
|
13
13
|
*/
|
|
14
14
|
export interface IErrorsFormatter {
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
* this formatter. Most common use is match by context type.
|
|
18
|
-
*
|
|
19
|
-
* @param host ArgumentsHost - nest.js wrapper over request context
|
|
20
|
-
* @param exception Exception itself
|
|
16
|
+
* Platform Transport protocol from `getProtocol`
|
|
21
17
|
*/
|
|
22
|
-
|
|
18
|
+
protocol: string;
|
|
23
19
|
|
|
24
20
|
/**
|
|
25
21
|
* Formatting algorithm that should match received exception with
|
|
@@ -40,12 +36,9 @@ export interface IErrorsFormatter {
|
|
|
40
36
|
*/
|
|
41
37
|
export interface IErrorsSender {
|
|
42
38
|
/**
|
|
43
|
-
*
|
|
44
|
-
* this formatter. Most common use is match by context type.
|
|
45
|
-
*
|
|
46
|
-
* @param host ArgumentsHost - nest.js wrapper over request context
|
|
39
|
+
* Platform Transport protocol from `getProtocol`
|
|
47
40
|
*/
|
|
48
|
-
|
|
41
|
+
protocol: string;
|
|
49
42
|
|
|
50
43
|
/**
|
|
51
44
|
* Implementation of sending error back to the client
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import './unhandled-rejection.handler';
|
|
2
2
|
|
|
3
|
+
export { ProtocolDetector } from './transport/protocol.detector';
|
|
4
|
+
|
|
3
5
|
export { X_REQUEST_ID } from './tracing/constants';
|
|
4
6
|
|
|
5
7
|
export {
|
|
@@ -62,6 +64,7 @@ export * from './types';
|
|
|
62
64
|
export * from './app-metadata/decorators';
|
|
63
65
|
|
|
64
66
|
export * from './app-metadata/app-metadata.const';
|
|
67
|
+
export { getTransportId } from './transport/get-transport-id';
|
|
65
68
|
|
|
66
69
|
export {
|
|
67
70
|
X_B3_PARENT_SPAN_ID,
|
package/src/platform.module.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DynamicModule, NestModule } from '@nestjs/common';
|
|
2
|
-
import { Inject
|
|
2
|
+
import { Inject } from '@nestjs/common';
|
|
3
3
|
import type { MiddlewareConsumer } from '@nestjs/common/interfaces';
|
|
4
4
|
import type { Constructor } from '@rsdk/common';
|
|
5
5
|
|
|
@@ -12,7 +12,6 @@ import { LoggingModule } from './logging';
|
|
|
12
12
|
import { TracingModule } from './tracing';
|
|
13
13
|
import { PlatformExtendedOptions } from './types';
|
|
14
14
|
|
|
15
|
-
@Module({})
|
|
16
15
|
export class PlatformModule implements NestModule {
|
|
17
16
|
constructor(
|
|
18
17
|
@Inject('PlatformExtendedOptions') private options: PlatformExtendedOptions,
|
|
@@ -33,30 +33,29 @@ export function saveAsyncHooksContext<T>(
|
|
|
33
33
|
if (activeSpan) {
|
|
34
34
|
Object.assign(activeSpan.spanContext(), span?.spanContext());
|
|
35
35
|
return fn(...args);
|
|
36
|
-
} else {
|
|
37
|
-
if (!span) {
|
|
38
|
-
return fn(...args);
|
|
39
|
-
}
|
|
40
|
-
const spanContext = api.trace.setSpan(api.context.active(), span);
|
|
41
|
-
|
|
42
|
-
return api.context.with(spanContext, async () =>
|
|
43
|
-
fn(...args)
|
|
44
|
-
.then(async (result) => {
|
|
45
|
-
span.setAttribute('response', TraceInjector.toAttribute(result));
|
|
46
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
47
|
-
span.end();
|
|
48
|
-
return result;
|
|
49
|
-
})
|
|
50
|
-
.catch(async (error) => {
|
|
51
|
-
span.recordException(error as ErrorLike);
|
|
52
|
-
span.setStatus({
|
|
53
|
-
code: SpanStatusCode.ERROR,
|
|
54
|
-
message: (error as ErrorLike).message,
|
|
55
|
-
});
|
|
56
|
-
span.end();
|
|
57
|
-
throw error;
|
|
58
|
-
}),
|
|
59
|
-
);
|
|
60
36
|
}
|
|
37
|
+
if (!span) {
|
|
38
|
+
return fn(...args);
|
|
39
|
+
}
|
|
40
|
+
const spanContext = api.trace.setSpan(api.context.active(), span);
|
|
41
|
+
|
|
42
|
+
return api.context.with(spanContext, async () =>
|
|
43
|
+
fn(...args)
|
|
44
|
+
.then(async (result) => {
|
|
45
|
+
span.setAttribute('response', TraceInjector.toAttribute(result));
|
|
46
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
47
|
+
span.end();
|
|
48
|
+
return result;
|
|
49
|
+
})
|
|
50
|
+
.catch(async (error) => {
|
|
51
|
+
span.recordException(error as ErrorLike);
|
|
52
|
+
span.setStatus({
|
|
53
|
+
code: SpanStatusCode.ERROR,
|
|
54
|
+
message: (error as ErrorLike).message,
|
|
55
|
+
});
|
|
56
|
+
span.end();
|
|
57
|
+
throw error;
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
61
60
|
};
|
|
62
61
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { createParamDecorator } from '@nestjs/common';
|
|
3
|
+
import type { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
|
|
4
|
+
import type { Transport } from '@nestjs/microservices';
|
|
5
|
+
import { TRANSPORT_METADATA } from '@nestjs/microservices/constants';
|
|
6
|
+
|
|
7
|
+
export const TransportId = createParamDecorator(
|
|
8
|
+
(_data: unknown, ctx: ExecutionContext | ExecutionContextHost) => {
|
|
9
|
+
return getTransportId(ctx);
|
|
10
|
+
},
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
export function getTransportId(
|
|
14
|
+
context: ExecutionContext | ExecutionContextHost,
|
|
15
|
+
): Transport {
|
|
16
|
+
return (
|
|
17
|
+
Reflect.getMetadata(TRANSPORT_METADATA, context.getHandler()) ??
|
|
18
|
+
Reflect.getMetadata(TRANSPORT_METADATA, context.getClass())
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ArgumentsHost } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { InternalException } from '../exceptions';
|
|
4
|
+
import type { ITransport } from '../types';
|
|
5
|
+
|
|
6
|
+
export class ProtocolDetector {
|
|
7
|
+
constructor(private transports: ITransport[]) {}
|
|
8
|
+
|
|
9
|
+
getProtocol(context: ArgumentsHost): string | undefined {
|
|
10
|
+
if (this.transports.length === 0) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const matchers = this.transports.map((tr) => ({
|
|
14
|
+
matched: tr.matchByContext(context),
|
|
15
|
+
tr,
|
|
16
|
+
}));
|
|
17
|
+
const matched = matchers.filter((matched) => matched.matched);
|
|
18
|
+
if (matched.length > 1) {
|
|
19
|
+
throw new InternalException('So many matchers for transports', {
|
|
20
|
+
cause: {
|
|
21
|
+
matchers,
|
|
22
|
+
matched,
|
|
23
|
+
context,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (matched.length === 0) {
|
|
28
|
+
throw new InternalException('No matchers found', {
|
|
29
|
+
cause: {
|
|
30
|
+
matchers,
|
|
31
|
+
matched,
|
|
32
|
+
context,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return matched[0].tr.getProtocol();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -9,6 +9,8 @@ import { MetricsModule } from '../metrics';
|
|
|
9
9
|
import type { PlatformExtendedOptions } from '../types';
|
|
10
10
|
import { isPrimaryTransport } from '../types';
|
|
11
11
|
|
|
12
|
+
import { ProtocolDetector } from './protocol.detector';
|
|
13
|
+
|
|
12
14
|
export class PlatformTransportModule {
|
|
13
15
|
static forOptions(options: PlatformExtendedOptions): DynamicModule {
|
|
14
16
|
return {
|
|
@@ -19,6 +21,14 @@ export class PlatformTransportModule {
|
|
|
19
21
|
...PlatformTransportModule.getTransportModules(options),
|
|
20
22
|
],
|
|
21
23
|
module: PlatformTransportModule,
|
|
24
|
+
providers: [
|
|
25
|
+
{
|
|
26
|
+
provide: ProtocolDetector,
|
|
27
|
+
useFactory: () => new ProtocolDetector(options.transports ?? []),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
global: true,
|
|
31
|
+
exports: [ProtocolDetector],
|
|
22
32
|
};
|
|
23
33
|
}
|
|
24
34
|
|
package/src/types/index.ts
CHANGED
package/src/types/transports.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ArgumentsHost } from '@nestjs/common';
|
|
1
2
|
import type { Controller, INestApplication } from '@nestjs/common/interfaces';
|
|
2
3
|
import type { AbstractHttpAdapter } from '@nestjs/core';
|
|
3
4
|
import type { MicroserviceOptions } from '@nestjs/microservices';
|
|
@@ -21,6 +22,18 @@ export interface ITransport {
|
|
|
21
22
|
*/
|
|
22
23
|
getProtocol(): string;
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Detect is it context of this transport
|
|
27
|
+
* !!! Do NOT check on getType() === 'rpc', this type corresponds to all microservices
|
|
28
|
+
*
|
|
29
|
+
* @param {ArgumentsHost} ctx
|
|
30
|
+
* @returns {boolean}
|
|
31
|
+
* @example
|
|
32
|
+
* return ctx.getType() === 'http'
|
|
33
|
+
* return ctx.getArgByIndex(1) instanceof MyTransportContext
|
|
34
|
+
*/
|
|
35
|
+
matchByContext(ctx: ArgumentsHost): boolean;
|
|
36
|
+
|
|
24
37
|
/**
|
|
25
38
|
* @returns error formatting algorithm
|
|
26
39
|
*/
|
|
@@ -50,6 +63,7 @@ export interface ITransport {
|
|
|
50
63
|
*/
|
|
51
64
|
export interface IPrimaryTransport extends ITransport {
|
|
52
65
|
getHealthController(): Constructor<Controller>;
|
|
66
|
+
|
|
53
67
|
getMetricsController(): Constructor<Controller>;
|
|
54
68
|
}
|
|
55
69
|
|
|
@@ -105,6 +119,7 @@ export interface IHttpTransport extends IPrimaryTransport {
|
|
|
105
119
|
app: INestApplication,
|
|
106
120
|
configContext: ConfigContext,
|
|
107
121
|
): Promise<void> | void;
|
|
122
|
+
|
|
108
123
|
createHttpOptions(configContext: ConfigContext): HttpOptions;
|
|
109
124
|
}
|
|
110
125
|
|
package/tsconfig.json
CHANGED
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
"declaration": true,
|
|
5
5
|
"outDir": "dist"
|
|
6
6
|
},
|
|
7
|
-
"include": [
|
|
8
|
-
|
|
7
|
+
"include": [
|
|
8
|
+
"src/**/*"
|
|
9
|
+
],
|
|
10
|
+
"exclude": [
|
|
11
|
+
"node_modules",
|
|
12
|
+
"dist",
|
|
13
|
+
"test",
|
|
14
|
+
"**/*.spec.ts",
|
|
15
|
+
"**/*.test.ts",
|
|
16
|
+
"**/*.spec.e2e.ts",
|
|
17
|
+
"**/*.test.e2e.ts"
|
|
18
|
+
]
|
|
9
19
|
}
|