@jsnw/nestjs-rabbitmq 1.3.6 → 2.0.1
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/README.md +94 -154
- package/dist/{index.js → lib/index.js} +1 -2
- package/dist/{rabbitmq → lib/rabbitmq}/rabbitmq-message.js +1 -1
- package/dist/{rabbitmq → lib/rabbitmq}/rabbitmq.js +8 -21
- package/dist/lib/rabbitmq-core.module.js +97 -0
- package/dist/lib/rabbitmq-explorer.service.js +89 -0
- package/dist/lib/rabbitmq.consts.js +5 -0
- package/dist/lib/rabbitmq.decorators.js +17 -0
- package/dist/lib/rabbitmq.module.js +50 -0
- package/dist/lib/rabbitmq.storage.js +48 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/rabbitmq/rabbitmq-message.d.ts +2 -3
- package/dist/types/rabbitmq/rabbitmq.d.ts +6 -19
- package/dist/types/rabbitmq-core.module.d.ts +22 -7
- package/dist/types/rabbitmq-explorer.service.d.ts +5 -6
- package/dist/types/rabbitmq.consts.d.ts +2 -3
- package/dist/types/rabbitmq.decorators.d.ts +3 -8
- package/dist/types/rabbitmq.module.d.ts +9 -8
- package/dist/types/rabbitmq.storage.d.ts +25 -0
- package/dist/types/rabbitmq.types.d.ts +3 -19
- package/package.json +4 -4
- package/dist/rabbitmq-core.module.js +0 -116
- package/dist/rabbitmq-explorer.service.js +0 -143
- package/dist/rabbitmq-instances-manager.js +0 -100
- package/dist/rabbitmq-metadata-storage.js +0 -38
- package/dist/rabbitmq.consts.js +0 -6
- package/dist/rabbitmq.decorators.js +0 -38
- package/dist/rabbitmq.helpers.js +0 -27
- package/dist/rabbitmq.module.js +0 -94
- package/dist/types/rabbitmq-instances-manager.d.ts +0 -23
- package/dist/types/rabbitmq-metadata-storage.d.ts +0 -21
- package/dist/types/rabbitmq.helpers.d.ts +0 -5
- /package/dist/{rabbitmq → lib/rabbitmq}/index.js +0 -0
- /package/dist/{rabbitmq → lib/rabbitmq}/rabbitmq-exchange.js +0 -0
- /package/dist/{rabbitmq → lib/rabbitmq}/rabbitmq-queue.js +0 -0
- /package/dist/{rabbitmq → lib/rabbitmq}/rabbitmq-subscriber.js +0 -0
- /package/dist/{rabbitmq → lib/rabbitmq}/rabbitmq.helpers.js +0 -0
- /package/dist/{rabbitmq.types.js → lib/rabbitmq.types.js} +0 -0
package/README.md
CHANGED
|
@@ -1,194 +1,134 @@
|
|
|
1
1
|
# @jsnw/nestjs-rabbitmq
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**A lightweight, strictly typed, and predictable RabbitMQ module for NestJS**
|
|
4
|
+
|
|
5
|
+
## Key features
|
|
6
|
+
- [rabbitmq-client](https://www.npmjs.com/package/rabbitmq-client) inside
|
|
7
|
+
- Full validation for both incoming and outgoing messages using [zod](https://www.npmjs.com/package/zod)
|
|
8
|
+
- Single connection
|
|
9
|
+
- Type-Safe publishing: You cannot publish an invalid payload
|
|
10
|
+
- Exchanges and queues are automatically declared upon application bootstrap
|
|
11
|
+
- No AI. The code is written by human, not a machine
|
|
4
12
|
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npm i -s @jsnw/nestjs-rabbitmq
|
|
16
|
+
npm i -s @jsnw/nestjs-rabbitmq @nestjs/core@11 @nestjs/common@11
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
Optionally, you can install `zod` and `rabbitmq-client`
|
|
12
20
|
|
|
13
21
|
## Quick Start
|
|
22
|
+
### 1. Define exchanges and queues
|
|
14
23
|
|
|
15
|
-
```
|
|
16
|
-
import {
|
|
17
|
-
import { RabbitmqModule, RabbitmqExchange, RabbitmqQueue } from '@jsnw/nestjs-rabbitmq';
|
|
24
|
+
```ts
|
|
25
|
+
import {RabbitmqExchange, RabbitmqQueue} from '@jsnw/nestjs-rabbitmq';
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
port: 5672,
|
|
25
|
-
username: 'guest',
|
|
26
|
-
password: 'guest',
|
|
27
|
-
isDefault: true
|
|
28
|
-
})
|
|
29
|
-
]
|
|
30
|
-
})
|
|
31
|
-
export class AppModule {}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Declaring Exchanges and Queues
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
const ordersExchange = new RabbitmqExchange({
|
|
38
|
-
name: 'orders',
|
|
39
|
-
type: 'topic',
|
|
40
|
-
durable: true
|
|
27
|
+
export const MY_EXCHANGE = new RabbitmqExchange({
|
|
28
|
+
name: 'my_exchange',
|
|
29
|
+
type: 'direct',
|
|
30
|
+
durable: true,
|
|
31
|
+
autoDelete: false
|
|
41
32
|
});
|
|
42
33
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
export const MY_QUEUE = new RabbitmqQueue({
|
|
35
|
+
name: 'my_queue',
|
|
36
|
+
durable: true,
|
|
37
|
+
autoDelete: false,
|
|
38
|
+
bindings: [
|
|
39
|
+
{exchange: MY_EXCHANGE, routingKeys: ['user.created']}
|
|
40
|
+
]
|
|
49
41
|
});
|
|
50
42
|
|
|
51
|
-
RabbitmqModule.forRoot({
|
|
52
|
-
name: 'main',
|
|
53
|
-
hostname: 'localhost',
|
|
54
|
-
port: 5672,
|
|
55
|
-
username: 'guest',
|
|
56
|
-
password: 'guest',
|
|
57
|
-
exchanges: [ordersExchange],
|
|
58
|
-
queues: [ordersQueue]
|
|
59
|
-
})
|
|
60
43
|
```
|
|
61
44
|
|
|
62
|
-
|
|
45
|
+
### 2. Register the module
|
|
63
46
|
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
import {
|
|
47
|
+
```ts
|
|
48
|
+
// app.module.ts
|
|
49
|
+
import {Module} from '@nestjs/common';
|
|
50
|
+
import {RabbitmqModule} from '@jsnw/nestjs-rabbitmq';
|
|
67
51
|
|
|
68
|
-
@
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
52
|
+
@Module({
|
|
53
|
+
imports: [
|
|
54
|
+
RabbitmqModule.forRoot({
|
|
55
|
+
hostname: 'localhost',
|
|
56
|
+
port: 5672,
|
|
57
|
+
username: 'guest',
|
|
58
|
+
password: 'guest',
|
|
59
|
+
exchanges: [MY_EXCHANGE],
|
|
60
|
+
queues: [MY_QUEUE]
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
})
|
|
64
|
+
export class AppModule {}
|
|
84
65
|
```
|
|
85
66
|
|
|
86
|
-
|
|
67
|
+
### 3. Define a Message Contract
|
|
87
68
|
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```
|
|
69
|
+
```ts
|
|
70
|
+
import {z} from 'zod';
|
|
71
|
+
import {RabbitmqMessage} from '@jsnw/nestjs-rabbitmq';
|
|
92
72
|
|
|
93
|
-
|
|
73
|
+
export const USER_CREATED_EVENT = RabbitmqMessage.template({
|
|
74
|
+
type: 'json',
|
|
75
|
+
exchange: MY_EXCHANGE,
|
|
76
|
+
durable: true,
|
|
77
|
+
routingKey: 'user.created',
|
|
78
|
+
schema: z.object({
|
|
79
|
+
id: z.number(),
|
|
80
|
+
email: z.string().email()
|
|
81
|
+
})
|
|
82
|
+
});
|
|
83
|
+
```
|
|
94
84
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
import {
|
|
85
|
+
### 4. Publishing messages
|
|
86
|
+
```ts
|
|
87
|
+
import {Injectable} from '@nestjs/common';
|
|
88
|
+
import {Rabbitmq} from '@jsnw/nestjs-rabbitmq';
|
|
98
89
|
|
|
99
90
|
@Injectable()
|
|
100
|
-
export class
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
91
|
+
export class UserService {
|
|
92
|
+
|
|
93
|
+
constructor(private readonly rabbit: Rabbitmq){}
|
|
94
|
+
|
|
95
|
+
async create(dto: any){
|
|
96
|
+
await this.rabbit.publish(
|
|
97
|
+
USER_CREATED_EVENT.make({
|
|
98
|
+
id: 1,
|
|
99
|
+
email: 'example@example.com'
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
109
104
|
}
|
|
110
105
|
```
|
|
111
106
|
|
|
112
|
-
###
|
|
113
|
-
|
|
114
|
-
- `instanceName`: RabbitMQ instance name
|
|
115
|
-
- `queue` (required): Queue to subscribe to
|
|
116
|
-
- `concurrency`: Number of concurrent message handlers (default: 1)
|
|
117
|
-
- `prefetchCount`: Number of messages to prefetch (default: 1)
|
|
118
|
-
- `prefetchSize`: Size of messages to prefetch in bytes (default: 0)
|
|
119
|
-
- `requeue`: Whether to requeue failed messages (default: false)
|
|
120
|
-
- `autoStart`: Auto-start consumer on boot (default: true)
|
|
121
|
-
- `id`: Unique identifier for manual start control
|
|
107
|
+
### 5. Subscribing to messages
|
|
122
108
|
|
|
123
|
-
|
|
109
|
+
```ts
|
|
110
|
+
import {Injectable} from '@nestjs/common';
|
|
111
|
+
import {RabbitmqSubscribe, type AsyncMessage} from '@jsnw/nestjs-rabbitmq';
|
|
124
112
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
113
|
+
@Injectable()
|
|
114
|
+
export class NotificationsService {
|
|
115
|
+
|
|
116
|
+
@RabbitmqSubscribe({
|
|
117
|
+
queue: MY_QUEUE,
|
|
118
|
+
validation: {
|
|
119
|
+
schema: USER_CREATED_EVENT.schema,
|
|
120
|
+
onFail: 'drop'
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
async onUserCreated(data: z.infer<typeof USER_CREATED_EVENT.schema>, message: AsyncMessage) {
|
|
129
124
|
|
|
130
|
-
|
|
131
|
-
orderId: z.string(),
|
|
132
|
-
amount: z.number()
|
|
133
|
-
});
|
|
125
|
+
}
|
|
134
126
|
|
|
135
|
-
@RabbitmqSubscribe({
|
|
136
|
-
instanceName: 'main',
|
|
137
|
-
queue: ordersQueue,
|
|
138
|
-
validation: {
|
|
139
|
-
schema: orderSchema,
|
|
140
|
-
onFail: 'drop' // or 'ack', 'requeue'
|
|
141
|
-
}
|
|
142
|
-
})
|
|
143
|
-
async handleOrderCreated(data: z.infer<typeof orderSchema>) {
|
|
144
|
-
// data is typed and validated
|
|
145
|
-
return 'ack';
|
|
146
127
|
}
|
|
147
128
|
```
|
|
148
129
|
|
|
149
|
-
##
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
const dlxExchange = new RabbitmqExchange({
|
|
153
|
-
name: 'orders.dlx',
|
|
154
|
-
type: 'topic',
|
|
155
|
-
durable: true
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
const queueWithDlx = new RabbitmqQueue({
|
|
159
|
-
name: 'order.created',
|
|
160
|
-
durable: true,
|
|
161
|
-
deadLetterExchange: dlxExchange,
|
|
162
|
-
deadLetterRoutingKey: 'order.failed',
|
|
163
|
-
bindings: [{ exchange: ordersExchange, routingKeys: ['order.created'] }]
|
|
164
|
-
});
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
## Multiple Instances
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
RabbitmqModule.forRoot({
|
|
171
|
-
name: 'instance1',
|
|
172
|
-
hostname: 'localhost',
|
|
173
|
-
port: 5672,
|
|
174
|
-
username: 'guest',
|
|
175
|
-
password: 'guest',
|
|
176
|
-
isDefault: true
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
RabbitmqModule.forRoot({
|
|
180
|
-
name: 'instance2',
|
|
181
|
-
hostname: 'other-host',
|
|
182
|
-
port: 5672,
|
|
183
|
-
username: 'guest',
|
|
184
|
-
password: 'guest'
|
|
185
|
-
})
|
|
186
|
-
```
|
|
130
|
+
## Author
|
|
131
|
+
Pavlo Baliuk (jsnow0177@gmail.com)
|
|
187
132
|
|
|
188
133
|
## License
|
|
189
|
-
|
|
190
134
|
MIT
|
|
191
|
-
|
|
192
|
-
## Author
|
|
193
|
-
|
|
194
|
-
Pavlo Baliuk (jsnow0177@gmail.com)
|
|
@@ -14,10 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
17
|
+
exports.RabbitmqSubscribe = exports.RabbitmqModule = void 0;
|
|
18
18
|
__exportStar(require("./rabbitmq"), exports);
|
|
19
19
|
var rabbitmq_module_1 = require("./rabbitmq.module");
|
|
20
20
|
Object.defineProperty(exports, "RabbitmqModule", { enumerable: true, get: function () { return rabbitmq_module_1.RabbitmqModule; } });
|
|
21
21
|
var rabbitmq_decorators_1 = require("./rabbitmq.decorators");
|
|
22
22
|
Object.defineProperty(exports, "RabbitmqSubscribe", { enumerable: true, get: function () { return rabbitmq_decorators_1.RabbitmqSubscribe; } });
|
|
23
|
-
Object.defineProperty(exports, "InjectRabbitmq", { enumerable: true, get: function () { return rabbitmq_decorators_1.InjectRabbitmq; } });
|
|
@@ -5,7 +5,6 @@ const rabbitmq_client_1 = require("rabbitmq-client");
|
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
6
|
const rabbitmq_subscriber_1 = require("./rabbitmq-subscriber");
|
|
7
7
|
class Rabbitmq {
|
|
8
|
-
name;
|
|
9
8
|
logger;
|
|
10
9
|
connection;
|
|
11
10
|
exchanges = new Map();
|
|
@@ -13,25 +12,11 @@ class Rabbitmq {
|
|
|
13
12
|
subscribers = new Map;
|
|
14
13
|
publisher = null;
|
|
15
14
|
/**
|
|
16
|
-
* @param {
|
|
17
|
-
* @param {Connection} arg2
|
|
15
|
+
* @param {Connection | RabbitmqConstructorParams} arg
|
|
18
16
|
*/
|
|
19
|
-
constructor(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.name = typeof arg1 === 'string' ? arg1 : arg1.name;
|
|
23
|
-
this.logger = new common_1.Logger(Rabbitmq.name + `(${this.name})`);
|
|
24
|
-
this.connection = typeof arg1 === 'string'
|
|
25
|
-
? arg2
|
|
26
|
-
: new rabbitmq_client_1.Connection({
|
|
27
|
-
connectionName: arg1.connectionName ?? arg1.name,
|
|
28
|
-
hostname: arg1.hostname,
|
|
29
|
-
port: arg1.port,
|
|
30
|
-
username: arg1.username,
|
|
31
|
-
password: arg1.password,
|
|
32
|
-
vhost: arg1.vhost ?? '/',
|
|
33
|
-
connectionTimeout: arg1.connectionTimeout ?? 10_000
|
|
34
|
-
});
|
|
17
|
+
constructor(arg) {
|
|
18
|
+
this.logger = new common_1.Logger(this.constructor.name);
|
|
19
|
+
this.connection = arg instanceof rabbitmq_client_1.Connection ? arg : new rabbitmq_client_1.Connection(arg);
|
|
35
20
|
}
|
|
36
21
|
/**
|
|
37
22
|
* @param {RabbitmqExchange} exchange
|
|
@@ -157,7 +142,7 @@ class Rabbitmq {
|
|
|
157
142
|
startSubscriber(id) {
|
|
158
143
|
const subscriber = this.subscribers.get(id);
|
|
159
144
|
if (!subscriber)
|
|
160
|
-
throw new Error(`Subscriber ${id} not found
|
|
145
|
+
throw new Error(`Subscriber ${id} not found`);
|
|
161
146
|
subscriber.start();
|
|
162
147
|
}
|
|
163
148
|
/**
|
|
@@ -167,7 +152,7 @@ class Rabbitmq {
|
|
|
167
152
|
async stopSubscriber(id) {
|
|
168
153
|
const subscriber = this.subscribers.get(id);
|
|
169
154
|
if (!subscriber)
|
|
170
|
-
throw new Error(`Subscriber ${id} not found
|
|
155
|
+
throw new Error(`Subscriber ${id} not found`);
|
|
171
156
|
await subscriber.stop();
|
|
172
157
|
}
|
|
173
158
|
/**
|
|
@@ -200,6 +185,8 @@ class Rabbitmq {
|
|
|
200
185
|
const promises = [];
|
|
201
186
|
for (const subscriber of this.subscribers.values())
|
|
202
187
|
promises.push(subscriber.stop());
|
|
188
|
+
if (this.publisher)
|
|
189
|
+
promises.push(this.publisher.close());
|
|
203
190
|
promises.push(this.connection.close());
|
|
204
191
|
await Promise.allSettled(promises);
|
|
205
192
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
var RabbitmqCoreModule_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.RabbitmqCoreModule = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const core_1 = require("@nestjs/core");
|
|
16
|
+
const rabbitmq_1 = require("./rabbitmq");
|
|
17
|
+
const rabbitmq_consts_1 = require("./rabbitmq.consts");
|
|
18
|
+
const rabbitmq_storage_1 = require("./rabbitmq.storage");
|
|
19
|
+
const rabbitmq_explorer_service_1 = require("./rabbitmq-explorer.service");
|
|
20
|
+
let RabbitmqCoreModule = RabbitmqCoreModule_1 = class RabbitmqCoreModule {
|
|
21
|
+
rabbit;
|
|
22
|
+
/**
|
|
23
|
+
* @param {RabbitmqOptions} options
|
|
24
|
+
* @return {DynamicModule}
|
|
25
|
+
*/
|
|
26
|
+
static forRoot(options) {
|
|
27
|
+
const optionsProvider = this.createOptionsProvider(options), rabbitmqProvider = this.createRabbitmqProvider();
|
|
28
|
+
return {
|
|
29
|
+
module: RabbitmqCoreModule_1,
|
|
30
|
+
imports: [],
|
|
31
|
+
providers: [
|
|
32
|
+
optionsProvider,
|
|
33
|
+
rabbitmqProvider
|
|
34
|
+
],
|
|
35
|
+
exports: [
|
|
36
|
+
rabbitmqProvider
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @param {RabbitmqOptions} options
|
|
42
|
+
* @return {ValueProvider}
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
static createOptionsProvider(options) {
|
|
46
|
+
return {
|
|
47
|
+
provide: rabbitmq_consts_1.RABBITMQ_OPTIONS_TOKEN,
|
|
48
|
+
useValue: options
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @return {FactoryProvider}
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
static createRabbitmqProvider() {
|
|
56
|
+
return {
|
|
57
|
+
provide: rabbitmq_1.Rabbitmq,
|
|
58
|
+
useFactory: (options) => {
|
|
59
|
+
const rabbitmq = new rabbitmq_1.Rabbitmq(options);
|
|
60
|
+
if (options.exchanges && options.exchanges.length > 0)
|
|
61
|
+
rabbitmq_storage_1.RabbitmqStorage.addExchanges(options.exchanges);
|
|
62
|
+
if (options.queues && options.queues.length > 0)
|
|
63
|
+
rabbitmq_storage_1.RabbitmqStorage.addQueues(options.queues);
|
|
64
|
+
return rabbitmq;
|
|
65
|
+
},
|
|
66
|
+
inject: [
|
|
67
|
+
rabbitmq_consts_1.RABBITMQ_OPTIONS_TOKEN
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* @param {Rabbitmq} rabbit
|
|
73
|
+
*/
|
|
74
|
+
constructor(rabbit) {
|
|
75
|
+
this.rabbit = rabbit;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @return {Promise<void>}
|
|
79
|
+
*/
|
|
80
|
+
async onApplicationShutdown() {
|
|
81
|
+
await this.rabbit.close();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
exports.RabbitmqCoreModule = RabbitmqCoreModule;
|
|
85
|
+
exports.RabbitmqCoreModule = RabbitmqCoreModule = RabbitmqCoreModule_1 = __decorate([
|
|
86
|
+
(0, common_1.Global)(),
|
|
87
|
+
(0, common_1.Module)({
|
|
88
|
+
imports: [
|
|
89
|
+
core_1.DiscoveryModule
|
|
90
|
+
],
|
|
91
|
+
providers: [
|
|
92
|
+
core_1.Reflector,
|
|
93
|
+
rabbitmq_explorer_service_1.RabbitmqExplorerService
|
|
94
|
+
]
|
|
95
|
+
}),
|
|
96
|
+
__metadata("design:paramtypes", [rabbitmq_1.Rabbitmq])
|
|
97
|
+
], RabbitmqCoreModule);
|
|
@@ -0,0 +1,89 @@
|
|
|
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.RabbitmqExplorerService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const core_1 = require("@nestjs/core");
|
|
15
|
+
const rabbitmq_1 = require("./rabbitmq");
|
|
16
|
+
const rabbitmq_storage_1 = require("./rabbitmq.storage");
|
|
17
|
+
const rabbitmq_consts_1 = require("./rabbitmq.consts");
|
|
18
|
+
let RabbitmqExplorerService = class RabbitmqExplorerService {
|
|
19
|
+
discoveryService;
|
|
20
|
+
metadataScanner;
|
|
21
|
+
reflector;
|
|
22
|
+
rabbitmq;
|
|
23
|
+
constructor(discoveryService, metadataScanner, reflector, rabbitmq) {
|
|
24
|
+
this.discoveryService = discoveryService;
|
|
25
|
+
this.metadataScanner = metadataScanner;
|
|
26
|
+
this.reflector = reflector;
|
|
27
|
+
this.rabbitmq = rabbitmq;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @return {Promise<void>}
|
|
31
|
+
*/
|
|
32
|
+
async onApplicationBootstrap() {
|
|
33
|
+
await this.setupInfrastructure();
|
|
34
|
+
await this.discoverSubscribers();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @return {Promise<void>}
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
async setupInfrastructure() {
|
|
41
|
+
const exchanges = rabbitmq_storage_1.RabbitmqStorage.getExchanges(), queues = rabbitmq_storage_1.RabbitmqStorage.getQueues();
|
|
42
|
+
if (exchanges.length > 0)
|
|
43
|
+
await Promise.all(exchanges.map(exchange => this.rabbitmq.declareExchange(exchange)));
|
|
44
|
+
if (queues.length > 0)
|
|
45
|
+
await Promise.all(queues.map(queue => this.rabbitmq.declareQueue(queue)));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @return {Promise<void>}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
async discoverSubscribers() {
|
|
52
|
+
const wrappers = [
|
|
53
|
+
...this.discoveryService.getProviders(),
|
|
54
|
+
...this.discoveryService.getControllers()
|
|
55
|
+
];
|
|
56
|
+
for (const wrapper of wrappers) {
|
|
57
|
+
const { instance } = wrapper;
|
|
58
|
+
if (!instance || typeof instance !== 'object')
|
|
59
|
+
continue;
|
|
60
|
+
const prototype = Object.getPrototypeOf(instance);
|
|
61
|
+
if (!prototype)
|
|
62
|
+
continue;
|
|
63
|
+
const methodNames = this.metadataScanner.getAllMethodNames(prototype);
|
|
64
|
+
for (const methodName of methodNames)
|
|
65
|
+
await this.registerIfSubscriber(instance, methodName);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @param {any} instance
|
|
70
|
+
* @param {string} methodName
|
|
71
|
+
* @return {Promise<void>}
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
async registerIfSubscriber(instance, methodName) {
|
|
75
|
+
const methodRef = instance[methodName];
|
|
76
|
+
const metadata = this.reflector.get(rabbitmq_consts_1.RABBITMQ_SUBSCRIPTION_METADATA, methodRef);
|
|
77
|
+
if (!metadata)
|
|
78
|
+
return;
|
|
79
|
+
await this.rabbitmq.subscribe(metadata, { instance, methodName });
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
exports.RabbitmqExplorerService = RabbitmqExplorerService;
|
|
83
|
+
exports.RabbitmqExplorerService = RabbitmqExplorerService = __decorate([
|
|
84
|
+
(0, common_1.Injectable)(),
|
|
85
|
+
__metadata("design:paramtypes", [core_1.DiscoveryService,
|
|
86
|
+
core_1.MetadataScanner,
|
|
87
|
+
core_1.Reflector,
|
|
88
|
+
rabbitmq_1.Rabbitmq])
|
|
89
|
+
], RabbitmqExplorerService);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RABBITMQ_SUBSCRIPTION_METADATA = exports.RABBITMQ_OPTIONS_TOKEN = void 0;
|
|
4
|
+
exports.RABBITMQ_OPTIONS_TOKEN = Symbol('RABBITMQ_OPTIONS');
|
|
5
|
+
exports.RABBITMQ_SUBSCRIPTION_METADATA = Symbol('RABBITMQ_SUBSCRIPTION_METADATA');
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RabbitmqSubscribe = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const rabbitmq_consts_1 = require("./rabbitmq.consts");
|
|
6
|
+
/**
|
|
7
|
+
* @param {RabbitmqSubscribeParams} subscription
|
|
8
|
+
* @return {MethodDecorator}
|
|
9
|
+
* @constructor
|
|
10
|
+
*/
|
|
11
|
+
const RabbitmqSubscribe = (subscription) => {
|
|
12
|
+
return (target, key, descriptor) => {
|
|
13
|
+
(0, common_1.SetMetadata)(rabbitmq_consts_1.RABBITMQ_SUBSCRIPTION_METADATA, subscription)(target, key, descriptor);
|
|
14
|
+
return descriptor;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.RabbitmqSubscribe = RabbitmqSubscribe;
|
|
@@ -0,0 +1,50 @@
|
|
|
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 RabbitmqModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.RabbitmqModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const rabbitmq_core_module_1 = require("./rabbitmq-core.module");
|
|
13
|
+
const rabbitmq_storage_1 = require("./rabbitmq.storage");
|
|
14
|
+
let RabbitmqModule = RabbitmqModule_1 = class RabbitmqModule {
|
|
15
|
+
/**
|
|
16
|
+
* @param {RabbitmqOptions} options
|
|
17
|
+
* @return {DynamicModule}
|
|
18
|
+
*/
|
|
19
|
+
static forRoot(options) {
|
|
20
|
+
return {
|
|
21
|
+
module: RabbitmqModule_1,
|
|
22
|
+
imports: [
|
|
23
|
+
rabbitmq_core_module_1.RabbitmqCoreModule.forRoot(options)
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* @param {(RabbitmqExchange | RabbitmqQueue)[] | {exchanges?: RabbitmqExchange[], queues?: RabbitmqQueue[]}} declarations
|
|
29
|
+
* @return {DynamicModule}
|
|
30
|
+
*/
|
|
31
|
+
static forFeature(declarations) {
|
|
32
|
+
if (declarations) {
|
|
33
|
+
if (Array.isArray(declarations) && declarations.length > 0)
|
|
34
|
+
rabbitmq_storage_1.RabbitmqStorage.addAny(declarations);
|
|
35
|
+
if ('exchanges' in declarations && Array.isArray(declarations.exchanges) && declarations.exchanges.length > 0)
|
|
36
|
+
rabbitmq_storage_1.RabbitmqStorage.addExchanges(declarations.exchanges);
|
|
37
|
+
if ('queues' in declarations && Array.isArray(declarations.queues) && declarations.queues.length > 0)
|
|
38
|
+
rabbitmq_storage_1.RabbitmqStorage.addQueues(declarations.queues);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
module: RabbitmqModule_1,
|
|
42
|
+
providers: [],
|
|
43
|
+
exports: []
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
exports.RabbitmqModule = RabbitmqModule;
|
|
48
|
+
exports.RabbitmqModule = RabbitmqModule = RabbitmqModule_1 = __decorate([
|
|
49
|
+
(0, common_1.Module)({})
|
|
50
|
+
], RabbitmqModule);
|