@adobe-commerce/aio-toolkit 1.2.2 → 1.2.3

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/CHANGELOG.md CHANGED
@@ -5,6 +5,61 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.2.3] - 2026-04-01
9
+
10
+ ### ✨ Features
11
+
12
+ - **feat(integration): Add `RabbitMQClient` — push-based AMQP consumer and publisher**
13
+
14
+ New `RabbitMQClient` class in `src/integration/rabbit-mq-client` provides a
15
+ clean, typed interface for consuming and publishing messages via AMQP (RabbitMQ).
16
+
17
+ **`consume(queueName, options, handler)`**
18
+ - Checks queue depth via `channel.checkQueue` — skips immediately when empty
19
+ - Sets `channel.prefetch(maxParallel)` for broker-side concurrency control
20
+ - Processes `effectiveBatch = min(batchSize, messageCount)` messages
21
+ - Acks on successful handler execution; nacks on failure (requeue configurable)
22
+ - Optional exchange assertion and queue binding via `options.exchange`
23
+ - Returns `ConsumeStats` — consumed, acked, nacked counts plus per-failure details
24
+
25
+ **`publish(queueName, payloads)`**
26
+ - Asserts queue and sends each payload via `sendToQueue` with `persistent: true`
27
+ - Records write-buffer-full (`sendToQueue` returns `false`) and thrown errors
28
+ - Returns `PublishStats` — published and failed counts plus per-failure details
29
+
30
+ Both methods open a dedicated connection per call and always close channel and
31
+ connection in a `finally` block.
32
+
33
+ **Exported types** (from `rabbit-mq-client/types`):
34
+ `RabbitMQCredentials`, `RabbitMQConsumeOptions`, `MessageHandler`,
35
+ `ConsumeStats`, `PublishStats`
36
+
37
+ **Note:** `batchSize` and `maxParallel` are required in `RabbitMQConsumeOptions`
38
+ — the caller must choose appropriate limits for their workload.
39
+
40
+ ### 🐛 Bug Fixes
41
+
42
+ - **fix(abdb): Preserve `error.cause` on `AbdbCollection` thrown errors**
43
+
44
+ `run()` now assigns `.cause` to each re-thrown `Error` so callers can access
45
+ the original error via `err.cause`. Previously the root cause was silently
46
+ discarded. Assignment is done via `(err as any).cause` for compatibility with
47
+ the ES2020 TypeScript target (the ES2022 `Error(msg, { cause })` constructor
48
+ overload is not available in ES2020 lib typings).
49
+
50
+ - **fix(abdb): Guard `DbError instanceof` check against undefined export**
51
+
52
+ The `DbError` branch now uses `DbError && error instanceof DbError` so the
53
+ code does not throw a `TypeError` in environments where `@adobe/aio-lib-db`
54
+ does not export `DbError` at runtime. Unrecognised errors fall through to the
55
+ `unexpected error` path as expected.
56
+
57
+ - **fix(abdb): Correct file header comment in `adobe-aio-lib-db.d.ts`**
58
+
59
+ The comment incorrectly read `@adobe/aio-lib-ims`; updated to `@adobe/aio-lib-db`.
60
+
61
+ ---
62
+
8
63
  ## [1.2.2] - 2026-04-01
9
64
 
10
65
  ### 🐛 Bug Fixes
package/README.md CHANGED
@@ -1508,6 +1508,107 @@ if (directInfo.isValid) {
1508
1508
  - `extract(headersOrParams)` - Extracts Bearer token from headers or OpenWhisk params
1509
1509
  - `info(token)` - Analyzes token string and returns validation/expiry details
1510
1510
 
1511
+ #### `RabbitMQClient`
1512
+ Push-based AMQP consumer and publisher for RabbitMQ. Manages the full connection lifecycle per call (connect → channel → close) and exposes a clean, typed interface without exposing raw AMQP primitives to the caller.
1513
+
1514
+ **Installation**
1515
+ ```bash
1516
+ npm install amqplib
1517
+ ```
1518
+
1519
+ **Basic Usage**
1520
+ ```typescript
1521
+ const { RabbitMQClient } = require('@adobe-commerce/aio-toolkit');
1522
+
1523
+ const client = new RabbitMQClient({
1524
+ host: 'rabbitmq.example.com',
1525
+ port: '5672',
1526
+ username: 'user',
1527
+ password: 'secret',
1528
+ vhost: '/',
1529
+ secure: false, // set true to use amqps://
1530
+ });
1531
+ ```
1532
+
1533
+ **Consuming messages**
1534
+ ```typescript
1535
+ const stats = await client.consume(
1536
+ 'orders-queue',
1537
+ { batchSize: 100, maxParallel: 10 },
1538
+ async (queueName, content) => {
1539
+ const order = JSON.parse(content);
1540
+ await processOrder(order);
1541
+ }
1542
+ );
1543
+
1544
+ console.log(`consumed=${stats.consumed} acked=${stats.acked} nacked=${stats.nacked}`);
1545
+ if (stats.errors.length) {
1546
+ console.error('Failed messages:', stats.errors);
1547
+ }
1548
+ ```
1549
+
1550
+ **Consuming with exchange binding**
1551
+ ```typescript
1552
+ const stats = await client.consume(
1553
+ 'orders-queue',
1554
+ {
1555
+ batchSize: 50,
1556
+ maxParallel: 5,
1557
+ exchange: 'orders-exchange', // asserts exchange + binds queue before consuming
1558
+ nackRequeue: false, // dead-letter failed messages instead of requeueing
1559
+ },
1560
+ async (queueName, content) => {
1561
+ await processOrder(JSON.parse(content));
1562
+ }
1563
+ );
1564
+ ```
1565
+
1566
+ **Publishing messages**
1567
+ ```typescript
1568
+ const payloads = orders.map(o => JSON.stringify(o));
1569
+ const stats = await client.publish('orders-queue', payloads);
1570
+
1571
+ console.log(`published=${stats.published} failed=${stats.failed}`);
1572
+ if (stats.errors.length) {
1573
+ console.error('Failed payloads:', stats.errors);
1574
+ }
1575
+ ```
1576
+
1577
+ **API Reference**
1578
+
1579
+ | Method | Description | Returns |
1580
+ |---|---|---|
1581
+ | `consume(queueName, options, handler)` | Checks queue depth, sets prefetch, and push-consumes up to `batchSize` messages | `Promise<ConsumeStats>` |
1582
+ | `publish(queueName, payloads)` | Asserts queue and enqueues each payload as a persistent message | `Promise<PublishStats>` |
1583
+
1584
+ **`RabbitMQConsumeOptions`**
1585
+
1586
+ | Field | Type | Required | Description |
1587
+ |---|---|---|---|
1588
+ | `batchSize` | `number` | ✅ | Maximum number of messages to process in this call |
1589
+ | `maxParallel` | `number` | ✅ | Max unacked messages in-flight at once (broker-side prefetch) |
1590
+ | `nackRequeue` | `boolean` | — | Requeue on nack (default: `true`) |
1591
+ | `exchange` | `string` | — | If set, asserts a `direct` exchange and binds the queue before consuming |
1592
+
1593
+ **`ConsumeStats`**
1594
+
1595
+ | Field | Type | Description |
1596
+ |---|---|---|
1597
+ | `consumed` | `number` | Total messages received from the broker |
1598
+ | `acked` | `number` | Messages successfully processed and acked |
1599
+ | `nacked` | `number` | Messages that failed handler and were nacked |
1600
+ | `errors` | `Array<{ content: string; error: unknown }>` | Per-failure details |
1601
+
1602
+ **`PublishStats`**
1603
+
1604
+ | Field | Type | Description |
1605
+ |---|---|---|
1606
+ | `published` | `number` | Messages successfully enqueued |
1607
+ | `failed` | `number` | Messages that could not be enqueued |
1608
+ | `errors` | `Array<{ payload: string; error: unknown }>` | Per-failure details (buffer full or thrown) |
1609
+
1610
+ ---
1611
+
1511
1612
  #### `InfiniteLoopBreaker`
1512
1613
  Detect and prevent infinite loops in event-driven applications.
1513
1614
 
package/dist/index.d.mts CHANGED
@@ -788,6 +788,50 @@ declare class OnboardCommerce {
788
788
  private logEventSubscriptionSummary;
789
789
  }
790
790
 
791
+ type RabbitMQCredentials = {
792
+ host: string;
793
+ port: string;
794
+ username: string;
795
+ password: string;
796
+ vhost: string;
797
+ secure?: boolean;
798
+ };
799
+ type RabbitMQConsumeOptions = {
800
+ batchSize: number;
801
+ maxParallel: number;
802
+ nackRequeue?: boolean;
803
+ exchange?: string;
804
+ };
805
+ type MessageHandler = (queueName: string, content: string) => Promise<void> | void;
806
+ type ConsumeStats = {
807
+ consumed: number;
808
+ acked: number;
809
+ nacked: number;
810
+ errors: Array<{
811
+ content: string;
812
+ error: unknown;
813
+ }>;
814
+ };
815
+ type PublishStats = {
816
+ published: number;
817
+ failed: number;
818
+ errors: Array<{
819
+ payload: string;
820
+ error: unknown;
821
+ }>;
822
+ };
823
+
824
+ declare class RabbitMQClient {
825
+ private readonly credentials;
826
+ constructor(credentials: RabbitMQCredentials);
827
+ consume(queueName: string, options: RabbitMQConsumeOptions, handler: MessageHandler): Promise<ConsumeStats>;
828
+ publish(queueName: string, payloads: string[]): Promise<PublishStats>;
829
+ private publishBatch;
830
+ private buildConnectionUrl;
831
+ private processBatch;
832
+ private processMessage;
833
+ }
834
+
791
835
  declare class AdobeAuth {
792
836
  static getToken(clientId: string, clientSecret: string, technicalAccountId: string, technicalAccountEmail: string, imsOrgId: string, scopes: string[], currentContext?: string): Promise<string>;
793
837
  }
@@ -1083,4 +1127,4 @@ declare class AdminUiSdk {
1083
1127
  getRegistration(): AdminUiSdkRegistration;
1084
1128
  }
1085
1129
 
1086
- export { AbdbCollection, type AbdbCollectionCallback, AbdbColumn, type AbdbColumnJson, type AbdbColumnOptions, AbdbColumnType, type AbdbRecord, AbdbRepository, type AbdbRepositoryFilter, type AbdbRunCallback, type AddColumnOptions, AdminUiSdk, type AdminUiSdkRegistration, AdobeAuth, AdobeCommerceClient, type AdobeIMSConfig, type BaseTelemetry, type BaseTelemetryValidator, BasicAuthConnection, BearerToken, type BearerTokenInfo, type CommerceEvent, type CommerceEventConfig, type CommerceEventField, type Connection, type CreateEventResult, CreateEvents, type CreateProviderParams, type CreateProviderResult, type CreateRegistrationResult, CreateRegistrations, type ErrorResponse, EventConsumerAction, type EventData, type EventMetadata, type EventMetadataInputModel, type EventMetadataListResponse, EventMetadataManager, type ExtendedRequestError, type FileMetadata, type FileRecord, FileRepository, GenerateBasicAuthToken, type GetProviderQueryParams, type GetRegistrationQueryParams, GraphQlAction, type HALLink, type Headers, HttpMethod, HttpStatus, IOEventsApiError, type IOEventsError, ImsConnection, ImsToken, type ImsTokenResult, InfiniteLoopBreaker, type InfiniteLoopData, IoEventsGlobals, JsonMessageProcessor, type ListProvidersQueryParams, type ListRegistrationQueryParams, type MenuItem, Oauth1aConnection, OnboardCommerce, type OnboardCommerceConfig, type OnboardCommerceResult, OnboardEvents, type OnboardEventsInput, type OnboardEventsResponse, OnboardEvents as OnboardIOEvents, Openwhisk, OpenwhiskAction, type OpenwhiskConfig, type Page, Parameters, type Provider, type ProviderInputModel, ProviderManager, PublishEvent, type PublishEventResult, type Registration, type RegistrationCreateModel, type RegistrationListResponse, RegistrationManager, RestClient, RuntimeAction, RuntimeActionResponse, type RuntimeActionResponseType, RuntimeApiGatewayService, ShippingCarrier, type ShippingCarrierData, ShippingCarrierMethod, type ShippingCarrierMethodAdditionalData, type ShippingCarrierMethodData, ShippingCarrierResponse, SignatureVerification, SuccessChecker, type SuccessResponse, Telemetry, TelemetryInputError, type TokenResult, Validator, WebhookAction, type WebhookActionAddResponse, type WebhookActionExceptionResponse, WebhookActionOperation, type WebhookActionRemoveResponse, type WebhookActionReplaceResponse, WebhookActionResponse, type WebhookActionResponseType, type WebhookActionSuccessResponse, type WorkspaceConfig };
1130
+ export { AbdbCollection, type AbdbCollectionCallback, AbdbColumn, type AbdbColumnJson, type AbdbColumnOptions, AbdbColumnType, type AbdbRecord, AbdbRepository, type AbdbRepositoryFilter, type AbdbRunCallback, type AddColumnOptions, AdminUiSdk, type AdminUiSdkRegistration, AdobeAuth, AdobeCommerceClient, type AdobeIMSConfig, type BaseTelemetry, type BaseTelemetryValidator, BasicAuthConnection, BearerToken, type BearerTokenInfo, type CommerceEvent, type CommerceEventConfig, type CommerceEventField, type Connection, type ConsumeStats, type CreateEventResult, CreateEvents, type CreateProviderParams, type CreateProviderResult, type CreateRegistrationResult, CreateRegistrations, type ErrorResponse, EventConsumerAction, type EventData, type EventMetadata, type EventMetadataInputModel, type EventMetadataListResponse, EventMetadataManager, type ExtendedRequestError, type FileMetadata, type FileRecord, FileRepository, GenerateBasicAuthToken, type GetProviderQueryParams, type GetRegistrationQueryParams, GraphQlAction, type HALLink, type Headers, HttpMethod, HttpStatus, IOEventsApiError, type IOEventsError, ImsConnection, ImsToken, type ImsTokenResult, InfiniteLoopBreaker, type InfiniteLoopData, IoEventsGlobals, JsonMessageProcessor, type ListProvidersQueryParams, type ListRegistrationQueryParams, type MenuItem, type MessageHandler, Oauth1aConnection, OnboardCommerce, type OnboardCommerceConfig, type OnboardCommerceResult, OnboardEvents, type OnboardEventsInput, type OnboardEventsResponse, OnboardEvents as OnboardIOEvents, Openwhisk, OpenwhiskAction, type OpenwhiskConfig, type Page, Parameters, type Provider, type ProviderInputModel, ProviderManager, PublishEvent, type PublishEventResult, type PublishStats, RabbitMQClient, type RabbitMQConsumeOptions, type RabbitMQCredentials, type Registration, type RegistrationCreateModel, type RegistrationListResponse, RegistrationManager, RestClient, RuntimeAction, RuntimeActionResponse, type RuntimeActionResponseType, RuntimeApiGatewayService, ShippingCarrier, type ShippingCarrierData, ShippingCarrierMethod, type ShippingCarrierMethodAdditionalData, type ShippingCarrierMethodData, ShippingCarrierResponse, SignatureVerification, SuccessChecker, type SuccessResponse, Telemetry, TelemetryInputError, type TokenResult, Validator, WebhookAction, type WebhookActionAddResponse, type WebhookActionExceptionResponse, WebhookActionOperation, type WebhookActionRemoveResponse, type WebhookActionReplaceResponse, WebhookActionResponse, type WebhookActionResponseType, type WebhookActionSuccessResponse, type WorkspaceConfig };
package/dist/index.d.ts CHANGED
@@ -788,6 +788,50 @@ declare class OnboardCommerce {
788
788
  private logEventSubscriptionSummary;
789
789
  }
790
790
 
791
+ type RabbitMQCredentials = {
792
+ host: string;
793
+ port: string;
794
+ username: string;
795
+ password: string;
796
+ vhost: string;
797
+ secure?: boolean;
798
+ };
799
+ type RabbitMQConsumeOptions = {
800
+ batchSize: number;
801
+ maxParallel: number;
802
+ nackRequeue?: boolean;
803
+ exchange?: string;
804
+ };
805
+ type MessageHandler = (queueName: string, content: string) => Promise<void> | void;
806
+ type ConsumeStats = {
807
+ consumed: number;
808
+ acked: number;
809
+ nacked: number;
810
+ errors: Array<{
811
+ content: string;
812
+ error: unknown;
813
+ }>;
814
+ };
815
+ type PublishStats = {
816
+ published: number;
817
+ failed: number;
818
+ errors: Array<{
819
+ payload: string;
820
+ error: unknown;
821
+ }>;
822
+ };
823
+
824
+ declare class RabbitMQClient {
825
+ private readonly credentials;
826
+ constructor(credentials: RabbitMQCredentials);
827
+ consume(queueName: string, options: RabbitMQConsumeOptions, handler: MessageHandler): Promise<ConsumeStats>;
828
+ publish(queueName: string, payloads: string[]): Promise<PublishStats>;
829
+ private publishBatch;
830
+ private buildConnectionUrl;
831
+ private processBatch;
832
+ private processMessage;
833
+ }
834
+
791
835
  declare class AdobeAuth {
792
836
  static getToken(clientId: string, clientSecret: string, technicalAccountId: string, technicalAccountEmail: string, imsOrgId: string, scopes: string[], currentContext?: string): Promise<string>;
793
837
  }
@@ -1083,4 +1127,4 @@ declare class AdminUiSdk {
1083
1127
  getRegistration(): AdminUiSdkRegistration;
1084
1128
  }
1085
1129
 
1086
- export { AbdbCollection, type AbdbCollectionCallback, AbdbColumn, type AbdbColumnJson, type AbdbColumnOptions, AbdbColumnType, type AbdbRecord, AbdbRepository, type AbdbRepositoryFilter, type AbdbRunCallback, type AddColumnOptions, AdminUiSdk, type AdminUiSdkRegistration, AdobeAuth, AdobeCommerceClient, type AdobeIMSConfig, type BaseTelemetry, type BaseTelemetryValidator, BasicAuthConnection, BearerToken, type BearerTokenInfo, type CommerceEvent, type CommerceEventConfig, type CommerceEventField, type Connection, type CreateEventResult, CreateEvents, type CreateProviderParams, type CreateProviderResult, type CreateRegistrationResult, CreateRegistrations, type ErrorResponse, EventConsumerAction, type EventData, type EventMetadata, type EventMetadataInputModel, type EventMetadataListResponse, EventMetadataManager, type ExtendedRequestError, type FileMetadata, type FileRecord, FileRepository, GenerateBasicAuthToken, type GetProviderQueryParams, type GetRegistrationQueryParams, GraphQlAction, type HALLink, type Headers, HttpMethod, HttpStatus, IOEventsApiError, type IOEventsError, ImsConnection, ImsToken, type ImsTokenResult, InfiniteLoopBreaker, type InfiniteLoopData, IoEventsGlobals, JsonMessageProcessor, type ListProvidersQueryParams, type ListRegistrationQueryParams, type MenuItem, Oauth1aConnection, OnboardCommerce, type OnboardCommerceConfig, type OnboardCommerceResult, OnboardEvents, type OnboardEventsInput, type OnboardEventsResponse, OnboardEvents as OnboardIOEvents, Openwhisk, OpenwhiskAction, type OpenwhiskConfig, type Page, Parameters, type Provider, type ProviderInputModel, ProviderManager, PublishEvent, type PublishEventResult, type Registration, type RegistrationCreateModel, type RegistrationListResponse, RegistrationManager, RestClient, RuntimeAction, RuntimeActionResponse, type RuntimeActionResponseType, RuntimeApiGatewayService, ShippingCarrier, type ShippingCarrierData, ShippingCarrierMethod, type ShippingCarrierMethodAdditionalData, type ShippingCarrierMethodData, ShippingCarrierResponse, SignatureVerification, SuccessChecker, type SuccessResponse, Telemetry, TelemetryInputError, type TokenResult, Validator, WebhookAction, type WebhookActionAddResponse, type WebhookActionExceptionResponse, WebhookActionOperation, type WebhookActionRemoveResponse, type WebhookActionReplaceResponse, WebhookActionResponse, type WebhookActionResponseType, type WebhookActionSuccessResponse, type WorkspaceConfig };
1130
+ export { AbdbCollection, type AbdbCollectionCallback, AbdbColumn, type AbdbColumnJson, type AbdbColumnOptions, AbdbColumnType, type AbdbRecord, AbdbRepository, type AbdbRepositoryFilter, type AbdbRunCallback, type AddColumnOptions, AdminUiSdk, type AdminUiSdkRegistration, AdobeAuth, AdobeCommerceClient, type AdobeIMSConfig, type BaseTelemetry, type BaseTelemetryValidator, BasicAuthConnection, BearerToken, type BearerTokenInfo, type CommerceEvent, type CommerceEventConfig, type CommerceEventField, type Connection, type ConsumeStats, type CreateEventResult, CreateEvents, type CreateProviderParams, type CreateProviderResult, type CreateRegistrationResult, CreateRegistrations, type ErrorResponse, EventConsumerAction, type EventData, type EventMetadata, type EventMetadataInputModel, type EventMetadataListResponse, EventMetadataManager, type ExtendedRequestError, type FileMetadata, type FileRecord, FileRepository, GenerateBasicAuthToken, type GetProviderQueryParams, type GetRegistrationQueryParams, GraphQlAction, type HALLink, type Headers, HttpMethod, HttpStatus, IOEventsApiError, type IOEventsError, ImsConnection, ImsToken, type ImsTokenResult, InfiniteLoopBreaker, type InfiniteLoopData, IoEventsGlobals, JsonMessageProcessor, type ListProvidersQueryParams, type ListRegistrationQueryParams, type MenuItem, type MessageHandler, Oauth1aConnection, OnboardCommerce, type OnboardCommerceConfig, type OnboardCommerceResult, OnboardEvents, type OnboardEventsInput, type OnboardEventsResponse, OnboardEvents as OnboardIOEvents, Openwhisk, OpenwhiskAction, type OpenwhiskConfig, type Page, Parameters, type Provider, type ProviderInputModel, ProviderManager, PublishEvent, type PublishEventResult, type PublishStats, RabbitMQClient, type RabbitMQConsumeOptions, type RabbitMQCredentials, type Registration, type RegistrationCreateModel, type RegistrationListResponse, RegistrationManager, RestClient, RuntimeAction, RuntimeActionResponse, type RuntimeActionResponseType, RuntimeApiGatewayService, ShippingCarrier, type ShippingCarrierData, ShippingCarrierMethod, type ShippingCarrierMethodAdditionalData, type ShippingCarrierMethodData, ShippingCarrierResponse, SignatureVerification, SuccessChecker, type SuccessResponse, Telemetry, TelemetryInputError, type TokenResult, Validator, WebhookAction, type WebhookActionAddResponse, type WebhookActionExceptionResponse, WebhookActionOperation, type WebhookActionRemoveResponse, type WebhookActionReplaceResponse, WebhookActionResponse, type WebhookActionResponseType, type WebhookActionSuccessResponse, type WorkspaceConfig };
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ __export(index_exports, {
64
64
  Parameters: () => parameters_default,
65
65
  ProviderManager: () => provider_default,
66
66
  PublishEvent: () => publish_event_default,
67
+ RabbitMQClient: () => rabbit_mq_client_default,
67
68
  RegistrationManager: () => registration_default,
68
69
  RestClient: () => rest_client_default,
69
70
  RuntimeAction: () => runtime_action_default,
@@ -5946,11 +5947,15 @@ var _AbdbCollection = class _AbdbCollection {
5946
5947
  const collection = await client.collection(this._name);
5947
5948
  return await callback(collection, client);
5948
5949
  } catch (error) {
5949
- if (error instanceof import_aio_lib_db.DbError) {
5950
- throw new Error(`AbdbCollection: database error: ${error.message}`);
5950
+ if (import_aio_lib_db.DbError && error instanceof import_aio_lib_db.DbError) {
5951
+ const dbErr = new Error(`AbdbCollection: database error: ${error.message}`);
5952
+ dbErr.cause = error;
5953
+ throw dbErr;
5951
5954
  }
5952
5955
  const detail = error instanceof Error ? error.message : String(error);
5953
- throw new Error(`AbdbCollection: unexpected error: ${detail}`);
5956
+ const unexpectedErr = new Error(`AbdbCollection: unexpected error: ${detail}`);
5957
+ unexpectedErr.cause = error;
5958
+ throw unexpectedErr;
5954
5959
  } finally {
5955
5960
  await client?.close();
5956
5961
  }
@@ -11757,6 +11762,185 @@ __name(_OnboardCommerce, "OnboardCommerce");
11757
11762
  var OnboardCommerce = _OnboardCommerce;
11758
11763
  var onboard_commerce_default = OnboardCommerce;
11759
11764
 
11765
+ // src/integration/rabbit-mq-client/index.ts
11766
+ var import_amqplib = __toESM(require("amqplib"));
11767
+ var _RabbitMQClient = class _RabbitMQClient {
11768
+ /**
11769
+ * @param credentials - AMQP connection credentials (host, port, username, password, vhost).
11770
+ */
11771
+ constructor(credentials) {
11772
+ this.credentials = credentials;
11773
+ }
11774
+ /**
11775
+ * Opens an AMQP connection, checks queue depth, sets prefetch for concurrency control,
11776
+ * and starts a push consumer. The broker delivers at most `maxParallel` unacked messages
11777
+ * at a time, so processing concurrency is naturally bounded without a separate semaphore.
11778
+ * The consumer is cancelled once `effectiveBatch = min(batchSize, messageCount)` messages
11779
+ * are received and processed. The connection is always closed in a `finally` block.
11780
+ *
11781
+ * @param queueName - Name of the queue to consume from.
11782
+ * @param options - Consume configuration (batchSize, maxParallel, nackRequeue, exchange).
11783
+ * @param handler - Callback invoked with the queue name and decoded string content of each message.
11784
+ * @returns Counts of consumed, acked, and nacked messages; plus per-failure details in `errors`.
11785
+ * @throws Propagates connection, exchange-assertion, or queue-assertion errors to the caller.
11786
+ */
11787
+ async consume(queueName, options, handler) {
11788
+ const connection = await import_amqplib.default.connect(this.buildConnectionUrl());
11789
+ let channel;
11790
+ try {
11791
+ channel = await connection.createChannel();
11792
+ if (options.exchange) {
11793
+ await channel.assertExchange(options.exchange, "direct", { durable: true });
11794
+ await channel.assertQueue(queueName, { durable: true });
11795
+ await channel.bindQueue(queueName, options.exchange, queueName);
11796
+ } else {
11797
+ await channel.assertQueue(queueName, { durable: true });
11798
+ }
11799
+ return await this.processBatch(channel, queueName, options, handler);
11800
+ } finally {
11801
+ await channel?.close();
11802
+ await connection.close();
11803
+ }
11804
+ }
11805
+ /**
11806
+ * Opens an AMQP connection, asserts the queue, and enqueues each payload in `payloads`.
11807
+ * Each payload is sent as a persistent message via `sendToQueue`. If the write buffer is
11808
+ * full (`sendToQueue` returns `false`) or the call throws, the payload is recorded in
11809
+ * `stats.errors` and counted as failed. The connection is always closed in a `finally`
11810
+ * block regardless of outcome.
11811
+ *
11812
+ * @param queueName - Name of the queue to publish to.
11813
+ * @param payloads - Array of string payloads to enqueue.
11814
+ * @returns Counts of published and failed messages; plus per-failure details in `errors`.
11815
+ * @throws Propagates connection or queue-assertion errors to the caller.
11816
+ */
11817
+ async publish(queueName, payloads) {
11818
+ const connection = await import_amqplib.default.connect(this.buildConnectionUrl());
11819
+ let channel;
11820
+ try {
11821
+ channel = await connection.createChannel();
11822
+ await channel.assertQueue(queueName, { durable: true });
11823
+ return this.publishBatch(channel, queueName, payloads);
11824
+ } finally {
11825
+ await channel?.close();
11826
+ await connection.close();
11827
+ }
11828
+ }
11829
+ /**
11830
+ * Sends each payload to the queue via `sendToQueue`. Tracks published and failed counts.
11831
+ * A payload is considered failed when `sendToQueue` returns `false` (write buffer full)
11832
+ * or throws an error.
11833
+ */
11834
+ publishBatch(channel, queueName, payloads) {
11835
+ const stats = { published: 0, failed: 0, errors: [] };
11836
+ for (const payload of payloads) {
11837
+ try {
11838
+ const sent = channel.sendToQueue(queueName, Buffer.from(payload), { persistent: true });
11839
+ if (sent) {
11840
+ stats.published++;
11841
+ } else {
11842
+ stats.failed++;
11843
+ stats.errors.push({ payload, error: new Error("Write buffer full") });
11844
+ }
11845
+ } catch (error) {
11846
+ stats.failed++;
11847
+ stats.errors.push({ payload, error });
11848
+ }
11849
+ }
11850
+ return stats;
11851
+ }
11852
+ /**
11853
+ * Builds the AMQP connection URL from the stored credentials.
11854
+ * Uses `amqps://` when `secure` is true, `amqp://` otherwise.
11855
+ * Username, password, and vhost are percent-encoded to handle special characters.
11856
+ */
11857
+ buildConnectionUrl() {
11858
+ const { host, port, username, password, vhost, secure = false } = this.credentials;
11859
+ const protocol = secure ? "amqps" : "amqp";
11860
+ return `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${host}:${port}/${encodeURIComponent(vhost)}`;
11861
+ }
11862
+ /**
11863
+ * Checks queue depth via `channel.checkQueue`, then sets `channel.prefetch(maxParallel)`
11864
+ * for broker-side concurrency control. Registers a push consumer that receives
11865
+ * `effectiveBatch = min(batchSize, messageCount)` messages. The Promise resolves after
11866
+ * `channel.consume` setup completes and all in-flight handlers have settled.
11867
+ *
11868
+ * Because the broker delivers at most `maxParallel` unacked messages at a time, processing
11869
+ * concurrency is bounded without a separate semaphore — each ack/nack releases a slot.
11870
+ */
11871
+ async processBatch(channel, queueName, options, handler) {
11872
+ const stats = { consumed: 0, acked: 0, nacked: 0, errors: [] };
11873
+ const maxParallel = Math.floor(options.maxParallel);
11874
+ const batchSize = Math.floor(options.batchSize);
11875
+ const { messageCount } = await channel.checkQueue(queueName);
11876
+ if (messageCount === 0) return stats;
11877
+ const effectiveBatch = Math.min(batchSize, messageCount);
11878
+ await channel.prefetch(maxParallel);
11879
+ return new Promise((resolve, reject) => {
11880
+ let consumerTag = "";
11881
+ let cancelRequested = false;
11882
+ let received = 0;
11883
+ let pending = 0;
11884
+ let setupDone = false;
11885
+ const maybeResolve = /* @__PURE__ */ __name(() => {
11886
+ if ((received >= effectiveBatch || cancelRequested) && pending === 0 && setupDone) {
11887
+ resolve(stats);
11888
+ }
11889
+ }, "maybeResolve");
11890
+ const msgCallback = /* @__PURE__ */ __name(async (msg) => {
11891
+ if (!msg || received >= effectiveBatch) return;
11892
+ received++;
11893
+ stats.consumed++;
11894
+ pending++;
11895
+ if (received >= effectiveBatch) {
11896
+ cancelRequested = true;
11897
+ if (consumerTag) {
11898
+ channel.cancel(consumerTag).catch(reject);
11899
+ }
11900
+ }
11901
+ await this.processMessage(channel, queueName, msg, stats, options, handler);
11902
+ pending--;
11903
+ maybeResolve();
11904
+ }, "msgCallback");
11905
+ channel.consume(queueName, msgCallback, { noAck: false }).then(async ({ consumerTag: tag }) => {
11906
+ consumerTag = tag;
11907
+ setupDone = true;
11908
+ if (cancelRequested) {
11909
+ channel.cancel(tag).catch(reject);
11910
+ } else if (received === 0) {
11911
+ const { messageCount: remaining } = await channel.checkQueue(queueName);
11912
+ if (remaining === 0) {
11913
+ cancelRequested = true;
11914
+ channel.cancel(tag).catch(reject);
11915
+ }
11916
+ }
11917
+ maybeResolve();
11918
+ }).catch(reject);
11919
+ });
11920
+ }
11921
+ /**
11922
+ * Invokes `handler` with the queue name and decoded message content. Acks on success.
11923
+ * On failure, nacks the message and records the content and error in `stats.errors`.
11924
+ * Whether to requeue on nack is controlled by `options.nackRequeue` (default: true).
11925
+ */
11926
+ async processMessage(channel, queueName, msg, stats, options, handler) {
11927
+ const { nackRequeue = true } = options;
11928
+ const content = msg.content.toString();
11929
+ try {
11930
+ await handler(queueName, content);
11931
+ channel.ack(msg);
11932
+ stats.acked++;
11933
+ } catch (error) {
11934
+ channel.nack(msg, false, nackRequeue);
11935
+ stats.errors.push({ content, error });
11936
+ stats.nacked++;
11937
+ }
11938
+ }
11939
+ };
11940
+ __name(_RabbitMQClient, "RabbitMQClient");
11941
+ var RabbitMQClient = _RabbitMQClient;
11942
+ var rabbit_mq_client_default = RabbitMQClient;
11943
+
11760
11944
  // src/commerce/adobe-commerce-client/index.ts
11761
11945
  var import_got = __toESM(require("got"));
11762
11946
  var _AdobeCommerceClient = class _AdobeCommerceClient {
@@ -12777,6 +12961,7 @@ var AdminUiSdk = _AdminUiSdk;
12777
12961
  Parameters,
12778
12962
  ProviderManager,
12779
12963
  PublishEvent,
12964
+ RabbitMQClient,
12780
12965
  RegistrationManager,
12781
12966
  RestClient,
12782
12967
  RuntimeAction,