@opra/rabbitmq 1.21.0 → 1.22.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/{esm/config-builder.js → config-builder.js} +2 -0
- package/package.json +12 -28
- package/{esm/rabbitmq-adapter.js → rabbitmq-adapter.js} +9 -6
- package/{esm/rabbitmq-context.js → rabbitmq-context.js} +6 -0
- package/cjs/augmentation/opra-common.augmentation.js +0 -19
- package/cjs/config-builder.js +0 -88
- package/cjs/constants.js +0 -6
- package/cjs/index.js +0 -7
- package/cjs/package.json +0 -3
- package/cjs/rabbitmq-adapter.js +0 -307
- package/cjs/rabbitmq-context.js +0 -39
- package/esm/package.json +0 -3
- package/types/index.d.cts +0 -4
- /package/{types/augmentation → augmentation}/opra-common.augmentation.d.ts +0 -0
- /package/{esm/augmentation → augmentation}/opra-common.augmentation.js +0 -0
- /package/{types/config-builder.d.ts → config-builder.d.ts} +0 -0
- /package/{types/constants.d.ts → constants.d.ts} +0 -0
- /package/{esm/constants.js → constants.js} +0 -0
- /package/{types/index.d.ts → index.d.ts} +0 -0
- /package/{esm/index.js → index.js} +0 -0
- /package/{types/rabbitmq-adapter.d.ts → rabbitmq-adapter.d.ts} +0 -0
- /package/{types/rabbitmq-context.d.ts → rabbitmq-context.d.ts} +0 -0
|
@@ -2,6 +2,8 @@ import { merge } from '@jsopen/objects';
|
|
|
2
2
|
import { MQ_CONTROLLER_METADATA, } from '@opra/common';
|
|
3
3
|
import { RMQ_OPERATION_METADATA, RMQ_OPERATION_METADATA_RESOLVER, } from './constants.js';
|
|
4
4
|
export class ConfigBuilder {
|
|
5
|
+
document;
|
|
6
|
+
config;
|
|
5
7
|
constructor(document, config) {
|
|
6
8
|
this.document = document;
|
|
7
9
|
this.config = config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/rabbitmq",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.1",
|
|
4
4
|
"description": "Opra RabbitMQ adapter",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,50 +8,34 @@
|
|
|
8
8
|
"@jsopen/objects": "^2.0.2",
|
|
9
9
|
"@browsery/type-is": "^2.0.1",
|
|
10
10
|
"content-type": "^1.0.5",
|
|
11
|
-
"iconv-lite": "^0.7.
|
|
12
|
-
"node-events-async": "^1.
|
|
11
|
+
"iconv-lite": "^0.7.1",
|
|
12
|
+
"node-events-async": "^1.5.0",
|
|
13
13
|
"tslib": "^2.8.1",
|
|
14
14
|
"valgen": "^5.18.2"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@opra/common": "^1.
|
|
18
|
-
"@opra/core": "^1.
|
|
17
|
+
"@opra/common": "^1.22.1",
|
|
18
|
+
"@opra/core": "^1.22.1",
|
|
19
19
|
"rabbitmq-client": ">=5.0.0 <6"
|
|
20
20
|
},
|
|
21
21
|
"type": "module",
|
|
22
|
+
"module": "./index.js",
|
|
23
|
+
"types": "./index.d.ts",
|
|
22
24
|
"exports": {
|
|
23
25
|
".": {
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
"default": "./esm/index.js"
|
|
27
|
-
},
|
|
28
|
-
"require": {
|
|
29
|
-
"types": "./types/index.d.cts",
|
|
30
|
-
"default": "./cjs/index.js"
|
|
31
|
-
},
|
|
32
|
-
"default": "./esm/index.js"
|
|
26
|
+
"types": "./index.d.ts",
|
|
27
|
+
"default": "./index.js"
|
|
33
28
|
},
|
|
34
29
|
"./package.json": "./package.json"
|
|
35
30
|
},
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20.0"
|
|
33
|
+
},
|
|
39
34
|
"repository": {
|
|
40
35
|
"type": "git",
|
|
41
36
|
"url": "git+https://github.com/panates/opra.git",
|
|
42
37
|
"directory": "packages/rabbitmq"
|
|
43
38
|
},
|
|
44
|
-
"engines": {
|
|
45
|
-
"node": ">=16.0",
|
|
46
|
-
"npm": ">=7.0.0"
|
|
47
|
-
},
|
|
48
|
-
"files": [
|
|
49
|
-
"cjs/",
|
|
50
|
-
"esm/",
|
|
51
|
-
"types/",
|
|
52
|
-
"LICENSE",
|
|
53
|
-
"README.md"
|
|
54
|
-
],
|
|
55
39
|
"keywords": [
|
|
56
40
|
"opra",
|
|
57
41
|
"rabbitmq",
|
|
@@ -21,6 +21,15 @@ const noOp = () => undefined;
|
|
|
21
21
|
* @class RabbitmqAdapter
|
|
22
22
|
*/
|
|
23
23
|
export class RabbitmqAdapter extends PlatformAdapter {
|
|
24
|
+
static PlatformName = 'rabbitmq';
|
|
25
|
+
_config;
|
|
26
|
+
_controllerInstances = new Map();
|
|
27
|
+
_connection;
|
|
28
|
+
_consumers = [];
|
|
29
|
+
_status = 'idle';
|
|
30
|
+
transform = 'mq';
|
|
31
|
+
platform = RabbitmqAdapter.PlatformName;
|
|
32
|
+
interceptors;
|
|
24
33
|
/**
|
|
25
34
|
*
|
|
26
35
|
* @param document
|
|
@@ -29,11 +38,6 @@ export class RabbitmqAdapter extends PlatformAdapter {
|
|
|
29
38
|
*/
|
|
30
39
|
constructor(document, config) {
|
|
31
40
|
super(config);
|
|
32
|
-
this._controllerInstances = new Map();
|
|
33
|
-
this._consumers = [];
|
|
34
|
-
this._status = 'idle';
|
|
35
|
-
this.transform = 'mq';
|
|
36
|
-
this.platform = RabbitmqAdapter.PlatformName;
|
|
37
41
|
this._document = document;
|
|
38
42
|
this._config = config;
|
|
39
43
|
if (!(this.document.api instanceof MQApi &&
|
|
@@ -299,4 +303,3 @@ export class RabbitmqAdapter extends PlatformAdapter {
|
|
|
299
303
|
return wrappedErrors;
|
|
300
304
|
}
|
|
301
305
|
}
|
|
302
|
-
RabbitmqAdapter.PlatformName = 'rabbitmq';
|
|
@@ -4,6 +4,12 @@ import { ExecutionContext } from '@opra/core';
|
|
|
4
4
|
* It extends the ExecutionContext and implements the AsyncEventEmitter.
|
|
5
5
|
*/
|
|
6
6
|
export class RabbitmqContext extends ExecutionContext {
|
|
7
|
+
queue;
|
|
8
|
+
consumer;
|
|
9
|
+
message;
|
|
10
|
+
content;
|
|
11
|
+
headers;
|
|
12
|
+
reply;
|
|
7
13
|
/**
|
|
8
14
|
* Constructor
|
|
9
15
|
* @param init the context options
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
require("@opra/core");
|
|
4
|
-
const common_1 = require("@opra/common");
|
|
5
|
-
const constants_js_1 = require("../constants.js");
|
|
6
|
-
/** Implementation **/
|
|
7
|
-
common_1.classes.MQOperationDecoratorFactory.augment((decorator, decoratorChain) => {
|
|
8
|
-
decorator.RabbitMQ = (config) => {
|
|
9
|
-
decoratorChain.push((_, target, propertyKey) => {
|
|
10
|
-
if (typeof config === 'function') {
|
|
11
|
-
Reflect.defineMetadata(constants_js_1.RMQ_OPERATION_METADATA_RESOLVER, config, target, propertyKey);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
Reflect.defineMetadata(constants_js_1.RMQ_OPERATION_METADATA, { ...config }, target, propertyKey);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
return decorator;
|
|
18
|
-
};
|
|
19
|
-
});
|
package/cjs/config-builder.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ConfigBuilder = void 0;
|
|
4
|
-
const objects_1 = require("@jsopen/objects");
|
|
5
|
-
const common_1 = require("@opra/common");
|
|
6
|
-
const constants_js_1 = require("./constants.js");
|
|
7
|
-
class ConfigBuilder {
|
|
8
|
-
constructor(document, config) {
|
|
9
|
-
this.document = document;
|
|
10
|
-
this.config = config;
|
|
11
|
-
}
|
|
12
|
-
async build() {
|
|
13
|
-
this.controllerInstances = new Map();
|
|
14
|
-
this.handlerArgs = [];
|
|
15
|
-
this._prepareConnectionOptions();
|
|
16
|
-
/** Initialize consumers */
|
|
17
|
-
for (const controller of this.document.getMqApi().controllers.values()) {
|
|
18
|
-
let instance = controller.instance;
|
|
19
|
-
if (!instance && controller.ctor)
|
|
20
|
-
instance = new controller.ctor();
|
|
21
|
-
if (!instance)
|
|
22
|
-
continue;
|
|
23
|
-
this.controllerInstances.set(controller, instance);
|
|
24
|
-
/** Build HandlerData array */
|
|
25
|
-
for (const operation of controller.operations.values()) {
|
|
26
|
-
const consumerConfig = await this._getConsumerConfig(controller, instance, operation);
|
|
27
|
-
if (!consumerConfig)
|
|
28
|
-
continue;
|
|
29
|
-
const args = {
|
|
30
|
-
// consumer: null as any,
|
|
31
|
-
controller,
|
|
32
|
-
instance,
|
|
33
|
-
operation,
|
|
34
|
-
consumerConfig,
|
|
35
|
-
// handler: null as any,
|
|
36
|
-
topics: (Array.isArray(operation.channel)
|
|
37
|
-
? operation.channel
|
|
38
|
-
: [operation.channel]).map(String),
|
|
39
|
-
};
|
|
40
|
-
this.handlerArgs.push(args);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
_prepareConnectionOptions() {
|
|
45
|
-
this.connectionOptions = {};
|
|
46
|
-
if (Array.isArray(this.config.connection))
|
|
47
|
-
this.connectionOptions.urls = this.config.connection;
|
|
48
|
-
else if (typeof this.config.connection === 'object') {
|
|
49
|
-
(0, objects_1.merge)(this.connectionOptions, this.config.connection, { deep: true });
|
|
50
|
-
}
|
|
51
|
-
else
|
|
52
|
-
this.connectionOptions.urls = [
|
|
53
|
-
this.config.connection || 'amqp://guest:guest@localhost:5672',
|
|
54
|
-
];
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
*
|
|
58
|
-
* @param controller
|
|
59
|
-
* @param instance
|
|
60
|
-
* @param operation
|
|
61
|
-
* @protected
|
|
62
|
-
*/
|
|
63
|
-
async _getConsumerConfig(controller, instance, operation) {
|
|
64
|
-
if (typeof instance[operation.name] !== 'function')
|
|
65
|
-
return;
|
|
66
|
-
const proto = controller.ctor?.prototype || Object.getPrototypeOf(instance);
|
|
67
|
-
if (Reflect.hasMetadata(common_1.MQ_CONTROLLER_METADATA, proto, operation.name))
|
|
68
|
-
return;
|
|
69
|
-
const operationConfig = {};
|
|
70
|
-
if (this.config.defaults) {
|
|
71
|
-
if (this.config.defaults.consumer) {
|
|
72
|
-
(0, objects_1.merge)(operationConfig, this.config.defaults.consumer, { deep: true });
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
let metadata = Reflect.getMetadata(constants_js_1.RMQ_OPERATION_METADATA, proto, operation.name);
|
|
76
|
-
if (!metadata) {
|
|
77
|
-
const configResolver = Reflect.getMetadata(constants_js_1.RMQ_OPERATION_METADATA_RESOLVER, proto, operation.name);
|
|
78
|
-
if (configResolver) {
|
|
79
|
-
metadata = await configResolver();
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (metadata && typeof metadata === 'object') {
|
|
83
|
-
(0, objects_1.merge)(operationConfig, metadata, { deep: true });
|
|
84
|
-
}
|
|
85
|
-
return operationConfig;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
exports.ConfigBuilder = ConfigBuilder;
|
package/cjs/constants.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RMQ_OPERATION_METADATA_RESOLVER = exports.RMQ_OPERATION_METADATA = exports.RMQ_DEFAULT_GROUP = void 0;
|
|
4
|
-
exports.RMQ_DEFAULT_GROUP = 'default';
|
|
5
|
-
exports.RMQ_OPERATION_METADATA = 'RMQ_OPERATION_METADATA';
|
|
6
|
-
exports.RMQ_OPERATION_METADATA_RESOLVER = 'RMQ_OPERATION_METADATA_RESOLVER';
|
package/cjs/index.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
require("./augmentation/opra-common.augmentation.js");
|
|
5
|
-
tslib_1.__exportStar(require("./constants.js"), exports);
|
|
6
|
-
tslib_1.__exportStar(require("./rabbitmq-adapter.js"), exports);
|
|
7
|
-
tslib_1.__exportStar(require("./rabbitmq-context.js"), exports);
|
package/cjs/package.json
DELETED
package/cjs/rabbitmq-adapter.js
DELETED
|
@@ -1,307 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RabbitmqAdapter = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const node_zlib_1 = tslib_1.__importDefault(require("node:zlib"));
|
|
6
|
-
const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
|
|
7
|
-
const common_1 = require("@opra/common");
|
|
8
|
-
const core_1 = require("@opra/core");
|
|
9
|
-
const content_type_1 = require("content-type");
|
|
10
|
-
const iconv_lite_1 = tslib_1.__importDefault(require("iconv-lite"));
|
|
11
|
-
const rabbit = tslib_1.__importStar(require("rabbitmq-client"));
|
|
12
|
-
const util_1 = require("util");
|
|
13
|
-
const valgen_1 = require("valgen");
|
|
14
|
-
const config_builder_js_1 = require("./config-builder.js");
|
|
15
|
-
const rabbitmq_context_js_1 = require("./rabbitmq-context.js");
|
|
16
|
-
const gunzipAsync = (0, util_1.promisify)(node_zlib_1.default.gunzip);
|
|
17
|
-
const deflateAsync = (0, util_1.promisify)(node_zlib_1.default.deflate);
|
|
18
|
-
const inflateAsync = (0, util_1.promisify)(node_zlib_1.default.inflate);
|
|
19
|
-
const brotliAsync = (0, util_1.promisify)(node_zlib_1.default.brotliCompress);
|
|
20
|
-
const globalErrorTypes = ['unhandledRejection', 'uncaughtException'];
|
|
21
|
-
const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
|
|
22
|
-
const noOp = () => undefined;
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
* @class RabbitmqAdapter
|
|
26
|
-
*/
|
|
27
|
-
class RabbitmqAdapter extends core_1.PlatformAdapter {
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
30
|
-
* @param document
|
|
31
|
-
* @param config
|
|
32
|
-
* @constructor
|
|
33
|
-
*/
|
|
34
|
-
constructor(document, config) {
|
|
35
|
-
super(config);
|
|
36
|
-
this._controllerInstances = new Map();
|
|
37
|
-
this._consumers = [];
|
|
38
|
-
this._status = 'idle';
|
|
39
|
-
this.transform = 'mq';
|
|
40
|
-
this.platform = RabbitmqAdapter.PlatformName;
|
|
41
|
-
this._document = document;
|
|
42
|
-
this._config = config;
|
|
43
|
-
if (!(this.document.api instanceof common_1.MQApi &&
|
|
44
|
-
this.document.api.platform === RabbitmqAdapter.PlatformName)) {
|
|
45
|
-
throw new TypeError(`The document doesn't expose a RabbitMQ Api`);
|
|
46
|
-
}
|
|
47
|
-
this.interceptors = [...(config.interceptors || [])];
|
|
48
|
-
globalErrorTypes.forEach(type => {
|
|
49
|
-
process.on(type, e => {
|
|
50
|
-
this._emitError(e);
|
|
51
|
-
return this.close();
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
signalTraps.forEach(type => {
|
|
55
|
-
process.once(type, () => this.close());
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
get api() {
|
|
59
|
-
return this.document.getMqApi();
|
|
60
|
-
}
|
|
61
|
-
get connection() {
|
|
62
|
-
return this._connection;
|
|
63
|
-
}
|
|
64
|
-
get scope() {
|
|
65
|
-
return this._config.scope;
|
|
66
|
-
}
|
|
67
|
-
get status() {
|
|
68
|
-
return this._status;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Starts the service
|
|
72
|
-
*/
|
|
73
|
-
async start() {
|
|
74
|
-
if (this.status !== 'idle')
|
|
75
|
-
return;
|
|
76
|
-
this._status = 'starting';
|
|
77
|
-
// const handlerArgs: HandlerArguments[] = [];
|
|
78
|
-
const configBuilder = new config_builder_js_1.ConfigBuilder(this.document, this._config);
|
|
79
|
-
await configBuilder.build();
|
|
80
|
-
this._connection = new rabbit.Connection(configBuilder.connectionOptions);
|
|
81
|
-
try {
|
|
82
|
-
/** Establish connection */
|
|
83
|
-
await this._connection.onConnect().catch(e => {
|
|
84
|
-
e.message = `RabbitMQ connection error. ${e.message}`;
|
|
85
|
-
throw e;
|
|
86
|
-
});
|
|
87
|
-
this.logger?.info?.(`Connected RabbitMQ at ${configBuilder.connectionOptions.urls}`);
|
|
88
|
-
/** Subscribe to queues */
|
|
89
|
-
const promises = [];
|
|
90
|
-
for (const args of configBuilder.handlerArgs) {
|
|
91
|
-
for (const queue of args.topics) {
|
|
92
|
-
const handler = this._createHandler(args);
|
|
93
|
-
promises.push(new Promise((resolve, reject) => {
|
|
94
|
-
const consumer = this._connection.createConsumer({
|
|
95
|
-
...args.consumerConfig,
|
|
96
|
-
queueOptions: {
|
|
97
|
-
...args.consumerConfig.queueOptions,
|
|
98
|
-
durable: args.consumerConfig.queueOptions?.durable ?? true,
|
|
99
|
-
},
|
|
100
|
-
queue,
|
|
101
|
-
}, async (msg, reply) => {
|
|
102
|
-
await this.emitAsync('message', msg, queue).catch(noOp);
|
|
103
|
-
try {
|
|
104
|
-
await handler(consumer, queue, msg, reply);
|
|
105
|
-
}
|
|
106
|
-
catch (e) {
|
|
107
|
-
this._emitError(e);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
this._consumers.push(consumer);
|
|
111
|
-
consumer.on('ready', () => {
|
|
112
|
-
this.logger?.info?.(`Subscribed to topic "${queue}"`);
|
|
113
|
-
resolve();
|
|
114
|
-
});
|
|
115
|
-
consumer.on('error', (err) => {
|
|
116
|
-
err.message = `Consumer error (${queue})". ${err.message}`;
|
|
117
|
-
err.queue = queue;
|
|
118
|
-
reject(err);
|
|
119
|
-
});
|
|
120
|
-
}));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
await Promise.all(promises);
|
|
124
|
-
this._status = 'started';
|
|
125
|
-
}
|
|
126
|
-
catch (err) {
|
|
127
|
-
this._emitError(err);
|
|
128
|
-
await this.close();
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Closes all connections and stops the service
|
|
133
|
-
*/
|
|
134
|
-
async close() {
|
|
135
|
-
if (this._consumers.length)
|
|
136
|
-
await Promise.allSettled(this._consumers.map(consumer => consumer.close()));
|
|
137
|
-
await this._connection?.close();
|
|
138
|
-
this._connection = undefined;
|
|
139
|
-
this._consumers = [];
|
|
140
|
-
this._controllerInstances.clear();
|
|
141
|
-
this._status = 'idle';
|
|
142
|
-
}
|
|
143
|
-
getControllerInstance(controllerPath) {
|
|
144
|
-
const controller = this.api.findController(controllerPath);
|
|
145
|
-
return controller && this._controllerInstances.get(controller);
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
*
|
|
149
|
-
* @param args
|
|
150
|
-
* @protected
|
|
151
|
-
*/
|
|
152
|
-
_createHandler(args) {
|
|
153
|
-
const { controller, instance, operation } = args;
|
|
154
|
-
/** Prepare parsers */
|
|
155
|
-
const decodePayload = operation.generateCodec('decode', {
|
|
156
|
-
scope: this.scope,
|
|
157
|
-
ignoreReadonlyFields: true,
|
|
158
|
-
});
|
|
159
|
-
operation.headers.forEach(header => {
|
|
160
|
-
let decode = this[core_1.kAssetCache].get(header, 'decode');
|
|
161
|
-
if (!decode) {
|
|
162
|
-
decode = header.generateCodec('decode', {
|
|
163
|
-
scope: this.scope,
|
|
164
|
-
ignoreReadonlyFields: true,
|
|
165
|
-
});
|
|
166
|
-
this[core_1.kAssetCache].set(header, 'decode', decode);
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
return async (consumer, queue, message, _reply) => {
|
|
170
|
-
if (!message)
|
|
171
|
-
return;
|
|
172
|
-
const operationHandler = instance[operation.name];
|
|
173
|
-
let replyCalled = false;
|
|
174
|
-
const reply = async (body, envelope) => {
|
|
175
|
-
if (replyCalled)
|
|
176
|
-
return;
|
|
177
|
-
replyCalled = true;
|
|
178
|
-
return _reply(body, envelope);
|
|
179
|
-
};
|
|
180
|
-
const headers = {};
|
|
181
|
-
/** Create context */
|
|
182
|
-
const context = new rabbitmq_context_js_1.RabbitmqContext({
|
|
183
|
-
__adapter: this,
|
|
184
|
-
__contDef: controller,
|
|
185
|
-
__controller: instance,
|
|
186
|
-
__oprDef: operation,
|
|
187
|
-
__handler: operationHandler,
|
|
188
|
-
queue,
|
|
189
|
-
consumer,
|
|
190
|
-
message,
|
|
191
|
-
content: undefined,
|
|
192
|
-
headers,
|
|
193
|
-
reply,
|
|
194
|
-
});
|
|
195
|
-
try {
|
|
196
|
-
/** Parse and decode `payload` */
|
|
197
|
-
let content = await this._parseContent(message);
|
|
198
|
-
if (content && decodePayload) {
|
|
199
|
-
if (Buffer.isBuffer(content))
|
|
200
|
-
content = content.toString('utf-8');
|
|
201
|
-
content = decodePayload(content);
|
|
202
|
-
}
|
|
203
|
-
// message.properties.
|
|
204
|
-
/** Parse and decode `headers` */
|
|
205
|
-
if (message.headers) {
|
|
206
|
-
for (const [k, v] of Object.entries(message.headers)) {
|
|
207
|
-
const header = operation.findHeader(k);
|
|
208
|
-
const decode = this[core_1.kAssetCache].get(header, 'decode') || valgen_1.vg.isAny();
|
|
209
|
-
headers[k] = decode(Buffer.isBuffer(v) ? v.toString() : v);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
context.content = content;
|
|
213
|
-
}
|
|
214
|
-
catch (e) {
|
|
215
|
-
this._emitError(e, context);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
await this.emitAsync('execute', context).catch(noOp);
|
|
219
|
-
try {
|
|
220
|
-
/** Call operation handler */
|
|
221
|
-
const result = await operationHandler.call(instance, context);
|
|
222
|
-
if (result !== undefined)
|
|
223
|
-
await reply(result);
|
|
224
|
-
await this.emitAsync('finish', context, result).catch(noOp);
|
|
225
|
-
}
|
|
226
|
-
catch (e) {
|
|
227
|
-
this._emitError(e, context);
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
async _parseContent(msg) {
|
|
232
|
-
if (!Buffer.isBuffer(msg.body))
|
|
233
|
-
return msg.body;
|
|
234
|
-
if (!msg.body?.length)
|
|
235
|
-
return;
|
|
236
|
-
let content = msg.body;
|
|
237
|
-
if (msg.contentEncoding) {
|
|
238
|
-
switch (msg.contentEncoding) {
|
|
239
|
-
case 'gzip':
|
|
240
|
-
case 'x-gzip': {
|
|
241
|
-
content = await gunzipAsync(content);
|
|
242
|
-
break;
|
|
243
|
-
}
|
|
244
|
-
case 'deflate':
|
|
245
|
-
case 'x-deflate': {
|
|
246
|
-
content = await deflateAsync(content);
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
case 'inflate':
|
|
250
|
-
case 'x-inflate': {
|
|
251
|
-
content = await inflateAsync(content);
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
case 'br': {
|
|
255
|
-
content = await brotliAsync(content);
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
case 'base64': {
|
|
259
|
-
content = content.toString('base64');
|
|
260
|
-
break;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
const mediaType = msg.contentType
|
|
265
|
-
? (0, content_type_1.parse)(msg.contentType || '')
|
|
266
|
-
: undefined;
|
|
267
|
-
if (mediaType && type_is_1.default.is(mediaType.type, ['json', 'xml', 'txt'])) {
|
|
268
|
-
const charset = (mediaType.parameters.charset || '').toLowerCase() || 'utf-8';
|
|
269
|
-
content = iconv_lite_1.default.decode(content, charset);
|
|
270
|
-
if (type_is_1.default.is(mediaType.type, ['json']))
|
|
271
|
-
return JSON.parse(content);
|
|
272
|
-
}
|
|
273
|
-
return content;
|
|
274
|
-
}
|
|
275
|
-
_emitError(error, context) {
|
|
276
|
-
Promise.resolve()
|
|
277
|
-
.then(async () => {
|
|
278
|
-
const logger = this.logger;
|
|
279
|
-
if (context) {
|
|
280
|
-
if (!context.errors.length)
|
|
281
|
-
context.errors.push(error);
|
|
282
|
-
context.errors = this._wrapExceptions(context.errors);
|
|
283
|
-
if (context.listenerCount('error')) {
|
|
284
|
-
await context
|
|
285
|
-
.emitAsync('error', context.errors[0], context)
|
|
286
|
-
.catch(noOp);
|
|
287
|
-
}
|
|
288
|
-
if (logger?.error) {
|
|
289
|
-
context.errors.forEach(err => logger.error(err));
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
else
|
|
293
|
-
logger?.error(error);
|
|
294
|
-
if (this.listenerCount('error'))
|
|
295
|
-
this._emitError(error, context);
|
|
296
|
-
})
|
|
297
|
-
.catch(noOp);
|
|
298
|
-
}
|
|
299
|
-
_wrapExceptions(exceptions) {
|
|
300
|
-
const wrappedErrors = exceptions.map(e => e instanceof common_1.OpraException ? e : new common_1.OpraException(e));
|
|
301
|
-
if (!wrappedErrors.length)
|
|
302
|
-
wrappedErrors.push(new common_1.OpraException('Internal Server Error'));
|
|
303
|
-
return wrappedErrors;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
exports.RabbitmqAdapter = RabbitmqAdapter;
|
|
307
|
-
RabbitmqAdapter.PlatformName = 'rabbitmq';
|
package/cjs/rabbitmq-context.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RabbitmqContext = void 0;
|
|
4
|
-
const core_1 = require("@opra/core");
|
|
5
|
-
/**
|
|
6
|
-
* RabbitmqContext class provides the context for handling RabbitMQ messages.
|
|
7
|
-
* It extends the ExecutionContext and implements the AsyncEventEmitter.
|
|
8
|
-
*/
|
|
9
|
-
class RabbitmqContext extends core_1.ExecutionContext {
|
|
10
|
-
/**
|
|
11
|
-
* Constructor
|
|
12
|
-
* @param init the context options
|
|
13
|
-
*/
|
|
14
|
-
constructor(init) {
|
|
15
|
-
super({
|
|
16
|
-
...init,
|
|
17
|
-
__docNode: init.__oprDef?.node ||
|
|
18
|
-
init.__contDef?.node ||
|
|
19
|
-
init.__adapter.document.node,
|
|
20
|
-
transport: 'mq',
|
|
21
|
-
platform: 'rabbitmq',
|
|
22
|
-
});
|
|
23
|
-
if (init.__contDef)
|
|
24
|
-
this.__contDef = init.__contDef;
|
|
25
|
-
if (init.__oprDef)
|
|
26
|
-
this.__oprDef = init.__oprDef;
|
|
27
|
-
if (init.__controller)
|
|
28
|
-
this.__controller = init.__controller;
|
|
29
|
-
if (init.__handler)
|
|
30
|
-
this.__handler = init.__handler;
|
|
31
|
-
this.consumer = init.consumer;
|
|
32
|
-
this.queue = init.queue;
|
|
33
|
-
this.message = init.message;
|
|
34
|
-
this.headers = init.headers || {};
|
|
35
|
-
this.content = init.content;
|
|
36
|
-
this.reply = init.reply;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.RabbitmqContext = RabbitmqContext;
|
package/esm/package.json
DELETED
package/types/index.d.cts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|