@rsdk/nats.transport 5.4.0-next.2
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 +10 -0
- package/dist/events.deserializer.d.ts +23 -0
- package/dist/events.deserializer.js +94 -0
- package/dist/events.deserializer.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.decorator.d.ts +3 -0
- package/dist/metadata.decorator.js +41 -0
- package/dist/metadata.decorator.js.map +1 -0
- package/dist/nats-jetstream-errors.formatter.d.ts +6 -0
- package/dist/nats-jetstream-errors.formatter.js +14 -0
- package/dist/nats-jetstream-errors.formatter.js.map +1 -0
- package/dist/nats-jetstream-transport.module.d.ts +2 -0
- package/dist/nats-jetstream-transport.module.js +17 -0
- package/dist/nats-jetstream-transport.module.js.map +1 -0
- package/dist/nats-jetstream.config.d.ts +5 -0
- package/dist/nats-jetstream.config.js +29 -0
- package/dist/nats-jetstream.config.js.map +1 -0
- package/dist/nats-jetstream.transport.d.ts +20 -0
- package/dist/nats-jetstream.transport.js +73 -0
- package/dist/nats-jetstream.transport.js.map +1 -0
- package/dist/nats.headers.d.ts +10 -0
- package/dist/nats.headers.js +28 -0
- package/dist/nats.headers.js.map +1 -0
- package/dist/payload.decorator.d.ts +8 -0
- package/dist/payload.decorator.js +9 -0
- package/dist/payload.decorator.js.map +1 -0
- package/dist/server.d.ts +136 -0
- package/dist/server.js +365 -0
- package/dist/server.js.map +1 -0
- package/dist/types/consume.options.d.ts +6 -0
- package/dist/types/consume.options.js +3 -0
- package/dist/types/consume.options.js.map +1 -0
- package/dist/types/consumer-info.type.d.ts +5 -0
- package/dist/types/consumer-info.type.js +3 -0
- package/dist/types/consumer-info.type.js.map +1 -0
- package/dist/types/consumers-map.type.d.ts +2 -0
- package/dist/types/consumers-map.type.js +3 -0
- package/dist/types/consumers-map.type.js.map +1 -0
- package/dist/types/event-type-with-options.type.d.ts +6 -0
- package/dist/types/event-type-with-options.type.js +3 -0
- package/dist/types/event-type-with-options.type.js.map +1 -0
- package/dist/types/mapping.type.d.ts +6 -0
- package/dist/types/mapping.type.js +3 -0
- package/dist/types/mapping.type.js.map +1 -0
- package/dist/types/nats-jetstream-transport-options.type.d.ts +2 -0
- package/dist/types/nats-jetstream-transport-options.type.js +3 -0
- package/dist/types/nats-jetstream-transport-options.type.js.map +1 -0
- package/jest.config.js +1 -0
- package/jest.config.unit.js +1 -0
- package/package.json +43 -0
- package/src/events.deserializer.ts +133 -0
- package/src/index.ts +5 -0
- package/src/metadata.decorator.ts +54 -0
- package/src/nats-jetstream-errors.formatter.ts +13 -0
- package/src/nats-jetstream-transport.module.ts +4 -0
- package/src/nats-jetstream.config.ts +14 -0
- package/src/nats-jetstream.transport.ts +94 -0
- package/src/nats.headers.ts +33 -0
- package/src/payload.decorator.ts +17 -0
- package/src/server.ts +491 -0
- package/src/types/consume.options.ts +6 -0
- package/src/types/consumer-info.type.ts +6 -0
- package/src/types/consumers-map.type.ts +3 -0
- package/src/types/event-type-with-options.type.ts +8 -0
- package/src/types/mapping.type.ts +8 -0
- package/src/types/nats-jetstream-transport-options.type.ts +3 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +7 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { applyDecorators } from '@nestjs/common';
|
|
2
|
+
import { EventPattern } from '@nestjs/microservices';
|
|
3
|
+
import { NATS_JETSTREAM_TRANSPORT } from '@nestjs-plugins/nestjs-nats-jetstream-transport';
|
|
4
|
+
import { BoolParser, ConfigMetadataRegistry } from '@rsdk/core';
|
|
5
|
+
import type { EventType } from '@rsdk/events.common';
|
|
6
|
+
import { RsdkMetadata } from '@rsdk/metadata';
|
|
7
|
+
import { NATS_TOPIC_RSDK_METADATA_SCOPE } from '@rsdk/nats.common';
|
|
8
|
+
import omit from 'lodash/omit';
|
|
9
|
+
|
|
10
|
+
import type { ConsumeOptions } from './types/consume.options';
|
|
11
|
+
|
|
12
|
+
const ConsumeMetadata =
|
|
13
|
+
<T>(eventType: EventType<T> | string): MethodDecorator =>
|
|
14
|
+
(target) => {
|
|
15
|
+
const rsdkMetadata = new RsdkMetadata(
|
|
16
|
+
target.constructor,
|
|
17
|
+
NATS_TOPIC_RSDK_METADATA_SCOPE,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const alias =
|
|
21
|
+
'NATS_STREAM_' +
|
|
22
|
+
((eventType as EventType).$group ?? eventType)
|
|
23
|
+
.replaceAll('.', '-')
|
|
24
|
+
.toUpperCase() +
|
|
25
|
+
'_IS_MIRROR';
|
|
26
|
+
|
|
27
|
+
ConfigMetadataRegistry.registerProperty(target, alias, {
|
|
28
|
+
description: '',
|
|
29
|
+
expectedInEnv: true,
|
|
30
|
+
key: alias,
|
|
31
|
+
parser: new BoolParser(),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (typeof eventType === 'string') {
|
|
35
|
+
rsdkMetadata.add({
|
|
36
|
+
topicName: eventType,
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
rsdkMetadata.add({
|
|
41
|
+
eventType: omit(eventType, 'toJSON', 'encode', 'decode'),
|
|
42
|
+
group: eventType.$group,
|
|
43
|
+
partitionKeyField: eventType.$partitionKeyField,
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const Consume = <T>(
|
|
48
|
+
eventType: EventType<T> | string,
|
|
49
|
+
options?: ConsumeOptions,
|
|
50
|
+
): MethodDecorator =>
|
|
51
|
+
applyDecorators(
|
|
52
|
+
EventPattern({ eventType, options }, NATS_JETSTREAM_TRANSPORT),
|
|
53
|
+
ConsumeMetadata(eventType),
|
|
54
|
+
);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IErrorsFormatter } from '@rsdk/core';
|
|
2
|
+
|
|
3
|
+
export class NatsJetstreamErrorsFormatter implements IErrorsFormatter {
|
|
4
|
+
protocol = 'nats-jetstream';
|
|
5
|
+
|
|
6
|
+
match(): boolean {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
format(ex: unknown): unknown {
|
|
11
|
+
return ex;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Config, ConfigSection, Property, StringParser } from '@rsdk/core';
|
|
2
|
+
|
|
3
|
+
export const NatsJetstreamConfigInstance = Symbol(
|
|
4
|
+
'NatsJetstreamConfigInstance',
|
|
5
|
+
);
|
|
6
|
+
|
|
7
|
+
@ConfigSection()
|
|
8
|
+
export class NatsJetstreamConfig extends Config {
|
|
9
|
+
@Property('NATS_JETSTREAM_NAME', new StringParser(), {
|
|
10
|
+
defaultValue: 'default',
|
|
11
|
+
description: 'NATS connection name',
|
|
12
|
+
})
|
|
13
|
+
name!: string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { ArgumentsHost, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import type { CustomStrategy } from '@nestjs/microservices';
|
|
3
|
+
import type { NatsJetStreamServerOptions } from '@nestjs-plugins/nestjs-nats-jetstream-transport';
|
|
4
|
+
import {
|
|
5
|
+
type ConfigContext,
|
|
6
|
+
type GenericHeaders,
|
|
7
|
+
type IErrorsFormatter,
|
|
8
|
+
type IErrorsTransformer,
|
|
9
|
+
type IMicroserviceTransport,
|
|
10
|
+
Manifest,
|
|
11
|
+
type NestModuleDefinitions,
|
|
12
|
+
} from '@rsdk/core';
|
|
13
|
+
import { LoggerFactory } from '@rsdk/logging';
|
|
14
|
+
import { DefaultNatsConfig } from '@rsdk/nats.common';
|
|
15
|
+
|
|
16
|
+
import type { NatsJetstreamTransportOptions } from './types/nats-jetstream-transport-options.type';
|
|
17
|
+
import { NatsHeaders } from './nats.headers';
|
|
18
|
+
import { NatsJetstreamConfig } from './nats-jetstream.config';
|
|
19
|
+
import { NatsJetstreamErrorsFormatter } from './nats-jetstream-errors.formatter';
|
|
20
|
+
import { NatsJetstreamTransportModule } from './nats-jetstream-transport.module';
|
|
21
|
+
import { NatsJetStreamServer } from './server';
|
|
22
|
+
|
|
23
|
+
export class NatsJetstreamTransport implements IMicroserviceTransport {
|
|
24
|
+
private readonly logger = LoggerFactory.create(NatsJetstreamTransport);
|
|
25
|
+
private servers: string[] = [];
|
|
26
|
+
private name = 'nats-jetstream-unknown';
|
|
27
|
+
|
|
28
|
+
constructor(private readonly options?: NatsJetstreamTransportOptions) {}
|
|
29
|
+
|
|
30
|
+
extractHeaders(ctx: ExecutionContext): GenericHeaders {
|
|
31
|
+
return new NatsHeaders(ctx);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getProtocol(): string {
|
|
35
|
+
return 'nats-jetstream';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
matchByContext(ctx: ArgumentsHost): boolean {
|
|
39
|
+
const natsCtx = ctx.getArgByIndex(1);
|
|
40
|
+
|
|
41
|
+
return NatsJetStreamServer.isNatsContext(natsCtx);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getErrorsFormatter(): IErrorsFormatter {
|
|
45
|
+
return new NatsJetstreamErrorsFormatter();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getErrorTransformers(): IErrorsTransformer[] {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
modules(): NestModuleDefinitions {
|
|
53
|
+
return [NatsJetstreamTransportModule];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
createMicroserviceOptions(): CustomStrategy {
|
|
57
|
+
const options: NatsJetStreamServerOptions = {
|
|
58
|
+
...this.options,
|
|
59
|
+
connectionOptions: {
|
|
60
|
+
...this.options?.connectionOptions,
|
|
61
|
+
name: this.name,
|
|
62
|
+
servers: this.servers,
|
|
63
|
+
},
|
|
64
|
+
consumerOptions: {
|
|
65
|
+
...this.options?.consumerOptions,
|
|
66
|
+
},
|
|
67
|
+
streamConfig: [],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
this.logger.trace('createMicroserviceOptions', { options });
|
|
71
|
+
|
|
72
|
+
const { name } = Manifest.getData();
|
|
73
|
+
const server = new NatsJetStreamServer(options, {
|
|
74
|
+
appName: name,
|
|
75
|
+
autoUpdateConsumers: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
strategy: server,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
init(configContext: ConfigContext): void {
|
|
84
|
+
const natsConfig = configContext.resolve(DefaultNatsConfig);
|
|
85
|
+
const natsJetstreamConfig = configContext.resolve(NatsJetstreamConfig);
|
|
86
|
+
|
|
87
|
+
this.name = natsJetstreamConfig.name;
|
|
88
|
+
this.servers = natsConfig.servers;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
onStart(): void {
|
|
92
|
+
this.logger.info(`Nats servers: ${this.servers.join(',')}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import type { GenericHeaders } from '@rsdk/core';
|
|
3
|
+
import { InputException } from '@rsdk/core';
|
|
4
|
+
|
|
5
|
+
import { NatsJetStreamServer } from './server';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @description хелпер для нормализованного извлечения заголовков из nats
|
|
9
|
+
*/
|
|
10
|
+
export class NatsHeaders implements GenericHeaders {
|
|
11
|
+
private readonly normalizedHeaders: Record<string, string>;
|
|
12
|
+
|
|
13
|
+
constructor(ctx: ExecutionContext) {
|
|
14
|
+
const natsCtx = ctx.getArgByIndex(1);
|
|
15
|
+
|
|
16
|
+
if (!NatsJetStreamServer.isNatsContext(natsCtx)) {
|
|
17
|
+
throw new InputException('Unexpected call with non Nats ArgumentHost');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.normalizedHeaders = Object.fromEntries(
|
|
21
|
+
Object.entries(natsCtx.message.headers || {}).map(([k, v]) => [
|
|
22
|
+
Array.isArray(k)
|
|
23
|
+
? k[0].toString().toLowerCase()
|
|
24
|
+
: k.toString().toLowerCase(),
|
|
25
|
+
v,
|
|
26
|
+
]),
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get(key: string): string | undefined {
|
|
31
|
+
return this.normalizedHeaders[key.toLowerCase()];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { createParamDecorator } from '@nestjs/common';
|
|
3
|
+
|
|
4
|
+
type Contract<T> = {
|
|
5
|
+
decode: (bytes: Uint8Array) => T;
|
|
6
|
+
encode: (data: T) => {
|
|
7
|
+
finish: () => Uint8Array;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const Payload = createParamDecorator(
|
|
12
|
+
<T>(contract: Contract<T>, ctx: ExecutionContext): T => {
|
|
13
|
+
const natsContext = ctx.getArgByIndex(1);
|
|
14
|
+
|
|
15
|
+
return contract.decode(natsContext.message.data);
|
|
16
|
+
},
|
|
17
|
+
);
|