@onify/fake-amqplib 0.8.3 → 0.9.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/index.js +74 -27
  3. package/package.json +6 -9
package/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ # 0.9.0
5
+
6
+ - support connecting with urlish object
7
+ - smqp@6
8
+
9
+ # 0.8.5
10
+
11
+ - ack/nack all only cares about messages consumed by channel, previously everything was gone
12
+
13
+ # 0.8.4
14
+
15
+ - ack/nack all fix
16
+
4
17
  # 0.8.3
5
18
 
6
19
  - Call confirm channel callback when the message is queued, not when it is consumed!
package/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const {Broker} = require('smqp');
4
4
  const {EventEmitter} = require('events');
5
- const {URL} = require('url');
5
+ const {URL, format: urlFormat} = require('url');
6
6
 
7
7
  const smqpSymbol = Symbol.for('smqp');
8
8
 
@@ -16,8 +16,8 @@ class FakeAmqpError extends Error {
16
16
  }
17
17
 
18
18
  class FakeAmqpNotFoundError extends FakeAmqpError {
19
- constructor(type, name, killConnection = false) {
20
- super(`Channel closed by server: 404 (NOT-FOUND) with message "NOT_FOUND - no ${type} '${name}' in vhost '/'`, 404, true, killConnection);
19
+ constructor(type, name, vhost, killConnection = false) {
20
+ super(`Channel closed by server: 404 (NOT-FOUND) with message "NOT_FOUND - no ${type} '${name}' in vhost '${vhost || '/'}'`, 404, true, killConnection);
21
21
  }
22
22
  }
23
23
 
@@ -44,7 +44,7 @@ function Fake(minorVersion) {
44
44
  }
45
45
 
46
46
  function connectSync(amqpUrl, ...args) {
47
- const {_broker} = connections.find((conn) => compareConnectionString(conn.options[0], amqpUrl)) || {};
47
+ const {_broker} = connections.find((conn) => compareConnectionString(conn._url, amqpUrl)) || {};
48
48
  const broker = _broker || Broker();
49
49
  const connection = Connection(broker, defaultVersion, amqpUrl, ...args);
50
50
  connections.push(connection);
@@ -57,16 +57,18 @@ function Fake(minorVersion) {
57
57
  }
58
58
  }
59
59
 
60
- function Connection(broker, version, ...connArgs) {
60
+ function Connection(broker, version, amqpUrl, ...connArgs) {
61
61
  const emitter = new EventEmitter();
62
62
  const options = connArgs.filter((a) => typeof a !== 'function');
63
63
  let closed = false;
64
64
  const channels = [];
65
+ const url = normalizeAmqpUrl(amqpUrl);
65
66
 
66
67
  return {
67
68
  _id: generateId(),
68
69
  _broker: broker,
69
70
  _version: version,
71
+ _url: url,
70
72
  get _closed() {
71
73
  return closed;
72
74
  },
@@ -89,6 +91,7 @@ function Fake(minorVersion) {
89
91
  return resolveOrCallback(args.slice(-1)[0], null, channel);
90
92
  },
91
93
  async close(...args) {
94
+ if (closed) return resolveOrCallback(args.slice(-1)[0]);
92
95
  closed = true;
93
96
 
94
97
  const idx = connections.indexOf(this);
@@ -145,9 +148,9 @@ function Fake(minorVersion) {
145
148
  function assertQueue(queueName, ...args) {
146
149
  const name = queueName ? queueName : 'amqp.gen-' + generateId();
147
150
  const options = typeof args[0] === 'object' ? args.shift() : {};
148
- const queue = broker.assertQueue(queueName, {...options, _connectionId: connection._id}, ...args);
151
+ const queue = broker.assertQueue(name, {...options, _connectionId: connection._id}, ...args);
149
152
  return {
150
- ...(!queueName ? {queue: name} : undefined),
153
+ queue: name,
151
154
  messageCount: queue.messageCount,
152
155
  consumerCount: queue.consumerCount,
153
156
  };
@@ -167,7 +170,7 @@ function Fake(minorVersion) {
167
170
  return callBroker(check, ...args);
168
171
 
169
172
  function check() {
170
- if (!broker.getExchange(name)) throw new FakeAmqpError(`Channel closed by server: 404 (NOT-FOUND) with message "NOT_FOUND - no exchange '${name}' in vhost '/'`, 404, true);
173
+ if (!broker.getExchange(name)) throw new FakeAmqpNotFoundError('exchange', name, connection._url.pathname);
171
174
  return true;
172
175
  }
173
176
  },
@@ -177,7 +180,7 @@ function Fake(minorVersion) {
177
180
  function check() {
178
181
  let queue;
179
182
  if (!(queue = broker.getQueue(name))) {
180
- throw new FakeAmqpNotFoundError('queue', name);
183
+ throw new FakeAmqpNotFoundError('queue', name, connection._url.pathname);
181
184
  }
182
185
 
183
186
  return {
@@ -191,7 +194,7 @@ function Fake(minorVersion) {
191
194
 
192
195
  function getMessage(...getargs) {
193
196
  const q = broker.getQueue(queue);
194
- if (!q) throw new FakeAmqpNotFoundError('queue');
197
+ if (!q) throw new FakeAmqpNotFoundError('queue', queue, connection._url.pathname);
195
198
  const msg = q.get(...getargs) || false;
196
199
  if (!msg) return msg;
197
200
  return new Message(msg);
@@ -202,7 +205,7 @@ function Fake(minorVersion) {
202
205
 
203
206
  function check() {
204
207
  const result = broker.deleteExchange(exchange, ...args);
205
- if (!result && version < 3.2) throw new FakeAmqpNotFoundError('exchange', exchange);
208
+ if (!result && version < 3.2) throw new FakeAmqpNotFoundError('exchange', exchange, connection._url.pathname);
206
209
  return result;
207
210
  }
208
211
  },
@@ -211,7 +214,7 @@ function Fake(minorVersion) {
211
214
 
212
215
  function check() {
213
216
  const result = broker.deleteQueue(queue, ...args);
214
- if (!result && version < 3.2) throw new FakeAmqpNotFoundError('queue', queue);
217
+ if (!result && version < 3.2) throw new FakeAmqpNotFoundError('queue', queue, connection._url.pathname);
215
218
  return result;
216
219
  }
217
220
  },
@@ -237,7 +240,7 @@ function Fake(minorVersion) {
237
240
 
238
241
  function check() {
239
242
  const result = broker.purgeQueue(queue);
240
- if (!result && version < 3.2) throw new FakeAmqpNotFoundError('queue', queue);
243
+ if (!result && version < 3.2) throw new FakeAmqpNotFoundError('queue', queue, connection._url.pathname);
241
244
  return result === undefined ? undefined : {messageCount: result};
242
245
  }
243
246
  },
@@ -268,7 +271,7 @@ function Fake(minorVersion) {
268
271
  if (!exchange) throw new FakeAmqpNotFoundError('exchange', source);
269
272
 
270
273
  const result = broker.unbindExchange(source, destination, pattern);
271
- if (!result && version <= 3.2) throw new FakeAmqpNotFoundError('binding', pattern);
274
+ if (!result && version <= 3.2) throw new FakeAmqpNotFoundError('binding', pattern, connection._url.pathname);
272
275
 
273
276
  return true;
274
277
  }
@@ -284,7 +287,7 @@ function Fake(minorVersion) {
284
287
  if (!exchange) throw new FakeAmqpNotFoundError('exchange', source);
285
288
 
286
289
  const binding = exchange.getBinding(queue, pattern);
287
- if (!binding && version <= 3.2) throw new FakeAmqpNotFoundError('binding', pattern, version < 3.2);
290
+ if (!binding && version <= 3.2) throw new FakeAmqpNotFoundError('binding', pattern, connection._url.pathname, version < 3.2);
288
291
 
289
292
  broker.unbindQueue(queue, source, pattern);
290
293
  return true;
@@ -295,14 +298,12 @@ function Fake(minorVersion) {
295
298
 
296
299
  function check() {
297
300
  const q = queue && broker.getQueue(queue);
298
- if (queue && !q) {
299
- throw new FakeAmqpNotFoundError('queue', queue);
301
+ if (!q) {
302
+ throw new FakeAmqpNotFoundError('queue', queue, connection._url.pathname);
300
303
  }
301
304
 
302
- if (q) {
303
- if (q.exclusive || (q.options.exclusive && q.options._connectionId !== connection._id)) {
304
- throw new FakeAmqpError(`Channel closed by server: 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - queue '${queue}' in vhost '/' in exclusive use"`, 403, true, true);
305
- }
305
+ if (q.exclusive || (q.options.exclusive && q.options._connectionId !== connection._id)) {
306
+ throw new FakeAmqpError(`Channel closed by server: 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - queue '${queue}' in vhost '${connection._url.pathname}' in exclusive use"`, 403, true, true);
306
307
  }
307
308
 
308
309
  const {consumerTag} = broker.consume(queue, onMessage && handler, {...options, channelName, prefetch});
@@ -328,8 +329,9 @@ function Fake(minorVersion) {
328
329
  ack(message, ...args) {
329
330
  broker.ack(message[smqpSymbol], ...args);
330
331
  },
331
- ackAll(message, ...args) {
332
- broker.ackAll(message[smqpSymbol], ...args);
332
+ ackAll() {
333
+ const consumers = broker.getConsumers().filter(({options}) => options.channelName === channelName);
334
+ consumers.forEach((c) => broker.getConsumer(c.consumerTag).ackAll());
333
335
  },
334
336
  ...(version >= 2.3 ? {
335
337
  nack(message, ...args) {
@@ -339,8 +341,9 @@ function Fake(minorVersion) {
339
341
  reject(message, ...args) {
340
342
  broker.reject(message[smqpSymbol], ...args);
341
343
  },
342
- nackAll(message, ...args) {
343
- broker.nackAll(message[smqpSymbol], ...args);
344
+ nackAll(requeue = false) {
345
+ const consumers = broker.getConsumers().filter(({options}) => options.channelName === channelName);
346
+ consumers.forEach((c) => broker.getConsumer(c.consumerTag).nackAll(requeue));
344
347
  },
345
348
  prefetch(val) {
346
349
  prefetch = val;
@@ -428,8 +431,9 @@ function generateId() {
428
431
  }
429
432
 
430
433
  function compareConnectionString(url1, url2) {
431
- const parsedUrl1 = new URL(url1);
432
- const parsedUrl2 = new URL(url2);
434
+ const parsedUrl1 = normalizeAmqpUrl(url1);
435
+ const parsedUrl2 = normalizeAmqpUrl(url2);
436
+
433
437
  return parsedUrl1.host === parsedUrl2.host && parsedUrl1.pathname === parsedUrl2.pathname;
434
438
  }
435
439
 
@@ -439,3 +443,46 @@ function Message(smqpMessage) {
439
443
  this.fields = smqpMessage.fields;
440
444
  this.properties = smqpMessage.properties;
441
445
  }
446
+
447
+ function normalizeAmqpUrl(url) {
448
+ if (!url) return url = new URL('amqp://localhost:5672/');
449
+ if (typeof url === 'string') url = new URL(url);
450
+
451
+ if (!(url instanceof URL)) {
452
+ const {
453
+ protocol = 'amqp',
454
+ hostname = 'localhost',
455
+ port = 5672,
456
+ vhost = '/',
457
+ username,
458
+ password,
459
+ ...rest
460
+ } = url;
461
+ let auth = username;
462
+ if (auth && password) {
463
+ auth += ':' + password;
464
+ }
465
+ url = new URL(urlFormat({
466
+ protocol,
467
+ hostname,
468
+ port,
469
+ pathname: vhost,
470
+ slashes: true,
471
+ auth,
472
+ }));
473
+
474
+ for (const k in rest) {
475
+ switch (k) {
476
+ case 'locale':
477
+ case 'frameMax':
478
+ case 'heartbeat':
479
+ url.searchParams.set(k, rest[k]);
480
+ break;
481
+ }
482
+ }
483
+ }
484
+
485
+ if (!url.port) url.port = 5672;
486
+ if (!url.pathname) url.pathname = '/';
487
+ return url;
488
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onify/fake-amqplib",
3
- "version": "0.8.3",
3
+ "version": "0.9.1",
4
4
  "description": "Fake amqplib",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
- "smqp": "^5.1.0"
24
+ "smqp": "^6.0.0"
25
25
  },
26
26
  "keywords": [
27
27
  "fake",
@@ -31,15 +31,12 @@
31
31
  "rabbitmq"
32
32
  ],
33
33
  "devDependencies": {
34
- "chai": "^4.2.0",
35
- "eslint": "^8.1.0",
36
- "mocha": "^9.1.3",
34
+ "chai": "^4.3.6",
35
+ "eslint": "^7.32.0",
36
+ "mocha": "^9.2.0",
37
37
  "nyc": "^15.1.0"
38
38
  },
39
39
  "files": [
40
40
  "index.js"
41
- ],
42
- "directories": {
43
- "test": "test"
44
- }
41
+ ]
45
42
  }