@geekmidas/events 0.0.2 → 0.2.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.
Files changed (215) hide show
  1. package/dist/{BasicConnection-C4_Y0nIj.d.mts → BasicConnection-BTRsXiuH.d.cts} +3 -2
  2. package/dist/BasicConnection-BTRsXiuH.d.cts.map +1 -0
  3. package/dist/BasicConnection-C-Cg2FJT.cjs.map +1 -1
  4. package/dist/BasicConnection-CpwybcC9.mjs.map +1 -1
  5. package/dist/{BasicConnection-CddnULuT.d.cts → BasicConnection-DIxtA7jK.d.mts} +3 -2
  6. package/dist/BasicConnection-DIxtA7jK.d.mts.map +1 -0
  7. package/dist/BasicPublisher-CXAVKxgq.cjs.map +1 -1
  8. package/dist/{BasicPublisher-DCBxaTwC.d.mts → BasicPublisher-CpJFK2oS.d.mts} +5 -3
  9. package/dist/BasicPublisher-CpJFK2oS.d.mts.map +1 -0
  10. package/dist/{BasicPublisher-V5hELHG9.d.cts → BasicPublisher-D1q0a2xp.d.cts} +5 -3
  11. package/dist/BasicPublisher-D1q0a2xp.d.cts.map +1 -0
  12. package/dist/BasicPublisher-DogbeHAH.mjs.map +1 -1
  13. package/dist/{BasicSubscriber-BB3aKeph.d.mts → BasicSubscriber-6w0Af4DD.d.mts} +5 -3
  14. package/dist/BasicSubscriber-6w0Af4DD.d.mts.map +1 -0
  15. package/dist/{BasicSubscriber-CCKfbRMo.mjs → BasicSubscriber-BJSZN22M.mjs} +2 -4
  16. package/dist/BasicSubscriber-BJSZN22M.mjs.map +1 -0
  17. package/dist/{BasicSubscriber-DOwgFw5j.d.cts → BasicSubscriber-DXxQewjc.d.cts} +5 -3
  18. package/dist/BasicSubscriber-DXxQewjc.d.cts.map +1 -0
  19. package/dist/{BasicSubscriber-BGqv3c8x.cjs → BasicSubscriber-mVJRMXhZ.cjs} +2 -4
  20. package/dist/BasicSubscriber-mVJRMXhZ.cjs.map +1 -0
  21. package/dist/{EventConnection-DZhn1Msl.d.cts → EventConnection-BaJRXdg7.d.cts} +2 -2
  22. package/dist/EventConnection-BaJRXdg7.d.cts.map +1 -0
  23. package/dist/EventConnection-ClLMoIUU.mjs.map +1 -1
  24. package/dist/EventConnection-F_N81SXu.cjs.map +1 -1
  25. package/dist/{EventConnection-DeXfLGom.d.mts → EventConnection-SOhtmxib.d.mts} +2 -2
  26. package/dist/EventConnection-SOhtmxib.d.mts.map +1 -0
  27. package/dist/EventConnection.d.cts +2 -2
  28. package/dist/EventConnection.d.mts +2 -2
  29. package/dist/{Publisher-C3m8JFXm.d.mts → Publisher-1CfcYRnm.d.mts} +4 -2
  30. package/dist/Publisher-1CfcYRnm.d.mts.map +1 -0
  31. package/dist/{Publisher-nXNVjL0e.d.cts → Publisher-BfNgvHwQ.d.cts} +4 -2
  32. package/dist/Publisher-BfNgvHwQ.d.cts.map +1 -0
  33. package/dist/Publisher-DS0aOh8r.mjs.map +1 -1
  34. package/dist/Publisher-ceu6OxCj.cjs.map +1 -1
  35. package/dist/Publisher.d.cts +2 -2
  36. package/dist/Publisher.d.mts +2 -2
  37. package/dist/{RabbitMQConnection-ungB0Zl6.cjs → RabbitMQConnection-Blj9Lo05.cjs} +2 -2
  38. package/dist/RabbitMQConnection-Blj9Lo05.cjs.map +1 -0
  39. package/dist/{RabbitMQConnection-7cWp_-_Q.d.cts → RabbitMQConnection-Bm8VCI2R.d.cts} +3 -2
  40. package/dist/RabbitMQConnection-Bm8VCI2R.d.cts.map +1 -0
  41. package/dist/{RabbitMQConnection-C2HC7J7K.d.mts → RabbitMQConnection-Ck-ktCp_.d.mts} +3 -2
  42. package/dist/RabbitMQConnection-Ck-ktCp_.d.mts.map +1 -0
  43. package/dist/{RabbitMQConnection-kU3MvN5P.mjs → RabbitMQConnection-Co7f5Xsx.mjs} +2 -2
  44. package/dist/RabbitMQConnection-Co7f5Xsx.mjs.map +1 -0
  45. package/dist/RabbitMQPublisher--DL6GM6g.cjs.map +1 -1
  46. package/dist/{RabbitMQPublisher-CpcbgrXj.d.cts → RabbitMQPublisher-COnxcWEZ.d.mts} +5 -3
  47. package/dist/RabbitMQPublisher-COnxcWEZ.d.mts.map +1 -0
  48. package/dist/RabbitMQPublisher-o_oVI3wr.mjs.map +1 -1
  49. package/dist/{RabbitMQPublisher-DDZi15Ro.d.mts → RabbitMQPublisher-qQT7-1-p.d.cts} +5 -3
  50. package/dist/RabbitMQPublisher-qQT7-1-p.d.cts.map +1 -0
  51. package/dist/{RabbitMQSubscriber-BplEJEk8.cjs → RabbitMQSubscriber-C8MYAihn.cjs} +2 -3
  52. package/dist/RabbitMQSubscriber-C8MYAihn.cjs.map +1 -0
  53. package/dist/{RabbitMQSubscriber-BJ9PTGny.d.cts → RabbitMQSubscriber-C_sZjDPU.d.mts} +5 -3
  54. package/dist/RabbitMQSubscriber-C_sZjDPU.d.mts.map +1 -0
  55. package/dist/{RabbitMQSubscriber-CIvIw8MG.d.mts → RabbitMQSubscriber-D12sssMb.d.cts} +5 -3
  56. package/dist/RabbitMQSubscriber-D12sssMb.d.cts.map +1 -0
  57. package/dist/{RabbitMQSubscriber-BaXqs5nO.mjs → RabbitMQSubscriber-DlGL0pC2.mjs} +2 -3
  58. package/dist/RabbitMQSubscriber-DlGL0pC2.mjs.map +1 -0
  59. package/dist/{SNSConnection-CAImaMM2.d.mts → SNSConnection-BDfQrVBO.d.cts} +3 -2
  60. package/dist/SNSConnection-BDfQrVBO.d.cts.map +1 -0
  61. package/dist/SNSConnection-D7wCf9Si.mjs.map +1 -1
  62. package/dist/SNSConnection-DVsC_pbB.cjs.map +1 -1
  63. package/dist/{SNSConnection-Cqbr7-Ho.d.cts → SNSConnection-mHb10nQ6.d.mts} +3 -2
  64. package/dist/SNSConnection-mHb10nQ6.d.mts.map +1 -0
  65. package/dist/{SNSPublisher-BZ6N3JI9.cjs → SNSPublisher-BoA8uLnw.cjs} +2 -3
  66. package/dist/SNSPublisher-BoA8uLnw.cjs.map +1 -0
  67. package/dist/{SNSPublisher-Dkhb4LU-.d.mts → SNSPublisher-CM7UAWtf.d.mts} +7 -6
  68. package/dist/SNSPublisher-CM7UAWtf.d.mts.map +1 -0
  69. package/dist/{SNSPublisher-BfWjzNiB.mjs → SNSPublisher-Drr4kHn6.mjs} +2 -3
  70. package/dist/SNSPublisher-Drr4kHn6.mjs.map +1 -0
  71. package/dist/{SNSPublisher-RVZFa7kL.d.cts → SNSPublisher-kpsSlGDn.d.cts} +7 -6
  72. package/dist/SNSPublisher-kpsSlGDn.d.cts.map +1 -0
  73. package/dist/{SNSSubscriber-C9YJWa7m.mjs → SNSSubscriber-CBIvQpqK.mjs} +4 -8
  74. package/dist/SNSSubscriber-CBIvQpqK.mjs.map +1 -0
  75. package/dist/{SNSSubscriber-UE0ia4XM.cjs → SNSSubscriber-CWiAJjpU.cjs} +4 -8
  76. package/dist/SNSSubscriber-CWiAJjpU.cjs.map +1 -0
  77. package/dist/{SNSSubscriber-B31JmkAE.d.mts → SNSSubscriber-DDB3--pm.d.cts} +4 -3
  78. package/dist/SNSSubscriber-DDB3--pm.d.cts.map +1 -0
  79. package/dist/{SNSSubscriber-k2UwKUxu.d.cts → SNSSubscriber-Dwo8391f.d.mts} +4 -3
  80. package/dist/SNSSubscriber-Dwo8391f.d.mts.map +1 -0
  81. package/dist/{SQSConnection-C5WFqZW7.d.mts → SQSConnection-B5Ep9Tma.d.cts} +3 -2
  82. package/dist/SQSConnection-B5Ep9Tma.d.cts.map +1 -0
  83. package/dist/{SQSConnection-geav2Rsn.d.cts → SQSConnection-BI_xOzyJ.d.mts} +3 -2
  84. package/dist/SQSConnection-BI_xOzyJ.d.mts.map +1 -0
  85. package/dist/SQSConnection-BwNjUPr4.cjs.map +1 -1
  86. package/dist/SQSConnection-Eleqqre3.mjs.map +1 -1
  87. package/dist/{SQSPublisher-CdsayOLV.d.mts → SQSPublisher-BN1ds6SN.d.mts} +5 -3
  88. package/dist/SQSPublisher-BN1ds6SN.d.mts.map +1 -0
  89. package/dist/{SQSPublisher-Utb_FTe5.d.cts → SQSPublisher-DFTqwzRW.d.cts} +5 -3
  90. package/dist/SQSPublisher-DFTqwzRW.d.cts.map +1 -0
  91. package/dist/SQSPublisher-DG9o4ME3.mjs.map +1 -1
  92. package/dist/SQSPublisher-Dq5353oZ.cjs.map +1 -1
  93. package/dist/{SQSSubscriber-DZDNgLE5.cjs → SQSSubscriber-B4sRXVl6.cjs} +5 -12
  94. package/dist/SQSSubscriber-B4sRXVl6.cjs.map +1 -0
  95. package/dist/{SQSSubscriber-B6iL1EnX.d.cts → SQSSubscriber-BO2me_gs.d.cts} +4 -3
  96. package/dist/SQSSubscriber-BO2me_gs.d.cts.map +1 -0
  97. package/dist/{SQSSubscriber-CD66P7hH.mjs → SQSSubscriber-CVGhZ8Nr.mjs} +5 -12
  98. package/dist/SQSSubscriber-CVGhZ8Nr.mjs.map +1 -0
  99. package/dist/{SQSSubscriber-DBeE4XAR.d.mts → SQSSubscriber-FyZFfr2-.d.mts} +4 -3
  100. package/dist/SQSSubscriber-FyZFfr2-.d.mts.map +1 -0
  101. package/dist/Subscriber-Bd9hb_jp.mjs.map +1 -1
  102. package/dist/{Subscriber-Cff9EIpv.d.mts → Subscriber-BxT-KzFJ.d.mts} +4 -2
  103. package/dist/Subscriber-BxT-KzFJ.d.mts.map +1 -0
  104. package/dist/{Subscriber-CpAwcUzb.d.cts → Subscriber-DDD_4Nlx.d.cts} +4 -2
  105. package/dist/Subscriber-DDD_4Nlx.d.cts.map +1 -0
  106. package/dist/Subscriber-saVOWuMq.cjs.map +1 -1
  107. package/dist/Subscriber.d.cts +2 -2
  108. package/dist/Subscriber.d.mts +2 -2
  109. package/dist/basic/BasicConnection.d.cts +2 -2
  110. package/dist/basic/BasicConnection.d.mts +2 -2
  111. package/dist/basic/BasicPublisher.d.cts +3 -3
  112. package/dist/basic/BasicPublisher.d.mts +3 -3
  113. package/dist/basic/BasicSubscriber.cjs +1 -1
  114. package/dist/basic/BasicSubscriber.d.cts +3 -3
  115. package/dist/basic/BasicSubscriber.d.mts +3 -3
  116. package/dist/basic/BasicSubscriber.mjs +1 -1
  117. package/dist/basic/index.cjs +1 -1
  118. package/dist/basic/index.d.cts +4 -4
  119. package/dist/basic/index.d.mts +4 -4
  120. package/dist/basic/index.mjs +1 -1
  121. package/dist/index.d.cts +4 -4
  122. package/dist/index.d.mts +4 -4
  123. package/dist/rabbitmq/RabbitMQConnection.cjs +1 -1
  124. package/dist/rabbitmq/RabbitMQConnection.d.cts +2 -2
  125. package/dist/rabbitmq/RabbitMQConnection.d.mts +2 -2
  126. package/dist/rabbitmq/RabbitMQConnection.mjs +1 -1
  127. package/dist/rabbitmq/RabbitMQPublisher.d.cts +3 -3
  128. package/dist/rabbitmq/RabbitMQPublisher.d.mts +3 -3
  129. package/dist/rabbitmq/RabbitMQSubscriber.cjs +1 -1
  130. package/dist/rabbitmq/RabbitMQSubscriber.d.cts +3 -3
  131. package/dist/rabbitmq/RabbitMQSubscriber.d.mts +3 -3
  132. package/dist/rabbitmq/RabbitMQSubscriber.mjs +1 -1
  133. package/dist/rabbitmq/index.cjs +2 -2
  134. package/dist/rabbitmq/index.d.cts +4 -4
  135. package/dist/rabbitmq/index.d.mts +4 -4
  136. package/dist/rabbitmq/index.mjs +2 -2
  137. package/dist/sns/SNSConnection.d.cts +2 -2
  138. package/dist/sns/SNSConnection.d.mts +2 -2
  139. package/dist/sns/SNSPublisher.cjs +1 -1
  140. package/dist/sns/SNSPublisher.d.cts +3 -3
  141. package/dist/sns/SNSPublisher.d.mts +3 -3
  142. package/dist/sns/SNSPublisher.mjs +1 -1
  143. package/dist/sns/SNSSubscriber.cjs +2 -2
  144. package/dist/sns/SNSSubscriber.d.cts +3 -3
  145. package/dist/sns/SNSSubscriber.d.mts +3 -3
  146. package/dist/sns/SNSSubscriber.mjs +2 -2
  147. package/dist/sns/index.cjs +3 -3
  148. package/dist/sns/index.d.cts +4 -4
  149. package/dist/sns/index.d.mts +4 -4
  150. package/dist/sns/index.mjs +3 -3
  151. package/dist/sqs/SQSConnection.d.cts +2 -2
  152. package/dist/sqs/SQSConnection.d.mts +2 -2
  153. package/dist/sqs/SQSPublisher.d.cts +3 -3
  154. package/dist/sqs/SQSPublisher.d.mts +3 -3
  155. package/dist/sqs/SQSSubscriber.cjs +1 -1
  156. package/dist/sqs/SQSSubscriber.d.cts +3 -3
  157. package/dist/sqs/SQSSubscriber.d.mts +3 -3
  158. package/dist/sqs/SQSSubscriber.mjs +1 -1
  159. package/dist/sqs/index.cjs +1 -1
  160. package/dist/sqs/index.d.cts +4 -4
  161. package/dist/sqs/index.d.mts +4 -4
  162. package/dist/sqs/index.mjs +1 -1
  163. package/dist/types-B63qHVOG.mjs.map +1 -1
  164. package/dist/types-CvSMEO5z.cjs.map +1 -1
  165. package/dist/{types-D0g-o6wX.d.mts → types-DSVsPgKd.d.mts} +2 -1
  166. package/dist/types-DSVsPgKd.d.mts.map +1 -0
  167. package/dist/{types-DEGUg5BA.d.cts → types-Dmbp1U-6.d.cts} +2 -1
  168. package/dist/types-Dmbp1U-6.d.cts.map +1 -0
  169. package/dist/types.d.cts +1 -1
  170. package/dist/types.d.mts +1 -1
  171. package/package.json +24 -5
  172. package/src/EventConnection.ts +31 -31
  173. package/src/Publisher.ts +78 -78
  174. package/src/Subscriber.ts +91 -91
  175. package/src/__tests__/EventConnection.spec.ts +42 -0
  176. package/src/__tests__/Publisher.spec.ts +96 -0
  177. package/src/__tests__/Subscriber.spec.ts +91 -23
  178. package/src/basic/BasicConnection.ts +35 -35
  179. package/src/basic/BasicPublisher.ts +8 -8
  180. package/src/basic/BasicSubscriber.ts +13 -16
  181. package/src/basic/__tests__/BasicSubscriber.spec.ts +116 -116
  182. package/src/index.ts +13 -13
  183. package/src/rabbitmq/RabbitMQConnection.ts +139 -139
  184. package/src/rabbitmq/RabbitMQPublisher.ts +48 -48
  185. package/src/rabbitmq/RabbitMQSubscriber.ts +100 -102
  186. package/src/rabbitmq/__tests__/RabbitMQPublisher.spec.ts +364 -364
  187. package/src/rabbitmq/__tests__/RabbitMQSubscriber.spec.ts +204 -204
  188. package/src/rabbitmq/index.ts +3 -3
  189. package/src/sns/SNSConnection.ts +76 -76
  190. package/src/sns/SNSPublisher.ts +54 -56
  191. package/src/sns/SNSSubscriber.ts +187 -191
  192. package/src/sns/__tests__/SNS-SQS-Integration.spec.ts +321 -321
  193. package/src/sns/__tests__/SNSPublisher.spec.ts +449 -0
  194. package/src/sns/__tests__/SNSSubscriber.spec.ts +527 -0
  195. package/src/sns/index.ts +3 -3
  196. package/src/sqs/SQSConnection.ts +75 -75
  197. package/src/sqs/SQSPublisher.ts +93 -93
  198. package/src/sqs/SQSSubscriber.ts +157 -165
  199. package/src/sqs/__tests__/SQSPublisher.spec.ts +178 -178
  200. package/src/sqs/index.ts +3 -3
  201. package/src/types.ts +28 -29
  202. package/tsconfig.json +9 -0
  203. package/tsdown.config.ts +1 -1
  204. package/dist/BasicSubscriber-BGqv3c8x.cjs.map +0 -1
  205. package/dist/BasicSubscriber-CCKfbRMo.mjs.map +0 -1
  206. package/dist/RabbitMQConnection-kU3MvN5P.mjs.map +0 -1
  207. package/dist/RabbitMQConnection-ungB0Zl6.cjs.map +0 -1
  208. package/dist/RabbitMQSubscriber-BaXqs5nO.mjs.map +0 -1
  209. package/dist/RabbitMQSubscriber-BplEJEk8.cjs.map +0 -1
  210. package/dist/SNSPublisher-BZ6N3JI9.cjs.map +0 -1
  211. package/dist/SNSPublisher-BfWjzNiB.mjs.map +0 -1
  212. package/dist/SNSSubscriber-C9YJWa7m.mjs.map +0 -1
  213. package/dist/SNSSubscriber-UE0ia4XM.cjs.map +0 -1
  214. package/dist/SQSSubscriber-CD66P7hH.mjs.map +0 -1
  215. package/dist/SQSSubscriber-DZDNgLE5.cjs.map +0 -1
@@ -1,16 +1,16 @@
1
1
  import {
2
- CreateTopicCommand,
3
- DeleteTopicCommand,
4
- SNSClient,
5
- SubscribeCommand,
6
- UnsubscribeCommand,
2
+ CreateTopicCommand,
3
+ DeleteTopicCommand,
4
+ SNSClient,
5
+ SubscribeCommand,
6
+ UnsubscribeCommand,
7
7
  } from '@aws-sdk/client-sns';
8
8
  import {
9
- CreateQueueCommand,
10
- DeleteQueueCommand,
11
- GetQueueAttributesCommand,
12
- SQSClient,
13
- SetQueueAttributesCommand,
9
+ CreateQueueCommand,
10
+ DeleteQueueCommand,
11
+ GetQueueAttributesCommand,
12
+ SetQueueAttributesCommand,
13
+ SQSClient,
14
14
  } from '@aws-sdk/client-sqs';
15
15
  import { describe, expect, it } from 'vitest';
16
16
  import { SQSConnection } from '../../sqs/SQSConnection';
@@ -24,366 +24,366 @@ type TestMessage = PublishableMessage<'user.created' | 'user.updated', any>;
24
24
  const LOCALSTACK_ENDPOINT = 'http://localhost:4566';
25
25
  const AWS_REGION = 'us-east-1';
26
26
  const AWS_CREDENTIALS = {
27
- accessKeyId: 'test',
28
- secretAccessKey: 'test',
27
+ accessKeyId: 'test',
28
+ secretAccessKey: 'test',
29
29
  };
30
30
 
31
31
  // Helper to create a unique topic name
32
32
  const uniqueTopicName = () =>
33
- `test-topic-${Date.now()}-${Math.random().toString(36).substring(7)}`;
33
+ `test-topic-${Date.now()}-${Math.random().toString(36).substring(7)}`;
34
34
 
35
35
  // Helper to create a unique queue name
36
36
  const uniqueQueueName = () =>
37
- `test-queue-${Date.now()}-${Math.random().toString(36).substring(7)}`;
37
+ `test-queue-${Date.now()}-${Math.random().toString(36).substring(7)}`;
38
38
 
39
39
  // Helper to create an SNS topic and return its ARN
40
40
  async function createTopic(topicName: string): Promise<string> {
41
- const client = new SNSClient({
42
- region: AWS_REGION,
43
- endpoint: LOCALSTACK_ENDPOINT,
44
- credentials: AWS_CREDENTIALS,
45
- });
41
+ const client = new SNSClient({
42
+ region: AWS_REGION,
43
+ endpoint: LOCALSTACK_ENDPOINT,
44
+ credentials: AWS_CREDENTIALS,
45
+ });
46
46
 
47
- const command = new CreateTopicCommand({
48
- Name: topicName,
49
- });
47
+ const command = new CreateTopicCommand({
48
+ Name: topicName,
49
+ });
50
50
 
51
- const response = await client.send(command);
52
- client.destroy();
51
+ const response = await client.send(command);
52
+ client.destroy();
53
53
 
54
- if (!response.TopicArn) {
55
- throw new Error('Failed to create topic');
56
- }
54
+ if (!response.TopicArn) {
55
+ throw new Error('Failed to create topic');
56
+ }
57
57
 
58
- return response.TopicArn;
58
+ return response.TopicArn;
59
59
  }
60
60
 
61
61
  // Helper to delete an SNS topic
62
62
  async function deleteTopic(topicArn: string): Promise<void> {
63
- const client = new SNSClient({
64
- region: AWS_REGION,
65
- endpoint: LOCALSTACK_ENDPOINT,
66
- credentials: AWS_CREDENTIALS,
67
- });
68
-
69
- const command = new DeleteTopicCommand({
70
- TopicArn: topicArn,
71
- });
72
-
73
- await client.send(command);
74
- client.destroy();
63
+ const client = new SNSClient({
64
+ region: AWS_REGION,
65
+ endpoint: LOCALSTACK_ENDPOINT,
66
+ credentials: AWS_CREDENTIALS,
67
+ });
68
+
69
+ const command = new DeleteTopicCommand({
70
+ TopicArn: topicArn,
71
+ });
72
+
73
+ await client.send(command);
74
+ client.destroy();
75
75
  }
76
76
 
77
77
  // Helper to create an SQS queue and return its URL
78
78
  async function createQueue(queueName: string): Promise<string> {
79
- const client = new SQSClient({
80
- region: AWS_REGION,
81
- endpoint: LOCALSTACK_ENDPOINT,
82
- credentials: AWS_CREDENTIALS,
83
- });
79
+ const client = new SQSClient({
80
+ region: AWS_REGION,
81
+ endpoint: LOCALSTACK_ENDPOINT,
82
+ credentials: AWS_CREDENTIALS,
83
+ });
84
84
 
85
- const command = new CreateQueueCommand({
86
- QueueName: queueName,
87
- });
85
+ const command = new CreateQueueCommand({
86
+ QueueName: queueName,
87
+ });
88
88
 
89
- const response = await client.send(command);
90
- client.destroy();
89
+ const response = await client.send(command);
90
+ client.destroy();
91
91
 
92
- if (!response.QueueUrl) {
93
- throw new Error('Failed to create queue');
94
- }
92
+ if (!response.QueueUrl) {
93
+ throw new Error('Failed to create queue');
94
+ }
95
95
 
96
- return response.QueueUrl;
96
+ return response.QueueUrl;
97
97
  }
98
98
 
99
99
  // Helper to get queue ARN
100
100
  async function getQueueArn(queueUrl: string): Promise<string> {
101
- const client = new SQSClient({
102
- region: AWS_REGION,
103
- endpoint: LOCALSTACK_ENDPOINT,
104
- credentials: AWS_CREDENTIALS,
105
- });
106
-
107
- const command = new GetQueueAttributesCommand({
108
- QueueUrl: queueUrl,
109
- AttributeNames: ['QueueArn'],
110
- });
111
-
112
- const response = await client.send(command);
113
- client.destroy();
114
-
115
- const queueArn = response.Attributes?.QueueArn;
116
- if (!queueArn) {
117
- throw new Error('Failed to get queue ARN');
118
- }
119
-
120
- return queueArn;
101
+ const client = new SQSClient({
102
+ region: AWS_REGION,
103
+ endpoint: LOCALSTACK_ENDPOINT,
104
+ credentials: AWS_CREDENTIALS,
105
+ });
106
+
107
+ const command = new GetQueueAttributesCommand({
108
+ QueueUrl: queueUrl,
109
+ AttributeNames: ['QueueArn'],
110
+ });
111
+
112
+ const response = await client.send(command);
113
+ client.destroy();
114
+
115
+ const queueArn = response.Attributes?.QueueArn;
116
+ if (!queueArn) {
117
+ throw new Error('Failed to get queue ARN');
118
+ }
119
+
120
+ return queueArn;
121
121
  }
122
122
 
123
123
  // Helper to set queue policy to allow SNS to send messages
124
124
  async function setQueuePolicy(
125
- queueUrl: string,
126
- queueArn: string,
127
- topicArn: string,
125
+ queueUrl: string,
126
+ queueArn: string,
127
+ topicArn: string,
128
128
  ): Promise<void> {
129
- const client = new SQSClient({
130
- region: AWS_REGION,
131
- endpoint: LOCALSTACK_ENDPOINT,
132
- credentials: AWS_CREDENTIALS,
133
- });
134
-
135
- const policy = {
136
- Version: '2012-10-17',
137
- Statement: [
138
- {
139
- Effect: 'Allow',
140
- Principal: '*',
141
- Action: 'SQS:SendMessage',
142
- Resource: queueArn,
143
- Condition: {
144
- ArnEquals: {
145
- 'aws:SourceArn': topicArn,
146
- },
147
- },
148
- },
149
- ],
150
- };
151
-
152
- const command = new SetQueueAttributesCommand({
153
- QueueUrl: queueUrl,
154
- Attributes: {
155
- Policy: JSON.stringify(policy),
156
- },
157
- });
158
-
159
- await client.send(command);
160
- client.destroy();
129
+ const client = new SQSClient({
130
+ region: AWS_REGION,
131
+ endpoint: LOCALSTACK_ENDPOINT,
132
+ credentials: AWS_CREDENTIALS,
133
+ });
134
+
135
+ const policy = {
136
+ Version: '2012-10-17',
137
+ Statement: [
138
+ {
139
+ Effect: 'Allow',
140
+ Principal: '*',
141
+ Action: 'SQS:SendMessage',
142
+ Resource: queueArn,
143
+ Condition: {
144
+ ArnEquals: {
145
+ 'aws:SourceArn': topicArn,
146
+ },
147
+ },
148
+ },
149
+ ],
150
+ };
151
+
152
+ const command = new SetQueueAttributesCommand({
153
+ QueueUrl: queueUrl,
154
+ Attributes: {
155
+ Policy: JSON.stringify(policy),
156
+ },
157
+ });
158
+
159
+ await client.send(command);
160
+ client.destroy();
161
161
  }
162
162
 
163
163
  // Helper to subscribe SQS queue to SNS topic
164
164
  async function subscribeQueueToTopic(
165
- topicArn: string,
166
- queueArn: string,
165
+ topicArn: string,
166
+ queueArn: string,
167
167
  ): Promise<string> {
168
- const client = new SNSClient({
169
- region: AWS_REGION,
170
- endpoint: LOCALSTACK_ENDPOINT,
171
- credentials: AWS_CREDENTIALS,
172
- });
173
-
174
- const command = new SubscribeCommand({
175
- TopicArn: topicArn,
176
- Protocol: 'sqs',
177
- Endpoint: queueArn,
178
- });
179
-
180
- const response = await client.send(command);
181
- client.destroy();
182
-
183
- if (!response.SubscriptionArn) {
184
- throw new Error('Failed to subscribe queue to topic');
185
- }
186
-
187
- return response.SubscriptionArn;
168
+ const client = new SNSClient({
169
+ region: AWS_REGION,
170
+ endpoint: LOCALSTACK_ENDPOINT,
171
+ credentials: AWS_CREDENTIALS,
172
+ });
173
+
174
+ const command = new SubscribeCommand({
175
+ TopicArn: topicArn,
176
+ Protocol: 'sqs',
177
+ Endpoint: queueArn,
178
+ });
179
+
180
+ const response = await client.send(command);
181
+ client.destroy();
182
+
183
+ if (!response.SubscriptionArn) {
184
+ throw new Error('Failed to subscribe queue to topic');
185
+ }
186
+
187
+ return response.SubscriptionArn;
188
188
  }
189
189
 
190
190
  // Helper to unsubscribe
191
191
  async function unsubscribe(subscriptionArn: string): Promise<void> {
192
- const client = new SNSClient({
193
- region: AWS_REGION,
194
- endpoint: LOCALSTACK_ENDPOINT,
195
- credentials: AWS_CREDENTIALS,
196
- });
197
-
198
- const command = new UnsubscribeCommand({
199
- SubscriptionArn: subscriptionArn,
200
- });
201
-
202
- await client.send(command);
203
- client.destroy();
192
+ const client = new SNSClient({
193
+ region: AWS_REGION,
194
+ endpoint: LOCALSTACK_ENDPOINT,
195
+ credentials: AWS_CREDENTIALS,
196
+ });
197
+
198
+ const command = new UnsubscribeCommand({
199
+ SubscriptionArn: subscriptionArn,
200
+ });
201
+
202
+ await client.send(command);
203
+ client.destroy();
204
204
  }
205
205
 
206
206
  // Helper to delete a queue
207
207
  async function deleteQueue(queueUrl: string): Promise<void> {
208
- const client = new SQSClient({
209
- region: AWS_REGION,
210
- endpoint: LOCALSTACK_ENDPOINT,
211
- credentials: AWS_CREDENTIALS,
212
- });
213
-
214
- const command = new DeleteQueueCommand({
215
- QueueUrl: queueUrl,
216
- });
217
-
218
- await client.send(command);
219
- client.destroy();
208
+ const client = new SQSClient({
209
+ region: AWS_REGION,
210
+ endpoint: LOCALSTACK_ENDPOINT,
211
+ credentials: AWS_CREDENTIALS,
212
+ });
213
+
214
+ const command = new DeleteQueueCommand({
215
+ QueueUrl: queueUrl,
216
+ });
217
+
218
+ await client.send(command);
219
+ client.destroy();
220
220
  }
221
221
 
222
222
  describe('SNS to SQS Integration Tests', () => {
223
- it('should publish to SNS and receive via SQS subscription', async () => {
224
- const topicName = uniqueTopicName();
225
- const queueName = uniqueQueueName();
226
-
227
- const topicArn = await createTopic(topicName);
228
- const queueUrl = await createQueue(queueName);
229
- const queueArn = await getQueueArn(queueUrl);
230
-
231
- // Set queue policy to allow SNS
232
- await setQueuePolicy(queueUrl, queueArn, topicArn);
233
-
234
- // Subscribe queue to topic
235
- const subscriptionArn = await subscribeQueueToTopic(topicArn, queueArn);
236
-
237
- try {
238
- // Wait a moment for subscription to be ready
239
- await new Promise((resolve) => setTimeout(resolve, 1000));
240
-
241
- // Create SNS publisher
242
- const snsConnection = new SNSConnection({
243
- topicArn,
244
- endpoint: LOCALSTACK_ENDPOINT,
245
- region: AWS_REGION,
246
- credentials: AWS_CREDENTIALS,
247
- });
248
- await snsConnection.connect();
249
-
250
- const snsPublisher = new SNSPublisher<TestMessage>(snsConnection);
251
-
252
- // Create SQS subscriber
253
- const sqsConnection = new SQSConnection({
254
- queueUrl,
255
- endpoint: LOCALSTACK_ENDPOINT,
256
- region: AWS_REGION,
257
- credentials: AWS_CREDENTIALS,
258
- });
259
- await sqsConnection.connect();
260
-
261
- const sqsSubscriber = new SQSSubscriber<TestMessage>(sqsConnection, {
262
- waitTimeSeconds: 1,
263
- });
264
-
265
- const receivedMessages: TestMessage[] = [];
266
-
267
- await sqsSubscriber.subscribe(['user.created'], async (message) => {
268
- receivedMessages.push(message);
269
- });
270
-
271
- // Publish via SNS
272
- await snsPublisher.publish([
273
- { type: 'user.created', payload: { userId: '123' } },
274
- ]);
275
-
276
- // Wait for message to be delivered (SNS to SQS is nearly instant)
277
- await new Promise((resolve) => setTimeout(resolve, 2000));
278
-
279
- sqsSubscriber.stop();
280
-
281
- expect(receivedMessages).toHaveLength(1);
282
- expect(receivedMessages[0].type).toBe('user.created');
283
- expect(receivedMessages[0].payload.userId).toBe('123');
284
-
285
- await snsConnection.close();
286
- await sqsConnection.close();
287
- } finally {
288
- await unsubscribe(subscriptionArn);
289
- await deleteQueue(queueUrl);
290
- await deleteTopic(topicArn);
291
- }
292
- }, 15000);
293
-
294
- it('should fan out to multiple SQS queues', async () => {
295
- const topicName = uniqueTopicName();
296
- const queue1Name = uniqueQueueName();
297
- const queue2Name = uniqueQueueName();
298
-
299
- const topicArn = await createTopic(topicName);
300
- const queue1Url = await createQueue(queue1Name);
301
- const queue2Url = await createQueue(queue2Name);
302
- const queue1Arn = await getQueueArn(queue1Url);
303
- const queue2Arn = await getQueueArn(queue2Url);
304
-
305
- await setQueuePolicy(queue1Url, queue1Arn, topicArn);
306
- await setQueuePolicy(queue2Url, queue2Arn, topicArn);
307
-
308
- const subscription1Arn = await subscribeQueueToTopic(topicArn, queue1Arn);
309
- const subscription2Arn = await subscribeQueueToTopic(topicArn, queue2Arn);
310
-
311
- try {
312
- await new Promise((resolve) => setTimeout(resolve, 1000));
313
-
314
- // Create SNS publisher
315
- const snsConnection = new SNSConnection({
316
- topicArn,
317
- endpoint: LOCALSTACK_ENDPOINT,
318
- region: AWS_REGION,
319
- credentials: AWS_CREDENTIALS,
320
- });
321
- await snsConnection.connect();
322
-
323
- const snsPublisher = new SNSPublisher<TestMessage>(snsConnection);
324
-
325
- // Create SQS subscribers for both queues
326
- const sqsConnection1 = new SQSConnection({
327
- queueUrl: queue1Url,
328
- endpoint: LOCALSTACK_ENDPOINT,
329
- region: AWS_REGION,
330
- credentials: AWS_CREDENTIALS,
331
- });
332
- await sqsConnection1.connect();
333
-
334
- const sqsConnection2 = new SQSConnection({
335
- queueUrl: queue2Url,
336
- endpoint: LOCALSTACK_ENDPOINT,
337
- region: AWS_REGION,
338
- credentials: AWS_CREDENTIALS,
339
- });
340
- await sqsConnection2.connect();
341
-
342
- const sqsSubscriber1 = new SQSSubscriber<TestMessage>(sqsConnection1, {
343
- waitTimeSeconds: 1,
344
- });
345
-
346
- const sqsSubscriber2 = new SQSSubscriber<TestMessage>(sqsConnection2, {
347
- waitTimeSeconds: 1,
348
- });
349
-
350
- const queue1Messages: TestMessage[] = [];
351
- const queue2Messages: TestMessage[] = [];
352
-
353
- await sqsSubscriber1.subscribe(['user.created'], async (message) => {
354
- queue1Messages.push(message);
355
- });
356
-
357
- await sqsSubscriber2.subscribe(['user.created'], async (message) => {
358
- queue2Messages.push(message);
359
- });
360
-
361
- // Publish via SNS
362
- await snsPublisher.publish([
363
- { type: 'user.created', payload: { userId: '456' } },
364
- ]);
365
-
366
- // Wait for messages
367
- await new Promise((resolve) => setTimeout(resolve, 3000));
368
-
369
- sqsSubscriber1.stop();
370
- sqsSubscriber2.stop();
371
-
372
- // Both queues should receive the message
373
- expect(queue1Messages).toHaveLength(1);
374
- expect(queue2Messages).toHaveLength(1);
375
- expect(queue1Messages[0].payload.userId).toBe('456');
376
- expect(queue2Messages[0].payload.userId).toBe('456');
377
-
378
- await snsConnection.close();
379
- await sqsConnection1.close();
380
- await sqsConnection2.close();
381
- } finally {
382
- await unsubscribe(subscription1Arn);
383
- await unsubscribe(subscription2Arn);
384
- await deleteQueue(queue1Url);
385
- await deleteQueue(queue2Url);
386
- await deleteTopic(topicArn);
387
- }
388
- }, 20000);
223
+ it('should publish to SNS and receive via SQS subscription', async () => {
224
+ const topicName = uniqueTopicName();
225
+ const queueName = uniqueQueueName();
226
+
227
+ const topicArn = await createTopic(topicName);
228
+ const queueUrl = await createQueue(queueName);
229
+ const queueArn = await getQueueArn(queueUrl);
230
+
231
+ // Set queue policy to allow SNS
232
+ await setQueuePolicy(queueUrl, queueArn, topicArn);
233
+
234
+ // Subscribe queue to topic
235
+ const subscriptionArn = await subscribeQueueToTopic(topicArn, queueArn);
236
+
237
+ try {
238
+ // Wait a moment for subscription to be ready
239
+ await new Promise((resolve) => setTimeout(resolve, 1000));
240
+
241
+ // Create SNS publisher
242
+ const snsConnection = new SNSConnection({
243
+ topicArn,
244
+ endpoint: LOCALSTACK_ENDPOINT,
245
+ region: AWS_REGION,
246
+ credentials: AWS_CREDENTIALS,
247
+ });
248
+ await snsConnection.connect();
249
+
250
+ const snsPublisher = new SNSPublisher<TestMessage>(snsConnection);
251
+
252
+ // Create SQS subscriber
253
+ const sqsConnection = new SQSConnection({
254
+ queueUrl,
255
+ endpoint: LOCALSTACK_ENDPOINT,
256
+ region: AWS_REGION,
257
+ credentials: AWS_CREDENTIALS,
258
+ });
259
+ await sqsConnection.connect();
260
+
261
+ const sqsSubscriber = new SQSSubscriber<TestMessage>(sqsConnection, {
262
+ waitTimeSeconds: 1,
263
+ });
264
+
265
+ const receivedMessages: TestMessage[] = [];
266
+
267
+ await sqsSubscriber.subscribe(['user.created'], async (message) => {
268
+ receivedMessages.push(message);
269
+ });
270
+
271
+ // Publish via SNS
272
+ await snsPublisher.publish([
273
+ { type: 'user.created', payload: { userId: '123' } },
274
+ ]);
275
+
276
+ // Wait for message to be delivered (SNS to SQS is nearly instant)
277
+ await new Promise((resolve) => setTimeout(resolve, 2000));
278
+
279
+ sqsSubscriber.stop();
280
+
281
+ expect(receivedMessages).toHaveLength(1);
282
+ expect(receivedMessages[0].type).toBe('user.created');
283
+ expect(receivedMessages[0].payload.userId).toBe('123');
284
+
285
+ await snsConnection.close();
286
+ await sqsConnection.close();
287
+ } finally {
288
+ await unsubscribe(subscriptionArn);
289
+ await deleteQueue(queueUrl);
290
+ await deleteTopic(topicArn);
291
+ }
292
+ }, 15000);
293
+
294
+ it('should fan out to multiple SQS queues', async () => {
295
+ const topicName = uniqueTopicName();
296
+ const queue1Name = uniqueQueueName();
297
+ const queue2Name = uniqueQueueName();
298
+
299
+ const topicArn = await createTopic(topicName);
300
+ const queue1Url = await createQueue(queue1Name);
301
+ const queue2Url = await createQueue(queue2Name);
302
+ const queue1Arn = await getQueueArn(queue1Url);
303
+ const queue2Arn = await getQueueArn(queue2Url);
304
+
305
+ await setQueuePolicy(queue1Url, queue1Arn, topicArn);
306
+ await setQueuePolicy(queue2Url, queue2Arn, topicArn);
307
+
308
+ const subscription1Arn = await subscribeQueueToTopic(topicArn, queue1Arn);
309
+ const subscription2Arn = await subscribeQueueToTopic(topicArn, queue2Arn);
310
+
311
+ try {
312
+ await new Promise((resolve) => setTimeout(resolve, 1000));
313
+
314
+ // Create SNS publisher
315
+ const snsConnection = new SNSConnection({
316
+ topicArn,
317
+ endpoint: LOCALSTACK_ENDPOINT,
318
+ region: AWS_REGION,
319
+ credentials: AWS_CREDENTIALS,
320
+ });
321
+ await snsConnection.connect();
322
+
323
+ const snsPublisher = new SNSPublisher<TestMessage>(snsConnection);
324
+
325
+ // Create SQS subscribers for both queues
326
+ const sqsConnection1 = new SQSConnection({
327
+ queueUrl: queue1Url,
328
+ endpoint: LOCALSTACK_ENDPOINT,
329
+ region: AWS_REGION,
330
+ credentials: AWS_CREDENTIALS,
331
+ });
332
+ await sqsConnection1.connect();
333
+
334
+ const sqsConnection2 = new SQSConnection({
335
+ queueUrl: queue2Url,
336
+ endpoint: LOCALSTACK_ENDPOINT,
337
+ region: AWS_REGION,
338
+ credentials: AWS_CREDENTIALS,
339
+ });
340
+ await sqsConnection2.connect();
341
+
342
+ const sqsSubscriber1 = new SQSSubscriber<TestMessage>(sqsConnection1, {
343
+ waitTimeSeconds: 1,
344
+ });
345
+
346
+ const sqsSubscriber2 = new SQSSubscriber<TestMessage>(sqsConnection2, {
347
+ waitTimeSeconds: 1,
348
+ });
349
+
350
+ const queue1Messages: TestMessage[] = [];
351
+ const queue2Messages: TestMessage[] = [];
352
+
353
+ await sqsSubscriber1.subscribe(['user.created'], async (message) => {
354
+ queue1Messages.push(message);
355
+ });
356
+
357
+ await sqsSubscriber2.subscribe(['user.created'], async (message) => {
358
+ queue2Messages.push(message);
359
+ });
360
+
361
+ // Publish via SNS
362
+ await snsPublisher.publish([
363
+ { type: 'user.created', payload: { userId: '456' } },
364
+ ]);
365
+
366
+ // Wait for messages
367
+ await new Promise((resolve) => setTimeout(resolve, 3000));
368
+
369
+ sqsSubscriber1.stop();
370
+ sqsSubscriber2.stop();
371
+
372
+ // Both queues should receive the message
373
+ expect(queue1Messages).toHaveLength(1);
374
+ expect(queue2Messages).toHaveLength(1);
375
+ expect(queue1Messages[0].payload.userId).toBe('456');
376
+ expect(queue2Messages[0].payload.userId).toBe('456');
377
+
378
+ await snsConnection.close();
379
+ await sqsConnection1.close();
380
+ await sqsConnection2.close();
381
+ } finally {
382
+ await unsubscribe(subscription1Arn);
383
+ await unsubscribe(subscription2Arn);
384
+ await deleteQueue(queue1Url);
385
+ await deleteQueue(queue2Url);
386
+ await deleteTopic(topicArn);
387
+ }
388
+ }, 20000);
389
389
  });