@mohamed_ayad40/common 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.
- package/package.json +23 -0
- package/src/index.ts +114 -0
- package/tsconfig.json +44 -0
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mohamed_ayad40/common",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared RabbitMQ client for microservices",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"amqplib": "^0.10.3"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/amqplib": "^0.10.5",
|
|
20
|
+
"@types/node": "^20.19.37",
|
|
21
|
+
"typescript": "^5.9.3"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import amqp from "amqplib";
|
|
2
|
+
|
|
3
|
+
export type RabbitMQConfig = {
|
|
4
|
+
url?: string
|
|
5
|
+
queues?: string[]
|
|
6
|
+
serviceName?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class RabbitMQClient {
|
|
10
|
+
private config: any;
|
|
11
|
+
private connection: any;
|
|
12
|
+
private channel: any;
|
|
13
|
+
constructor(config: RabbitMQConfig = {}){
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async connect() {
|
|
18
|
+
try {
|
|
19
|
+
const rabbitMQUrl = this.config.url || 'amqp://localhost:5672';
|
|
20
|
+
this.connection = await amqp.connect(rabbitMQUrl);
|
|
21
|
+
this.channel = this.connection.createChannel();
|
|
22
|
+
|
|
23
|
+
if (this.config.queues) {
|
|
24
|
+
for (const queue of this.config.queues) {
|
|
25
|
+
await this.channel.assertQueue(queue, { durable: true });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const serviceName = this.config.serviceName || "Service";
|
|
29
|
+
console.log(`${serviceName}: RabbitMQ connected successfully`);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
const serviceName = this.config.serviceName || "Service";
|
|
32
|
+
console.error(`${serviceName}: RabbitMQ connected successfully`, error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async publishToQueue(queue: string, message: string) {
|
|
38
|
+
try {
|
|
39
|
+
if (!this.channel) {
|
|
40
|
+
console.error("RabbitMQ channel not available");
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
await this.channel.assertQueue(queue, { durable: true });
|
|
44
|
+
this.channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)), {
|
|
45
|
+
persistent: true,
|
|
46
|
+
});
|
|
47
|
+
console.log(`Message published to queue ${queue}:`, message);
|
|
48
|
+
return true;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error(`Error publishing message to the queue`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async consumeFromQueue(
|
|
56
|
+
queue: string,
|
|
57
|
+
handler: (message: any) => Promise<void>,
|
|
58
|
+
options: { noAck?: boolean } = { noAck: false }
|
|
59
|
+
) {
|
|
60
|
+
try {
|
|
61
|
+
if (!this.channel) {
|
|
62
|
+
console.error("RabbitMQ channel not available")
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
await this.channel.assertQueue(queue, { durable: true })
|
|
66
|
+
this.channel.consume(queue, async (msg: any) => {
|
|
67
|
+
if (msg) {
|
|
68
|
+
try {
|
|
69
|
+
const content = JSON.parse(msg.content.toString())
|
|
70
|
+
await handler(content)
|
|
71
|
+
if (!options.noAck) {
|
|
72
|
+
this.channel?.ack(msg)
|
|
73
|
+
}
|
|
74
|
+
console.log(`Started consuming from queue: ${queue}`)
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error("Error consuming message to queue")
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error("Error publishing message to queue")
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
getChannel() {
|
|
89
|
+
return this.channel;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
isConnected() {
|
|
93
|
+
return this.channel !== null && this.connection !== null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async close(): Promise<void> {
|
|
97
|
+
try {
|
|
98
|
+
if (this.channel) {
|
|
99
|
+
await this.channel.close();
|
|
100
|
+
this.channel = null;
|
|
101
|
+
}
|
|
102
|
+
if (this.connection) {
|
|
103
|
+
await this.connection.close();
|
|
104
|
+
this.connection = null;
|
|
105
|
+
}
|
|
106
|
+
console.log("RabbitMQ connection closed");
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error("Error closing RabbitMQ connection", error);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default RabbitMQClient;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
// File Layout
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
|
|
8
|
+
// Environment Settings
|
|
9
|
+
// See also https://aka.ms/tsconfig/module
|
|
10
|
+
"module": "nodenext",
|
|
11
|
+
"target": "esnext",
|
|
12
|
+
"types": [],
|
|
13
|
+
// For nodejs:
|
|
14
|
+
// "lib": ["esnext"],
|
|
15
|
+
// "types": ["node"],
|
|
16
|
+
// and npm install -D @types/node
|
|
17
|
+
|
|
18
|
+
// Other Outputs
|
|
19
|
+
"sourceMap": true,
|
|
20
|
+
"declaration": true,
|
|
21
|
+
"declarationMap": true,
|
|
22
|
+
|
|
23
|
+
// Stricter Typechecking Options
|
|
24
|
+
"noUncheckedIndexedAccess": true,
|
|
25
|
+
"exactOptionalPropertyTypes": true,
|
|
26
|
+
|
|
27
|
+
// Style Options
|
|
28
|
+
// "noImplicitReturns": true,
|
|
29
|
+
// "noImplicitOverride": true,
|
|
30
|
+
// "noUnusedLocals": true,
|
|
31
|
+
// "noUnusedParameters": true,
|
|
32
|
+
// "noFallthroughCasesInSwitch": true,
|
|
33
|
+
// "noPropertyAccessFromIndexSignature": true,
|
|
34
|
+
|
|
35
|
+
// Recommended Options
|
|
36
|
+
"strict": true,
|
|
37
|
+
"jsx": "react-jsx",
|
|
38
|
+
"verbatimModuleSyntax": true,
|
|
39
|
+
"isolatedModules": true,
|
|
40
|
+
"noUncheckedSideEffectImports": true,
|
|
41
|
+
"moduleDetection": "force",
|
|
42
|
+
"skipLibCheck": true,
|
|
43
|
+
}
|
|
44
|
+
}
|