Skip to content

Support multiple queueName entries and fix queueName extraction in serverless-offline-sqs #262

@renanlido

Description

@renanlido

Description

When using the serverless-offline-sqs plugin with an array of queueName values or with ARNs, the current implementation:

  • Fails to extract the queue name correctly due to a misplaced switch('string').
  • Only creates a single SQS listener per function, ignoring additional names passed via --queueName or defined as an array.

This issue proposes:

  1. Replacing the faulty switch with clear if/else if logic—including a guard for missing properties.
  2. Expanding SQS.create() to flatten both configured and overridden queueName arrays, creating one listener per queue.

Serverless Configuration

custom:
  serverless-offline-sqs:
    autoCreate: true
    queueName:
      - appLogsQueue
      - ediProcessingQueue
    region: ${env:AWS_REGION, 'us-east-1'}
    endpoint: ${env:AWS_ENDPOINT, 'http://localhost:4566'}
    accessKeyId: ${env:AWS_ACCESS_KEY_ID, 'develop'}
    secretAccessKey: ${env:AWS_SECRET_ACCESS_KEY, 'develop'}
    apiVersion: 2012-11-05
    skipCacheInvalidation: false

Steps to Reproduce

  1. Define two queues under queueName in serverless.yml as shown above.
  2. Run serverless offline --queueName queueA,queueB.
  3. Observe that only one listener is created, and ARNs or object definitions are not parsed correctly.

Proposed Changes

diff --git a/src/sqs-event-definition.js b/src/sqs-event-definition.js
index a38bb0c..849df93 100644
--- a/src/sqs-event-definition.js
+++ b/src/sqs-event-definition.js
@@ -10,23 +10,14 @@ class SQSEventDefinition {
-    switch ('string') {
-      case typeof rawSqsEventDefinition: {
-        queueName = extractQueueNameFromARN(rawSqsEventDefinition);
-        break;
-      }
-      case typeof rawSqsEventDefinition.arn: {
-        queueName = extractQueueNameFromARN(rawSqsEventDefinition.arn);
-        break;
-      }
-      case typeof rawSqsEventDefinition.queueName: {
-        queueName = rawSqsEventDefinition.queueName;
-        break;
-      }
-      // No default
+    if (typeof rawSqsEventDefinition === 'string') {
+      queueName = extractQueueNameFromARN(rawSqsEventDefinition);
+    } else if (rawSqsEventDefinition.arn) {
+      queueName = extractQueueNameFromARN(rawSqsEventDefinition.arn);
+    } else if (rawSqsEventDefinition.queueName) {
+      queueName = rawSqsEventDefinition.queueName;
+    } else {
+      throw new Error('SQSEventDefinition: missing queueName or arn');
     }
     this.enabled = isNil(enabled) ? true : enabled;
diff --git a/src/sqs.js b/src/sqs.js
index 82e8aab..7155739 100644
--- a/src/sqs.js
+++ b/src/sqs.js
@@ -37,7 +37,17 @@ class SQS {
-    return Promise.all(events.map(({functionKey, sqs}) => this._create(functionKey, sqs)));
+    // Flatten configured and overridden queueName arrays into individual tasks
+    const tasks = events.flatMap(({ functionKey, sqs }) => {
+      const originalNames = Array.isArray(sqs.queueName)
+        ? sqs.queueName
+        : [sqs.queueName];
+      const override = this.options.queueName;
+      const finalNames = override
+        ? Array.isArray(override)
+          ? override
+          : [override]
+        : originalNames;
+
+      return finalNames.map(name => ({ functionKey, sqs: { ...sqs, queueName: name } }));
+    });
+    return Promise.all(tasks.map(({ functionKey, sqs }) => this._create(functionKey, sqs)));

Expected Behavior

  • Both appLogsQueue and ediProcessingQueue are automatically created and bound to the function.
  • Overriding via CLI (--queueName) spawns one listener per provided name.
  • Any missing arn or queueName throws a clear, early error.

Additional Context

This change restores correct parsing of ARNs, supports array-based configuration, and fully honors CLI overrides—critical for workflows that fan out to multiple queues in local development.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions