sqs-consumer 6.0.1 → 6.1.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/.github/CONTRIBUTING.md +10 -0
- package/.github/ISSUE_TEMPLATE/bug-report.yml +115 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/workflows/cla.yml +25 -0
- package/.github/workflows/codeql.yml +76 -0
- package/README.md +24 -20
- package/dist/consumer.d.ts +1 -31
- package/dist/consumer.js +12 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +15 -0
- package/dist/types.d.ts +30 -0
- package/package.json +2 -2
- package/src/consumer.ts +19 -39
- package/src/index.ts +2 -1
- package/src/types.ts +33 -0
- package/.github/ISSUE_TEMPLATE/bug-report.md +0 -27
- package/.github/ISSUE_TEMPLATE/feature-request.md +0 -19
- package/.github/ISSUE_TEMPLATE/technical-question.md +0 -16
- package/test/consumer.test.ts +0 -979
package/.github/CONTRIBUTING.md
CHANGED
|
@@ -34,6 +34,16 @@ Follow the setup instructions in the [README](../README.md).
|
|
|
34
34
|
|
|
35
35
|
Ensure all your code is thoroughly tested and that this testing is detailed in the pull request.
|
|
36
36
|
|
|
37
|
+
## Contributors Licence Agreement
|
|
38
|
+
|
|
39
|
+
In order to accept contributions, we need all contributors grant Us a licence to the intellectual
|
|
40
|
+
property rights in their Contributions. This Agreement (“Agreement”) is intended to protect your
|
|
41
|
+
rights as a contributor, and to help ensure that the intellectual property contained
|
|
42
|
+
within is available to the whole community, to use and build on.
|
|
43
|
+
|
|
44
|
+
When you raise a pull request and you haven't previously signed a CLA, the bot will automatically
|
|
45
|
+
ask you to do this. You must complete this step in order for your PR to be merged.
|
|
46
|
+
|
|
37
47
|
## Pull Request Process
|
|
38
48
|
|
|
39
49
|
1. Make sure you have opened an issue and it was approved by a project maintainer before working on a PR
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
name: 'Bug report'
|
|
2
|
+
title: "[Bug]: "
|
|
3
|
+
labels: ["bug", "triage"]
|
|
4
|
+
description: Report a reproducible bug or regression
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thank you for reporting an issue!
|
|
10
|
+
|
|
11
|
+
This issue tracker is for reporting reproducible bugs or regression's found in this package, if you have a question or feature request, please report it within the [Discussions tab](https://github.com/bbc/sqs-consumer/discussions) instead.
|
|
12
|
+
|
|
13
|
+
Before submitting a new bug/issue, please check the links below to see if there is a solution or question posted there already:
|
|
14
|
+
|
|
15
|
+
- [Discussions](https://github.com/bbc/sqs-consumer/discussions)
|
|
16
|
+
- [Open Issues](https://github.com/bbc/sqs-consumer/issues?q=is%3Aopen+is%3Aissue)
|
|
17
|
+
- [Closed Issues](https://github.com/bbc/sqs-consumer/issues?q=is%3Aissue+is%3Aclosed)
|
|
18
|
+
|
|
19
|
+
The more information you fill in, the better the community can help you.
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: description
|
|
22
|
+
attributes:
|
|
23
|
+
label: Describe the bug
|
|
24
|
+
description: Provide a clear and concise description of what the bug is.
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: input
|
|
28
|
+
id: link
|
|
29
|
+
attributes:
|
|
30
|
+
label: Your minimal, reproducible example
|
|
31
|
+
description: |
|
|
32
|
+
Please add a link to a minimal reproduction.
|
|
33
|
+
Note:
|
|
34
|
+
- Please keep your example as simple and reproduceable as possible, try leaving out dependencies that are not required for reproduction.
|
|
35
|
+
- To create a shareable code example for web, you can use CodeSandbox (https://codesandbox.io/s/new) or Stackblitz (https://stackblitz.com/).
|
|
36
|
+
- Please make sure the example is complete and runnable - e.g. avoid localhost URLs.
|
|
37
|
+
placeholder: |
|
|
38
|
+
e.g. Code Sandbox, Stackblitz, Expo Snack or TypeScript playground
|
|
39
|
+
validations:
|
|
40
|
+
required: true
|
|
41
|
+
- type: textarea
|
|
42
|
+
id: steps
|
|
43
|
+
attributes:
|
|
44
|
+
label: Steps to reproduce
|
|
45
|
+
description: Describe the steps we have to take to reproduce the behavior.
|
|
46
|
+
placeholder: |
|
|
47
|
+
1. Go to '...'
|
|
48
|
+
2. Click on '....'
|
|
49
|
+
3. Scroll down to '....'
|
|
50
|
+
4. See error
|
|
51
|
+
validations:
|
|
52
|
+
required: true
|
|
53
|
+
- type: textarea
|
|
54
|
+
id: expected
|
|
55
|
+
attributes:
|
|
56
|
+
label: Expected behavior
|
|
57
|
+
description: Provide a clear and concise description of what you expected to happen.
|
|
58
|
+
placeholder: |
|
|
59
|
+
As a user, I expected ___ behavior but i am seeing ___
|
|
60
|
+
validations:
|
|
61
|
+
required: true
|
|
62
|
+
- type: dropdown
|
|
63
|
+
attributes:
|
|
64
|
+
label: How often does this bug happen?
|
|
65
|
+
description: |
|
|
66
|
+
Following the repro steps above, how easily are you able to reproduce this bug?
|
|
67
|
+
options:
|
|
68
|
+
- Every time
|
|
69
|
+
- Often
|
|
70
|
+
- Sometimes
|
|
71
|
+
- Only once
|
|
72
|
+
- type: textarea
|
|
73
|
+
id: screenshots_or_videos
|
|
74
|
+
attributes:
|
|
75
|
+
label: Screenshots or Videos
|
|
76
|
+
description: |
|
|
77
|
+
If applicable, add screenshots or a video to help explain your problem.
|
|
78
|
+
For more information on the supported file image/file types and the file size limits, please refer
|
|
79
|
+
to the following link: https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/attaching-files
|
|
80
|
+
placeholder: |
|
|
81
|
+
You can drag your video or image files inside of this editor ↓
|
|
82
|
+
- type: textarea
|
|
83
|
+
id: platform
|
|
84
|
+
attributes:
|
|
85
|
+
label: Platform
|
|
86
|
+
description: |
|
|
87
|
+
Please let us know which Operating System and Node version you were using when the issue occurred.
|
|
88
|
+
placeholder: |
|
|
89
|
+
- OS: [e.g. macOS, Windows, Linux, iOS, Android]
|
|
90
|
+
- Node Version: [e.g. 16.6.0]
|
|
91
|
+
validations:
|
|
92
|
+
required: true
|
|
93
|
+
- type: input
|
|
94
|
+
id: package-version
|
|
95
|
+
attributes:
|
|
96
|
+
label: Package version
|
|
97
|
+
description: |
|
|
98
|
+
Please let us know the exact version of the package you were using when the issue occurred. Please don't just put in "latest", as this is subject to change.
|
|
99
|
+
placeholder: |
|
|
100
|
+
e.g. v6.0.0
|
|
101
|
+
validations:
|
|
102
|
+
required: true
|
|
103
|
+
- type: input
|
|
104
|
+
id: ts-version
|
|
105
|
+
attributes:
|
|
106
|
+
label: AWS SDK version
|
|
107
|
+
description: |
|
|
108
|
+
Please include what version of the AWS SDK you are using
|
|
109
|
+
placeholder: |
|
|
110
|
+
e.g. v3.226.0
|
|
111
|
+
- type: textarea
|
|
112
|
+
id: additional
|
|
113
|
+
attributes:
|
|
114
|
+
label: Additional context
|
|
115
|
+
description: Add any other context about the problem here.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: "CLA Check"
|
|
2
|
+
on:
|
|
3
|
+
issue_comment:
|
|
4
|
+
types: [created]
|
|
5
|
+
pull_request_target:
|
|
6
|
+
types: [opened,closed,synchronize]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
CLAAssistant:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: "CLA Check"
|
|
13
|
+
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
|
14
|
+
uses: contributor-assistant/github-action@v2.2.0
|
|
15
|
+
env:
|
|
16
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
17
|
+
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
|
18
|
+
with:
|
|
19
|
+
path-to-signatures: 'sqs-consumer/v1/cla.json'
|
|
20
|
+
remote-organization-name: 'bbc'
|
|
21
|
+
remote-repository-name: 'cla-signatures'
|
|
22
|
+
path-to-document: 'https://bbc.github.io/cla-signatures/cla/v1/cla.html'
|
|
23
|
+
branch: 'main'
|
|
24
|
+
allowlist: bot*
|
|
25
|
+
custom-allsigned-prcomment: '**CLA CHECK** All Contributors have signed the CLA'
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
+
# to commit it to your repository.
|
|
3
|
+
#
|
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
+
# or to provide custom queries or build logic.
|
|
6
|
+
#
|
|
7
|
+
# ******** NOTE ********
|
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
|
10
|
+
# supported CodeQL languages.
|
|
11
|
+
#
|
|
12
|
+
name: "CodeQL"
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [ "main" ]
|
|
17
|
+
pull_request:
|
|
18
|
+
# The branches below must be a subset of the branches above
|
|
19
|
+
branches: [ "main" ]
|
|
20
|
+
schedule:
|
|
21
|
+
- cron: '43 21 * * 2'
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
analyze:
|
|
25
|
+
name: Analyze
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
permissions:
|
|
28
|
+
actions: read
|
|
29
|
+
contents: read
|
|
30
|
+
security-events: write
|
|
31
|
+
|
|
32
|
+
strategy:
|
|
33
|
+
fail-fast: false
|
|
34
|
+
matrix:
|
|
35
|
+
language: [ 'javascript' ]
|
|
36
|
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
37
|
+
# Use only 'java' to analyze code written in Java, Kotlin or both
|
|
38
|
+
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
|
39
|
+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
|
40
|
+
|
|
41
|
+
steps:
|
|
42
|
+
- name: Checkout repository
|
|
43
|
+
uses: actions/checkout@v3
|
|
44
|
+
|
|
45
|
+
# Initializes the CodeQL tools for scanning.
|
|
46
|
+
- name: Initialize CodeQL
|
|
47
|
+
uses: github/codeql-action/init@v2
|
|
48
|
+
with:
|
|
49
|
+
languages: ${{ matrix.language }}
|
|
50
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
51
|
+
# By default, queries listed here will override any specified in a config file.
|
|
52
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
53
|
+
|
|
54
|
+
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
55
|
+
# queries: security-extended,security-and-quality
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
|
59
|
+
# If this step fails, then you should remove it and run the build manually (see below)
|
|
60
|
+
- name: Autobuild
|
|
61
|
+
uses: github/codeql-action/autobuild@v2
|
|
62
|
+
|
|
63
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
|
64
|
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
65
|
+
|
|
66
|
+
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
|
67
|
+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
|
68
|
+
|
|
69
|
+
# - run: |
|
|
70
|
+
# echo "Run, Build Application using script"
|
|
71
|
+
# ./location_of_script_within_repo/buildscript.sh
|
|
72
|
+
|
|
73
|
+
- name: Perform CodeQL Analysis
|
|
74
|
+
uses: github/codeql-action/analyze@v2
|
|
75
|
+
with:
|
|
76
|
+
category: "/language:${{matrix.language}}"
|
package/README.md
CHANGED
|
@@ -48,6 +48,8 @@ app.start();
|
|
|
48
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.
|
|
49
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).
|
|
50
50
|
|
|
51
|
+
You can also find some examples of sqs-consumer implemented in various ways within the [examples directory](./examples/).
|
|
52
|
+
|
|
51
53
|
### Credentials
|
|
52
54
|
|
|
53
55
|
By default the consumer will look for AWS credentials in the places [specified by the AWS SDK](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html#Setting_AWS_Credentials). The simplest option is to export your credentials as environment variables:
|
|
@@ -92,6 +94,10 @@ app.on('timeout_error', (err) => {
|
|
|
92
94
|
app.start();
|
|
93
95
|
```
|
|
94
96
|
|
|
97
|
+
### AWS IAM Permissions
|
|
98
|
+
|
|
99
|
+
Consumer will receive and delete messages from the SQS queue. Ensure `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:DeleteMessageBatch`, `sqs:ChangeMessageVisibility` and `sqs:ChangeMessageVisibilityBatch` access is granted on the queue being consumed.
|
|
100
|
+
|
|
95
101
|
## API
|
|
96
102
|
|
|
97
103
|
### `Consumer.create(options)`
|
|
@@ -100,22 +106,24 @@ Creates a new SQS consumer.
|
|
|
100
106
|
|
|
101
107
|
#### Options
|
|
102
108
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
| Option | Type | Description |
|
|
110
|
+
| ---------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
111
|
+
| `queueUrl` | String | The SQS queue URL |
|
|
112
|
+
| `region` | String | The AWS region (default `eu-west-1`) |
|
|
113
|
+
| `handleMessage` | Function | An `async` function (or function that returns a `Promise`) to be called whenever a message is received. Receives an SQS message object as its first argument. |
|
|
114
|
+
| `handleMessageBatch` | Function | An `async` function (or function that returns a `Promise`) to be called whenever a batch of messages is received. Similar to `handleMessage` but will receive the list of messages, not each message individually. **If both are set, `handleMessageBatch` overrides `handleMessage`**. In the case that you need to ack only some of the messages, return an array with the successful messages only. |
|
|
115
|
+
| `handleMessageTimeout` | Number | Time in ms to wait for `handleMessage` to process a message before timing out. Emits `timeout_error` on timeout. By default, if `handleMessage` times out, the unprocessed message returns to the end of the queue. |
|
|
116
|
+
| `attributeNames` | Array | List of queue attributes to retrieve (i.e. `['All', 'ApproximateFirstReceiveTimestamp', 'ApproximateReceiveCount']`). |
|
|
117
|
+
| `messageAttributeNames` | Array | List of message attributes to retrieve (i.e. `['name', 'address']`). |
|
|
118
|
+
| `batchSize` | Number | The number of messages to request from SQS when polling (default `1`). This cannot be higher than the [AWS limit of 10](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-messages.html). |
|
|
119
|
+
| `visibilityTimeout` | Number | The duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. |
|
|
120
|
+
| `heartbeatInterval` | Number | The interval (in seconds) between requests to extend the message visibility timeout. On each heartbeat the visibility is extended by adding `visibilityTimeout` to the number of seconds since the start of the handler function. This value must less than `visibilityTimeout`. |
|
|
121
|
+
| `terminateVisibilityTimeout` | Boolean | If true, sets the message visibility timeout to 0 after a `processing_error` (defaults to `false`). |
|
|
122
|
+
| `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`). |
|
|
123
|
+
| `authenticationErrorTimeout` | Number | The duration (in milliseconds) to wait before retrying after an authentication error (defaults to `10000`). |
|
|
124
|
+
| `pollingWaitTimeMs` | Number | The duration (in milliseconds) to wait before repolling the queue (defaults to `0`). |
|
|
125
|
+
| `sqs` | SQSClient | 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 |
|
|
126
|
+
| `shouldDeleteMessages` | Boolean | Default to `true`, if you don't want the package to delete messages from sqs set this to `false` |
|
|
119
127
|
|
|
120
128
|
### `consumer.start()`
|
|
121
129
|
|
|
@@ -144,10 +152,6 @@ Each consumer is an [`EventEmitter`](http://nodejs.org/api/events.html) and emit
|
|
|
144
152
|
| `stopped` | None | Fired when the consumer finally stops its work. |
|
|
145
153
|
| `empty` | None | Fired when the queue is empty (All messages have been consumed). |
|
|
146
154
|
|
|
147
|
-
### AWS IAM Permissions
|
|
148
|
-
|
|
149
|
-
Consumer will receive and delete messages from the SQS queue. Ensure `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:DeleteMessageBatch`, `sqs:ChangeMessageVisibility` and `sqs:ChangeMessageVisibilityBatch` access is granted on the queue being consumed.
|
|
150
|
-
|
|
151
155
|
### Contributing
|
|
152
156
|
|
|
153
157
|
See contributing [guidelines](https://github.com/bbc/sqs-consumer/blob/main/.github/CONTRIBUTING.md).
|
package/dist/consumer.d.ts
CHANGED
|
@@ -1,35 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { SQSClient, Message } from '@aws-sdk/client-sqs';
|
|
3
2
|
import { EventEmitter } from 'events';
|
|
4
|
-
|
|
5
|
-
queueUrl?: string;
|
|
6
|
-
attributeNames?: string[];
|
|
7
|
-
messageAttributeNames?: string[];
|
|
8
|
-
stopped?: boolean;
|
|
9
|
-
batchSize?: number;
|
|
10
|
-
visibilityTimeout?: number;
|
|
11
|
-
waitTimeSeconds?: number;
|
|
12
|
-
authenticationErrorTimeout?: number;
|
|
13
|
-
pollingWaitTimeMs?: number;
|
|
14
|
-
terminateVisibilityTimeout?: boolean;
|
|
15
|
-
heartbeatInterval?: number;
|
|
16
|
-
sqs?: SQSClient;
|
|
17
|
-
region?: string;
|
|
18
|
-
handleMessageTimeout?: number;
|
|
19
|
-
shouldDeleteMessages?: boolean;
|
|
20
|
-
handleMessage?(message: Message): Promise<void>;
|
|
21
|
-
handleMessageBatch?(messages: Message[]): Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
interface Events {
|
|
24
|
-
response_processed: [];
|
|
25
|
-
empty: [];
|
|
26
|
-
message_received: [Message];
|
|
27
|
-
message_processed: [Message];
|
|
28
|
-
error: [Error, void | Message | Message[]];
|
|
29
|
-
timeout_error: [Error, Message];
|
|
30
|
-
processing_error: [Error, Message];
|
|
31
|
-
stopped: [];
|
|
32
|
-
}
|
|
3
|
+
import { ConsumerOptions, Events } from './types';
|
|
33
4
|
export declare class Consumer extends EventEmitter {
|
|
34
5
|
private queueUrl;
|
|
35
6
|
private handleMessage;
|
|
@@ -69,4 +40,3 @@ export declare class Consumer extends EventEmitter {
|
|
|
69
40
|
private changeVisibilityTimeoutBatch;
|
|
70
41
|
private startHeartbeat;
|
|
71
42
|
}
|
|
72
|
-
export {};
|
package/dist/consumer.js
CHANGED
|
@@ -40,7 +40,8 @@ function isConnectionError(err) {
|
|
|
40
40
|
if (err instanceof errors_1.SQSError) {
|
|
41
41
|
return (err.statusCode === 403 ||
|
|
42
42
|
err.code === 'CredentialsError' ||
|
|
43
|
-
err.code === 'UnknownEndpoint'
|
|
43
|
+
err.code === 'UnknownEndpoint' ||
|
|
44
|
+
err.code === 'AWS.SimpleQueueService.NonExistentQueue');
|
|
44
45
|
}
|
|
45
46
|
return false;
|
|
46
47
|
}
|
|
@@ -272,9 +273,11 @@ class Consumer extends events_1.EventEmitter {
|
|
|
272
273
|
return this.changeVisibilityTimeoutBatch(messages, this.visibilityTimeout);
|
|
273
274
|
});
|
|
274
275
|
}
|
|
275
|
-
await this.executeBatchHandler(messages);
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
const ackedMessages = await this.executeBatchHandler(messages);
|
|
277
|
+
if (ackedMessages.length > 0) {
|
|
278
|
+
await this.deleteMessageBatch(ackedMessages);
|
|
279
|
+
}
|
|
280
|
+
ackedMessages.forEach((message) => {
|
|
278
281
|
this.emit('message_processed', message);
|
|
279
282
|
});
|
|
280
283
|
}
|
|
@@ -310,7 +313,11 @@ class Consumer extends events_1.EventEmitter {
|
|
|
310
313
|
}
|
|
311
314
|
async executeBatchHandler(messages) {
|
|
312
315
|
try {
|
|
313
|
-
await this.handleMessageBatch(messages);
|
|
316
|
+
const result = await this.handleMessageBatch(messages);
|
|
317
|
+
if (result instanceof Object) {
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
return messages;
|
|
314
321
|
}
|
|
315
322
|
catch (err) {
|
|
316
323
|
err.message = `Unexpected message handler failure: ${err.message}`;
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { Consumer
|
|
1
|
+
export { Consumer } from './consumer';
|
|
2
|
+
export * from './types';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.Consumer = void 0;
|
|
4
18
|
var consumer_1 = require("./consumer");
|
|
5
19
|
Object.defineProperty(exports, "Consumer", { enumerable: true, get: function () { return consumer_1.Consumer; } });
|
|
20
|
+
__exportStar(require("./types"), exports);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
import { SQSClient, Message } from '@aws-sdk/client-sqs';
|
|
2
|
+
export interface ConsumerOptions {
|
|
3
|
+
queueUrl: string;
|
|
4
|
+
attributeNames?: string[];
|
|
5
|
+
messageAttributeNames?: string[];
|
|
6
|
+
stopped?: boolean;
|
|
7
|
+
batchSize?: number;
|
|
8
|
+
visibilityTimeout?: number;
|
|
9
|
+
waitTimeSeconds?: number;
|
|
10
|
+
authenticationErrorTimeout?: number;
|
|
11
|
+
pollingWaitTimeMs?: number;
|
|
12
|
+
terminateVisibilityTimeout?: boolean;
|
|
13
|
+
heartbeatInterval?: number;
|
|
14
|
+
sqs?: SQSClient;
|
|
15
|
+
region?: string;
|
|
16
|
+
handleMessageTimeout?: number;
|
|
17
|
+
shouldDeleteMessages?: boolean;
|
|
18
|
+
handleMessage?(message: Message): Promise<void>;
|
|
19
|
+
handleMessageBatch?(messages: Message[]): Promise<Message[] | void>;
|
|
20
|
+
}
|
|
21
|
+
export interface Events {
|
|
22
|
+
response_processed: [];
|
|
23
|
+
empty: [];
|
|
24
|
+
message_received: [Message];
|
|
25
|
+
message_processed: [Message];
|
|
26
|
+
error: [Error, void | Message | Message[]];
|
|
27
|
+
timeout_error: [Error, Message];
|
|
28
|
+
processing_error: [Error, Message];
|
|
29
|
+
stopped: [];
|
|
30
|
+
}
|
|
1
31
|
export type AWSError = {
|
|
2
32
|
/**
|
|
3
33
|
* Name, eg. ConditionalCheckFailedException
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sqs-consumer",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Build SQS-based Node applications without the boilerplate",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"build": "npm run clean && tsc",
|
|
9
9
|
"watch": "tsc --watch",
|
|
10
10
|
"clean": "rm -fr dist/*",
|
|
11
|
-
"
|
|
11
|
+
"prepublishOnly": "npm run build",
|
|
12
12
|
"pretest": "npm run build",
|
|
13
13
|
"test": "mocha --recursive --full-trace --exit",
|
|
14
14
|
"coverage": "nyc mocha && nyc report --reporter=html && nyc report --reporter=json-summary",
|
package/src/consumer.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import Debug from 'debug';
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
20
20
|
|
|
21
|
-
import { AWSError } from './types';
|
|
21
|
+
import { AWSError, ConsumerOptions, Events } from './types';
|
|
22
22
|
import { autoBind } from './bind';
|
|
23
23
|
import { SQSError, TimeoutError } from './errors';
|
|
24
24
|
|
|
@@ -72,7 +72,8 @@ function isConnectionError(err: Error): boolean {
|
|
|
72
72
|
return (
|
|
73
73
|
err.statusCode === 403 ||
|
|
74
74
|
err.code === 'CredentialsError' ||
|
|
75
|
-
err.code === 'UnknownEndpoint'
|
|
75
|
+
err.code === 'UnknownEndpoint' ||
|
|
76
|
+
err.code === 'AWS.SimpleQueueService.NonExistentQueue'
|
|
76
77
|
);
|
|
77
78
|
}
|
|
78
79
|
return false;
|
|
@@ -94,41 +95,10 @@ function hasMessages(response: ReceiveMessageCommandOutput): boolean {
|
|
|
94
95
|
return response.Messages && response.Messages.length > 0;
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
export interface ConsumerOptions {
|
|
98
|
-
queueUrl?: string;
|
|
99
|
-
attributeNames?: string[];
|
|
100
|
-
messageAttributeNames?: string[];
|
|
101
|
-
stopped?: boolean;
|
|
102
|
-
batchSize?: number;
|
|
103
|
-
visibilityTimeout?: number;
|
|
104
|
-
waitTimeSeconds?: number;
|
|
105
|
-
authenticationErrorTimeout?: number;
|
|
106
|
-
pollingWaitTimeMs?: number;
|
|
107
|
-
terminateVisibilityTimeout?: boolean;
|
|
108
|
-
heartbeatInterval?: number;
|
|
109
|
-
sqs?: SQSClient;
|
|
110
|
-
region?: string;
|
|
111
|
-
handleMessageTimeout?: number;
|
|
112
|
-
shouldDeleteMessages?: boolean;
|
|
113
|
-
handleMessage?(message: Message): Promise<void>;
|
|
114
|
-
handleMessageBatch?(messages: Message[]): Promise<void>;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
interface Events {
|
|
118
|
-
response_processed: [];
|
|
119
|
-
empty: [];
|
|
120
|
-
message_received: [Message];
|
|
121
|
-
message_processed: [Message];
|
|
122
|
-
error: [Error, void | Message | Message[]];
|
|
123
|
-
timeout_error: [Error, Message];
|
|
124
|
-
processing_error: [Error, Message];
|
|
125
|
-
stopped: [];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
98
|
export class Consumer extends EventEmitter {
|
|
129
99
|
private queueUrl: string;
|
|
130
100
|
private handleMessage: (message: Message) => Promise<void>;
|
|
131
|
-
private handleMessageBatch: (message: Message[]) => Promise<void>;
|
|
101
|
+
private handleMessageBatch: (message: Message[]) => Promise<Message[] | void>;
|
|
132
102
|
private handleMessageTimeout: number;
|
|
133
103
|
private attributeNames: string[];
|
|
134
104
|
private messageAttributeNames: string[];
|
|
@@ -390,9 +360,13 @@ export class Consumer extends EventEmitter {
|
|
|
390
360
|
);
|
|
391
361
|
});
|
|
392
362
|
}
|
|
393
|
-
await this.executeBatchHandler(messages);
|
|
394
|
-
|
|
395
|
-
|
|
363
|
+
const ackedMessages = await this.executeBatchHandler(messages);
|
|
364
|
+
|
|
365
|
+
if (ackedMessages.length > 0) {
|
|
366
|
+
await this.deleteMessageBatch(ackedMessages);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
ackedMessages.forEach((message) => {
|
|
396
370
|
this.emit('message_processed', message);
|
|
397
371
|
});
|
|
398
372
|
} catch (err) {
|
|
@@ -433,9 +407,15 @@ export class Consumer extends EventEmitter {
|
|
|
433
407
|
}
|
|
434
408
|
}
|
|
435
409
|
|
|
436
|
-
private async executeBatchHandler(messages: Message[]): Promise<
|
|
410
|
+
private async executeBatchHandler(messages: Message[]): Promise<Message[]> {
|
|
437
411
|
try {
|
|
438
|
-
await this.handleMessageBatch(messages);
|
|
412
|
+
const result = await this.handleMessageBatch(messages);
|
|
413
|
+
|
|
414
|
+
if (result instanceof Object) {
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return messages;
|
|
439
419
|
} catch (err) {
|
|
440
420
|
err.message = `Unexpected message handler failure: ${err.message}`;
|
|
441
421
|
throw err;
|
package/src/index.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { Consumer
|
|
1
|
+
export { Consumer } from './consumer';
|
|
2
|
+
export * from './types';
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
import { SQSClient, Message } from '@aws-sdk/client-sqs';
|
|
2
|
+
|
|
3
|
+
export interface ConsumerOptions {
|
|
4
|
+
queueUrl: string;
|
|
5
|
+
attributeNames?: string[];
|
|
6
|
+
messageAttributeNames?: string[];
|
|
7
|
+
stopped?: boolean;
|
|
8
|
+
batchSize?: number;
|
|
9
|
+
visibilityTimeout?: number;
|
|
10
|
+
waitTimeSeconds?: number;
|
|
11
|
+
authenticationErrorTimeout?: number;
|
|
12
|
+
pollingWaitTimeMs?: number;
|
|
13
|
+
terminateVisibilityTimeout?: boolean;
|
|
14
|
+
heartbeatInterval?: number;
|
|
15
|
+
sqs?: SQSClient;
|
|
16
|
+
region?: string;
|
|
17
|
+
handleMessageTimeout?: number;
|
|
18
|
+
shouldDeleteMessages?: boolean;
|
|
19
|
+
handleMessage?(message: Message): Promise<void>;
|
|
20
|
+
handleMessageBatch?(messages: Message[]): Promise<Message[] | void>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface Events {
|
|
24
|
+
response_processed: [];
|
|
25
|
+
empty: [];
|
|
26
|
+
message_received: [Message];
|
|
27
|
+
message_processed: [Message];
|
|
28
|
+
error: [Error, void | Message | Message[]];
|
|
29
|
+
timeout_error: [Error, Message];
|
|
30
|
+
processing_error: [Error, Message];
|
|
31
|
+
stopped: [];
|
|
32
|
+
}
|
|
33
|
+
|
|
1
34
|
export type AWSError = {
|
|
2
35
|
/**
|
|
3
36
|
* Name, eg. ConditionalCheckFailedException
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug report
|
|
3
|
-
about: Create a report to help us improve
|
|
4
|
-
title: ''
|
|
5
|
-
labels: bug
|
|
6
|
-
assignees: ''
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
**Describe the bug**
|
|
10
|
-
A clear and concise description of what the bug is.
|
|
11
|
-
|
|
12
|
-
**To Reproduce**
|
|
13
|
-
Steps to reproduce the behaviour:
|
|
14
|
-
|
|
15
|
-
1. Go to '...'
|
|
16
|
-
2. Select '....'
|
|
17
|
-
3. Scroll down to '....'
|
|
18
|
-
4. See error
|
|
19
|
-
|
|
20
|
-
**Expected behaviour**
|
|
21
|
-
A clear and concise description of what you expected to happen.
|
|
22
|
-
|
|
23
|
-
**screenshots**
|
|
24
|
-
If applicable, add screenshots to help explain your problem.
|
|
25
|
-
|
|
26
|
-
**Additional context**
|
|
27
|
-
Add any other context about the problem here, such as specific device information.
|