sqs-producer 2.2.0 → 3.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/.eslintignore ADDED
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ coverage
3
+ bake-scripts
4
+ dist
@@ -4,7 +4,6 @@ about: Create a report to help us improve
4
4
  title: ''
5
5
  labels: bug
6
6
  assignees: ''
7
-
8
7
  ---
9
8
 
10
9
  **Describe the bug**
@@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
12
11
 
13
12
  **To Reproduce**
14
13
  Steps to reproduce the behaviour:
14
+
15
15
  1. Go to '...'
16
16
  2. Select '....'
17
17
  3. Scroll down to '....'
@@ -24,4 +24,4 @@ A clear and concise description of what you expected to happen.
24
24
  If applicable, add screenshots to help explain your problem.
25
25
 
26
26
  **Additional context**
27
- Add any other context about the problem here, such as specific device information.
27
+ Add any other context about the problem here, such as specific device information.
@@ -4,7 +4,6 @@ about: Suggest an idea for this project
4
4
  title: ''
5
5
  labels: feature-request
6
6
  assignees: ''
7
-
8
7
  ---
9
8
 
10
9
  **The problem**
@@ -4,7 +4,6 @@ about: Want to ask a technical question about the project
4
4
  title: ''
5
5
  labels: 'question'
6
6
  assignees: ''
7
-
8
7
  ---
9
8
 
10
9
  **Question**
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ coverage
3
+ bake-scripts
4
+ dist
package/.prettierrc.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ singleQuote: true,
3
+ arrowParens: 'always',
4
+ trailingComma: 'none'
5
+ };
package/README.md CHANGED
@@ -1,9 +1,8 @@
1
- sqs-producer
2
- ====================
1
+ # sqs-producer
3
2
 
4
3
  [![NPM downloads](https://img.shields.io/npm/dm/sqs-producer.svg?style=flat)](https://npmjs.org/package/sqs-producer)
5
4
  [![Build Status](https://github.com/bbc/sqs-producer/actions/workflows/test.yml/badge.svg)](https://github.com/bbc/sqs-producer/actions/workflows/test.yml)
6
- [![Code Climate](https://codeclimate.com/github/BBC/sqs-producer/badges/gpa.svg)](https://codeclimate.com/github/BBC/sqs-producer)
5
+ [![Code Climate](https://codeclimate.com/github/BBC/sqs-producer/badges/gpa.svg)](https://codeclimate.com/github/BBC/sqs-producer)
7
6
  [![Test Coverage](https://codeclimate.com/github/BBC/sqs-producer/badges/coverage.svg)](https://codeclimate.com/github/BBC/sqs-producer)
8
7
 
9
8
  Enqueues messages onto a given SQS queue
@@ -13,11 +12,19 @@ Enqueues messages onto a given SQS queue
13
12
  ```
14
13
  npm install sqs-producer
15
14
  ```
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 v2.2.0:
18
+ >
19
+ > ```bash
20
+ > npm install sqs-producer@5.8.0 --save-dev
21
+ > ```
22
+
16
23
  ## Usage
17
24
 
18
25
  ```js
19
- const { Producer } = require('sqs-producer');
20
- import AWS from 'aws-sdk'
26
+ import { Producer } from 'sqs-producer';
27
+ import { SQSClient } from '@aws-sdk/client-sqs';
21
28
 
22
29
  // create simple producer
23
30
  const producer = Producer.create({
@@ -25,19 +32,6 @@ const producer = Producer.create({
25
32
  region: 'eu-west-1'
26
33
  });
27
34
 
28
- // create custom producer (supporting all opts as per the API docs: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SQS.html#constructor-property)
29
- AWS.config.update({
30
- accessKeyId: 'yourAccessKey',
31
- secretAccessKey: 'yourSecret',
32
- region: 'eu-west-1',
33
- });
34
-
35
- const producer = Producer.create({
36
- queueUrl: 'https://sqs.eu-west-1.amazonaws.com/account-id/queue-name',
37
- region: 'eu-west-1',
38
- sqs: new AWS.SQS(),
39
- });
40
-
41
35
  // send messages to the queue
42
36
  await producer.send(['msg1', 'msg2']);
43
37
 
@@ -46,10 +40,12 @@ const size = await producer.queueSize();
46
40
  console.log(`There are ${size} messages on the queue.`);
47
41
 
48
42
  // send a message to the queue with a specific ID (by default the body is used as the ID)
49
- await producer.send([{
50
- id: 'id1',
51
- body: 'Hello world'
52
- }]);
43
+ await producer.send([
44
+ {
45
+ id: 'id1',
46
+ body: 'Hello world'
47
+ }
48
+ ]);
53
49
 
54
50
  // send a message to the queue with
55
51
  // - delaySeconds (must be an number contained within 0 and 900)
@@ -80,13 +76,45 @@ await producer.send([
80
76
  //
81
77
  // http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queue-recommendations.html
82
78
  await producer.send({
83
- id: "testId",
79
+ id: 'testId',
84
80
  body: 'Hello world from our FIFO queue!',
85
81
  groupId: 'group1234',
86
82
  deduplicationId: 'abcdef123456' // typically a hash of the message body
87
83
  });
88
84
  ```
89
85
 
86
+ ### Credentials
87
+
88
+ 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:
89
+
90
+ ```bash
91
+ export AWS_SECRET_ACCESS_KEY=...
92
+ export AWS_ACCESS_KEY_ID=...
93
+ ```
94
+
95
+ 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.
96
+
97
+ ```js
98
+ import { Producer } from 'sqs-producer';
99
+ import { SQSClient } from '@aws-sdk/client-sqs';
100
+
101
+ // create simple producer
102
+ const producer = Producer.create({
103
+ queueUrl: 'https://sqs.eu-west-1.amazonaws.com/account-id/queue-name',
104
+ region: 'eu-west-1',
105
+ sqs: new SQSClient({
106
+ region: 'my-region',
107
+ credentials: {
108
+ accessKeyId: 'yourAccessKey',
109
+ secretAccessKey: 'yourSecret'
110
+ }
111
+ })
112
+ });
113
+
114
+ // send messages to the queue
115
+ await producer.send(['msg1', 'msg2']);
116
+ ```
117
+
90
118
  ## Development
91
119
 
92
120
  ### Test
@@ -96,6 +124,7 @@ npm test
96
124
  ```
97
125
 
98
126
  ### Coverage
127
+
99
128
  For coverage report, run the command:
100
129
 
101
130
  ```
@@ -103,6 +132,7 @@ npm run coverage
103
132
  ```
104
133
 
105
134
  ### Lint
135
+
106
136
  To check for problems using ESLint
107
137
 
108
138
  ```
@@ -110,4 +140,5 @@ npm run lint
110
140
  ```
111
141
 
112
142
  ## Contributing
143
+
113
144
  See [contributing guildlines](./.github/CONTRIBUTING.md)
@@ -1,21 +1,20 @@
1
- import { SQS } from 'aws-sdk';
2
- import { SendMessageBatchResultEntryList } from 'aws-sdk/clients/sqs';
1
+ import { SQSClient, SendMessageBatchResultEntry } from '@aws-sdk/client-sqs';
3
2
  import { Message } from './types';
4
3
  interface ProducerOptions {
5
4
  queueUrl?: string;
6
5
  batchSize?: number;
7
- sqs?: SQS;
6
+ sqs?: SQSClient;
8
7
  region?: string;
9
8
  }
10
9
  export declare class Producer {
11
10
  static create: (options: ProducerOptions) => Producer;
12
11
  queueUrl: string;
13
12
  batchSize: number;
14
- sqs: SQS;
13
+ sqs: SQSClient;
15
14
  region?: string;
16
15
  constructor(options: ProducerOptions);
17
16
  queueSize(): Promise<number>;
18
- send(messages: string | Message | (string | Message)[]): Promise<SendMessageBatchResultEntryList>;
17
+ send(messages: string | Message | (string | Message)[]): Promise<SendMessageBatchResultEntry[]>;
19
18
  private validate;
20
19
  private sendBatch;
21
20
  }
package/dist/producer.js CHANGED
@@ -1,24 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Producer = void 0;
4
- const aws_sdk_1 = require("aws-sdk");
4
+ const client_sqs_1 = require("@aws-sdk/client-sqs");
5
5
  const types_1 = require("./types");
6
- const requiredOptions = [
7
- 'queueUrl'
8
- ];
6
+ const requiredOptions = ['queueUrl'];
9
7
  class Producer {
10
8
  constructor(options) {
11
9
  this.validate(options);
12
10
  this.queueUrl = options.queueUrl;
13
11
  this.batchSize = options.batchSize || 10;
14
- this.sqs = options.sqs || new aws_sdk_1.SQS(Object.assign(Object.assign({}, options), { region: options.region || 'eu-west-1' }));
12
+ this.sqs =
13
+ options.sqs ||
14
+ new client_sqs_1.SQSClient(Object.assign(Object.assign({}, options), { region: options.region || 'eu-west-1' }));
15
15
  }
16
16
  async queueSize() {
17
- const result = await this.sqs.getQueueAttributes({
17
+ const command = new client_sqs_1.GetQueueAttributesCommand({
18
18
  QueueUrl: this.queueUrl,
19
19
  AttributeNames: ['ApproximateNumberOfMessages']
20
- }).promise();
21
- return Number(result && result.Attributes && result.Attributes.ApproximateNumberOfMessages);
20
+ });
21
+ const result = await this.sqs.send(command);
22
+ return Number(result &&
23
+ result.Attributes &&
24
+ result.Attributes.ApproximateNumberOfMessages);
22
25
  }
23
26
  async send(messages) {
24
27
  const failedMessages = [];
@@ -44,7 +47,8 @@ class Producer {
44
47
  QueueUrl: this.queueUrl,
45
48
  Entries: batch.map(types_1.toEntry)
46
49
  };
47
- const result = await this.sqs.sendMessageBatch(params).promise();
50
+ const command = new client_sqs_1.SendMessageBatchCommand(params);
51
+ const result = await this.sqs.send(command);
48
52
  const failedMessagesBatch = failedMessages.concat(result.Failed.map((entry) => entry.Id));
49
53
  const successfulMessagesBatch = successfulMessages.concat(result.Successful);
50
54
  if (endIndex < messages.length) {
package/dist/types.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { SQS } from 'aws-sdk';
2
- import { SendMessageBatchRequestEntry } from 'aws-sdk/clients/sqs';
1
+ import { SendMessageBatchRequestEntry, MessageAttributeValue } from '@aws-sdk/client-sqs';
3
2
  export interface Message {
4
3
  id: string;
5
4
  body: string;
6
5
  groupId?: string;
7
6
  deduplicationId?: string;
8
7
  delaySeconds?: number;
9
- messageAttributes?: SQS.MessageBodyAttributeMap;
8
+ messageAttributes?: {
9
+ [key: string]: MessageAttributeValue;
10
+ };
10
11
  }
11
12
  export declare function toEntry(message: string | Message): SendMessageBatchRequestEntry;
package/dist/types.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toEntry = void 0;
4
- const { isObject, isString, isMessageAttributeValid } = require('./validation');
4
+ const validation_1 = require("./validation");
5
5
  function entryFromObject(message) {
6
6
  if (!message.body) {
7
7
  throw new Error(`Object messages must have 'body' prop`);
@@ -13,7 +13,7 @@ function entryFromObject(message) {
13
13
  throw new Error(`FIFO Queue messages must have 'groupId' prop`);
14
14
  }
15
15
  if (message.id) {
16
- if (!isString(message.id)) {
16
+ if (!(0, validation_1.isString)(message.id)) {
17
17
  throw new Error('Message.id value must be a string');
18
18
  }
19
19
  }
@@ -22,27 +22,28 @@ function entryFromObject(message) {
22
22
  MessageBody: message.body
23
23
  };
24
24
  if (message.delaySeconds) {
25
- if ((typeof message.delaySeconds !== 'number') ||
26
- (message.delaySeconds < 0 || message.delaySeconds > 900)) {
25
+ if (typeof message.delaySeconds !== 'number' ||
26
+ message.delaySeconds < 0 ||
27
+ message.delaySeconds > 900) {
27
28
  throw new Error('Message.delaySeconds value must be a number contained within [0 - 900]');
28
29
  }
29
30
  entry.DelaySeconds = message.delaySeconds;
30
31
  }
31
32
  if (message.messageAttributes) {
32
- if (!isObject(message.messageAttributes)) {
33
+ if (!(0, validation_1.isObject)(message.messageAttributes)) {
33
34
  throw new Error('Message.messageAttributes must be an object');
34
35
  }
35
- Object.values(message.messageAttributes).every(isMessageAttributeValid);
36
+ Object.values(message.messageAttributes).every(validation_1.isMessageAttributeValid);
36
37
  entry.MessageAttributes = message.messageAttributes;
37
38
  }
38
39
  if (message.groupId) {
39
- if (!isString(message.groupId)) {
40
+ if (!(0, validation_1.isString)(message.groupId)) {
40
41
  throw new Error('Message.groupId value must be a string');
41
42
  }
42
43
  entry.MessageGroupId = message.groupId;
43
44
  }
44
45
  if (message.deduplicationId) {
45
- if (!isString(message.deduplicationId)) {
46
+ if (!(0, validation_1.isString)(message.deduplicationId)) {
46
47
  throw new Error('Message.deduplicationId value must be a string');
47
48
  }
48
49
  entry.MessageDeduplicationId = message.deduplicationId;
@@ -56,10 +57,10 @@ function entryFromString(message) {
56
57
  };
57
58
  }
58
59
  function toEntry(message) {
59
- if (isString(message)) {
60
+ if ((0, validation_1.isString)(message)) {
60
61
  return entryFromString(message);
61
62
  }
62
- if (isObject(message)) {
63
+ if ((0, validation_1.isObject)(message)) {
63
64
  return entryFromObject(message);
64
65
  }
65
66
  throw new Error('A message can either be an object or a string');
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "sqs-producer",
3
- "version": "2.2.0",
3
+ "version": "3.0.0-alpha.1",
4
4
  "description": "Enqueues messages onto a given SQS queue",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "test": "mocha --recursive --full-trace --exit",
9
- "posttest": "npm run lint",
9
+ "posttest": "npm run lint && npm run format:check",
10
10
  "coverage": "nyc mocha && nyc report --reporter=html && nyc report --reporter=json-summary",
11
11
  "lcov": "nyc mocha && nyc report --reporter=lcov",
12
- "lint": "tsc --noEmit",
12
+ "lint": "eslint . --ext .ts",
13
+ "lint:fix": "eslint . --fix",
14
+ "format": "prettier --loglevel warn --write \"**/*.{js,json,jsx,md,ts,tsx,html}\"",
15
+ "format:check": "prettier --check \"**/*.{js,json,jsx,md,ts,tsx,html}\"",
13
16
  "build": "npm run clean && tsc",
14
17
  "prepublish": "npm run build",
15
18
  "pretest": "npm run build",
@@ -41,17 +44,21 @@
41
44
  "@types/node": "^18.11.12",
42
45
  "@types/sinon": "^10.0.13",
43
46
  "chai": "^4.3.7",
47
+ "eslint": "^8.29.0",
48
+ "eslint-config-iplayer-ts": "^4.1.0",
49
+ "eslint-config-prettier": "^4.3.0",
44
50
  "mocha": "^10.1.0",
45
51
  "nyc": "^15.1.0",
52
+ "prettier": "^2.8.1",
46
53
  "sinon": "^15.0.0",
47
54
  "ts-node": "^10.9.1",
48
55
  "typescript": "^4.9.4"
49
56
  },
50
57
  "dependencies": {
51
- "aws-sdk": "^2.1271.0"
58
+ "@aws-sdk/client-sqs": "^3.226.0"
52
59
  },
53
60
  "peerDependencies": {
54
- "aws-sdk": "^2.1271.0"
61
+ "@aws-sdk/client-sqs": "^3.226.0"
55
62
  },
56
63
  "mocha": {
57
64
  "spec": "test/**/**/*.test.ts",
@@ -69,5 +76,30 @@
69
76
  ],
70
77
  "sourceMap": true,
71
78
  "instrument": true
79
+ },
80
+ "eslintConfig": {
81
+ "extends": [
82
+ "iplayer-ts",
83
+ "prettier",
84
+ "prettier/react",
85
+ "prettier/@typescript-eslint"
86
+ ],
87
+ "parserOptions": {
88
+ "sourceType": "module"
89
+ },
90
+ "rules": {
91
+ "@typescript-eslint/naming-convention": [
92
+ "error",
93
+ {
94
+ "selector": "variable",
95
+ "format": [
96
+ "camelCase",
97
+ "UPPER_CASE",
98
+ "PascalCase"
99
+ ],
100
+ "leadingUnderscore": "allow"
101
+ }
102
+ ]
103
+ }
72
104
  }
73
105
  }
package/src/producer.ts CHANGED
@@ -1,14 +1,16 @@
1
- import { SQS } from 'aws-sdk';
2
- import { SendMessageBatchResultEntryList } from 'aws-sdk/clients/sqs';
1
+ import {
2
+ SQSClient,
3
+ SendMessageBatchResultEntry,
4
+ SendMessageBatchCommand,
5
+ GetQueueAttributesCommand
6
+ } from '@aws-sdk/client-sqs';
3
7
  import { Message, toEntry } from './types';
4
- const requiredOptions = [
5
- 'queueUrl'
6
- ];
8
+ const requiredOptions = ['queueUrl'];
7
9
 
8
10
  interface ProducerOptions {
9
11
  queueUrl?: string;
10
12
  batchSize?: number;
11
- sqs?: SQS;
13
+ sqs?: SQSClient;
12
14
  region?: string;
13
15
  }
14
16
 
@@ -16,35 +18,50 @@ export class Producer {
16
18
  static create: (options: ProducerOptions) => Producer;
17
19
  queueUrl: string;
18
20
  batchSize: number;
19
- sqs: SQS;
21
+ sqs: SQSClient;
20
22
  region?: string;
21
23
 
22
24
  constructor(options: ProducerOptions) {
23
25
  this.validate(options);
24
26
  this.queueUrl = options.queueUrl;
25
27
  this.batchSize = options.batchSize || 10;
26
- this.sqs = options.sqs || new SQS({
27
- ...options,
28
- region: options.region || 'eu-west-1'
29
- });
28
+ this.sqs =
29
+ options.sqs ||
30
+ new SQSClient({
31
+ ...options,
32
+ region: options.region || 'eu-west-1'
33
+ });
30
34
  }
31
35
 
32
36
  async queueSize(): Promise<number> {
33
- const result = await this.sqs.getQueueAttributes({
37
+ const command = new GetQueueAttributesCommand({
34
38
  QueueUrl: this.queueUrl,
35
39
  AttributeNames: ['ApproximateNumberOfMessages']
36
- }).promise();
40
+ });
37
41
 
38
- return Number(result && result.Attributes && result.Attributes.ApproximateNumberOfMessages);
42
+ const result = await this.sqs.send(command);
43
+
44
+ return Number(
45
+ result &&
46
+ result.Attributes &&
47
+ result.Attributes.ApproximateNumberOfMessages
48
+ );
39
49
  }
40
50
 
41
- async send(messages: string | Message | (string | Message)[]): Promise<SendMessageBatchResultEntryList> {
51
+ async send(
52
+ messages: string | Message | (string | Message)[]
53
+ ): Promise<SendMessageBatchResultEntry[]> {
42
54
  const failedMessages = [];
43
55
  const successfulMessages = [];
44
56
  const startIndex = 0;
45
57
  const messagesArr = !Array.isArray(messages) ? [messages] : messages;
46
58
 
47
- return this.sendBatch(failedMessages, successfulMessages, messagesArr, startIndex);
59
+ return this.sendBatch(
60
+ failedMessages,
61
+ successfulMessages,
62
+ messagesArr,
63
+ startIndex
64
+ );
48
65
  }
49
66
 
50
67
  private validate(options: ProducerOptions): void {
@@ -58,7 +75,12 @@ export class Producer {
58
75
  }
59
76
  }
60
77
 
61
- private async sendBatch(failedMessages?: string[], successfulMessages?: SendMessageBatchResultEntryList, messages?: (string | Message)[], startIndex?: number): Promise<SendMessageBatchResultEntryList> {
78
+ private async sendBatch(
79
+ failedMessages?: string[],
80
+ successfulMessages?: SendMessageBatchResultEntry[],
81
+ messages?: (string | Message)[],
82
+ startIndex?: number
83
+ ): Promise<SendMessageBatchResultEntry[]> {
62
84
  const endIndex = startIndex + this.batchSize;
63
85
  const batch = messages.slice(startIndex, endIndex);
64
86
  const params = {
@@ -66,20 +88,31 @@ export class Producer {
66
88
  Entries: batch.map(toEntry)
67
89
  };
68
90
 
69
- const result = await this.sqs.sendMessageBatch(params).promise();
70
- const failedMessagesBatch = failedMessages.concat(result.Failed.map((entry) => entry.Id));
71
- const successfulMessagesBatch = successfulMessages.concat(result.Successful);
91
+ const command = new SendMessageBatchCommand(params);
92
+ const result = await this.sqs.send(command);
93
+ const failedMessagesBatch = failedMessages.concat(
94
+ result.Failed.map((entry) => entry.Id)
95
+ );
96
+ const successfulMessagesBatch = successfulMessages.concat(
97
+ result.Successful
98
+ );
72
99
 
73
100
  if (endIndex < messages.length) {
74
- return this.sendBatch(failedMessagesBatch, successfulMessagesBatch, messages, endIndex);
101
+ return this.sendBatch(
102
+ failedMessagesBatch,
103
+ successfulMessagesBatch,
104
+ messages,
105
+ endIndex
106
+ );
75
107
  }
76
108
 
77
109
  if (failedMessagesBatch.length === 0) {
78
110
  return successfulMessagesBatch;
79
111
  }
80
- throw new Error(`Failed to send messages: ${failedMessagesBatch.join(', ')}`);
112
+ throw new Error(
113
+ `Failed to send messages: ${failedMessagesBatch.join(', ')}`
114
+ );
81
115
  }
82
-
83
116
  }
84
117
 
85
118
  Producer.create = (options: ProducerOptions): Producer => {
package/src/types.ts CHANGED
@@ -1,88 +1,101 @@
1
- import { SQS } from 'aws-sdk';
2
- import { SendMessageBatchRequestEntry } from 'aws-sdk/clients/sqs';
3
- const { isObject, isString, isMessageAttributeValid } = require('./validation');
1
+ import {
2
+ SendMessageBatchRequestEntry,
3
+ MessageAttributeValue
4
+ } from '@aws-sdk/client-sqs';
5
+ import { isObject, isString, isMessageAttributeValid } from './validation';
4
6
 
5
7
  export interface Message {
6
- id: string;
7
- body: string;
8
- groupId?: string;
9
- deduplicationId?: string;
10
- delaySeconds?: number;
11
- messageAttributes?: SQS.MessageBodyAttributeMap;
8
+ id: string;
9
+ body: string;
10
+ groupId?: string;
11
+ deduplicationId?: string;
12
+ delaySeconds?: number;
13
+ messageAttributes?: { [key: string]: MessageAttributeValue };
12
14
  }
13
15
 
14
16
  function entryFromObject(message: Message): SendMessageBatchRequestEntry {
15
- if (!message.body) {
16
- throw new Error(`Object messages must have 'body' prop`);
17
- }
17
+ if (!message.body) {
18
+ throw new Error(`Object messages must have 'body' prop`);
19
+ }
18
20
 
19
- if (!message.groupId && !message.deduplicationId && !message.id) {
20
- throw new Error(`Object messages must have 'id' prop`);
21
- }
21
+ if (!message.groupId && !message.deduplicationId && !message.id) {
22
+ throw new Error(`Object messages must have 'id' prop`);
23
+ }
22
24
 
23
- if (message.deduplicationId && !message.groupId) {
24
- throw new Error(`FIFO Queue messages must have 'groupId' prop`);
25
- }
25
+ if (message.deduplicationId && !message.groupId) {
26
+ throw new Error(`FIFO Queue messages must have 'groupId' prop`);
27
+ }
26
28
 
27
- if (message.id) {
28
- if (!isString(message.id)) {
29
- throw new Error('Message.id value must be a string');
30
- }
29
+ if (message.id) {
30
+ if (!isString(message.id)) {
31
+ throw new Error('Message.id value must be a string');
32
+ }
33
+ }
34
+
35
+ const entry: SendMessageBatchRequestEntry = {
36
+ Id: message.id,
37
+ MessageBody: message.body
38
+ };
39
+
40
+ if (message.delaySeconds) {
41
+ if (
42
+ typeof message.delaySeconds !== 'number' ||
43
+ message.delaySeconds < 0 ||
44
+ message.delaySeconds > 900
45
+ ) {
46
+ throw new Error(
47
+ 'Message.delaySeconds value must be a number contained within [0 - 900]'
48
+ );
31
49
  }
32
50
 
33
- const entry: SendMessageBatchRequestEntry = {
34
- Id: message.id,
35
- MessageBody: message.body
36
- };
37
-
38
- if (message.delaySeconds) {
39
- if ((typeof message.delaySeconds !== 'number') ||
40
- (message.delaySeconds < 0 || message.delaySeconds > 900)) {
41
- throw new Error('Message.delaySeconds value must be a number contained within [0 - 900]');
42
- }
51
+ entry.DelaySeconds = message.delaySeconds;
52
+ }
43
53
 
44
- entry.DelaySeconds = message.delaySeconds;
54
+ if (message.messageAttributes) {
55
+ if (!isObject(message.messageAttributes)) {
56
+ throw new Error('Message.messageAttributes must be an object');
45
57
  }
46
58
 
47
- if (message.messageAttributes) {
48
- if (!isObject(message.messageAttributes)) {
49
- throw new Error('Message.messageAttributes must be an object');
50
- }
59
+ Object.values(message.messageAttributes).every(isMessageAttributeValid);
51
60
 
52
- Object.values(message.messageAttributes).every(isMessageAttributeValid);
61
+ entry.MessageAttributes = message.messageAttributes;
62
+ }
53
63
 
54
- entry.MessageAttributes = message.messageAttributes;
64
+ if (message.groupId) {
65
+ if (!isString(message.groupId)) {
66
+ throw new Error('Message.groupId value must be a string');
55
67
  }
56
68
 
57
- if (message.groupId) {
58
- if (!isString(message.groupId)) {
59
- throw new Error('Message.groupId value must be a string');
60
- }
69
+ entry.MessageGroupId = message.groupId;
70
+ }
61
71
 
62
- entry.MessageGroupId = message.groupId;
72
+ if (message.deduplicationId) {
73
+ if (!isString(message.deduplicationId)) {
74
+ throw new Error('Message.deduplicationId value must be a string');
63
75
  }
64
76
 
65
- if (message.deduplicationId) {
66
- if (!isString(message.deduplicationId)) {
67
- throw new Error('Message.deduplicationId value must be a string');
68
- }
69
-
70
- entry.MessageDeduplicationId = message.deduplicationId;
71
- }
77
+ entry.MessageDeduplicationId = message.deduplicationId;
78
+ }
72
79
 
73
- return entry;
80
+ return entry;
74
81
  }
75
82
 
76
83
  function entryFromString(message: string): SendMessageBatchRequestEntry {
77
- return {
78
- Id: message,
79
- MessageBody: message
80
- };
84
+ return {
85
+ Id: message,
86
+ MessageBody: message
87
+ };
81
88
  }
82
89
 
83
- export function toEntry(message: string | Message): SendMessageBatchRequestEntry {
84
- if (isString(message)) { return entryFromString(<string>message); }
85
- if (isObject(message)) { return entryFromObject(<Message>message); }
86
-
87
- throw new Error('A message can either be an object or a string');
90
+ export function toEntry(
91
+ message: string | Message
92
+ ): SendMessageBatchRequestEntry {
93
+ if (isString(message)) {
94
+ return entryFromString(message as string);
95
+ }
96
+ if (isObject(message)) {
97
+ return entryFromObject(message as Message);
98
+ }
99
+
100
+ throw new Error('A message can either be an object or a string');
88
101
  }
package/src/validation.ts CHANGED
@@ -1,18 +1,17 @@
1
-
2
1
  export function isString(value: any): boolean {
3
- return typeof value === 'string' || value instanceof String;
2
+ return typeof value === 'string' || value instanceof String;
4
3
  }
5
4
 
6
5
  export function isObject(value: any): boolean {
7
- return value && typeof value === 'object' && value instanceof Object;
6
+ return value && typeof value === 'object' && value instanceof Object;
8
7
  }
9
8
 
10
9
  export function isMessageAttributeValid(messageAttribute: any): boolean {
11
- if (!messageAttribute.DataType) {
12
- throw new Error('A MessageAttribute must have a DataType key');
13
- }
14
- if (!isString(messageAttribute.DataType)) {
15
- throw new Error('The DataType key of a MessageAttribute must be a String');
16
- }
17
- return true;
10
+ if (!messageAttribute.DataType) {
11
+ throw new Error('A MessageAttribute must have a DataType key');
12
+ }
13
+ if (!isString(messageAttribute.DataType)) {
14
+ throw new Error('The DataType key of a MessageAttribute must be a String');
15
+ }
16
+ return true;
18
17
  }
package/tsconfig.json CHANGED
@@ -9,11 +9,6 @@
9
9
  "noUnusedLocals": true,
10
10
  "declaration": true
11
11
  },
12
- "include": [
13
- "src/**/*"
14
- ],
15
- "exclude": [
16
- "node_modules",
17
- "dist"
18
- ]
12
+ "include": ["src/**/*"],
13
+ "exclude": ["node_modules", "dist"]
19
14
  }