@bolt.tech/kafka-utils 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/build/dependencies/paramstore/paramstore.d.ts +6 -0
  2. package/build/dependencies/paramstore/paramstore.js +27 -0
  3. package/build/index.d.ts +5 -0
  4. package/build/index.js +51 -0
  5. package/build/kafkaServer.d.ts +1 -0
  6. package/build/kafkaServer.js +78 -0
  7. package/build/store/interfaces/assestTriggerNotification.interface.d.ts +27 -0
  8. package/build/store/interfaces/assestTriggerNotification.interface.js +2 -0
  9. package/build/store/interfaces/authEmailNotification.interface.d.ts +11 -0
  10. package/build/store/interfaces/authEmailNotification.interface.js +2 -0
  11. package/build/store/interfaces/boltChargerNotificationV2.interface.d.ts +20 -0
  12. package/build/store/interfaces/boltChargerNotificationV2.interface.js +2 -0
  13. package/build/store/interfaces/kafkaSecret.interface.d.ts +5 -0
  14. package/build/store/interfaces/kafkaSecret.interface.js +2 -0
  15. package/build/store/interfaces/notification.interface.d.ts +35 -0
  16. package/build/store/interfaces/notification.interface.js +2 -0
  17. package/build/store/types/notification.type.d.ts +2 -0
  18. package/build/store/types/notification.type.js +2 -0
  19. package/build/utils/kafka/brokers.kafka.d.ts +1 -0
  20. package/build/utils/kafka/brokers.kafka.js +24 -0
  21. package/build/utils/kafka/config.kafka.d.ts +7 -0
  22. package/build/utils/kafka/config.kafka.js +27 -0
  23. package/build/utils/kafka/producer.kafka.d.ts +8 -0
  24. package/build/utils/kafka/producer.kafka.js +52 -0
  25. package/build/utils/kafka/publisher.kafka.d.ts +1 -0
  26. package/build/utils/kafka/publisher.kafka.js +28 -0
  27. package/build/utils/kafka/topicMap.kafka.d.ts +1 -0
  28. package/build/utils/kafka/topicMap.kafka.js +11 -0
  29. package/build/utils/schemaRegistry/notificationSchema.registry.d.ts +15 -0
  30. package/build/utils/schemaRegistry/notificationSchema.registry.js +64 -0
  31. package/build/utils/schemaRegistry/pickSchema.d.ts +1 -0
  32. package/build/utils/schemaRegistry/pickSchema.js +38 -0
  33. package/build/utils/schemaRegistry/registry.util.d.ts +8 -0
  34. package/build/utils/schemaRegistry/registry.util.js +21 -0
  35. package/package.json +36 -0
@@ -0,0 +1,6 @@
1
+ export declare class ParamStore {
2
+ private PARAMSTORE_PATH;
3
+ private NODE_ENV_LOCAL;
4
+ constructor(PARAMSTORE_PATH: string, NODE_ENV_LOCAL: string);
5
+ getParams(): Promise<void>;
6
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ParamStore = void 0;
13
+ const bolt_paramstore_1 = require("bolt-paramstore");
14
+ class ParamStore {
15
+ constructor(PARAMSTORE_PATH, NODE_ENV_LOCAL) {
16
+ this.PARAMSTORE_PATH = PARAMSTORE_PATH;
17
+ this.NODE_ENV_LOCAL = NODE_ENV_LOCAL;
18
+ }
19
+ getParams() {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ yield (0, bolt_paramstore_1.getParameters)(`/${this.PARAMSTORE_PATH}/common/`);
22
+ if (this.NODE_ENV_LOCAL === "TRUE")
23
+ yield (0, bolt_paramstore_1.getParameters)(`/local/${this.PARAMSTORE_PATH}/`);
24
+ });
25
+ }
26
+ }
27
+ exports.ParamStore = ParamStore;
@@ -0,0 +1,5 @@
1
+ import { notificationType } from './store/types/notification.type';
2
+ declare let notificationType: notificationType;
3
+ export declare function initialiseNotification(paramStorePath: "dev" | "prod", nodeEnvLocal: "TRUE" | "FALSE", serviceName: string, notificationType: notificationType): Promise<void>;
4
+ export declare function sendNotification(userId: string, message: any): Promise<void>;
5
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.initialiseNotification = initialiseNotification;
13
+ exports.sendNotification = sendNotification;
14
+ const getTopic = require('./kafka/topicMap.kafka');
15
+ let notificationType;
16
+ function initialiseNotification(paramStorePath, nodeEnvLocal, serviceName, notificationType) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ try {
19
+ notificationType = notificationType;
20
+ const KafkaServer = require('./kafkaServer');
21
+ const kafkaInstance = new KafkaServer();
22
+ yield kafkaInstance.setupKafka(paramStorePath, nodeEnvLocal, serviceName, notificationType);
23
+ this.setupShutdownHandlers();
24
+ console.log("---------------------------------------------");
25
+ console.log("Notification utility is ready.");
26
+ console.log("---------------------------------------------");
27
+ }
28
+ catch (e) {
29
+ console.log("🔴 kafka-utils: initialiseNotification", e);
30
+ }
31
+ });
32
+ }
33
+ const NotificationSchema = require('./schemaRegistry/notificationSchema.registry');
34
+ const publishToKafka = require('./kafka/publisher.kafka');
35
+ function sendNotification(userId, message) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ try {
38
+ if (!this.notificationSchema) {
39
+ throw new Error("Notification schema is not initialised");
40
+ }
41
+ const topic = getTopic(notificationType);
42
+ let key = userId;
43
+ const instance = NotificationSchema.getInstance();
44
+ const schemaId = yield instance.getSchemaId();
45
+ yield publishToKafka(topic, schemaId, { key, value: message });
46
+ }
47
+ catch (e) {
48
+ console.log("🔴 kafka-utils: sendNotification", e);
49
+ }
50
+ });
51
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ const producer_kafka_1 = require("./utils/kafka/producer.kafka");
36
+ const config_kafka_1 = require("./utils/kafka/config.kafka");
37
+ const dotenv = __importStar(require("dotenv"));
38
+ const paramstore_1 = require("./dependencies/paramstore/paramstore");
39
+ const notificationSchema_registry_1 = require("./utils/schemaRegistry/notificationSchema.registry");
40
+ const registry_util_1 = require("./utils/schemaRegistry/registry.util");
41
+ const getKafkaBrokers = require('./utils/kafka/brokers.kafka');
42
+ class KafkaServer {
43
+ constructor() {
44
+ // public express: express.Application;
45
+ this.paramStore = null;
46
+ this.schemaRegistry = null;
47
+ this.notificationSchema = null;
48
+ this.handleShutdown = () => __awaiter(this, void 0, void 0, function* () {
49
+ console.log('Shutting down Kafka Server...');
50
+ yield producer_kafka_1.KafkaProducer.shutdown();
51
+ process.exit(0);
52
+ });
53
+ dotenv.config();
54
+ }
55
+ setupKafka(paramStorePath, nodeEnvLocal, serviceName, notificationType) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ // Retrieve values from paramstore
58
+ this.paramStore = new paramstore_1.ParamStore(paramStorePath, nodeEnvLocal);
59
+ yield this.paramStore.getParams();
60
+ // Get Kafka brokers
61
+ const kafkaConnectionDetails = yield getKafkaBrokers();
62
+ const kafka = config_kafka_1.KafkaConfig.getConfig(kafkaConnectionDetails, serviceName);
63
+ // Connect to Kafka
64
+ yield producer_kafka_1.KafkaProducer.connect(kafka);
65
+ // Connect to Schema Registry
66
+ registry_util_1.SchemaRegistryS.connect(process.env.SCHEMA_REGISTRY_URL);
67
+ this.schemaRegistry = registry_util_1.SchemaRegistryS.getInstance();
68
+ // Register Notification schema
69
+ this.notificationSchema = notificationSchema_registry_1.NotificationSchema.getInstance();
70
+ yield this.notificationSchema.register(notificationType);
71
+ });
72
+ }
73
+ setupShutdownHandlers() {
74
+ process.on('SIGINT', this.handleShutdown);
75
+ process.on('SIGTERM', this.handleShutdown);
76
+ }
77
+ }
78
+ module.exports = KafkaServer;
@@ -0,0 +1,27 @@
1
+ export interface IAssetsTriggerNotification {
2
+ user?: IUser;
3
+ message?: IMessage;
4
+ appId?: string;
5
+ smsObj?: ISmsObj;
6
+ oneSignalPayload?: IOneSignalPayload;
7
+ }
8
+ export interface IUser {
9
+ inAppNotificationUserId?: string;
10
+ pushNotificationUserId?: string;
11
+ emailIds?: string[];
12
+ phoneNumbers?: string[];
13
+ }
14
+ export interface IMessage {
15
+ body?: string;
16
+ subject?: string;
17
+ priority?: number;
18
+ }
19
+ export interface ISmsObj {
20
+ smsType?: string;
21
+ templateId?: string;
22
+ }
23
+ export interface IOneSignalPayload {
24
+ alert?: string;
25
+ sos?: boolean;
26
+ vin?: string;
27
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ export interface IAuthNotificationSchema {
2
+ user?: IUser;
3
+ message?: IMessage;
4
+ }
5
+ export interface IUser {
6
+ emailIds: string[];
7
+ }
8
+ export interface IMessage {
9
+ body?: string;
10
+ subject?: string;
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ export interface IBoltChargerNotificationV2 {
2
+ user?: IUser;
3
+ message?: IMessage;
4
+ appId?: string;
5
+ smsObj?: ISmsObj;
6
+ }
7
+ export interface IUser {
8
+ pushNotificationUserId?: string;
9
+ inAppNotificationUserId?: string;
10
+ phoneNumbers: string[];
11
+ emailIds: string[];
12
+ }
13
+ export interface IMessage {
14
+ body?: string;
15
+ subject?: string;
16
+ }
17
+ export interface ISmsObj {
18
+ smsType?: string;
19
+ templateId?: string;
20
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export interface IKafkaSecret {
2
+ username: string;
3
+ password: string;
4
+ brokers: string[];
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,35 @@
1
+ export interface IUser {
2
+ inAppNotificationUserId: string;
3
+ pushNotificationUserId: string;
4
+ emailIds: string[];
5
+ phoneNumbers: string[];
6
+ }
7
+ export interface IMessage {
8
+ body: string;
9
+ subject: string;
10
+ priority: number;
11
+ attachments: Uint8Array[];
12
+ html: string;
13
+ }
14
+ export interface ISmsObj {
15
+ smsType: string;
16
+ templateId: string;
17
+ }
18
+ export interface IOneSignalPayload {
19
+ alert: string;
20
+ sos: boolean;
21
+ vin: string;
22
+ }
23
+ export interface IAttachment {
24
+ filename: string;
25
+ filetype: string;
26
+ content: Uint8Array;
27
+ }
28
+ export interface INotification {
29
+ user: IUser;
30
+ message: IMessage;
31
+ appId: string;
32
+ smsObj: ISmsObj;
33
+ oneSignalPayload: IOneSignalPayload;
34
+ Attachment: IAttachment;
35
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ /** For three different topics and corresponding schemas */
2
+ export type notificationType = "bolt" | "asset-triggers" | "common";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const bolt_paramstore_1 = require("bolt-paramstore");
13
+ function getKafkaBrokers() {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const slug = process.env.NODE_ENV_LOCAL === "TRUE" ? "KAFKA_CREDENTIALS_EXTERNAL" : "KAFKA_CREDENTIALS";
16
+ const config = yield (0, bolt_paramstore_1.getSecret)(`${process.env.PARAMSTORE_PATH}/common/${slug}`);
17
+ if (!config.brokers) {
18
+ throw new Error('Kafka brokers configuration not found.');
19
+ }
20
+ config.brokers = JSON.parse(config.brokers);
21
+ return config;
22
+ });
23
+ }
24
+ module.exports = { getKafkaBroker: getKafkaBrokers };
@@ -0,0 +1,7 @@
1
+ import { Kafka } from 'kafkajs';
2
+ import { IKafkaSecret } from '../../store/interfaces/kafkaSecret.interface';
3
+ export declare class KafkaConfig {
4
+ private static config;
5
+ private constructor();
6
+ static getConfig(config: IKafkaSecret, clientId: string): Kafka;
7
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.KafkaConfig = void 0;
7
+ const dotenv_1 = __importDefault(require("dotenv"));
8
+ const kafkajs_1 = require("kafkajs");
9
+ dotenv_1.default.config();
10
+ class KafkaConfig {
11
+ constructor() { }
12
+ static getConfig(config, clientId) {
13
+ if (!this.config) {
14
+ this.config = new kafkajs_1.Kafka({
15
+ clientId: clientId,
16
+ brokers: config.brokers,
17
+ sasl: {
18
+ mechanism: "plain",
19
+ username: config.username,
20
+ password: config.password
21
+ }
22
+ });
23
+ }
24
+ return this.config;
25
+ }
26
+ }
27
+ exports.KafkaConfig = KafkaConfig;
@@ -0,0 +1,8 @@
1
+ import { Kafka, Producer } from 'kafkajs';
2
+ export declare class KafkaProducer {
3
+ private static producer;
4
+ private constructor();
5
+ static connect(kafka: Kafka): Promise<void>;
6
+ static getProducer(): Promise<Producer>;
7
+ static shutdown(): Promise<void>;
8
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.KafkaProducer = void 0;
13
+ class KafkaProducer {
14
+ constructor() { }
15
+ static connect(kafka) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ try {
18
+ if (this.producer)
19
+ return;
20
+ this.producer = kafka.producer();
21
+ yield this.producer.connect();
22
+ }
23
+ catch (error) {
24
+ console.log(error);
25
+ }
26
+ });
27
+ }
28
+ static getProducer() {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ try {
31
+ if (!this.producer)
32
+ throw new Error("Producer not connected");
33
+ return this.producer;
34
+ }
35
+ catch (error) {
36
+ console.log('KafkaProducer: error while connecting', error);
37
+ throw error;
38
+ }
39
+ });
40
+ }
41
+ static shutdown() {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ try {
44
+ yield this.producer.disconnect();
45
+ }
46
+ catch (error) {
47
+ console.log('KafkaProducer: error while disconnecting', error);
48
+ }
49
+ });
50
+ }
51
+ }
52
+ exports.KafkaProducer = KafkaProducer;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const registry_util_1 = require("./../schemaRegistry/registry.util");
13
+ const producer_kafka_1 = require("./producer.kafka");
14
+ function publishToKafka(topic, schemaId, message) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ try {
17
+ const encodedMessage = yield registry_util_1.SchemaRegistryS.getInstance().encode(schemaId, message.value);
18
+ const payload = { topic, messages: [{ key: message.key, value: encodedMessage }] };
19
+ const producer = yield producer_kafka_1.KafkaProducer.getProducer();
20
+ yield producer.send(payload);
21
+ console.log(`✅ Published to kafka for key: ${message.key}`);
22
+ }
23
+ catch (e) {
24
+ console.log(`🔴 publishToKafka Error: ${message}`, e);
25
+ }
26
+ });
27
+ }
28
+ module.exports = publishToKafka;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const typeTopicMap = {
4
+ "common": "COMMON_NOTIFICATIONS",
5
+ "asset-triggers": "ASSET_TRIGGER_NOTIFICATIONS",
6
+ "bolt": "BOLT_CHARGERS_NOTIFICATIONS"
7
+ };
8
+ function getTopic(type) {
9
+ return typeTopicMap[type];
10
+ }
11
+ module.exports = getTopic;
@@ -0,0 +1,15 @@
1
+ import { notificationType } from './../../store/types/notification.type';
2
+ export declare class NotificationSchema {
3
+ private static instance;
4
+ private registry;
5
+ private registeredSchemaId;
6
+ private constructor();
7
+ static getInstance(): NotificationSchema;
8
+ register(notificationType: notificationType): Promise<void>;
9
+ getSchemaId(): number;
10
+ /**
11
+ * Reads schema from protobuf file and stringifies it. Will throw an error in case proto file has multiple message
12
+ * @returns Stringified schema
13
+ */
14
+ private getSchema;
15
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.NotificationSchema = void 0;
13
+ const confluent_schema_registry_1 = require("@kafkajs/confluent-schema-registry");
14
+ const registry_util_1 = require("./registry.util");
15
+ const fs = require('fs');
16
+ const protoSchemaBuffer = require('protocol-buffers-schema');
17
+ const pickSchema = require('./pickSchema');
18
+ class NotificationSchema {
19
+ constructor() {
20
+ this.registry = registry_util_1.SchemaRegistryS.getInstance();
21
+ }
22
+ static getInstance() {
23
+ if (!this.instance)
24
+ this.instance = new NotificationSchema();
25
+ return this.instance;
26
+ }
27
+ register(notificationType) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ try {
30
+ const { path, subject } = pickSchema(notificationType);
31
+ if (!path) {
32
+ throw new Error(`Schema ${path} not found`);
33
+ }
34
+ const schema = this.getSchema(path);
35
+ const protoSchema = {
36
+ schema,
37
+ type: confluent_schema_registry_1.SchemaType.PROTOBUF
38
+ };
39
+ const { id } = yield this.registry.register(protoSchema, { subject, compatibility: confluent_schema_registry_1.COMPATIBILITY.FULL });
40
+ this.registeredSchemaId = id;
41
+ }
42
+ catch (e) {
43
+ console.log(e);
44
+ throw e;
45
+ }
46
+ });
47
+ }
48
+ getSchemaId() {
49
+ return this.registeredSchemaId;
50
+ }
51
+ /**
52
+ * Reads schema from protobuf file and stringifies it. Will throw an error in case proto file has multiple message
53
+ * @returns Stringified schema
54
+ */
55
+ getSchema(path) {
56
+ var _a;
57
+ const dataRead = fs.readFileSync(path);
58
+ const notificationMessage = protoSchemaBuffer.parse(dataRead);
59
+ if (((_a = notificationMessage === null || notificationMessage === void 0 ? void 0 : notificationMessage.messages) === null || _a === void 0 ? void 0 : _a.length) > 1)
60
+ throw new Error(`One schema file cannot have multiple schemas`);
61
+ return protoSchemaBuffer.stringify(notificationMessage);
62
+ }
63
+ }
64
+ exports.NotificationSchema = NotificationSchema;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require('path');
4
+ const schemaMap = {
5
+ 'common': {
6
+ path: path.join(__dirname, '..', '..', 'store', 'schemas', 'proto', 'commonNotification.proto'),
7
+ subject: "common_notification"
8
+ },
9
+ 'asset-triggers': {
10
+ path: path.join(__dirname, '..', '..', 'store', 'schemas', 'proto', 'assetTriggersNotification.proto'),
11
+ subject: "asset_trigger_notification_details"
12
+ },
13
+ 'bolt': {
14
+ path: path.join(__dirname, '..', '..', 'store', 'schemas', 'proto', 'boltNotification.proto'),
15
+ subject: "bolt_charger_notification_v2"
16
+ }
17
+ };
18
+ function pickSchema(notificationType) {
19
+ let schemaPath;
20
+ switch (notificationType) {
21
+ case 'bolt':
22
+ schemaPath = schemaMap["common"];
23
+ break;
24
+ case 'asset-triggers':
25
+ schemaPath = schemaMap["asset-triggers"];
26
+ break;
27
+ case 'bolt':
28
+ schemaPath = schemaMap["bolt"];
29
+ break;
30
+ default:
31
+ throw new Error(`Schema ${notificationType} not found`);
32
+ }
33
+ if (!schemaPath) {
34
+ throw new Error(`Schema ${notificationType} not saved`);
35
+ }
36
+ return schemaPath;
37
+ }
38
+ module.exports = pickSchema;
@@ -0,0 +1,8 @@
1
+ import { SchemaRegistry } from "@kafkajs/confluent-schema-registry";
2
+ export declare class SchemaRegistryS extends SchemaRegistry {
3
+ private static instance;
4
+ private constructor();
5
+ static connect(url: string): void;
6
+ static getInstance(): SchemaRegistryS;
7
+ getRegistry(url: string): SchemaRegistryS;
8
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemaRegistryS = void 0;
4
+ const confluent_schema_registry_1 = require("@kafkajs/confluent-schema-registry");
5
+ class SchemaRegistryS extends confluent_schema_registry_1.SchemaRegistry {
6
+ constructor(url) {
7
+ super({ host: `${url}` });
8
+ }
9
+ static connect(url) {
10
+ this.instance = new SchemaRegistryS(url);
11
+ }
12
+ static getInstance() {
13
+ if (!this.instance)
14
+ throw new Error('Schema Registry is not connected yet. First connect to schema registry');
15
+ return this.instance;
16
+ }
17
+ getRegistry(url) {
18
+ return SchemaRegistryS.instance;
19
+ }
20
+ }
21
+ exports.SchemaRegistryS = SchemaRegistryS;
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@bolt.tech/kafka-utils",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "files": [
8
+ "build/*"
9
+ ],
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "build": "rm -rf ./build/ && tsc",
13
+ "pub": "rm -rf build/ && npm run build && npm publish --access=public"
14
+ },
15
+ "keywords": [],
16
+ "author": "",
17
+ "license": "ISC",
18
+ "bugs": {
19
+ "url": "https://bitbucket.org/i_bansal/kafka-utils/issues"
20
+ },
21
+ "homepage": "https://bitbucket.org/i_bansal/kafka-utils#readme",
22
+ "dependencies": {
23
+ "@kafkajs/confluent-schema-registry": "^3.3.0",
24
+ "axios": "^1.7.2",
25
+ "bolt-paramstore": "^1.0.12",
26
+ "cors": "^2.8.5",
27
+ "dotenv": "^16.4.5",
28
+ "kafkajs": "^2.2.4",
29
+ "protocol-buffers-schema": "^3.6.0",
30
+ "ts-node": "^10.9.2"
31
+ },
32
+ "devDependencies": {
33
+ "@types/express": "^4.17.21",
34
+ "@types/node": "^22.5.2"
35
+ }
36
+ }