@xrystal/core 3.28.0 → 3.28.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "author": "Yusuf Yasir KAYGUSUZ",
3
3
  "name": "@xrystal/core",
4
- "version": "3.28.0",
4
+ "version": "3.28.2",
5
5
  "description": "Project core for xrystal",
6
6
  "publishConfig": {
7
7
  "access": "public",
@@ -1,6 +1,5 @@
1
1
  import Configs from "../configs";
2
2
  import System from "../system";
3
- import KafkaForCoreSeeder from "./seeder";
4
3
  import { IProvide } from "../../utils";
5
4
  type KafkaInstanceType = {
6
5
  clientId: string;
@@ -16,13 +15,13 @@ export default class KafkaForCore implements IProvide<any> {
16
15
  private brokers;
17
16
  private username;
18
17
  private password;
19
- constructor({ system, configs, kafkaForCoreSeeder }: {
18
+ constructor({ system, configs, }: {
20
19
  system: System;
21
20
  configs: Configs;
22
- kafkaForCoreSeeder: KafkaForCoreSeeder;
23
21
  });
24
22
  onInit: ({}: {}) => Promise<void>;
25
23
  kafkaLoader: ({ clientId, brokers, username, password }: KafkaInstanceType) => Promise<any>;
24
+ initializeKafkaInfrastructure: () => Promise<void>;
26
25
  sendMessage: (topic: string, message: any) => Promise<void>;
27
26
  get producer(): any;
28
27
  get instance(): any;
@@ -7,12 +7,10 @@ export default class KafkaForCore {
7
7
  username = null;
8
8
  password = null;
9
9
  #system;
10
- #kafkaForCoreSeeder;
11
10
  #configs;
12
- constructor({ system, configs, kafkaForCoreSeeder }) {
11
+ constructor({ system, configs, }) {
13
12
  this.#system = system;
14
13
  this.#configs = configs;
15
- this.#kafkaForCoreSeeder = kafkaForCoreSeeder;
16
14
  }
17
15
  onInit = async ({}) => {
18
16
  this.clientId = this.#configs.all?.kafkaClientId;
@@ -34,7 +32,7 @@ export default class KafkaForCore {
34
32
  username: this.username,
35
33
  password: this.password
36
34
  });
37
- await this.#kafkaForCoreSeeder.initializeKafkaInfrastructure();
35
+ await this.initializeKafkaInfrastructure();
38
36
  };
39
37
  kafkaLoader = async ({ clientId, brokers, username, password }) => {
40
38
  const kafkaConfig = {
@@ -64,6 +62,47 @@ export default class KafkaForCore {
64
62
  console.error(`Kafka ${error}`);
65
63
  }
66
64
  };
65
+ initializeKafkaInfrastructure = async () => {
66
+ const { kafkaBrokers, kafkaTopics, isKafkaPassive, } = {
67
+ isKafkaPassive: process.env.IS_KAFKA_PASSIVE === 'true' ? true : false,
68
+ kafkaBrokers: process.env?.KAFKA_BROKERS,
69
+ kafkaTopics: [
70
+ ...new Set([
71
+ ...this.#configs.all.kafkaTopics
72
+ ])
73
+ ],
74
+ };
75
+ if (isKafkaPassive === true || !kafkaBrokers) {
76
+ return;
77
+ }
78
+ const topicsToCreate = Array.isArray(kafkaTopics) ? kafkaTopics : [];
79
+ if (topicsToCreate.length === 0)
80
+ return;
81
+ const admin = this._instance.admin();
82
+ try {
83
+ await admin.connect();
84
+ const existingTopics = await admin.listTopics();
85
+ const newTopics = topicsToCreate
86
+ .filter(topic => !existingTopics.includes(topic))
87
+ .map(topic => ({
88
+ topic,
89
+ numPartitions: 1,
90
+ replicationFactor: 1
91
+ }));
92
+ if (newTopics.length > 0) {
93
+ await admin.createTopics({
94
+ waitForLeaders: true,
95
+ topics: newTopics
96
+ });
97
+ }
98
+ }
99
+ catch (error) {
100
+ //console.log('Core kafka error', error)
101
+ }
102
+ finally {
103
+ await admin.disconnect();
104
+ }
105
+ };
67
106
  // => Helpers
68
107
  sendMessage = async (topic, message) => {
69
108
  if (!this.producer)
@@ -5,6 +5,7 @@ import path from "node:path";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { Partitioners } from "kafkajs";
7
7
  import { LoggerLayerEnum } from '../../utils/models/enums/index';
8
+ import { LogDto } from "../../utils";
8
9
  class KafkaTransport extends Transport {
9
10
  service;
10
11
  constructor(opts, service) {
@@ -153,7 +154,7 @@ export default class Logger {
153
154
  await this.kafkaProducer.send({
154
155
  topic: this.kafkaLogsTopic,
155
156
  messages: [{
156
- value: JSON.stringify({
157
+ value: JSON.stringify(LogDto.getSchema({
157
158
  level,
158
159
  service: this.serviceName,
159
160
  message,
@@ -162,7 +163,7 @@ export default class Logger {
162
163
  timestamp: new Date().toISOString(),
163
164
  id: id || null,
164
165
  env: this.#configs.all.env
165
- }, this.safeReplacer)
166
+ }), this.safeReplacer)
166
167
  }],
167
168
  acks: 1
168
169
  });
@@ -0,0 +1,44 @@
1
+ import { NodeEnvEnum } from "../enums";
2
+ export interface ILogDto {
3
+ level: string;
4
+ service: string;
5
+ message: string;
6
+ payload?: Record<string, any>;
7
+ code: string | number;
8
+ timestamp: string;
9
+ id?: string | number;
10
+ env: NodeEnvEnum;
11
+ }
12
+ export declare class LogDto {
13
+ static getSchema({ level, service, message, payload, code, timestamp, id, env }: ILogDto): {
14
+ level: string;
15
+ service: string;
16
+ message: string;
17
+ payload: Record<string, any>;
18
+ code: string | number;
19
+ timestamp: string;
20
+ id: string | number;
21
+ env: NodeEnvEnum;
22
+ };
23
+ }
24
+ export interface MetadataDto<M = any> {
25
+ source: string;
26
+ eventType: string;
27
+ timestamp: number;
28
+ correlationId: string;
29
+ userId?: string;
30
+ extra?: M;
31
+ }
32
+ export interface IQueueDto<P = any, M = any> {
33
+ source: string;
34
+ eventType: string;
35
+ userId?: string;
36
+ payload: P;
37
+ metadata?: M;
38
+ }
39
+ export declare class QueueDto {
40
+ static getSchema<P, M>(data: IQueueDto<P, M>): {
41
+ metadata: MetadataDto<M>;
42
+ payload: P;
43
+ };
44
+ }
@@ -0,0 +1,36 @@
1
+ export class LogDto {
2
+ static getSchema({ level, service, message, payload, code, timestamp, id, env }) {
3
+ if (!level || !service || !message || !timestamp || !env) {
4
+ throw new Error("Missing data other data required!");
5
+ }
6
+ return {
7
+ level,
8
+ service,
9
+ message,
10
+ payload,
11
+ code,
12
+ timestamp,
13
+ id,
14
+ env
15
+ };
16
+ }
17
+ }
18
+ export class QueueDto {
19
+ static getSchema(data) {
20
+ if (!data.source || !data.eventType) {
21
+ throw new Error("Source and eventType are required");
22
+ }
23
+ const metadata = {
24
+ source: data.source,
25
+ eventType: data.eventType,
26
+ timestamp: Date.now(),
27
+ correlationId: Math.random().toString(36).substring(7),
28
+ userId: data.userId,
29
+ extra: data.metadata
30
+ };
31
+ return {
32
+ metadata,
33
+ payload: data.payload
34
+ };
35
+ }
36
+ }
@@ -2,9 +2,10 @@ import _ from 'lodash';
2
2
  import x from './classes/class.x';
3
3
  import locator from './classes/class.service-locator';
4
4
  export * from './classes/class.tmp-file-loader';
5
- export * from './classes/class.response';
6
- export * from './classes/class.client';
7
5
  export * from './classes/class.interfaces';
6
+ export * from './classes/class.dtos';
7
+ export * from './classes/class.response';
8
+ export * from './classes/class.clients';
8
9
  export * from './types';
9
10
  export * from './enums';
10
11
  export { x, locator, _ };
@@ -2,9 +2,10 @@ import _ from 'lodash';
2
2
  import x from './classes/class.x';
3
3
  import locator from './classes/class.service-locator';
4
4
  export * from './classes/class.tmp-file-loader';
5
- export * from './classes/class.response';
6
- export * from './classes/class.client';
7
5
  export * from './classes/class.interfaces';
6
+ export * from './classes/class.dtos';
7
+ export * from './classes/class.response';
8
+ export * from './classes/class.clients';
8
9
  export * from './types';
9
10
  export * from './enums';
10
11
  export { x, locator, _ };
@@ -1,11 +0,0 @@
1
- import { Kafka } from "kafkajs";
2
- import Configs from "source/loader/configs";
3
- export default class KafkaForCoreSeeder {
4
- #private;
5
- constructor({ kafka, cache, configs, }: {
6
- kafka: Kafka;
7
- cache: Cache;
8
- configs: Configs;
9
- });
10
- initializeKafkaInfrastructure: () => Promise<void>;
11
- }
@@ -1,50 +0,0 @@
1
- export default class KafkaForCoreSeeder {
2
- #configs;
3
- #kafka;
4
- #cache;
5
- constructor({ kafka, cache, configs, }) {
6
- this.#kafka = kafka;
7
- this.#cache = cache;
8
- this.#configs = configs;
9
- }
10
- initializeKafkaInfrastructure = async () => {
11
- const { kafkaBrokers, kafkaTopics, isKafkaPassive, } = {
12
- isKafkaPassive: process.env.IS_KAFKA_PASSIVE === 'true' ? true : false,
13
- kafkaBrokers: process.env?.KAFKA_BROKERS,
14
- kafkaTopics: [
15
- ...new Set([
16
- ...this.#configs.all.kafkaTopics
17
- ])
18
- ],
19
- };
20
- if (isKafkaPassive === true || !kafkaBrokers)
21
- return;
22
- const topicsToCreate = Array.isArray(kafkaTopics) ? kafkaTopics : [];
23
- if (topicsToCreate.length === 0)
24
- return;
25
- const admin = this.#kafka.admin();
26
- try {
27
- await admin.connect();
28
- const existingTopics = await admin.listTopics();
29
- const newTopics = topicsToCreate
30
- .filter(topic => !existingTopics.includes(topic))
31
- .map(topic => ({
32
- topic,
33
- numPartitions: 1,
34
- replicationFactor: 1
35
- }));
36
- if (newTopics.length > 0) {
37
- await admin.createTopics({
38
- waitForLeaders: true,
39
- topics: newTopics
40
- });
41
- }
42
- }
43
- catch (error) {
44
- console.log('comming', error);
45
- }
46
- finally {
47
- await admin.disconnect();
48
- }
49
- };
50
- }