arnavmq 0.16.4 → 0.17.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.
@@ -16,7 +16,7 @@ jobs:
16
16
 
17
17
  strategy:
18
18
  matrix:
19
- node-version: [16.x, 18.x, 20.x]
19
+ node-version: [20.x, 22.x, 24.x]
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
@@ -42,7 +42,7 @@ jobs:
42
42
 
43
43
  - uses: actions/setup-node@v3
44
44
  with:
45
- node-version: 20.x
45
+ node-version: 22.x
46
46
  registry-url: https://registry.npmjs.org
47
47
 
48
48
  - run: npm publish --access public
package/README.md CHANGED
@@ -171,7 +171,7 @@ const arnavmq = require('arnavmq')({
171
171
  consumerSuffix: '',
172
172
 
173
173
  // generate a hostname so we can track this connection on the broker (rabbitmq management plugin)
174
- hostname: process.env.HOSTNAME || process.env.USER || uuid.v4(),
174
+ hostname: process.env.HOSTNAME || process.env.USER || crypto.randomUUID(),
175
175
 
176
176
  /**
177
177
  * A logger object with a log function for each of the log levels ("debug", "info", "warn", or "error").
@@ -0,0 +1,82 @@
1
+ import globals from 'globals';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import js from '@eslint/js';
5
+ import { FlatCompat } from '@eslint/eslintrc';
6
+
7
+ // eslint-disable-next-line no-underscore-dangle
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ // eslint-disable-next-line no-underscore-dangle
10
+ const __dirname = path.dirname(__filename);
11
+ const compat = new FlatCompat({
12
+ baseDirectory: __dirname,
13
+ recommendedConfig: js.configs.recommended,
14
+ allConfig: js.configs.all,
15
+ });
16
+
17
+ export default [
18
+ {
19
+ ignores: [
20
+ 'bin/**/*',
21
+ 'build/**/*',
22
+ 'coverage/**/*',
23
+ 'docs/**/*',
24
+ 'jsdoc/**/*',
25
+ 'templates/**/*',
26
+ 'tests/bench/**/*',
27
+ 'tests/fixtures/**/*',
28
+ 'tests/performance/**/*',
29
+ 'tmp/**/*',
30
+ 'public/**/*',
31
+ 'node_modules/**/*',
32
+ 'lib-cov/**/*',
33
+ '.grunt/**/*',
34
+ '.sonar/**/*',
35
+ 'logs/**/*',
36
+ '.idea/**/*',
37
+ 'samples/**/*',
38
+ ],
39
+ },
40
+ ...compat.extends('eslint-config-prettier'),
41
+ {
42
+ languageOptions: {
43
+ globals: {
44
+ ...globals.node,
45
+ ...globals.mocha,
46
+ ...globals.mongo,
47
+ },
48
+ },
49
+
50
+ rules: {
51
+ 'no-await-in-loop': 0,
52
+ 'comma-dangle': 0,
53
+ 'max-classes-per-file': 0,
54
+
55
+ 'max-len': [
56
+ 'error',
57
+ {
58
+ code: 190,
59
+ ignoreComments: true,
60
+ ignoreUrls: true,
61
+ },
62
+ ],
63
+
64
+ 'no-underscore-dangle': [
65
+ 1,
66
+ {
67
+ allow: ['_config', '_connection', '_maxListeners'],
68
+ allowAfterThis: true,
69
+ },
70
+ ],
71
+
72
+ 'no-return-await': 'off',
73
+ 'no-console': 'error',
74
+ 'no-param-reassign': 'error',
75
+ 'global-require': 'error',
76
+ 'no-unused-expressions': 'error',
77
+ 'no-sequences': 'error',
78
+ 'prefer-rest-params': 'error',
79
+ 'func-names': ['error', 'as-needed'],
80
+ },
81
+ },
82
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arnavmq",
3
- "version": "0.16.4",
3
+ "version": "0.17.1",
4
4
  "description": "ArnavMQ is a RabbitMQ wrapper",
5
5
  "keywords": [
6
6
  "rabbitmq",
@@ -34,26 +34,26 @@
34
34
  },
35
35
  "homepage": "https://github.com/bringg/node-arnavmq#readme",
36
36
  "dependencies": {
37
- "@types/amqplib": "^0.10.5",
38
- "amqplib": "^0.10.3",
37
+ "@types/amqplib": "^0.10.7",
38
+ "amqplib": "^0.10.9",
39
39
  "p-defer": "^3.0.0",
40
- "serialize-error": "^8.0.1",
41
- "uuid": "^9.0.0"
40
+ "serialize-error": "^8.0.1"
42
41
  },
43
42
  "devDependencies": {
43
+ "@eslint/js": "^9.13.0",
44
44
  "child-process-promise": "^2.2.1",
45
45
  "dot-only-hunter": "^1.0.3",
46
- "eslint": "^8.25.0",
47
- "eslint-config-airbnb-base": "^15.0.0",
48
- "eslint-config-prettier": "^9.0.0",
49
- "eslint-plugin-import": "^2.26.0",
50
- "mocha": "^10.0.0",
51
- "nyc": "^15.1.0",
46
+ "eslint": "^9.13.0",
47
+ "eslint-config-prettier": "^10.0.1",
48
+ "eslint-plugin-import": "^2.31.0",
49
+ "globals": "^17.0.0",
50
+ "mocha": "^11.0.1",
51
+ "nyc": "^17.0.0",
52
52
  "prettier": "^3.0.0",
53
- "sinon": "^17.0.1",
53
+ "sinon": "^21.0.1",
54
54
  "typescript": "^5.3.3"
55
55
  },
56
56
  "engines": {
57
- "node": ">=14"
57
+ "node": ">=18"
58
58
  }
59
59
  }
package/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const uuid = require('uuid');
1
+ const crypto = require('crypto');
2
2
  const connection = require('./modules/connection');
3
3
  const { setLogger } = require('./modules/logger');
4
4
 
@@ -28,7 +28,7 @@ module.exports = (config) => {
28
28
  consumerSuffix: '',
29
29
 
30
30
  // generate a hostname so we can track this connection on the broker (rabbitmq management plugin)
31
- hostname: process.env.HOSTNAME || process.env.USER || uuid.v4(),
31
+ hostname: process.env.HOSTNAME || process.env.USER || crypto.randomUUID(),
32
32
 
33
33
  ...config,
34
34
  };
@@ -190,10 +190,10 @@ class Consumer {
190
190
  params: { queue, message: messageString },
191
191
  });
192
192
 
193
- // main answer management chaining
194
- // receive message, parse it, execute callback, check if should answer, ack/reject message
195
- const body = parsers.in(msg);
193
+ let body = {};
196
194
  try {
195
+ body = parsers.in(msg);
196
+
197
197
  const action = { message: msg, content: body, callback };
198
198
  await this.hooks.trigger(this, ConsumerHooks.beforeProcessMessageEvent, {
199
199
  queue,
@@ -203,13 +203,20 @@ class Consumer {
203
203
  const res = await action.callback(body, msg.properties);
204
204
  await this.checkRpc(msg.properties, queue, res);
205
205
  } catch (error) {
206
- // if something bad happened in the callback, reject the message so we can requeue it (or not)
207
206
  logger.error({
208
207
  message: `${loggerAlias} Failed processing message from queue ${queue}: ${error.message}`,
209
208
  error,
210
209
  params: { queue, message: messageString },
211
210
  });
212
211
 
212
+ if (error instanceof SyntaxError) {
213
+ // For parsing errors, reject the message and don't requeue it.
214
+ await this._rejectMessageAfterProcess(channel, queue, msg, body, false, error);
215
+ // Backward compatibility: For parsing errors, throw to let client handle it
216
+ throw error;
217
+ }
218
+
219
+ // For callback errors, use default behavior with _rejectMessageAfterProcess
213
220
  await this._rejectMessageAfterProcess(channel, queue, msg, body, this._connection.config.requeue, error);
214
221
  return;
215
222
  }
@@ -274,7 +281,4 @@ class Consumer {
274
281
  }
275
282
  }
276
283
 
277
- /* eslint no-unused-expressions: "off" */
278
- /* eslint no-sequences: "off" */
279
- /* eslint arrow-body-style: "off" */
280
284
  module.exports = Consumer;
@@ -103,7 +103,7 @@ module.exports = class BaseHooks {
103
103
 
104
104
  const hookPromises = [];
105
105
  // This rule intends to restrict it for arrays, but this is a Set which doesn't have a '.map' function to use instead.
106
- // eslint-disable-next-line no-restricted-syntax
106
+
107
107
  for (const callback of callbacks) {
108
108
  hookPromises.push(runHook(source, eventName, payload, callback));
109
109
  }
@@ -33,19 +33,19 @@ module.exports.in = (msg) => {
33
33
  * @param {object} options amqp.node message options object
34
34
  * @return {Buffer} node.js Buffer object, sent by amqp.node
35
35
  */
36
- /* eslint no-param-reassign: "off" */
37
36
  module.exports.out = (content, options) => {
37
+ let parsedContent = content;
38
38
  const falsie = [undefined, null];
39
39
  if (!falsie.includes(content) && typeof content !== 'string') {
40
- if (content.error instanceof Error) {
41
- content.error = serializeError(content.error);
40
+ if (parsedContent.error instanceof Error) {
41
+ parsedContent.error = serializeError(parsedContent.error);
42
42
  }
43
43
  // if content is not a string, we JSONify it (JSON.parse can handle numbers, etc. so we can skip all the checks)
44
- content = JSON.stringify(content);
44
+ parsedContent = JSON.stringify(parsedContent);
45
45
  options.contentType = 'application/json';
46
- } else if (falsie.includes(content)) {
46
+ } else if (falsie.includes(parsedContent)) {
47
47
  return Buffer.from([]);
48
48
  }
49
49
 
50
- return Buffer.from(content, 'utf-8');
50
+ return Buffer.from(parsedContent, 'utf-8');
51
51
  };
@@ -205,7 +205,6 @@ class Producer {
205
205
  * @param {object} options message options (persistent, durable, rpc, etc.)
206
206
  * @return {Promise} checkRpc response
207
207
  */
208
- /* eslint prefer-rest-params: off */
209
208
  produce(queue, msg, options) {
210
209
  return this.publish(queue, msg, options);
211
210
  }
@@ -217,7 +216,6 @@ class Producer {
217
216
  * @param {object} options message options (persistent, durable, rpc, etc.)
218
217
  * @return {Promise} checkRpc response
219
218
  */
220
- /* eslint no-param-reassign: "off" */
221
219
  async publish(queue, msg, options) {
222
220
  // default options are persistent and durable because we do not want to miss any outgoing message
223
221
  // unless user specify it
@@ -236,6 +234,7 @@ class Producer {
236
234
  async _sendToQueue(queue, message, settings, currentRetryNumber) {
237
235
  // undefined can't be serialized/buffered :p
238
236
  if (!message) {
237
+ // eslint-disable-next-line no-param-reassign
239
238
  message = null;
240
239
  }
241
240
 
@@ -311,7 +310,4 @@ class Producer {
311
310
  }
312
311
  }
313
312
 
314
- /* eslint no-unused-expressions: "off" */
315
- /* eslint no-sequences: "off" */
316
- /* eslint arrow-body-style: "off" */
317
313
  module.exports = Producer;
@@ -1,4 +1,4 @@
1
- const uuid = require('uuid');
1
+ const crypto = require('crypto');
2
2
 
3
3
  function empty() {}
4
4
 
@@ -19,7 +19,7 @@ function getCorrelationId(options) {
19
19
  if (options.correlationId) {
20
20
  return options.correlationId;
21
21
  }
22
- return uuid.v4();
22
+ return crypto.randomUUID();
23
23
  }
24
24
 
25
25
  module.exports = {
@@ -5,8 +5,8 @@ interface ChannelConfig {
5
5
  }
6
6
 
7
7
  declare class Channels {
8
- constructor(connection: amqp.Connection, config: ChannelConfig);
9
- private readonly _connection: amqp.Connection;
8
+ constructor(connection: amqp.ChannelModel, config: ChannelConfig);
9
+ private readonly _connection: amqp.ChannelModel;
10
10
  private readonly _config: ChannelConfig;
11
11
  private readonly _channels: Map<string, { chann: Promise<amqp.Channel>; config: ChannelConfig }>;
12
12
  get(queue: string, config: ChannelConfig): Promise<amqp.Channel>;
@@ -57,14 +57,14 @@ interface ConnectionConfig {
57
57
  declare class Connection {
58
58
  constructor(config: ConnectionConfig);
59
59
 
60
- private _connectionPromise: Promise<amqp.Connection>;
60
+ private _connectionPromise: Promise<amqp.ChannelModel>;
61
61
  private _config: ConnectionConfig;
62
62
  public hooks: ConnectionHooks;
63
63
 
64
64
  get config(): ConnectionConfig;
65
65
  set config(value: ConnectionConfig);
66
66
 
67
- getConnection(): Promise<amqp.Connection>;
67
+ getConnection(): Promise<amqp.ChannelModel>;
68
68
  getChannel(queue: string, config: channels.ChannelConfig): Promise<amqp.Channel>;
69
69
  getDefaultChannel(): Promise<amqp.Channel>;
70
70
  /**
@@ -74,14 +74,14 @@ declare class Connection {
74
74
  */
75
75
  addListener(on: string, func: Function): Promise<void>;
76
76
 
77
- private _connect(): Promise<amqp.Connection>;
77
+ private _connect(): Promise<amqp.ChannelModel>;
78
78
  }
79
79
 
80
80
  declare function connection(config: ConnectionConfig): Connection;
81
81
 
82
82
  declare namespace connection {
83
83
  export interface Connection {
84
- getConnection(): Promise<amqp.Connection>;
84
+ getConnection(): Promise<amqp.ChannelModel>;
85
85
  getChannel(queue: string, config: channels.ChannelConfig): Promise<amqp.Channel>;
86
86
  getDefaultChannel(): Promise<amqp.Channel>;
87
87
  /**
@@ -8,7 +8,7 @@ type AfterConnectInfo = {
8
8
  config: ConnectionConfig;
9
9
  } & (
10
10
  | {
11
- connection: amqp.Connection;
11
+ connection: amqp.ChannelModel;
12
12
  error: undefined;
13
13
  }
14
14
  | {