unnbound-events 1.0.2 → 1.0.4

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
@@ -67,7 +67,7 @@ await client.http({ port: 3000 });
67
67
  export const handler = client.sqs();
68
68
 
69
69
  // SQS long-poll listener (env-driven)
70
- // Env: SQS_QUEUE_URL, AWS_REGION, AWS_SQS_ENDPOINT (optional)
70
+ // Env: UNNBOUND_SQS_QUEUE_URL (or SQS_QUEUE_URL), AWS_REGION, AWS_SQS_ENDPOINT (optional)
71
71
  await client.sqsListen();
72
72
  ```
73
73
 
@@ -94,3 +94,42 @@ interface QueueEnvelope {
94
94
  addons?: Record<string, unknown>;
95
95
  }
96
96
  ```
97
+
98
+ ## Environment Variables
99
+
100
+ ### SQS Configuration
101
+
102
+ The SDK looks for SQS configuration in this order:
103
+
104
+ 1. **Options passed to `sqsListen()` or `start()`**
105
+ 2. **Environment variables** (in order of preference):
106
+ - `UNNBOUND_SQS_QUEUE_URL` (custom Unnbound variable)
107
+ - `SQS_QUEUE_URL` (standard variable)
108
+ - `QUEUE_URL` (fallback)
109
+
110
+ **Required:**
111
+
112
+ - `UNNBOUND_SQS_QUEUE_URL` or `SQS_QUEUE_URL` - The SQS queue URL
113
+
114
+ **Optional:**
115
+
116
+ - `AWS_REGION` - AWS region (defaults to `us-east-1`)
117
+ - `AWS_SQS_ENDPOINT` - Custom SQS endpoint (for LocalStack, etc.)
118
+
119
+ **Example:**
120
+
121
+ ```bash
122
+ export UNNBOUND_SQS_QUEUE_URL="https://sqs.us-west-2.amazonaws.com/123456789012/my-queue"
123
+ export AWS_REGION="us-west-2"
124
+ ```
125
+
126
+ ### AWS Credentials
127
+
128
+ When running in ECS with a Task Role, no additional credentials are needed. The AWS SDK will automatically use the ECS Task Role credentials.
129
+
130
+ For local development or other environments, set:
131
+
132
+ ```bash
133
+ export AWS_ACCESS_KEY_ID="your-access-key"
134
+ export AWS_SECRET_ACCESS_KEY="your-secret-key"
135
+ ```
@@ -196,12 +196,20 @@ function createEventsClient() {
196
196
  }
197
197
  const env = globalThis
198
198
  .process?.env ?? {};
199
- const queueUrl = options?.queueUrl || env.SQS_QUEUE_URL || env.QUEUE_URL;
199
+ const queueUrl = options?.queueUrl || env.UNNBOUND_SQS_QUEUE_URL || env.SQS_QUEUE_URL || env.QUEUE_URL;
200
200
  if (!queueUrl || queueUrl === undefined) {
201
- throw new Error('SQS queue URL not provided. Set SQS_QUEUE_URL env or pass options.queueUrl');
201
+ throw new Error('SQS queue URL not provided. Set UNNBOUND_SQS_QUEUE_URL, SQS_QUEUE_URL env or pass options.queueUrl');
202
202
  }
203
203
  const region = options?.region || env.AWS_REGION || 'us-east-1';
204
204
  const endpoint = env.AWS_SQS_ENDPOINT || env.AWS_ENDPOINT_URL || undefined;
205
+ // Log SQS configuration for debugging
206
+ unnbound_logger_sdk_1.logger.info({
207
+ queueUrl: queueUrl.replace(/\/[^/]+$/, '/***'), // Mask queue name for security
208
+ region,
209
+ endpoint,
210
+ hasCredentials: !!(env.AWS_ACCESS_KEY_ID || env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI),
211
+ executionEnv: env.AWS_EXECUTION_ENV,
212
+ }, 'Starting SQS listener');
205
213
  const waitTimeSeconds = options?.waitTimeSeconds ?? 10;
206
214
  const maxMessages = options?.maxMessages ?? 10;
207
215
  const visibilityTimeout = options?.visibilityTimeoutSeconds;
@@ -247,11 +255,31 @@ function createEventsClient() {
247
255
  // Start async loop without awaiting
248
256
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
249
257
  loop();
250
- return Promise.resolve({
251
- stop() {
252
- stopped = true;
253
- return Promise.resolve();
254
- },
258
+ // Test the SQS connection immediately to catch early errors
259
+ return new Promise((resolve, reject) => {
260
+ const testConnection = async () => {
261
+ try {
262
+ const testParams = {
263
+ QueueUrl: queueUrl,
264
+ MaxNumberOfMessages: 1,
265
+ WaitTimeSeconds: 0, // Don't wait, just test connection
266
+ };
267
+ await sqs.send(new awsSqs.ReceiveMessageCommand(testParams));
268
+ unnbound_logger_sdk_1.logger.info('SQS connection test successful');
269
+ resolve({
270
+ stop() {
271
+ stopped = true;
272
+ return Promise.resolve();
273
+ },
274
+ });
275
+ }
276
+ catch (error) {
277
+ unnbound_logger_sdk_1.logger.error({ err: error, queueUrl: queueUrl.replace(/\/[^/]+$/, '/***') }, 'SQS connection test failed');
278
+ reject(error instanceof Error ? error : new Error(String(error)));
279
+ }
280
+ };
281
+ // Run connection test after a short delay to allow the async loop to start
282
+ setTimeout(testConnection, 100);
255
283
  });
256
284
  },
257
285
  async start(options) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unnbound-events",
3
3
  "description": "Unified events SDK to handle HTTP routes and SQS messages with a single routing API.",
4
- "version": "1.0.2",
4
+ "version": "1.0.4",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {