sqs-consumer 5.8.0 → 6.0.0-alpha.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 +19 -43
- package/dist/consumer.d.ts +10 -11
- package/dist/consumer.js +19 -19
- package/dist/errors.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +59 -0
- package/dist/types.js +2 -0
- package/examples/express-simple/dist/app.d.ts +4 -0
- package/examples/express-simple/dist/app.js +97 -0
- package/examples/express-simple/dist/utils/consumer.d.ts +1 -0
- package/examples/express-simple/dist/utils/consumer.js +63 -0
- package/examples/express-simple/dist/utils/producer.d.ts +1 -0
- package/examples/express-simple/dist/utils/producer.js +10 -0
- package/examples/express-simple/dist/utils/sqs.d.ts +1 -0
- package/examples/express-simple/dist/utils/sqs.js +33 -0
- package/package.json +3 -3
- package/src/consumer.ts +71 -60
- package/src/errors.ts +2 -2
- package/src/index.ts +1 -1
- package/src/types.ts +70 -0
- package/test/consumer.test.ts +283 -174
package/README.md
CHANGED
|
@@ -13,10 +13,17 @@ Build SQS-based applications without the boilerplate. Just define an async funct
|
|
|
13
13
|
npm install sqs-consumer --save-dev
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
> **Note**
|
|
17
|
+
> This library assumes you are using [AWS SDK v3](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-sqs/index.html). If you are using v2, please install v5.8.0:
|
|
18
|
+
>
|
|
19
|
+
> ```bash
|
|
20
|
+
> npm install sqs-consumer@5.8.0 --save-dev
|
|
21
|
+
> ```
|
|
22
|
+
|
|
16
23
|
## Usage
|
|
17
24
|
|
|
18
25
|
```js
|
|
19
|
-
|
|
26
|
+
import { Consumer } from 'sqs-consumer';
|
|
20
27
|
|
|
21
28
|
const app = Consumer.create({
|
|
22
29
|
queueUrl: 'https://sqs.eu-west-1.amazonaws.com/account-id/queue-name',
|
|
@@ -40,37 +47,6 @@ app.start();
|
|
|
40
47
|
- Messages are deleted from the queue once the handler function has completed successfully.
|
|
41
48
|
- Throwing an error (or returning a rejected promise) from the handler function will cause the message to be left on the queue. An [SQS redrive policy](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSDeadLetterQueue.html) can be used to move messages that cannot be processed to a dead letter queue.
|
|
42
49
|
- By default messages are processed one at a time – a new message won't be received until the first one has been processed. To process messages in parallel, use the `batchSize` option [detailed below](#options).
|
|
43
|
-
- By default, the default Node.js HTTP/HTTPS SQS agent creates a new TCP connection for every new request ([AWS SQS documentation](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html)). To avoid the cost of establishing a new connection, you can reuse an existing connection by passing a new SQS instance with `keepAlive: true`.
|
|
44
|
-
|
|
45
|
-
```js
|
|
46
|
-
const { Consumer } = require('sqs-consumer');
|
|
47
|
-
const AWS = require('aws-sdk');
|
|
48
|
-
const https = require('https');
|
|
49
|
-
|
|
50
|
-
const app = Consumer.create({
|
|
51
|
-
queueUrl: 'https://sqs.eu-west-1.amazonaws.com/account-id/queue-name',
|
|
52
|
-
handleMessage: async (message) => {
|
|
53
|
-
// do some work with `message`
|
|
54
|
-
},
|
|
55
|
-
sqs: new AWS.SQS({
|
|
56
|
-
httpOptions: {
|
|
57
|
-
agent: new https.Agent({
|
|
58
|
-
keepAlive: true
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
app.on('error', (err) => {
|
|
65
|
-
console.error(err.message);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
app.on('processing_error', (err) => {
|
|
69
|
-
console.error(err.message);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
app.start();
|
|
73
|
-
```
|
|
74
50
|
|
|
75
51
|
### Credentials
|
|
76
52
|
|
|
@@ -81,24 +57,24 @@ export AWS_SECRET_ACCESS_KEY=...
|
|
|
81
57
|
export AWS_ACCESS_KEY_ID=...
|
|
82
58
|
```
|
|
83
59
|
|
|
84
|
-
If you need to specify your credentials manually, you can use a pre-configured instance of the [
|
|
60
|
+
If you need to specify your credentials manually, you can use a pre-configured instance of the [SQS Client](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-sqs/classes/sqsclient.html) client.
|
|
85
61
|
|
|
86
62
|
```js
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
AWS.config.update({
|
|
91
|
-
region: 'eu-west-1',
|
|
92
|
-
accessKeyId: '...',
|
|
93
|
-
secretAccessKey: '...'
|
|
94
|
-
});
|
|
63
|
+
import { Consumer } from 'sqs-consumer';
|
|
64
|
+
import { SQSClient } from '@aws-sdk/client-sqs';
|
|
95
65
|
|
|
96
66
|
const app = Consumer.create({
|
|
97
67
|
queueUrl: 'https://sqs.eu-west-1.amazonaws.com/account-id/queue-name',
|
|
98
68
|
handleMessage: async (message) => {
|
|
99
69
|
// ...
|
|
100
70
|
},
|
|
101
|
-
sqs: new
|
|
71
|
+
sqs: new SQSClient({
|
|
72
|
+
region: 'my-region',
|
|
73
|
+
credentials: {
|
|
74
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
75
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
|
76
|
+
}
|
|
77
|
+
})
|
|
102
78
|
});
|
|
103
79
|
|
|
104
80
|
app.on('error', (err) => {
|
|
@@ -138,7 +114,7 @@ Creates a new SQS consumer.
|
|
|
138
114
|
- `waitTimeSeconds` - _Number_ - The duration (in seconds) for which the call will wait for a message to arrive in the queue before returning (defaults to `20`).
|
|
139
115
|
- `authenticationErrorTimeout` - _Number_ - The duration (in milliseconds) to wait before retrying after an authentication error (defaults to `10000`).
|
|
140
116
|
- `pollingWaitTimeMs` - _Number_ - The duration (in milliseconds) to wait before repolling the queue (defaults to `0`).
|
|
141
|
-
- `sqs` - _Object_ - An optional [
|
|
117
|
+
- `sqs` - _Object_ - An optional [SQS Client](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-sqs/classes/sqsclient.html) object to use if you need to configure the client manually
|
|
142
118
|
- `shouldDeleteMessages` - _Boolean_ - Default to `true`, if you don't want the package to delete messages from sqs set this to `false`
|
|
143
119
|
|
|
144
120
|
### `consumer.start()`
|
package/dist/consumer.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import {
|
|
2
|
+
import { SQSClient, Message } from '@aws-sdk/client-sqs';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
-
export type SQSMessage = SQS.Types.Message;
|
|
5
4
|
export interface ConsumerOptions {
|
|
6
5
|
queueUrl?: string;
|
|
7
6
|
attributeNames?: string[];
|
|
@@ -14,21 +13,21 @@ export interface ConsumerOptions {
|
|
|
14
13
|
pollingWaitTimeMs?: number;
|
|
15
14
|
terminateVisibilityTimeout?: boolean;
|
|
16
15
|
heartbeatInterval?: number;
|
|
17
|
-
sqs?:
|
|
16
|
+
sqs?: SQSClient;
|
|
18
17
|
region?: string;
|
|
19
18
|
handleMessageTimeout?: number;
|
|
20
19
|
shouldDeleteMessages?: boolean;
|
|
21
|
-
handleMessage?(message:
|
|
22
|
-
handleMessageBatch?(messages:
|
|
20
|
+
handleMessage?(message: Message): Promise<void>;
|
|
21
|
+
handleMessageBatch?(messages: Message[]): Promise<void>;
|
|
23
22
|
}
|
|
24
23
|
interface Events {
|
|
25
24
|
response_processed: [];
|
|
26
25
|
empty: [];
|
|
27
|
-
message_received: [
|
|
28
|
-
message_processed: [
|
|
29
|
-
error: [Error, void |
|
|
30
|
-
timeout_error: [Error,
|
|
31
|
-
processing_error: [Error,
|
|
26
|
+
message_received: [Message];
|
|
27
|
+
message_processed: [Message];
|
|
28
|
+
error: [Error, void | Message | Message[]];
|
|
29
|
+
timeout_error: [Error, Message];
|
|
30
|
+
processing_error: [Error, Message];
|
|
32
31
|
stopped: [];
|
|
33
32
|
}
|
|
34
33
|
export declare class Consumer extends EventEmitter {
|
|
@@ -67,7 +66,7 @@ export declare class Consumer extends EventEmitter {
|
|
|
67
66
|
private processMessageBatch;
|
|
68
67
|
private deleteMessageBatch;
|
|
69
68
|
private executeBatchHandler;
|
|
70
|
-
private
|
|
69
|
+
private changeVisibilityTimeoutBatch;
|
|
71
70
|
private startHeartbeat;
|
|
72
71
|
}
|
|
73
72
|
export {};
|
package/dist/consumer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Consumer = void 0;
|
|
4
|
-
const
|
|
4
|
+
const client_sqs_1 = require("@aws-sdk/client-sqs");
|
|
5
5
|
const debug_1 = require("debug");
|
|
6
6
|
const events_1 = require("events");
|
|
7
7
|
const bind_1 = require("./bind");
|
|
@@ -45,13 +45,14 @@ function isConnectionError(err) {
|
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
function toSQSError(err, message) {
|
|
48
|
+
var _a, _b;
|
|
48
49
|
const sqsError = new errors_1.SQSError(message);
|
|
49
|
-
sqsError.code = err.
|
|
50
|
-
sqsError.statusCode = err.
|
|
51
|
-
sqsError.
|
|
52
|
-
sqsError.
|
|
53
|
-
sqsError.
|
|
54
|
-
sqsError.time =
|
|
50
|
+
sqsError.code = err.name;
|
|
51
|
+
sqsError.statusCode = (_a = err.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode;
|
|
52
|
+
sqsError.retryable = (_b = err.$retryable) === null || _b === void 0 ? void 0 : _b.throttling;
|
|
53
|
+
sqsError.service = err.$service;
|
|
54
|
+
sqsError.fault = err.$fault;
|
|
55
|
+
sqsError.time = new Date();
|
|
55
56
|
return sqsError;
|
|
56
57
|
}
|
|
57
58
|
function hasMessages(response) {
|
|
@@ -81,7 +82,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
81
82
|
this.shouldDeleteMessages = (_d = options.shouldDeleteMessages) !== null && _d !== void 0 ? _d : true;
|
|
82
83
|
this.sqs =
|
|
83
84
|
options.sqs ||
|
|
84
|
-
new
|
|
85
|
+
new client_sqs_1.SQSClient({
|
|
85
86
|
region: options.region || process.env.AWS_REGION || 'eu-west-1'
|
|
86
87
|
});
|
|
87
88
|
(0, bind_1.autoBind)(this);
|
|
@@ -156,7 +157,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
156
157
|
}
|
|
157
158
|
async receiveMessage(params) {
|
|
158
159
|
try {
|
|
159
|
-
return await this.sqs.
|
|
160
|
+
return await this.sqs.send(new client_sqs_1.ReceiveMessageCommand(params));
|
|
160
161
|
}
|
|
161
162
|
catch (err) {
|
|
162
163
|
throw toSQSError(err, `SQS receive message failed: ${err.message}`);
|
|
@@ -173,7 +174,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
173
174
|
ReceiptHandle: message.ReceiptHandle
|
|
174
175
|
};
|
|
175
176
|
try {
|
|
176
|
-
await this.sqs.
|
|
177
|
+
await this.sqs.send(new client_sqs_1.DeleteMessageCommand(deleteParams));
|
|
177
178
|
}
|
|
178
179
|
catch (err) {
|
|
179
180
|
throw toSQSError(err, `SQS delete message failed: ${err.message}`);
|
|
@@ -206,13 +207,12 @@ class Consumer extends events_1.EventEmitter {
|
|
|
206
207
|
}
|
|
207
208
|
async changeVisibilityTimeout(message, timeout) {
|
|
208
209
|
try {
|
|
209
|
-
|
|
210
|
-
.changeMessageVisibility({
|
|
210
|
+
const input = {
|
|
211
211
|
QueueUrl: this.queueUrl,
|
|
212
212
|
ReceiptHandle: message.ReceiptHandle,
|
|
213
213
|
VisibilityTimeout: timeout
|
|
214
|
-
}
|
|
215
|
-
|
|
214
|
+
};
|
|
215
|
+
return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityCommand(input));
|
|
216
216
|
}
|
|
217
217
|
catch (err) {
|
|
218
218
|
this.emit('error', toSQSError(err, `Error changing visibility timeout: ${err.message}`), message);
|
|
@@ -269,7 +269,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
269
269
|
try {
|
|
270
270
|
if (this.heartbeatInterval) {
|
|
271
271
|
heartbeat = this.startHeartbeat(async () => {
|
|
272
|
-
return this.
|
|
272
|
+
return this.changeVisibilityTimeoutBatch(messages, this.visibilityTimeout);
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
await this.executeBatchHandler(messages);
|
|
@@ -281,7 +281,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
281
281
|
catch (err) {
|
|
282
282
|
this.emit('error', err, messages);
|
|
283
283
|
if (this.terminateVisibilityTimeout) {
|
|
284
|
-
await this.
|
|
284
|
+
await this.changeVisibilityTimeoutBatch(messages, 0);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
finally {
|
|
@@ -302,7 +302,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
302
302
|
}))
|
|
303
303
|
};
|
|
304
304
|
try {
|
|
305
|
-
await this.sqs.
|
|
305
|
+
await this.sqs.send(new client_sqs_1.DeleteMessageBatchCommand(deleteParams));
|
|
306
306
|
}
|
|
307
307
|
catch (err) {
|
|
308
308
|
throw toSQSError(err, `SQS delete message failed: ${err.message}`);
|
|
@@ -317,7 +317,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
317
317
|
throw err;
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
|
-
async
|
|
320
|
+
async changeVisibilityTimeoutBatch(messages, timeout) {
|
|
321
321
|
const params = {
|
|
322
322
|
QueueUrl: this.queueUrl,
|
|
323
323
|
Entries: messages.map((message) => ({
|
|
@@ -327,7 +327,7 @@ class Consumer extends events_1.EventEmitter {
|
|
|
327
327
|
}))
|
|
328
328
|
};
|
|
329
329
|
try {
|
|
330
|
-
return await this.sqs.
|
|
330
|
+
return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityBatchCommand(params));
|
|
331
331
|
}
|
|
332
332
|
catch (err) {
|
|
333
333
|
this.emit('error', toSQSError(err, `Error changing visibility timeout: ${err.message}`), messages);
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
declare class SQSError extends Error {
|
|
2
2
|
code: string;
|
|
3
3
|
statusCode: number;
|
|
4
|
-
|
|
5
|
-
hostname: string;
|
|
4
|
+
service: string;
|
|
6
5
|
time: Date;
|
|
7
6
|
retryable: boolean;
|
|
7
|
+
fault: 'client' | 'server';
|
|
8
8
|
constructor(message: string);
|
|
9
9
|
}
|
|
10
10
|
declare class TimeoutError extends Error {
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { Consumer, ConsumerOptions } from './consumer';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type AWSError = {
|
|
2
|
+
/**
|
|
3
|
+
* Name, eg. ConditionalCheckFailedException
|
|
4
|
+
*/
|
|
5
|
+
name: string;
|
|
6
|
+
/**
|
|
7
|
+
* Human-readable error response message
|
|
8
|
+
*/
|
|
9
|
+
message: string;
|
|
10
|
+
/**
|
|
11
|
+
* Non-standard stacktrace
|
|
12
|
+
*/
|
|
13
|
+
stack?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Whether the client or server are at fault.
|
|
16
|
+
*/
|
|
17
|
+
readonly $fault?: 'client' | 'server';
|
|
18
|
+
/**
|
|
19
|
+
* The service that encountered the exception.
|
|
20
|
+
*/
|
|
21
|
+
readonly $service?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Indicates that an error MAY be retried by the client.
|
|
24
|
+
*/
|
|
25
|
+
readonly $retryable?: {
|
|
26
|
+
/**
|
|
27
|
+
* Indicates that the error is a retryable throttling error.
|
|
28
|
+
*/
|
|
29
|
+
readonly throttling?: boolean;
|
|
30
|
+
};
|
|
31
|
+
$metadata?: {
|
|
32
|
+
/**
|
|
33
|
+
* The status code of the last HTTP response received for this operation.
|
|
34
|
+
*/
|
|
35
|
+
httpStatusCode?: number;
|
|
36
|
+
/**
|
|
37
|
+
* A unique identifier for the last request sent for this operation. Often
|
|
38
|
+
* requested by AWS service teams to aid in debugging.
|
|
39
|
+
*/
|
|
40
|
+
requestId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* A secondary identifier for the last request sent. Used for debugging.
|
|
43
|
+
*/
|
|
44
|
+
extendedRequestId?: string;
|
|
45
|
+
/**
|
|
46
|
+
* A tertiary identifier for the last request sent. Used for debugging.
|
|
47
|
+
*/
|
|
48
|
+
cfId?: string;
|
|
49
|
+
/**
|
|
50
|
+
* The number of times this operation was attempted.
|
|
51
|
+
*/
|
|
52
|
+
attempts?: number;
|
|
53
|
+
/**
|
|
54
|
+
* The total amount of time (in milliseconds) that was spent waiting between
|
|
55
|
+
* retry attempts.
|
|
56
|
+
*/
|
|
57
|
+
totalRetryDelay?: number;
|
|
58
|
+
};
|
|
59
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const { consumer } = require('./utils/consumer');
|
|
3
|
+
const { producer } = require('./utils/producer');
|
|
4
|
+
const expressApp = express();
|
|
5
|
+
expressApp.get('/', (_, res) => {
|
|
6
|
+
res.send('Hello! Send me a request to one of my other endpoints to test SQS Consumer!');
|
|
7
|
+
});
|
|
8
|
+
expressApp.get('/queue-size', async (_, res) => {
|
|
9
|
+
// get the current size of the queue
|
|
10
|
+
const size = await producer.queueSize();
|
|
11
|
+
res.send({
|
|
12
|
+
message: 'Queue size retrieved!',
|
|
13
|
+
data: size
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
expressApp.post('/sample', async (_, res) => {
|
|
17
|
+
// send messages to the queue
|
|
18
|
+
const messages = await producer.send(['msg1', 'msg2']);
|
|
19
|
+
res.send({
|
|
20
|
+
message: 'Sample messages sent successfully!',
|
|
21
|
+
data: messages
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
expressApp.post('/sample-with-id', async (_, res) => {
|
|
25
|
+
// send a message to the queue with a specific ID (by default the body is used as the ID)
|
|
26
|
+
const messages = await producer.send([
|
|
27
|
+
{
|
|
28
|
+
id: 'id1',
|
|
29
|
+
body: 'Hello world'
|
|
30
|
+
}
|
|
31
|
+
]);
|
|
32
|
+
res.send({
|
|
33
|
+
message: 'Sample messages sent successfully!',
|
|
34
|
+
data: messages
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
expressApp.post('/sample-with-attributes', async (_, res) => {
|
|
38
|
+
// send a message to the queue with
|
|
39
|
+
// - messageAttributes
|
|
40
|
+
const messages = await producer.send([
|
|
41
|
+
{
|
|
42
|
+
id: 'id1',
|
|
43
|
+
body: 'Hello world with two string attributes: attr1 and attr2',
|
|
44
|
+
messageAttributes: {
|
|
45
|
+
attr1: { DataType: 'String', StringValue: 'stringValue' },
|
|
46
|
+
attr2: { DataType: 'String', StringValue: 'stringValue2' },
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]);
|
|
50
|
+
res.send({
|
|
51
|
+
message: 'Sample messages sent successfully!',
|
|
52
|
+
data: messages
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
expressApp.post('/sample-with-delay', async (_, res) => {
|
|
56
|
+
// send a message to the queue with
|
|
57
|
+
// - delaySeconds (must be an number contained within 0 and 900)
|
|
58
|
+
const messages = await producer.send([
|
|
59
|
+
{
|
|
60
|
+
id: 'id1',
|
|
61
|
+
body: 'Hello world delayed by 5 seconds',
|
|
62
|
+
delaySeconds: 5
|
|
63
|
+
}
|
|
64
|
+
]);
|
|
65
|
+
res.send({
|
|
66
|
+
message: 'Sample messages sent successfully!',
|
|
67
|
+
data: messages
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
expressApp.post('/sample-with-fido', async (_, res) => {
|
|
71
|
+
// send a message to a FIFO queue
|
|
72
|
+
//
|
|
73
|
+
// note that AWS FIFO queues require two additional params:
|
|
74
|
+
// - groupId (string)
|
|
75
|
+
// - deduplicationId (string)
|
|
76
|
+
//
|
|
77
|
+
// deduplicationId can be excluded if content-based deduplication is enabled
|
|
78
|
+
//
|
|
79
|
+
// http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queue-recommendations.html
|
|
80
|
+
const messages = await producer.send({
|
|
81
|
+
id: 'testId',
|
|
82
|
+
body: 'Hello world from our FIFO queue!',
|
|
83
|
+
groupId: 'group1234',
|
|
84
|
+
deduplicationId: 'abcdef123456' // typically a hash of the message body
|
|
85
|
+
});
|
|
86
|
+
res.send({
|
|
87
|
+
message: 'Sample messages sent successfully!',
|
|
88
|
+
data: messages
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
expressApp.listen(3026, () => {
|
|
92
|
+
// eslint-disable-next-line no-console
|
|
93
|
+
console.log('STARTING SQS CONSUMER');
|
|
94
|
+
consumer.start();
|
|
95
|
+
// eslint-disable-next-line no-console
|
|
96
|
+
console.log('EXPRESS APP LISTENING ON: http://localhost:3026');
|
|
97
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const { Consumer } = require('../../../dist/index');
|
|
4
|
+
const { QUEUE_URL, sqs } = require('./sqs');
|
|
5
|
+
const consumer = Consumer.create({
|
|
6
|
+
queueUrl: QUEUE_URL,
|
|
7
|
+
sqs,
|
|
8
|
+
handleMessage: async (message) => {
|
|
9
|
+
// eslint-disable-next-line no-console
|
|
10
|
+
console.log('RECEIVED SQS MESSAGE:');
|
|
11
|
+
// eslint-disable-next-line no-console
|
|
12
|
+
console.log(message);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
consumer.on('error', (err) => {
|
|
16
|
+
// eslint-disable-next-line no-console
|
|
17
|
+
console.log('RECEIVED SQS ERROR:');
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.error(err.message);
|
|
20
|
+
});
|
|
21
|
+
consumer.on('processing_error', (err) => {
|
|
22
|
+
// eslint-disable-next-line no-console
|
|
23
|
+
console.log('RECEIVED SQS PROCESSING ERROR:');
|
|
24
|
+
// eslint-disable-next-line no-console
|
|
25
|
+
console.error(err.message);
|
|
26
|
+
});
|
|
27
|
+
consumer.on('timeout_error', (err) => {
|
|
28
|
+
// eslint-disable-next-line no-console
|
|
29
|
+
console.log('RECEIVED SQS TIMEOUT ERROR:');
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.error(err.message);
|
|
32
|
+
});
|
|
33
|
+
consumer.on('timeout_error', (err) => {
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log('RECEIVED SQS TIMEOUT ERROR:');
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.error(err.message);
|
|
38
|
+
});
|
|
39
|
+
consumer.on('message_received', (message) => {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.log('RECEIVED SQS MESSAGE:');
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.error(message);
|
|
44
|
+
});
|
|
45
|
+
consumer.on('message_processed', (message) => {
|
|
46
|
+
// eslint-disable-next-line no-console
|
|
47
|
+
console.log('RECEIVED SQS MESSAGE PROCESSED:');
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.error(message);
|
|
50
|
+
});
|
|
51
|
+
consumer.on('response_processed', () => {
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.log('RECEIVED SQS RESPONSE PROCESSED:');
|
|
54
|
+
});
|
|
55
|
+
consumer.on('stopped', () => {
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
console.log('RECEIVED SQS STOPPED:');
|
|
58
|
+
});
|
|
59
|
+
consumer.on('empty', () => {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log('RECEIVED SQS EMPTY:');
|
|
62
|
+
});
|
|
63
|
+
exports.consumer = consumer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const { Producer } = require('sqs-producer');
|
|
4
|
+
const { QUEUE_URL, sqsConfig, sqs } = require('./sqs');
|
|
5
|
+
const producer = Producer.create({
|
|
6
|
+
queueUrl: QUEUE_URL,
|
|
7
|
+
region: sqsConfig.region,
|
|
8
|
+
sqs
|
|
9
|
+
});
|
|
10
|
+
exports.producer = producer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const { Endpoint, SQS } = require('aws-sdk');
|
|
4
|
+
const sqsConfig = {
|
|
5
|
+
region: 'eu-west-1',
|
|
6
|
+
};
|
|
7
|
+
if (process.env.SQS_ENDPOINT) {
|
|
8
|
+
sqsConfig.endpoint = new Endpoint(process.env.SQS_ENDPOINT);
|
|
9
|
+
}
|
|
10
|
+
else if (process.env.NODE_ENV === 'development') {
|
|
11
|
+
sqsConfig.endpoint = new Endpoint('http://localhost:4566');
|
|
12
|
+
}
|
|
13
|
+
if (process.env.SQS_ACCESS_KEY_ID) {
|
|
14
|
+
sqsConfig.accessKeyId = process.env.SQS_ACCESS_KEY_ID;
|
|
15
|
+
}
|
|
16
|
+
else if (process.env.NODE_ENV === 'development') {
|
|
17
|
+
sqsConfig.accessKeyId = 'na';
|
|
18
|
+
}
|
|
19
|
+
if (process.env.SQS_SECRET_ACCESS_KEY) {
|
|
20
|
+
sqsConfig.secretAccessKey = process.env.SQS_SECRET_ACCESS_KEY;
|
|
21
|
+
}
|
|
22
|
+
else if (process.env.NODE_ENV === 'development') {
|
|
23
|
+
sqsConfig.secretAccessKey = 'na';
|
|
24
|
+
}
|
|
25
|
+
exports.sqs =
|
|
26
|
+
!sqsConfig.endpoint && process.env.NODE_ENV === 'development'
|
|
27
|
+
? null
|
|
28
|
+
: new SQS(sqsConfig);
|
|
29
|
+
exports.QUEUE_NAME = process.env.SQS_QUEUE_NAME || 'sqs-consumer-data';
|
|
30
|
+
exports.QUEUE_URL =
|
|
31
|
+
process.env.SQS_QUEUE_URL ||
|
|
32
|
+
'http://localhost:4566/000000000000/sqs-consumer-data';
|
|
33
|
+
exports.sqsConfig = sqsConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sqs-consumer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-alpha.1",
|
|
4
4
|
"description": "Build SQS-based Node applications without the boilerplate",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"typescript": "^4.9.4"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"aws-sdk": "^
|
|
55
|
+
"@aws-sdk/client-sqs": "^3.226.0",
|
|
56
56
|
"debug": "^4.3.4"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"aws-sdk": "^
|
|
59
|
+
"@aws-sdk/client-sqs": "^3.226.0"
|
|
60
60
|
},
|
|
61
61
|
"mocha": {
|
|
62
62
|
"spec": "test/**/**/*.test.ts",
|