@nestjstools/messaging-amazon-sqs-extension 1.2.0 → 1.3.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <image src="nestjstools-logo.png" width="400">
3
3
  </p>
4
4
 
5
- # @nestjstools/messaging-amazon-sqs -extension
5
+ # @nestjstools/messaging-amazon-sqs-extension
6
6
 
7
7
  A NestJS library for managing asynchronous and synchronous messages with support for buses, handlers, channels, and consumers. This library simplifies building scalable and decoupled applications by facilitating robust message handling pipelines while ensuring flexibility and reliability.
8
8
 
@@ -32,11 +32,11 @@ yarn add @nestjstools/messaging @nestjstools/messaging-amazon-sqs-extension
32
32
  import { Module } from '@nestjs/common';
33
33
  import { MessagingModule } from '@nestjstools/messaging';
34
34
  import { SendMessageHandler } from './handlers/send-message.handler';
35
- import { MessagerAmazonSQSExtensionModule, AmazonSQSChannelConfig } from "@nestjstools/messager-amazon-sqs-extension";
35
+ import { AmazonSqsChannelConfig, MessagingAmazonSqsExtensionModule } from '@nestjstools/messaging-amazon-sqs-extension';
36
36
 
37
37
  @Module({
38
38
  imports: [
39
- MessagerAmazonSQSExtensionModule, // Importing the SQS extension module
39
+ MessagingAmazonSqsExtensionModule, // Importing the SQS extension module
40
40
  MessagingModule.forRoot({
41
41
  buses: [
42
42
  {
@@ -57,7 +57,8 @@ import { MessagerAmazonSQSExtensionModule, AmazonSQSChannelConfig } from "@nestj
57
57
  },
58
58
  maxNumberOfMessages: 3, // optional
59
59
  visibilityTimeout: 10, // optional
60
- waitTimeSeconds: 5, // Every 5 seconds consumer will pull 3 messages from queue - optional
60
+ waitTimeSeconds: 5, // Every 5 seconds consumer will pull 3 messages from queue - optional,
61
+ deadLetterQueue: false,
61
62
  }),
62
63
  ],
63
64
  debug: true, // Optional: Enable debugging for Messaging operations
@@ -81,7 +82,7 @@ export class AppController {
81
82
  ) {}
82
83
 
83
84
  @Get('/sqs')
84
- createUserAsyncViaPuSubBus(): string {
85
+ createUser(): string {
85
86
  this.sqsMessageBus.dispatch(new RoutingMessage(new CreateUser('John FROM SQS'), 'my_app_command.create_user'));
86
87
 
87
88
  return 'Message sent';
@@ -177,17 +178,18 @@ this.sqsMessageBus.dispatch(
177
178
  ### AmazonSqsChannel
178
179
 
179
180
  #### **AmazonSqsChannelConfig**
180
- | **Property** | **Description** | **Default Value** |
181
- | ------------------------- | ------------------------------------------------------------------------------------------------------ |-------------------|
182
- | **`name`** | The name of the Amazon SQS channel (e.g., `'sqs-event'`). | |
183
- | **`region`** | The AWS region for the SQS queue (e.g., `'us-east-1'`). | |
184
- | **`queueUrl`** | The URL of the SQS queue (e.g., `'http://localhost:9324/queue/test_queue'`). | |
185
- | **`credentials`** | AWS credentials for SQS (optional). | |
186
- | **`enableConsumer`** | Whether to enable message consumption (i.e., processing received messages). | `true` |
187
- | **`autoCreate`** | Automatically create the queue if it doesn’t exist. | `true` |
188
- | **`maxNumberOfMessages`** | The maximum number of messages to retrieve from the queue in one request. | 1 |
189
- | **`visibilityTimeout`** | The time in seconds that the message will remain invisible to other consumers after being fetched. | 20 |
190
- | **`waitTimeSeconds`** | The amount of time (in seconds) for long polling. The consumer will wait up to this time for messages. | 10 |
181
+ | **Property** | **Description** | **Default Value** |
182
+ |---------------------------|---------------------------------------------------------------------------------------------------------------------------------------|-------------------|
183
+ | **`name`** | The name of the Amazon SQS channel (e.g., `'sqs-event'`). | |
184
+ | **`region`** | The AWS region for the SQS queue (e.g., `'us-east-1'`). | |
185
+ | **`queueUrl`** | The URL of the SQS queue (e.g., `'http://localhost:9324/queue/test_queue'`). | |
186
+ | **`credentials`** | AWS credentials for SQS (optional). | |
187
+ | **`enableConsumer`** | Whether to enable message consumption (i.e., processing received messages). | `true` |
188
+ | **`autoCreate`** | Automatically create the queue if it doesn’t exist. | `true` |
189
+ | **`maxNumberOfMessages`** | The maximum number of messages to retrieve from the queue in one request. | 1 |
190
+ | **`visibilityTimeout`** | The time in seconds that the message will remain invisible to other consumers after being fetched. | 20 |
191
+ | **`waitTimeSeconds`** | The amount of time (in seconds) for long polling. The consumer will wait up to this time for messages. | 10 |
192
+ | **`deadLetterQueue`** | When set to `true`, a dead-letter queue (DLQ) is automatically created. The DLQ name follows the pattern: `<queue_name>_dead_letter`. | `false` |
191
193
  ---
192
194
 
193
195
  ## Real world working example with RabbitMQ & Redis - but might be helpful to understand how it works
@@ -9,7 +9,8 @@ export declare class AmazonSqsChannelConfig extends ChannelConfig {
9
9
  readonly visibilityTimeout?: number;
10
10
  readonly waitTimeSeconds?: number;
11
11
  readonly autoCreate?: boolean;
12
- constructor({ name, credentials, queueUrl, maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, region, autoCreate, enableConsumer, avoidErrorsForNotExistedHandlers, middlewares, normalizer, }: AmazonSqsChannelConfig);
12
+ readonly deadLetterQueue?: boolean;
13
+ constructor({ name, credentials, queueUrl, maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, region, autoCreate, deadLetterQueue, enableConsumer, avoidErrorsForNotExistedHandlers, middlewares, normalizer, }: AmazonSqsChannelConfig);
13
14
  }
14
15
  interface Credentials {
15
16
  accessKeyId: string;
@@ -12,7 +12,8 @@ class AmazonSqsChannelConfig extends messaging_1.ChannelConfig {
12
12
  visibilityTimeout;
13
13
  waitTimeSeconds;
14
14
  autoCreate;
15
- constructor({ name, credentials, queueUrl, maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, region, autoCreate, enableConsumer, avoidErrorsForNotExistedHandlers, middlewares, normalizer, }) {
15
+ deadLetterQueue;
16
+ constructor({ name, credentials, queueUrl, maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, region, autoCreate, deadLetterQueue, enableConsumer, avoidErrorsForNotExistedHandlers, middlewares, normalizer, }) {
16
17
  super(name, avoidErrorsForNotExistedHandlers, middlewares, enableConsumer, normalizer);
17
18
  let url;
18
19
  try {
@@ -30,6 +31,7 @@ class AmazonSqsChannelConfig extends messaging_1.ChannelConfig {
30
31
  this.visibilityTimeout = visibilityTimeout ?? 20;
31
32
  this.waitTimeSeconds = waitTimeSeconds ?? 10;
32
33
  this.autoCreate = autoCreate ?? false;
34
+ this.deadLetterQueue = deadLetterQueue ?? false;
33
35
  }
34
36
  }
35
37
  exports.AmazonSqsChannelConfig = AmazonSqsChannelConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"amazon-sqs.channel-config.js","sourceRoot":"","sources":["../../src/channel/amazon-sqs.channel-config.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AAEvD,MAAa,sBAAuB,SAAQ,yBAAa;IACvC,WAAW,CAAe;IAC1B,QAAQ,CAAS;IACjB,SAAS,CAAU;IACnB,QAAQ,CAAU;IAClB,MAAM,CAAS;IACf,mBAAmB,CAAU;IAC7B,iBAAiB,CAAU;IAC3B,eAAe,CAAU;IACzB,UAAU,CAAW;IAErC,YAAY,EACE,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,MAAM,EACN,UAAU,EACV,cAAc,EACd,gCAAgC,EAChC,WAAW,EACX,UAAU,GACa;QACnC,KAAK,CAAC,IAAI,EAAE,gCAAgC,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC;QACR,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,GAAG,CAAC,CAAA;QACpD,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,KAAK,CAAC;IACxC,CAAC;CACF;AA3CD,wDA2CC"}
1
+ {"version":3,"file":"amazon-sqs.channel-config.js","sourceRoot":"","sources":["../../src/channel/amazon-sqs.channel-config.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AAEvD,MAAa,sBAAuB,SAAQ,yBAAa;IACvC,WAAW,CAAe;IAC1B,QAAQ,CAAS;IACjB,SAAS,CAAU;IACnB,QAAQ,CAAU;IAClB,MAAM,CAAS;IACf,mBAAmB,CAAU;IAC7B,iBAAiB,CAAU;IAC3B,eAAe,CAAU;IACzB,UAAU,CAAW;IACrB,eAAe,CAAW;IAE1C,YAAY,EACE,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,MAAM,EACN,UAAU,EACV,eAAe,EACf,cAAc,EACd,gCAAgC,EAChC,WAAW,EACX,UAAU,GACa;QACnC,KAAK,CAAC,IAAI,EAAE,gCAAgC,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC;QACR,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,GAAG,CAAC,CAAA;QACpD,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,KAAK,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,KAAK,CAAC;IAClD,CAAC;CACF;AA9CD,wDA8CC"}
@@ -7,5 +7,6 @@ export declare class AmazonSqsMessagingConsumer implements IMessagingConsumer<Am
7
7
  private channel?;
8
8
  consume(dispatcher: ConsumerMessageDispatcher, channel: AmazonSqsChannel): Promise<void>;
9
9
  onError(errored: ConsumerDispatchedMessageError, channel: AmazonSqsChannel): Promise<void>;
10
+ private createDeadLetterQueue;
10
11
  onApplicationShutdown(signal?: string): Promise<any>;
11
12
  }
@@ -44,10 +44,34 @@ let AmazonSqsMessagingConsumer = class AmazonSqsMessagingConsumer {
44
44
  await delay(channel.config.waitTimeSeconds);
45
45
  }
46
46
  }
47
+ await this.createDeadLetterQueue(channel);
47
48
  processPollMessages();
48
49
  return Promise.resolve();
49
50
  }
50
51
  async onError(errored, channel) {
52
+ if (!channel.config.deadLetterQueue) {
53
+ return Promise.resolve();
54
+ }
55
+ const command = new client_sqs_1.SendMessageCommand({
56
+ QueueUrl: `${channel.config.queueUrl}_dead_letter`,
57
+ MessageBody: JSON.stringify(errored.dispatchedConsumerMessage.message),
58
+ MessageAttributes: {
59
+ messagingRoutingKey: {
60
+ DataType: "String",
61
+ StringValue: errored.dispatchedConsumerMessage.routingKey,
62
+ }
63
+ },
64
+ });
65
+ await channel.client.send(command);
66
+ return Promise.resolve();
67
+ }
68
+ createDeadLetterQueue(channel) {
69
+ if (!channel.config.deadLetterQueue) {
70
+ return Promise.resolve();
71
+ }
72
+ channel.client.send(new client_sqs_1.CreateQueueCommand({
73
+ QueueName: `${channel.config.queueName}_dead_letter`,
74
+ }));
51
75
  return Promise.resolve();
52
76
  }
53
77
  async onApplicationShutdown(signal) {
@@ -1 +1 @@
1
- {"version":3,"file":"amazon-sqs-messaging.consumer.js","sourceRoot":"","sources":["../../src/consumer/amazon-sqs-messaging.consumer.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sEAAiE;AACjE,sDAA6E;AAE7E,2CAAmE;AACnE,sDAAyD;AAEzD,oDAI6B;AAItB,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IAC7B,OAAO,GAAsB,SAAS,CAAC;IAE/C,KAAK,CAAC,OAAO,CAAC,UAAqC,EAAE,OAAyB;QAC5E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAEnC,KAAK,UAAU,mBAAmB;YAChC,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YACnF,OAAO,IAAI,EAAE,CAAC;gBACV,MAAM,aAAa,GAAG;oBACpB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ;oBACjC,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB;oBACvD,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe;oBAC/C,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB;oBACnD,qBAAqB,EAAE,CAAC,KAAK,CAAC;iBAC/B,CAAC;gBAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,kCAAqB,CAAC,aAAa,CAAC,CAAC,CAAC;gBAE7E,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtD,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;wBACxC,MAAM,KAAK,GAAG,OAAO,CAAC,iBAA0D,CAAC;wBACjF,MAAM,WAAW,GAAG,OAAO,CAAC,IAAc,CAAC;wBAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,mBAAmB,CAAC,WAAqB,CAAC;wBACnE,UAAU,CAAC,QAAQ,CAAC,IAAI,2BAAe,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,CAAC,CAAA;wBAC7E,MAAM,YAAY,GAAG;4BACnB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ;4BACjC,aAAa,EAAE,OAAO,CAAC,aAAa;yBACrC,CAAC;wBACF,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,iCAAoB,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC5D,CAAC;gBACH,CAAC;gBACH,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,eAAyB,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAED,mBAAmB,EAAE,CAAC;QAEtB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAuC,EAAE,OAAyB;QAC9E,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,MAAe;QACzC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;CACF,CAAA;AAnDY,gEAA0B;qCAA1B,0BAA0B;IAFtC,IAAA,mBAAU,GAAE;IACZ,IAAA,2BAAe,EAAC,qCAAgB,CAAC;GACrB,0BAA0B,CAmDtC"}
1
+ {"version":3,"file":"amazon-sqs-messaging.consumer.js","sourceRoot":"","sources":["../../src/consumer/amazon-sqs-messaging.consumer.ts"],"names":[],"mappings":"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"}