@rsdk/nats.common 5.3.0-next.4
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/client/client.config.d.ts +6 -0
- package/dist/client/client.config.js +36 -0
- package/dist/client/client.config.js.map +1 -0
- package/dist/client/client.constants.d.ts +2 -0
- package/dist/client/client.constants.js +6 -0
- package/dist/client/client.constants.js.map +1 -0
- package/dist/client/client.decorators.d.ts +2 -0
- package/dist/client/client.decorators.js +10 -0
- package/dist/client/client.decorators.js.map +1 -0
- package/dist/client/client.metadata.d.ts +21 -0
- package/dist/client/client.metadata.js +10 -0
- package/dist/client/client.metadata.js.map +1 -0
- package/dist/client/client.module.d.ts +2 -0
- package/dist/client/client.module.js +27 -0
- package/dist/client/client.module.js.map +1 -0
- package/dist/client/client.provider.d.ts +2 -0
- package/dist/client/client.provider.js +18 -0
- package/dist/client/client.provider.js.map +1 -0
- package/dist/client/producer.provider.d.ts +4 -0
- package/dist/client/producer.provider.js +12 -0
- package/dist/client/producer.provider.js.map +1 -0
- package/dist/client/topics.service.d.ts +8 -0
- package/dist/client/topics.service.js +35 -0
- package/dist/client/topics.service.js.map +1 -0
- package/dist/event.codec.d.ts +22 -0
- package/dist/event.codec.js +32 -0
- package/dist/event.codec.js.map +1 -0
- package/dist/event.type.d.ts +23 -0
- package/dist/event.type.js +18 -0
- package/dist/event.type.js.map +1 -0
- package/dist/exceptions/exception.handler.d.ts +1 -0
- package/dist/exceptions/exception.handler.js +9 -0
- package/dist/exceptions/exception.handler.js.map +1 -0
- package/dist/exceptions/missing-topics.exception.d.ts +6 -0
- package/dist/exceptions/missing-topics.exception.js +19 -0
- package/dist/exceptions/missing-topics.exception.js.map +1 -0
- package/dist/exceptions/payload-format.exception.d.ts +5 -0
- package/dist/exceptions/payload-format.exception.js +11 -0
- package/dist/exceptions/payload-format.exception.js.map +1 -0
- package/dist/exceptions/unknown-nats.exception.d.ts +4 -0
- package/dist/exceptions/unknown-nats.exception.js +17 -0
- package/dist/exceptions/unknown-nats.exception.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/payload.format.d.ts +31 -0
- package/dist/payload.format.js +46 -0
- package/dist/payload.format.js.map +1 -0
- package/package.json +30 -0
- package/src/client/client.config.ts +24 -0
- package/src/client/client.constants.ts +2 -0
- package/src/client/client.decorators.ts +12 -0
- package/src/client/client.metadata.ts +30 -0
- package/src/client/client.module.ts +15 -0
- package/src/client/client.provider.ts +21 -0
- package/src/client/producer.provider.ts +17 -0
- package/src/client/topics.service.ts +21 -0
- package/src/event.codec.ts +37 -0
- package/src/event.type.ts +38 -0
- package/src/exceptions/exception.handler.ts +9 -0
- package/src/exceptions/missing-topics.exception.ts +17 -0
- package/src/exceptions/payload-format.exception.ts +10 -0
- package/src/exceptions/unknown-nats.exception.ts +13 -0
- package/src/index.ts +27 -0
- package/src/payload.format.ts +51 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +7 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
## [5.3.0-next.4](https://github.com/R-Vision/rsdk/compare/v5.3.0-next.3...v5.3.0-next.4) (2024-11-05)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **nats.producer:** direct nats producer alpha implementation ([#301](https://github.com/R-Vision/rsdk/issues/301)) ([d173b51](https://github.com/R-Vision/rsdk/commit/d173b51c664c718a214cdc695708cfdd40fc4dcb))
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DefaultNatsConfig = exports.NatsConfigInstance = void 0;
|
|
13
|
+
const core_1 = require("@rsdk/core");
|
|
14
|
+
exports.NatsConfigInstance = Symbol('NatsConfigInstance');
|
|
15
|
+
let DefaultNatsConfig = class DefaultNatsConfig extends core_1.Config {
|
|
16
|
+
servers;
|
|
17
|
+
debug;
|
|
18
|
+
};
|
|
19
|
+
exports.DefaultNatsConfig = DefaultNatsConfig;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, core_1.Property)('NATS_SERVERS', new core_1.ArrayParser(new core_1.StringParser()), {
|
|
22
|
+
description: 'NATS server URLs',
|
|
23
|
+
}),
|
|
24
|
+
__metadata("design:type", Array)
|
|
25
|
+
], DefaultNatsConfig.prototype, "servers", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, core_1.Property)('NATS_DEBUG', new core_1.BoolParser(), {
|
|
28
|
+
defaultValue: false,
|
|
29
|
+
description: 'Enable NATS debug',
|
|
30
|
+
}),
|
|
31
|
+
__metadata("design:type", Boolean)
|
|
32
|
+
], DefaultNatsConfig.prototype, "debug", void 0);
|
|
33
|
+
exports.DefaultNatsConfig = DefaultNatsConfig = __decorate([
|
|
34
|
+
(0, core_1.ConfigSection)()
|
|
35
|
+
], DefaultNatsConfig);
|
|
36
|
+
//# sourceMappingURL=client.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.config.js","sourceRoot":"","sources":["../../src/client/client.config.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAOoB;AAEP,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAGxD,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,aAAM;IAI3C,OAAO,CAAY;IAMnB,KAAK,CAAW;CACjB,CAAA;AAXY,8CAAiB;AAI5B;IAHC,IAAA,eAAQ,EAAC,cAAc,EAAE,IAAI,kBAAW,CAAC,IAAI,mBAAY,EAAE,CAAC,EAAE;QAC7D,WAAW,EAAE,kBAAkB;KAChC,CAAC;;kDACiB;AAMnB;IAJC,IAAA,eAAQ,EAAC,YAAY,EAAE,IAAI,iBAAU,EAAE,EAAE;QACxC,YAAY,EAAE,KAAK;QACnB,WAAW,EAAE,mBAAmB;KACjC,CAAC;;gDACc;4BAVL,iBAAiB;IAD7B,IAAA,oBAAa,GAAE;GACH,iBAAiB,CAW7B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NATS_PRODUCER_INJECTION_TOKEN = exports.NATS_CLIENT_INJECTION_TOKEN = void 0;
|
|
4
|
+
exports.NATS_CLIENT_INJECTION_TOKEN = Symbol('NatsClient');
|
|
5
|
+
exports.NATS_PRODUCER_INJECTION_TOKEN = Symbol('NatsProducer');
|
|
6
|
+
//# sourceMappingURL=client.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.constants.js","sourceRoot":"","sources":["../../src/client/client.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,2BAA2B,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AACnD,QAAA,6BAA6B,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InjectNatsProducer = exports.InjectNatsClient = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const client_constants_1 = require("./client.constants");
|
|
6
|
+
const InjectNatsClient = () => (0, common_1.Inject)(client_constants_1.NATS_CLIENT_INJECTION_TOKEN);
|
|
7
|
+
exports.InjectNatsClient = InjectNatsClient;
|
|
8
|
+
const InjectNatsProducer = () => (0, common_1.Inject)(client_constants_1.NATS_PRODUCER_INJECTION_TOKEN);
|
|
9
|
+
exports.InjectNatsProducer = InjectNatsProducer;
|
|
10
|
+
//# sourceMappingURL=client.decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.decorators.js","sourceRoot":"","sources":["../../src/client/client.decorators.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAExC,yDAG4B;AAErB,MAAM,gBAAgB,GAAG,GAAuB,EAAE,CACvD,IAAA,eAAM,EAAC,8CAA2B,CAAC,CAAC;AADzB,QAAA,gBAAgB,oBACS;AAE/B,MAAM,kBAAkB,GAAG,GAAuB,EAAE,CACzD,IAAA,eAAM,EAAC,gDAA6B,CAAC,CAAC;AAD3B,QAAA,kBAAkB,sBACS"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { EventType } from '../event.type';
|
|
2
|
+
export declare enum TopicType {
|
|
3
|
+
PRODUCE = 0
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* TODO: Здесь надо разбираться с неймингом. Потому что хрен
|
|
7
|
+
* поймёшь сейчас, что это за типы
|
|
8
|
+
*/
|
|
9
|
+
export type NatsTopicMetadataByTopic = {
|
|
10
|
+
type: TopicType;
|
|
11
|
+
topicName: string;
|
|
12
|
+
};
|
|
13
|
+
export type NatsTopicMetadataByEventType = {
|
|
14
|
+
type: TopicType;
|
|
15
|
+
topicName: string;
|
|
16
|
+
group: string;
|
|
17
|
+
partitionKeyField: string | null;
|
|
18
|
+
eventType?: Pick<EventType, '$type' | '$group' | '$partitionKeyField'>;
|
|
19
|
+
};
|
|
20
|
+
export type NatsTopicMetadata = NatsTopicMetadataByEventType | NatsTopicMetadataByTopic;
|
|
21
|
+
export declare const NATS_TOPIC_RSDK_METADATA_SCOPE = "nats-stream";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NATS_TOPIC_RSDK_METADATA_SCOPE = exports.TopicType = void 0;
|
|
4
|
+
var TopicType;
|
|
5
|
+
(function (TopicType) {
|
|
6
|
+
// CONSUME,
|
|
7
|
+
TopicType[TopicType["PRODUCE"] = 0] = "PRODUCE";
|
|
8
|
+
})(TopicType || (exports.TopicType = TopicType = {}));
|
|
9
|
+
exports.NATS_TOPIC_RSDK_METADATA_SCOPE = 'nats-stream';
|
|
10
|
+
//# sourceMappingURL=client.metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.metadata.js","sourceRoot":"","sources":["../../src/client/client.metadata.ts"],"names":[],"mappings":";;;AAEA,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,WAAW;IACX,+CAAO,CAAA;AACT,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAwBY,QAAA,8BAA8B,GAAG,aAAa,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.NatsClientModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const core_1 = require("@rsdk/core");
|
|
12
|
+
const client_config_1 = require("./client.config");
|
|
13
|
+
const client_provider_1 = require("./client.provider");
|
|
14
|
+
const producer_provider_1 = require("./producer.provider");
|
|
15
|
+
const topics_service_1 = require("./topics.service");
|
|
16
|
+
let NatsClientModule = class NatsClientModule {
|
|
17
|
+
};
|
|
18
|
+
exports.NatsClientModule = NatsClientModule;
|
|
19
|
+
exports.NatsClientModule = NatsClientModule = __decorate([
|
|
20
|
+
(0, common_1.Global)(),
|
|
21
|
+
(0, common_1.Module)({
|
|
22
|
+
imports: [core_1.PlatformConfigModule.forFeature(client_config_1.DefaultNatsConfig)],
|
|
23
|
+
providers: [producer_provider_1.natsProducerProvider, client_provider_1.natsProvider, topics_service_1.TopicsService],
|
|
24
|
+
exports: [producer_provider_1.natsProducerProvider, client_provider_1.natsProvider, topics_service_1.TopicsService],
|
|
25
|
+
})
|
|
26
|
+
], NatsClientModule);
|
|
27
|
+
//# sourceMappingURL=client.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.module.js","sourceRoot":"","sources":["../../src/client/client.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAChD,qCAAkD;AAElD,mDAAoD;AACpD,uDAAiD;AACjD,2DAA2D;AAC3D,qDAAiD;AAQ1C,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAAG,CAAA;AAAnB,4CAAgB;2BAAhB,gBAAgB;IAN5B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,2BAAoB,CAAC,UAAU,CAAC,iCAAiB,CAAC,CAAC;QAC7D,SAAS,EAAE,CAAC,wCAAoB,EAAE,8BAAY,EAAE,8BAAa,CAAC;QAC9D,OAAO,EAAE,CAAC,wCAAoB,EAAE,8BAAY,EAAE,8BAAa,CAAC;KAC7D,CAAC;GACW,gBAAgB,CAAG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.natsProvider = void 0;
|
|
4
|
+
const core_1 = require("@rsdk/core");
|
|
5
|
+
const nats_1 = require("nats");
|
|
6
|
+
const client_config_1 = require("./client.config");
|
|
7
|
+
const client_constants_1 = require("./client.constants");
|
|
8
|
+
exports.natsProvider = {
|
|
9
|
+
inject: [client_config_1.DefaultNatsConfig, core_1.APP_NAME],
|
|
10
|
+
provide: client_constants_1.NATS_CLIENT_INJECTION_TOKEN,
|
|
11
|
+
async useFactory(config, name) {
|
|
12
|
+
return await (0, nats_1.connect)({
|
|
13
|
+
name: `${name}-${process.pid}`,
|
|
14
|
+
...config,
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=client.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.provider.js","sourceRoot":"","sources":["../../src/client/client.provider.ts"],"names":[],"mappings":";;;AACA,qCAAsC;AAEtC,+BAA+B;AAE/B,mDAAoD;AACpD,yDAAiE;AAEpD,QAAA,YAAY,GAAoB;IAC3C,MAAM,EAAE,CAAC,iCAAiB,EAAE,eAAQ,CAAC;IACrC,OAAO,EAAE,8CAA2B;IACpC,KAAK,CAAC,UAAU,CACd,MAAyB,EACzB,IAAY;QAEZ,OAAO,MAAM,IAAA,cAAO,EAAC;YACnB,IAAI,EAAE,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE;YAC9B,GAAG,MAAM;SACV,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.natsProducerProvider = void 0;
|
|
4
|
+
const client_constants_1 = require("./client.constants");
|
|
5
|
+
exports.natsProducerProvider = {
|
|
6
|
+
inject: [client_constants_1.NATS_CLIENT_INJECTION_TOKEN],
|
|
7
|
+
provide: client_constants_1.NATS_PRODUCER_INJECTION_TOKEN,
|
|
8
|
+
async useFactory(client) {
|
|
9
|
+
return client.jetstream();
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=producer.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"producer.provider.js","sourceRoot":"","sources":["../../src/client/producer.provider.ts"],"names":[],"mappings":";;;AAGA,yDAG4B;AAIf,QAAA,oBAAoB,GAAoB;IACnD,MAAM,EAAE,CAAC,8CAA2B,CAAC;IACrC,OAAO,EAAE,gDAA6B;IACtC,KAAK,CAAC,UAAU,CAAC,MAAsB;QACrC,OAAO,MAAM,CAAC,SAAS,EAAE,CAAC;IAC5B,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RsdkMetadataProvider } from '@rsdk/metadata';
|
|
2
|
+
import type { TopicType } from './client.metadata';
|
|
3
|
+
export declare class TopicsService {
|
|
4
|
+
private readonly provider;
|
|
5
|
+
constructor(provider: RsdkMetadataProvider);
|
|
6
|
+
getTopics(type: TopicType): string[];
|
|
7
|
+
private getResources;
|
|
8
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TopicsService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const metadata_1 = require("@rsdk/metadata");
|
|
15
|
+
const client_metadata_1 = require("./client.metadata");
|
|
16
|
+
let TopicsService = class TopicsService {
|
|
17
|
+
provider;
|
|
18
|
+
constructor(provider) {
|
|
19
|
+
this.provider = provider;
|
|
20
|
+
}
|
|
21
|
+
getTopics(type) {
|
|
22
|
+
return this.getResources()
|
|
23
|
+
.filter(({ value }) => value.type === type)
|
|
24
|
+
.map(({ value }) => value.topicName);
|
|
25
|
+
}
|
|
26
|
+
getResources() {
|
|
27
|
+
return this.provider.get(client_metadata_1.NATS_TOPIC_RSDK_METADATA_SCOPE);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.TopicsService = TopicsService;
|
|
31
|
+
exports.TopicsService = TopicsService = __decorate([
|
|
32
|
+
(0, common_1.Injectable)(),
|
|
33
|
+
__metadata("design:paramtypes", [metadata_1.RsdkMetadataProvider])
|
|
34
|
+
], TopicsService);
|
|
35
|
+
//# sourceMappingURL=topics.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topics.service.js","sourceRoot":"","sources":["../../src/client/topics.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAE5C,6CAAsD;AAGtD,uDAAmE;AAG5D,IAAM,aAAa,GAAnB,MAAM,aAAa;IACK;IAA7B,YAA6B,QAA8B;QAA9B,aAAQ,GAAR,QAAQ,CAAsB;IAAG,CAAC;IAE/D,SAAS,CAAC,IAAe;QACvB,OAAO,IAAI,CAAC,YAAY,EAAE;aACvB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;aAC1C,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAEO,YAAY;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAoB,gDAA8B,CAAC,CAAC;IAC9E,CAAC;CACF,CAAA;AAZY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;qCAE4B,+BAAoB;GADhD,aAAa,CAYzB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Payload } from 'nats';
|
|
2
|
+
import type { EventPayload, EventType } from './event.type';
|
|
3
|
+
export interface EventCodec<E extends EventType> {
|
|
4
|
+
decode<P extends EventPayload<E> = EventPayload<E>>(payload: Payload): P;
|
|
5
|
+
encode<P extends EventPayload<E> = EventPayload<E>>(payload: P): Payload;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Protobuf-encoding strategy
|
|
9
|
+
*/
|
|
10
|
+
export declare class ProtoEventCodec<E extends EventType> implements EventCodec<E> {
|
|
11
|
+
readonly eventType: E;
|
|
12
|
+
constructor(eventType: E);
|
|
13
|
+
decode<P extends EventPayload<E>>(buffer: Buffer): P;
|
|
14
|
+
encode<P extends EventPayload<E>>(payload: P): Buffer;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* JSON-encoding strategy
|
|
18
|
+
*/
|
|
19
|
+
export declare class JSONEventCodec<E extends EventType> implements EventCodec<E> {
|
|
20
|
+
decode<P extends EventPayload<E>>(payload: string): P;
|
|
21
|
+
encode<P extends EventPayload<E>>(payload: P): Payload;
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JSONEventCodec = exports.ProtoEventCodec = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Protobuf-encoding strategy
|
|
6
|
+
*/
|
|
7
|
+
class ProtoEventCodec {
|
|
8
|
+
eventType;
|
|
9
|
+
constructor(eventType) {
|
|
10
|
+
this.eventType = eventType;
|
|
11
|
+
}
|
|
12
|
+
decode(buffer) {
|
|
13
|
+
return this.eventType.decode(buffer);
|
|
14
|
+
}
|
|
15
|
+
encode(payload) {
|
|
16
|
+
return Buffer.from(this.eventType.encode(payload).finish());
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ProtoEventCodec = ProtoEventCodec;
|
|
20
|
+
/**
|
|
21
|
+
* JSON-encoding strategy
|
|
22
|
+
*/
|
|
23
|
+
class JSONEventCodec {
|
|
24
|
+
decode(payload) {
|
|
25
|
+
return JSON.parse(payload);
|
|
26
|
+
}
|
|
27
|
+
encode(payload) {
|
|
28
|
+
return JSON.stringify(payload);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.JSONEventCodec = JSONEventCodec;
|
|
32
|
+
//# sourceMappingURL=event.codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.codec.js","sourceRoot":"","sources":["../src/event.codec.ts"],"names":[],"mappings":";;;AAUA;;GAEG;AACH,MAAa,eAAe;IACL;IAArB,YAAqB,SAAY;QAAZ,cAAS,GAAT,SAAS,CAAG;IAAG,CAAC;IAErC,MAAM,CAA4B,MAAc;QAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,CAA4B,OAAU;QAC1C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;CACF;AAVD,0CAUC;AAED;;GAEG;AACH,MAAa,cAAc;IACzB,MAAM,CAA4B,OAAe;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,CAA4B,OAAU;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AARD,wCAQC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Reader, Writer } from 'protobufjs/minimal';
|
|
2
|
+
/**
|
|
3
|
+
* Генерируется при компиляции proto-файлов
|
|
4
|
+
*/
|
|
5
|
+
export interface EventType<T = any> {
|
|
6
|
+
$group: string;
|
|
7
|
+
$partitionKeyField: string | null;
|
|
8
|
+
$type: string;
|
|
9
|
+
encode(message: T): Writer;
|
|
10
|
+
decode(data: Uint8Array | Reader): T;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Выводит тип payload из EventType
|
|
14
|
+
*/
|
|
15
|
+
export type EventPayload<E extends EventType> = E extends EventType<infer P> ? P : never;
|
|
16
|
+
/**
|
|
17
|
+
* Проверяет, является ли переданный тип EventType
|
|
18
|
+
*/
|
|
19
|
+
export declare const isEventType: <T = any>(x: any) => x is EventType<T>;
|
|
20
|
+
/**
|
|
21
|
+
* Генерирует имя subject из EventType
|
|
22
|
+
*/
|
|
23
|
+
export declare const getSubjectName: (eventType: EventType, partitionKey?: string) => string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSubjectName = exports.isEventType = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Проверяет, является ли переданный тип EventType
|
|
6
|
+
*/
|
|
7
|
+
const isEventType = (x) => typeof x === 'object' &&
|
|
8
|
+
typeof x.$type === 'string' &&
|
|
9
|
+
typeof x.$group === 'string';
|
|
10
|
+
exports.isEventType = isEventType;
|
|
11
|
+
/**
|
|
12
|
+
* Генерирует имя subject из EventType
|
|
13
|
+
*/
|
|
14
|
+
const getSubjectName = (eventType, partitionKey) => {
|
|
15
|
+
return `events.${eventType.$type}${partitionKey ? `.${partitionKey}` : ''}`;
|
|
16
|
+
};
|
|
17
|
+
exports.getSubjectName = getSubjectName;
|
|
18
|
+
//# sourceMappingURL=event.type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.type.js","sourceRoot":"","sources":["../src/event.type.ts"],"names":[],"mappings":";;;AAqBA;;GAEG;AACI,MAAM,WAAW,GAAG,CAAU,CAAM,EAAqB,EAAE,CAChE,OAAO,CAAC,KAAK,QAAQ;IACrB,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;IAC3B,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;AAHlB,QAAA,WAAW,eAGO;AAE/B;;GAEG;AACI,MAAM,cAAc,GAAG,CAC5B,SAAoB,EACpB,YAAqB,EACb,EAAE;IACV,OAAO,UAAU,SAAS,CAAC,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9E,CAAC,CAAC;AALW,QAAA,cAAc,kBAKzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const handleNatsException: (error: unknown, pattern: string, details?: unknown) => never;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleNatsException = void 0;
|
|
4
|
+
const unknown_nats_exception_1 = require("./unknown-nats.exception");
|
|
5
|
+
const handleNatsException = (error, pattern, details) => {
|
|
6
|
+
throw new unknown_nats_exception_1.UnknownNatsException(error, pattern, details);
|
|
7
|
+
};
|
|
8
|
+
exports.handleNatsException = handleNatsException;
|
|
9
|
+
//# sourceMappingURL=exception.handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exception.handler.js","sourceRoot":"","sources":["../../src/exceptions/exception.handler.ts"],"names":[],"mappings":";;;AAAA,qEAAgE;AAEzD,MAAM,mBAAmB,GAAG,CACjC,KAAc,EACd,OAAe,EACf,OAAiB,EACV,EAAE;IACT,MAAM,IAAI,6CAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC,CAAC;AANW,QAAA,mBAAmB,uBAM9B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExceptionsProps } from '@rsdk/core';
|
|
2
|
+
import { InternalException } from '@rsdk/core';
|
|
3
|
+
export declare class MissingStreamOrSubjectException extends InternalException {
|
|
4
|
+
readonly topics: string[];
|
|
5
|
+
constructor(topics: string[], props?: ExceptionsProps);
|
|
6
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MissingStreamOrSubjectException = void 0;
|
|
4
|
+
const core_1 = require("@rsdk/core");
|
|
5
|
+
class MissingStreamOrSubjectException extends core_1.InternalException {
|
|
6
|
+
topics;
|
|
7
|
+
constructor(topics, props = {}) {
|
|
8
|
+
super('Expected stream or subject not found', {
|
|
9
|
+
...props,
|
|
10
|
+
details: {
|
|
11
|
+
...props.details,
|
|
12
|
+
topics,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
this.topics = topics;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.MissingStreamOrSubjectException = MissingStreamOrSubjectException;
|
|
19
|
+
//# sourceMappingURL=missing-topics.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-topics.exception.js","sourceRoot":"","sources":["../../src/exceptions/missing-topics.exception.ts"],"names":[],"mappings":";;;AACA,qCAA+C;AAE/C,MAAa,+BAAgC,SAAQ,wBAAiB;IAEzD;IADX,YACW,MAAgB,EACzB,QAAyB,EAAE;QAE3B,KAAK,CAAC,sCAAsC,EAAE;YAC5C,GAAG,KAAK;YACR,OAAO,EAAE;gBACP,GAAG,KAAK,CAAC,OAAO;gBAChB,MAAM;aACP;SACF,CAAC,CAAC;QATM,WAAM,GAAN,MAAM,CAAU;IAU3B,CAAC;CACF;AAbD,0EAaC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PayloadFormatException = void 0;
|
|
4
|
+
const core_1 = require("@rsdk/core");
|
|
5
|
+
class PayloadFormatException extends core_1.BootstrapException {
|
|
6
|
+
constructor(value, allowed) {
|
|
7
|
+
super(`PayloadFormat has wrong value: ${value}, allowed: ${allowed.join(',')}`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.PayloadFormatException = PayloadFormatException;
|
|
11
|
+
//# sourceMappingURL=payload-format.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-format.exception.js","sourceRoot":"","sources":["../../src/exceptions/payload-format.exception.ts"],"names":[],"mappings":";;;AACA,qCAAgD;AAEhD,MAAa,sBAAuB,SAAQ,yBAAkB;IAC5D,YAAY,KAAa,EAAE,OAAoB;QAC7C,KAAK,CACH,kCAAkC,KAAK,cAAc,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CACzE,CAAC;IACJ,CAAC;CACF;AAND,wDAMC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnknownNatsException = void 0;
|
|
4
|
+
const core_1 = require("@rsdk/core");
|
|
5
|
+
class UnknownNatsException extends core_1.InternalException {
|
|
6
|
+
constructor(cause, pattern, details) {
|
|
7
|
+
super('Unknown exception from Nats Server', {
|
|
8
|
+
details: {
|
|
9
|
+
pattern,
|
|
10
|
+
details: details,
|
|
11
|
+
},
|
|
12
|
+
cause,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.UnknownNatsException = UnknownNatsException;
|
|
17
|
+
//# sourceMappingURL=unknown-nats.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-nats.exception.js","sourceRoot":"","sources":["../../src/exceptions/unknown-nats.exception.ts"],"names":[],"mappings":";;;AAAA,qCAA+C;AAE/C,MAAa,oBAAqB,SAAQ,wBAAiB;IACzD,YAAY,KAAc,EAAE,OAAe,EAAE,OAAiB;QAC5D,KAAK,CAAC,oCAAoC,EAAE;YAC1C,OAAO,EAAE;gBACP,OAAO;gBACP,OAAO,EAAE,OAAO;aACjB;YACD,KAAK;SACN,CAAC,CAAC;IACL,CAAC;CACF;AAVD,oDAUC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { EventType, EventPayload, isEventType, getSubjectName, } from './event.type';
|
|
2
|
+
export { EventCodec, ProtoEventCodec, JSONEventCodec } from './event.codec';
|
|
3
|
+
export { PayloadFormat, DEFAULT_PAYLOAD_FORMAT, X_FORMAT_HEADER, X_TYPE_HEADER, } from './payload.format';
|
|
4
|
+
export { NatsTopicMetadata, NatsTopicMetadataByEventType, NatsTopicMetadataByTopic, TopicType, NATS_TOPIC_RSDK_METADATA_SCOPE, } from './client/client.metadata';
|
|
5
|
+
export { NATS_CLIENT_INJECTION_TOKEN, NATS_PRODUCER_INJECTION_TOKEN, } from './client/client.constants';
|
|
6
|
+
export type { Producer } from './client/producer.provider';
|
|
7
|
+
export { NatsClientModule } from './client/client.module';
|
|
8
|
+
export { handleNatsException } from './exceptions/exception.handler';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleNatsException = exports.NatsClientModule = exports.NATS_PRODUCER_INJECTION_TOKEN = exports.NATS_CLIENT_INJECTION_TOKEN = exports.NATS_TOPIC_RSDK_METADATA_SCOPE = exports.TopicType = exports.X_TYPE_HEADER = exports.X_FORMAT_HEADER = exports.DEFAULT_PAYLOAD_FORMAT = exports.PayloadFormat = exports.JSONEventCodec = exports.ProtoEventCodec = exports.getSubjectName = exports.isEventType = void 0;
|
|
4
|
+
var event_type_1 = require("./event.type");
|
|
5
|
+
Object.defineProperty(exports, "isEventType", { enumerable: true, get: function () { return event_type_1.isEventType; } });
|
|
6
|
+
Object.defineProperty(exports, "getSubjectName", { enumerable: true, get: function () { return event_type_1.getSubjectName; } });
|
|
7
|
+
var event_codec_1 = require("./event.codec");
|
|
8
|
+
Object.defineProperty(exports, "ProtoEventCodec", { enumerable: true, get: function () { return event_codec_1.ProtoEventCodec; } });
|
|
9
|
+
Object.defineProperty(exports, "JSONEventCodec", { enumerable: true, get: function () { return event_codec_1.JSONEventCodec; } });
|
|
10
|
+
var payload_format_1 = require("./payload.format");
|
|
11
|
+
Object.defineProperty(exports, "PayloadFormat", { enumerable: true, get: function () { return payload_format_1.PayloadFormat; } });
|
|
12
|
+
Object.defineProperty(exports, "DEFAULT_PAYLOAD_FORMAT", { enumerable: true, get: function () { return payload_format_1.DEFAULT_PAYLOAD_FORMAT; } });
|
|
13
|
+
Object.defineProperty(exports, "X_FORMAT_HEADER", { enumerable: true, get: function () { return payload_format_1.X_FORMAT_HEADER; } });
|
|
14
|
+
Object.defineProperty(exports, "X_TYPE_HEADER", { enumerable: true, get: function () { return payload_format_1.X_TYPE_HEADER; } });
|
|
15
|
+
var client_metadata_1 = require("./client/client.metadata");
|
|
16
|
+
Object.defineProperty(exports, "TopicType", { enumerable: true, get: function () { return client_metadata_1.TopicType; } });
|
|
17
|
+
Object.defineProperty(exports, "NATS_TOPIC_RSDK_METADATA_SCOPE", { enumerable: true, get: function () { return client_metadata_1.NATS_TOPIC_RSDK_METADATA_SCOPE; } });
|
|
18
|
+
var client_constants_1 = require("./client/client.constants");
|
|
19
|
+
Object.defineProperty(exports, "NATS_CLIENT_INJECTION_TOKEN", { enumerable: true, get: function () { return client_constants_1.NATS_CLIENT_INJECTION_TOKEN; } });
|
|
20
|
+
Object.defineProperty(exports, "NATS_PRODUCER_INJECTION_TOKEN", { enumerable: true, get: function () { return client_constants_1.NATS_PRODUCER_INJECTION_TOKEN; } });
|
|
21
|
+
var client_module_1 = require("./client/client.module");
|
|
22
|
+
Object.defineProperty(exports, "NatsClientModule", { enumerable: true, get: function () { return client_module_1.NatsClientModule; } });
|
|
23
|
+
var exception_handler_1 = require("./exceptions/exception.handler");
|
|
24
|
+
Object.defineProperty(exports, "handleNatsException", { enumerable: true, get: function () { return exception_handler_1.handleNatsException; } });
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAKsB;AAFpB,yGAAA,WAAW,OAAA;AACX,4GAAA,cAAc,OAAA;AAEhB,6CAA4E;AAAvD,8GAAA,eAAe,OAAA;AAAE,6GAAA,cAAc,OAAA;AACpD,mDAK0B;AAJxB,+GAAA,aAAa,OAAA;AACb,wHAAA,sBAAsB,OAAA;AACtB,iHAAA,eAAe,OAAA;AACf,+GAAA,aAAa,OAAA;AAEf,4DAMkC;AAFhC,4GAAA,SAAS,OAAA;AACT,iIAAA,8BAA8B,OAAA;AAEhC,8DAGmC;AAFjC,+HAAA,2BAA2B,OAAA;AAC3B,iIAAA,6BAA6B,OAAA;AAG/B,wDAA0D;AAAjD,iHAAA,gBAAgB,OAAA;AACzB,oEAAqE;AAA5D,wHAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Способ сериализации данных события
|
|
3
|
+
*/
|
|
4
|
+
export declare enum PayloadFormat {
|
|
5
|
+
PROTOBUF = "protobuf",
|
|
6
|
+
JSON = "json"
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Проверяет, является ли переданная строка - одним
|
|
10
|
+
* из значений перечисления PayloadFormat
|
|
11
|
+
*/
|
|
12
|
+
export declare const isPayloadFormat: (value: string) => value is PayloadFormat;
|
|
13
|
+
/**
|
|
14
|
+
* Проверяет, является ли переданная строка - одним
|
|
15
|
+
* из значений перечисления PayloadFormat. В случае,
|
|
16
|
+
* если передано неверное значение - бросает ошибку
|
|
17
|
+
*/
|
|
18
|
+
export declare const assertIsPayloadFormat: (value: string) => asserts value is PayloadFormat;
|
|
19
|
+
/**
|
|
20
|
+
* Заголовок в kafka, через который передаётся способ
|
|
21
|
+
* сериализации
|
|
22
|
+
*/
|
|
23
|
+
export declare const X_FORMAT_HEADER = "X-Format";
|
|
24
|
+
/**
|
|
25
|
+
* Сериализация по умолчанию (protobuf)
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_PAYLOAD_FORMAT = PayloadFormat.PROTOBUF;
|
|
28
|
+
/**
|
|
29
|
+
* Заголовок в nats, через который передаётся тип сообщения
|
|
30
|
+
*/
|
|
31
|
+
export declare const X_TYPE_HEADER = "X-Type";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.X_TYPE_HEADER = exports.DEFAULT_PAYLOAD_FORMAT = exports.X_FORMAT_HEADER = exports.assertIsPayloadFormat = exports.isPayloadFormat = exports.PayloadFormat = void 0;
|
|
4
|
+
const common_1 = require("@rsdk/common");
|
|
5
|
+
const payload_format_exception_1 = require("./exceptions/payload-format.exception");
|
|
6
|
+
/**
|
|
7
|
+
* Способ сериализации данных события
|
|
8
|
+
*/
|
|
9
|
+
var PayloadFormat;
|
|
10
|
+
(function (PayloadFormat) {
|
|
11
|
+
PayloadFormat["PROTOBUF"] = "protobuf";
|
|
12
|
+
PayloadFormat["JSON"] = "json";
|
|
13
|
+
})(PayloadFormat || (exports.PayloadFormat = PayloadFormat = {}));
|
|
14
|
+
const allowed = common_1.Enum.values(PayloadFormat);
|
|
15
|
+
/**
|
|
16
|
+
* Проверяет, является ли переданная строка - одним
|
|
17
|
+
* из значений перечисления PayloadFormat
|
|
18
|
+
*/
|
|
19
|
+
const isPayloadFormat = (value) => allowed.includes(value);
|
|
20
|
+
exports.isPayloadFormat = isPayloadFormat;
|
|
21
|
+
/**
|
|
22
|
+
* Проверяет, является ли переданная строка - одним
|
|
23
|
+
* из значений перечисления PayloadFormat. В случае,
|
|
24
|
+
* если передано неверное значение - бросает ошибку
|
|
25
|
+
*/
|
|
26
|
+
const assertIsPayloadFormat = (value) => {
|
|
27
|
+
if ((0, exports.isPayloadFormat)(value)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
throw new payload_format_exception_1.PayloadFormatException(value, allowed);
|
|
31
|
+
};
|
|
32
|
+
exports.assertIsPayloadFormat = assertIsPayloadFormat;
|
|
33
|
+
/**
|
|
34
|
+
* Заголовок в kafka, через который передаётся способ
|
|
35
|
+
* сериализации
|
|
36
|
+
*/
|
|
37
|
+
exports.X_FORMAT_HEADER = 'X-Format';
|
|
38
|
+
/**
|
|
39
|
+
* Сериализация по умолчанию (protobuf)
|
|
40
|
+
*/
|
|
41
|
+
exports.DEFAULT_PAYLOAD_FORMAT = PayloadFormat.PROTOBUF;
|
|
42
|
+
/**
|
|
43
|
+
* Заголовок в nats, через который передаётся тип сообщения
|
|
44
|
+
*/
|
|
45
|
+
exports.X_TYPE_HEADER = 'X-Type';
|
|
46
|
+
//# sourceMappingURL=payload.format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.format.js","sourceRoot":"","sources":["../src/payload.format.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AAEpC,oFAA+E;AAE/E;;GAEG;AACH,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,sCAAqB,CAAA;IACrB,8BAAa,CAAA;AACf,CAAC,EAHW,aAAa,6BAAb,aAAa,QAGxB;AAED,MAAM,OAAO,GAAG,aAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AAE3C;;;GAGG;AACI,MAAM,eAAe,GAAG,CAAC,KAAa,EAA0B,EAAE,CACvE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AADb,QAAA,eAAe,mBACF;AAE1B;;;;GAIG;AACI,MAAM,qBAAqB,GAAG,CACnC,KAAa,EACmB,EAAE;IAClC,IAAI,IAAA,uBAAe,EAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IAED,MAAM,IAAI,iDAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC;AARW,QAAA,qBAAqB,yBAQhC;AAEF;;;GAGG;AACU,QAAA,eAAe,GAAG,UAAU,CAAC;AAE1C;;GAEG;AACU,QAAA,sBAAsB,GAAG,aAAa,CAAC,QAAQ,CAAC;AAE7D;;GAEG;AACU,QAAA,aAAa,GAAG,QAAQ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rsdk/nats.common",
|
|
3
|
+
"version": "5.3.0-next.4",
|
|
4
|
+
"description": "Common functionality for nats consumers and producers",
|
|
5
|
+
"license": "Apache License 2.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"url": "https://github.com/R-Vision/rsdk"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"@nestjs/common": "^10.0.0",
|
|
15
|
+
"@nestjs/core": "^10.0.0",
|
|
16
|
+
"@nestjs/microservices": "^10.0.0",
|
|
17
|
+
"@rsdk/common": "*",
|
|
18
|
+
"@rsdk/core": "*",
|
|
19
|
+
"@rsdk/logging": "*",
|
|
20
|
+
"@rsdk/metadata": "*",
|
|
21
|
+
"nats": "^2.28.2",
|
|
22
|
+
"reflect-metadata": "^0.1.12 || ^0.2.0",
|
|
23
|
+
"rxjs": "^7.8.1"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"lodash": "^4.17.21",
|
|
27
|
+
"protobufjs": "^7.2.3"
|
|
28
|
+
},
|
|
29
|
+
"gitHead": "6d80aacd87b9cc36cfcff8c0c050e4fe31810276"
|
|
30
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ArrayParser,
|
|
3
|
+
BoolParser,
|
|
4
|
+
Config,
|
|
5
|
+
ConfigSection,
|
|
6
|
+
Property,
|
|
7
|
+
StringParser,
|
|
8
|
+
} from '@rsdk/core';
|
|
9
|
+
|
|
10
|
+
export const NatsConfigInstance = Symbol('NatsConfigInstance');
|
|
11
|
+
|
|
12
|
+
@ConfigSection()
|
|
13
|
+
export class DefaultNatsConfig extends Config {
|
|
14
|
+
@Property('NATS_SERVERS', new ArrayParser(new StringParser()), {
|
|
15
|
+
description: 'NATS server URLs',
|
|
16
|
+
})
|
|
17
|
+
servers!: string[];
|
|
18
|
+
|
|
19
|
+
@Property('NATS_DEBUG', new BoolParser(), {
|
|
20
|
+
defaultValue: false,
|
|
21
|
+
description: 'Enable NATS debug',
|
|
22
|
+
})
|
|
23
|
+
debug!: boolean;
|
|
24
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Inject } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
NATS_CLIENT_INJECTION_TOKEN,
|
|
5
|
+
NATS_PRODUCER_INJECTION_TOKEN,
|
|
6
|
+
} from './client.constants';
|
|
7
|
+
|
|
8
|
+
export const InjectNatsClient = (): ParameterDecorator =>
|
|
9
|
+
Inject(NATS_CLIENT_INJECTION_TOKEN);
|
|
10
|
+
|
|
11
|
+
export const InjectNatsProducer = (): ParameterDecorator =>
|
|
12
|
+
Inject(NATS_PRODUCER_INJECTION_TOKEN);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EventType } from '../event.type';
|
|
2
|
+
|
|
3
|
+
export enum TopicType {
|
|
4
|
+
// CONSUME,
|
|
5
|
+
PRODUCE,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* TODO: Здесь надо разбираться с неймингом. Потому что хрен
|
|
10
|
+
* поймёшь сейчас, что это за типы
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type NatsTopicMetadataByTopic = {
|
|
14
|
+
type: TopicType;
|
|
15
|
+
topicName: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type NatsTopicMetadataByEventType = {
|
|
19
|
+
type: TopicType;
|
|
20
|
+
topicName: string;
|
|
21
|
+
group: string;
|
|
22
|
+
partitionKeyField: string | null;
|
|
23
|
+
eventType?: Pick<EventType, '$type' | '$group' | '$partitionKeyField'>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type NatsTopicMetadata =
|
|
27
|
+
| NatsTopicMetadataByEventType
|
|
28
|
+
| NatsTopicMetadataByTopic;
|
|
29
|
+
|
|
30
|
+
export const NATS_TOPIC_RSDK_METADATA_SCOPE = 'nats-stream';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Global, Module } from '@nestjs/common';
|
|
2
|
+
import { PlatformConfigModule } from '@rsdk/core';
|
|
3
|
+
|
|
4
|
+
import { DefaultNatsConfig } from './client.config';
|
|
5
|
+
import { natsProvider } from './client.provider';
|
|
6
|
+
import { natsProducerProvider } from './producer.provider';
|
|
7
|
+
import { TopicsService } from './topics.service';
|
|
8
|
+
|
|
9
|
+
@Global()
|
|
10
|
+
@Module({
|
|
11
|
+
imports: [PlatformConfigModule.forFeature(DefaultNatsConfig)],
|
|
12
|
+
providers: [natsProducerProvider, natsProvider, TopicsService],
|
|
13
|
+
exports: [natsProducerProvider, natsProvider, TopicsService],
|
|
14
|
+
})
|
|
15
|
+
export class NatsClientModule {}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FactoryProvider } from '@nestjs/common';
|
|
2
|
+
import { APP_NAME } from '@rsdk/core';
|
|
3
|
+
import type { NatsConnection } from 'nats';
|
|
4
|
+
import { connect } from 'nats';
|
|
5
|
+
|
|
6
|
+
import { DefaultNatsConfig } from './client.config';
|
|
7
|
+
import { NATS_CLIENT_INJECTION_TOKEN } from './client.constants';
|
|
8
|
+
|
|
9
|
+
export const natsProvider: FactoryProvider = {
|
|
10
|
+
inject: [DefaultNatsConfig, APP_NAME],
|
|
11
|
+
provide: NATS_CLIENT_INJECTION_TOKEN,
|
|
12
|
+
async useFactory(
|
|
13
|
+
config: DefaultNatsConfig,
|
|
14
|
+
name: string,
|
|
15
|
+
): Promise<NatsConnection> {
|
|
16
|
+
return await connect({
|
|
17
|
+
name: `${name}-${process.pid}`,
|
|
18
|
+
...config,
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FactoryProvider } from '@nestjs/common';
|
|
2
|
+
import type { JetStreamClient, NatsConnection } from 'nats';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
NATS_CLIENT_INJECTION_TOKEN,
|
|
6
|
+
NATS_PRODUCER_INJECTION_TOKEN,
|
|
7
|
+
} from './client.constants';
|
|
8
|
+
|
|
9
|
+
export type Producer = JetStreamClient;
|
|
10
|
+
|
|
11
|
+
export const natsProducerProvider: FactoryProvider = {
|
|
12
|
+
inject: [NATS_CLIENT_INJECTION_TOKEN],
|
|
13
|
+
provide: NATS_PRODUCER_INJECTION_TOKEN,
|
|
14
|
+
async useFactory(client: NatsConnection): Promise<Producer> {
|
|
15
|
+
return client.jetstream();
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import type { Resource } from '@rsdk/metadata';
|
|
3
|
+
import { RsdkMetadataProvider } from '@rsdk/metadata';
|
|
4
|
+
|
|
5
|
+
import type { NatsTopicMetadata, TopicType } from './client.metadata';
|
|
6
|
+
import { NATS_TOPIC_RSDK_METADATA_SCOPE } from './client.metadata';
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class TopicsService {
|
|
10
|
+
constructor(private readonly provider: RsdkMetadataProvider) {}
|
|
11
|
+
|
|
12
|
+
getTopics(type: TopicType): string[] {
|
|
13
|
+
return this.getResources()
|
|
14
|
+
.filter(({ value }) => value.type === type)
|
|
15
|
+
.map(({ value }) => value.topicName);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private getResources(): Resource<NatsTopicMetadata>[] {
|
|
19
|
+
return this.provider.get<NatsTopicMetadata>(NATS_TOPIC_RSDK_METADATA_SCOPE);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Payload } from 'nats';
|
|
2
|
+
|
|
3
|
+
import type { EventPayload, EventType } from './event.type';
|
|
4
|
+
|
|
5
|
+
export interface EventCodec<E extends EventType> {
|
|
6
|
+
decode<P extends EventPayload<E> = EventPayload<E>>(payload: Payload): P;
|
|
7
|
+
|
|
8
|
+
encode<P extends EventPayload<E> = EventPayload<E>>(payload: P): Payload;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Protobuf-encoding strategy
|
|
13
|
+
*/
|
|
14
|
+
export class ProtoEventCodec<E extends EventType> implements EventCodec<E> {
|
|
15
|
+
constructor(readonly eventType: E) {}
|
|
16
|
+
|
|
17
|
+
decode<P extends EventPayload<E>>(buffer: Buffer): P {
|
|
18
|
+
return this.eventType.decode(buffer);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
encode<P extends EventPayload<E>>(payload: P): Buffer {
|
|
22
|
+
return Buffer.from(this.eventType.encode(payload).finish());
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* JSON-encoding strategy
|
|
28
|
+
*/
|
|
29
|
+
export class JSONEventCodec<E extends EventType> implements EventCodec<E> {
|
|
30
|
+
decode<P extends EventPayload<E>>(payload: string): P {
|
|
31
|
+
return JSON.parse(payload);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
encode<P extends EventPayload<E>>(payload: P): Payload {
|
|
35
|
+
return JSON.stringify(payload);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Reader, Writer } from 'protobufjs/minimal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Генерируется при компиляции proto-файлов
|
|
5
|
+
*/
|
|
6
|
+
export interface EventType<T = any> {
|
|
7
|
+
$group: string;
|
|
8
|
+
$partitionKeyField: string | null;
|
|
9
|
+
$type: string;
|
|
10
|
+
|
|
11
|
+
encode(message: T): Writer;
|
|
12
|
+
|
|
13
|
+
decode(data: Uint8Array | Reader): T;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Выводит тип payload из EventType
|
|
18
|
+
*/
|
|
19
|
+
export type EventPayload<E extends EventType> =
|
|
20
|
+
E extends EventType<infer P> ? P : never;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Проверяет, является ли переданный тип EventType
|
|
24
|
+
*/
|
|
25
|
+
export const isEventType = <T = any>(x: any): x is EventType<T> =>
|
|
26
|
+
typeof x === 'object' &&
|
|
27
|
+
typeof x.$type === 'string' &&
|
|
28
|
+
typeof x.$group === 'string';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Генерирует имя subject из EventType
|
|
32
|
+
*/
|
|
33
|
+
export const getSubjectName = (
|
|
34
|
+
eventType: EventType,
|
|
35
|
+
partitionKey?: string,
|
|
36
|
+
): string => {
|
|
37
|
+
return `events.${eventType.$type}${partitionKey ? `.${partitionKey}` : ''}`;
|
|
38
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ExceptionsProps } from '@rsdk/core';
|
|
2
|
+
import { InternalException } from '@rsdk/core';
|
|
3
|
+
|
|
4
|
+
export class MissingStreamOrSubjectException extends InternalException {
|
|
5
|
+
constructor(
|
|
6
|
+
readonly topics: string[],
|
|
7
|
+
props: ExceptionsProps = {},
|
|
8
|
+
) {
|
|
9
|
+
super('Expected stream or subject not found', {
|
|
10
|
+
...props,
|
|
11
|
+
details: {
|
|
12
|
+
...props.details,
|
|
13
|
+
topics,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EnumValue } from '@rsdk/common';
|
|
2
|
+
import { BootstrapException } from '@rsdk/core';
|
|
3
|
+
|
|
4
|
+
export class PayloadFormatException extends BootstrapException {
|
|
5
|
+
constructor(value: string, allowed: EnumValue[]) {
|
|
6
|
+
super(
|
|
7
|
+
`PayloadFormat has wrong value: ${value}, allowed: ${allowed.join(',')}`,
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InternalException } from '@rsdk/core';
|
|
2
|
+
|
|
3
|
+
export class UnknownNatsException extends InternalException {
|
|
4
|
+
constructor(cause: unknown, pattern: string, details?: unknown) {
|
|
5
|
+
super('Unknown exception from Nats Server', {
|
|
6
|
+
details: {
|
|
7
|
+
pattern,
|
|
8
|
+
details: details,
|
|
9
|
+
},
|
|
10
|
+
cause,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export {
|
|
2
|
+
EventType,
|
|
3
|
+
EventPayload,
|
|
4
|
+
isEventType,
|
|
5
|
+
getSubjectName,
|
|
6
|
+
} from './event.type';
|
|
7
|
+
export { EventCodec, ProtoEventCodec, JSONEventCodec } from './event.codec';
|
|
8
|
+
export {
|
|
9
|
+
PayloadFormat,
|
|
10
|
+
DEFAULT_PAYLOAD_FORMAT,
|
|
11
|
+
X_FORMAT_HEADER,
|
|
12
|
+
X_TYPE_HEADER,
|
|
13
|
+
} from './payload.format';
|
|
14
|
+
export {
|
|
15
|
+
NatsTopicMetadata,
|
|
16
|
+
NatsTopicMetadataByEventType,
|
|
17
|
+
NatsTopicMetadataByTopic,
|
|
18
|
+
TopicType,
|
|
19
|
+
NATS_TOPIC_RSDK_METADATA_SCOPE,
|
|
20
|
+
} from './client/client.metadata';
|
|
21
|
+
export {
|
|
22
|
+
NATS_CLIENT_INJECTION_TOKEN,
|
|
23
|
+
NATS_PRODUCER_INJECTION_TOKEN,
|
|
24
|
+
} from './client/client.constants';
|
|
25
|
+
export type { Producer } from './client/producer.provider';
|
|
26
|
+
export { NatsClientModule } from './client/client.module';
|
|
27
|
+
export { handleNatsException } from './exceptions/exception.handler';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Enum } from '@rsdk/common';
|
|
2
|
+
|
|
3
|
+
import { PayloadFormatException } from './exceptions/payload-format.exception';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Способ сериализации данных события
|
|
7
|
+
*/
|
|
8
|
+
export enum PayloadFormat {
|
|
9
|
+
PROTOBUF = 'protobuf',
|
|
10
|
+
JSON = 'json',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const allowed = Enum.values(PayloadFormat);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Проверяет, является ли переданная строка - одним
|
|
17
|
+
* из значений перечисления PayloadFormat
|
|
18
|
+
*/
|
|
19
|
+
export const isPayloadFormat = (value: string): value is PayloadFormat =>
|
|
20
|
+
allowed.includes(value);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Проверяет, является ли переданная строка - одним
|
|
24
|
+
* из значений перечисления PayloadFormat. В случае,
|
|
25
|
+
* если передано неверное значение - бросает ошибку
|
|
26
|
+
*/
|
|
27
|
+
export const assertIsPayloadFormat = (
|
|
28
|
+
value: string,
|
|
29
|
+
): asserts value is PayloadFormat => {
|
|
30
|
+
if (isPayloadFormat(value)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
throw new PayloadFormatException(value, allowed);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Заголовок в kafka, через который передаётся способ
|
|
39
|
+
* сериализации
|
|
40
|
+
*/
|
|
41
|
+
export const X_FORMAT_HEADER = 'X-Format';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Сериализация по умолчанию (protobuf)
|
|
45
|
+
*/
|
|
46
|
+
export const DEFAULT_PAYLOAD_FORMAT = PayloadFormat.PROTOBUF;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Заголовок в nats, через который передаётся тип сообщения
|
|
50
|
+
*/
|
|
51
|
+
export const X_TYPE_HEADER = 'X-Type';
|