@jsnw/nestjs-rabbitmq 1.3.5 → 2.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/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/{rabbitmq-core.module.js → lib/rabbitmq-core.module.js} +48 -42
- package/dist/{rabbitmq-explorer.service.js → lib/rabbitmq-explorer.service.js} +16 -39
- package/dist/lib/rabbitmq.consts.js +5 -0
- package/dist/lib/rabbitmq.decorators.js +17 -0
- package/dist/{rabbitmq.module.js → lib/rabbitmq.module.js} +15 -20
- 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 -17
- package/package.json +4 -4
- 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/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
|
}
|
|
@@ -36,18 +36,12 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
37
|
exports.RabbitmqCoreModule = void 0;
|
|
38
38
|
const common_1 = require("@nestjs/common");
|
|
39
|
+
const rabbitmq_1 = require("./rabbitmq");
|
|
39
40
|
const rabbitmq_consts_1 = require("./rabbitmq.consts");
|
|
40
|
-
const
|
|
41
|
-
const rabbitmq_instances_manager_1 = require("./rabbitmq-instances-manager");
|
|
41
|
+
const rabbitmq_storage_1 = require("./rabbitmq.storage");
|
|
42
42
|
const rabbitmq_explorer_service_1 = require("./rabbitmq-explorer.service");
|
|
43
|
-
const rabbitmq_1 = require("./rabbitmq");
|
|
44
43
|
let RabbitmqCoreModule = (() => {
|
|
45
|
-
let _classDecorators = [(0, common_1.Global)(), (0, common_1.Module)({
|
|
46
|
-
providers: [
|
|
47
|
-
rabbitmq_instances_manager_1.RabbitmqInstancesManager,
|
|
48
|
-
rabbitmq_explorer_service_1.RabbitmqExplorerService
|
|
49
|
-
]
|
|
50
|
-
})];
|
|
44
|
+
let _classDecorators = [(0, common_1.Global)(), (0, common_1.Module)({})];
|
|
51
45
|
let _classDescriptor;
|
|
52
46
|
let _classExtraInitializers = [];
|
|
53
47
|
let _classThis;
|
|
@@ -60,56 +54,68 @@ let RabbitmqCoreModule = (() => {
|
|
|
60
54
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
61
55
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
62
56
|
}
|
|
57
|
+
rabbit;
|
|
63
58
|
/**
|
|
64
|
-
* @param {
|
|
59
|
+
* @param {RabbitmqOptions} options
|
|
65
60
|
* @return {DynamicModule}
|
|
66
61
|
*/
|
|
67
|
-
static forRoot(
|
|
68
|
-
const
|
|
69
|
-
const instanceProvider = this.createInstanceProvider(params);
|
|
70
|
-
providers.push(instanceProvider);
|
|
71
|
-
if (params.isDefault)
|
|
72
|
-
providers.push({
|
|
73
|
-
provide: (0, rabbitmq_helpers_1.getInstanceToken)(rabbitmq_consts_1.RABBITMQ_INSTANCE_DEFAULT_NAME),
|
|
74
|
-
useExisting: (0, rabbitmq_helpers_1.getInstanceToken)(params)
|
|
75
|
-
});
|
|
62
|
+
static forRoot(options) {
|
|
63
|
+
const optionsProvider = this.createOptionsProvider(options), rabbitmqProvider = this.createRabbitmqProvider();
|
|
76
64
|
return {
|
|
77
65
|
module: RabbitmqCoreModule,
|
|
78
|
-
providers:
|
|
79
|
-
|
|
66
|
+
providers: [
|
|
67
|
+
optionsProvider,
|
|
68
|
+
rabbitmqProvider,
|
|
69
|
+
rabbitmq_explorer_service_1.RabbitmqExplorerService
|
|
70
|
+
],
|
|
71
|
+
exports: [
|
|
72
|
+
rabbitmqProvider
|
|
73
|
+
]
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @param {RabbitmqOptions} options
|
|
78
|
+
* @return {ValueProvider}
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
static createOptionsProvider(options) {
|
|
82
|
+
return {
|
|
83
|
+
provide: rabbitmq_consts_1.RABBITMQ_OPTIONS_TOKEN,
|
|
84
|
+
useValue: options
|
|
80
85
|
};
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
83
|
-
* @param {RabbitmqForRootParams} params
|
|
84
88
|
* @return {FactoryProvider}
|
|
85
89
|
* @private
|
|
86
90
|
*/
|
|
87
|
-
static
|
|
88
|
-
const instanceToken = (0, rabbitmq_helpers_1.getInstanceToken)(params);
|
|
91
|
+
static createRabbitmqProvider() {
|
|
89
92
|
return {
|
|
90
|
-
provide:
|
|
91
|
-
useFactory: (
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
hostname: params.hostname,
|
|
99
|
-
port: params.port,
|
|
100
|
-
username: params.username,
|
|
101
|
-
password: params.password,
|
|
102
|
-
vhost: params.vhost,
|
|
103
|
-
connectionTimeout: params.connectionTimeout
|
|
104
|
-
});
|
|
105
|
-
im.addInstance(instanceToken, instance);
|
|
106
|
-
return instance;
|
|
93
|
+
provide: rabbitmq_1.Rabbitmq,
|
|
94
|
+
useFactory: (options) => {
|
|
95
|
+
const rabbitmq = new rabbitmq_1.Rabbitmq(options);
|
|
96
|
+
if (options.exchanges && options.exchanges.length > 0)
|
|
97
|
+
rabbitmq_storage_1.RabbitmqStorage.addExchanges(options.exchanges);
|
|
98
|
+
if (options.queues && options.queues.length > 0)
|
|
99
|
+
rabbitmq_storage_1.RabbitmqStorage.addQueues(options.queues);
|
|
100
|
+
return rabbitmq;
|
|
107
101
|
},
|
|
108
102
|
inject: [
|
|
109
|
-
|
|
103
|
+
rabbitmq_consts_1.RABBITMQ_OPTIONS_TOKEN
|
|
110
104
|
]
|
|
111
105
|
};
|
|
112
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* @param {Rabbitmq} rabbit
|
|
109
|
+
*/
|
|
110
|
+
constructor(rabbit) {
|
|
111
|
+
this.rabbit = rabbit;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* @return {Promise<void>}
|
|
115
|
+
*/
|
|
116
|
+
async onApplicationShutdown() {
|
|
117
|
+
await this.rabbit.close();
|
|
118
|
+
}
|
|
113
119
|
};
|
|
114
120
|
return RabbitmqCoreModule = _classThis;
|
|
115
121
|
})();
|
|
@@ -36,8 +36,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
37
|
exports.RabbitmqExplorerService = void 0;
|
|
38
38
|
const common_1 = require("@nestjs/common");
|
|
39
|
-
const
|
|
40
|
-
const rabbitmq_helpers_1 = require("./rabbitmq.helpers");
|
|
39
|
+
const rabbitmq_storage_1 = require("./rabbitmq.storage");
|
|
41
40
|
const rabbitmq_consts_1 = require("./rabbitmq.consts");
|
|
42
41
|
let RabbitmqExplorerService = (() => {
|
|
43
42
|
let _classDecorators = [(0, common_1.Injectable)()];
|
|
@@ -56,43 +55,36 @@ let RabbitmqExplorerService = (() => {
|
|
|
56
55
|
discoveryService;
|
|
57
56
|
metadataScanner;
|
|
58
57
|
reflector;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
constructor(discoveryService, metadataScanner, reflector, instancesManager) {
|
|
58
|
+
rabbitmq;
|
|
59
|
+
constructor(discoveryService, metadataScanner, reflector, rabbitmq) {
|
|
62
60
|
this.discoveryService = discoveryService;
|
|
63
61
|
this.metadataScanner = metadataScanner;
|
|
64
62
|
this.reflector = reflector;
|
|
65
|
-
this.
|
|
63
|
+
this.rabbitmq = rabbitmq;
|
|
66
64
|
}
|
|
67
65
|
/**
|
|
68
66
|
* @return {Promise<void>}
|
|
69
67
|
*/
|
|
70
68
|
async onApplicationBootstrap() {
|
|
71
69
|
await this.setupInfrastructure();
|
|
72
|
-
await this.
|
|
70
|
+
await this.discoverSubscribers();
|
|
73
71
|
}
|
|
74
72
|
/**
|
|
75
73
|
* @return {Promise<void>}
|
|
76
74
|
* @private
|
|
77
75
|
*/
|
|
78
76
|
async setupInfrastructure() {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const exchanges = Array.from(metadata.exchanges), queues = Array.from(metadata.queues);
|
|
85
|
-
if (exchanges.length > 0)
|
|
86
|
-
await Promise.all(exchanges.map(exchange => instance.declareExchange(exchange)));
|
|
87
|
-
if (queues.length > 0)
|
|
88
|
-
await Promise.all(queues.map(queue => instance.declareQueue(queue)));
|
|
89
|
-
}
|
|
77
|
+
const exchanges = rabbitmq_storage_1.RabbitmqStorage.getExchanges(), queues = rabbitmq_storage_1.RabbitmqStorage.getQueues();
|
|
78
|
+
if (exchanges.length > 0)
|
|
79
|
+
await Promise.all(exchanges.map(exchange => this.rabbitmq.declareExchange(exchange)));
|
|
80
|
+
if (queues.length > 0)
|
|
81
|
+
await Promise.all(queues.map(queue => this.rabbitmq.declareQueue(queue)));
|
|
90
82
|
}
|
|
91
83
|
/**
|
|
92
84
|
* @return {Promise<void>}
|
|
93
85
|
* @private
|
|
94
86
|
*/
|
|
95
|
-
async
|
|
87
|
+
async discoverSubscribers() {
|
|
96
88
|
const wrappers = [
|
|
97
89
|
...this.discoveryService.getProviders(),
|
|
98
90
|
...this.discoveryService.getControllers()
|
|
@@ -106,7 +98,7 @@ let RabbitmqExplorerService = (() => {
|
|
|
106
98
|
continue;
|
|
107
99
|
const methodNames = this.metadataScanner.getAllMethodNames(prototype);
|
|
108
100
|
for (const methodName of methodNames)
|
|
109
|
-
await this.
|
|
101
|
+
await this.registerIfSubscriber(instance, methodName);
|
|
110
102
|
}
|
|
111
103
|
}
|
|
112
104
|
/**
|
|
@@ -115,27 +107,12 @@ let RabbitmqExplorerService = (() => {
|
|
|
115
107
|
* @return {Promise<void>}
|
|
116
108
|
* @private
|
|
117
109
|
*/
|
|
118
|
-
async
|
|
110
|
+
async registerIfSubscriber(instance, methodName) {
|
|
119
111
|
const methodRef = instance[methodName];
|
|
120
|
-
const
|
|
121
|
-
if (!
|
|
112
|
+
const metadata = this.reflector.get(rabbitmq_consts_1.RABBITMQ_SUBSCRIPTION_METADATA, methodRef);
|
|
113
|
+
if (!metadata)
|
|
122
114
|
return;
|
|
123
|
-
|
|
124
|
-
if (!rabbitmqInstance) {
|
|
125
|
-
this.logger.error(`Instance ${subscriptionMetadata.instanceName}" not found for subscriber ${instance.constructor.name}.${methodName}`);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
this.logger.log(`Registering subscriber: ${instance.constructor.name}.${methodName} -> ${subscriptionMetadata.queue.name}`);
|
|
129
|
-
await rabbitmqInstance.subscribe({
|
|
130
|
-
id: subscriptionMetadata.id,
|
|
131
|
-
queue: subscriptionMetadata.queue,
|
|
132
|
-
requeue: subscriptionMetadata.requeue,
|
|
133
|
-
concurrency: subscriptionMetadata.concurrency,
|
|
134
|
-
prefetchSize: subscriptionMetadata.prefetchSize,
|
|
135
|
-
prefetchCount: subscriptionMetadata.prefetchCount,
|
|
136
|
-
autoStart: subscriptionMetadata.autoStart,
|
|
137
|
-
validation: subscriptionMetadata.validation
|
|
138
|
-
}, { instance: instance, methodName: methodName });
|
|
115
|
+
await this.rabbitmq.subscribe(metadata, { instance, methodName });
|
|
139
116
|
}
|
|
140
117
|
};
|
|
141
118
|
return RabbitmqExplorerService = _classThis;
|
|
@@ -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;
|