@adobe-commerce/aio-toolkit 1.2.4 → 1.2.6
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 +145 -0
- package/README.md +169 -0
- package/dist/aio-toolkit-cli-workflow/bin/cli.js +2048 -0
- package/dist/aio-toolkit-cli-workflow/bin/cli.js.map +1 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js +16 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js.map +1 -1
- package/dist/index.d.mts +51 -6
- package/dist/index.d.ts +51 -6
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +213 -0
- package/dist/index.mjs.map +1 -1
- package/files/cursor-context/commands/aio-toolkit-analyze-adobe-commerce-module.md +612 -0
- package/files/cursor-context/commands/aio-toolkit-create-amazon-sqs-consumer.md +445 -0
- package/files/cursor-context/commands/aio-toolkit-create-event-consumer-action.md +6 -0
- package/files/cursor-context/commands/aio-toolkit-create-graphql-action.md +21 -7
- package/files/cursor-context/commands/aio-toolkit-create-openwhisk-action.md +326 -0
- package/files/cursor-context/commands/aio-toolkit-create-runtime-action.md +15 -5
- package/files/cursor-context/commands/aio-toolkit-create-shipping-carrier.md +681 -0
- package/files/cursor-context/commands/aio-toolkit-create-webhook-action.md +22 -9
- package/files/cursor-context/rules/aio-toolkit-create-adobe-commerce-client.mdc +252 -116
- package/files/cursor-context/rules/aio-toolkit-oop-best-practices.mdc +10 -4
- package/files/cursor-context/rules/aio-toolkit-setup-new-relic-telemetry.mdc +167 -2
- package/files/cursor-context/rules/aio-toolkit-use-abdb-collection.mdc +610 -0
- package/files/cursor-context/rules/aio-toolkit-use-abdb-repository.mdc +705 -0
- package/files/cursor-context/rules/aio-toolkit-use-adobe-auth.mdc +442 -0
- package/files/cursor-context/rules/aio-toolkit-use-amazon-sqs-publish.mdc +397 -0
- package/files/cursor-context/rules/aio-toolkit-use-file-repository.mdc +502 -0
- package/files/cursor-context/rules/aio-toolkit-use-publish-event.mdc +510 -0
- package/files/cursor-context/rules/aio-toolkit-use-runtime-api-gateway-service.mdc +542 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@ __export(index_exports, {
|
|
|
38
38
|
AdminUiSdk: () => AdminUiSdk,
|
|
39
39
|
AdobeAuth: () => adobe_auth_default,
|
|
40
40
|
AdobeCommerceClient: () => adobe_commerce_client_default,
|
|
41
|
+
AmazonSQSClient: () => amazon_sqs_client_default,
|
|
41
42
|
BasicAuthConnection: () => basic_auth_connection_default,
|
|
42
43
|
BearerToken: () => bearer_token_default,
|
|
43
44
|
CreateEvents: () => create_events_default,
|
|
@@ -11940,6 +11941,213 @@ __name(_RabbitMQClient, "RabbitMQClient");
|
|
|
11940
11941
|
var RabbitMQClient = _RabbitMQClient;
|
|
11941
11942
|
var rabbit_mq_client_default = RabbitMQClient;
|
|
11942
11943
|
|
|
11944
|
+
// src/integration/amazon-sqs-client/index.ts
|
|
11945
|
+
var import_crypto5 = require("crypto");
|
|
11946
|
+
var import_client_sqs = require("@aws-sdk/client-sqs");
|
|
11947
|
+
|
|
11948
|
+
// src/integration/amazon-sqs-client/types.ts
|
|
11949
|
+
var SQS_MAX_BATCH_SIZE = 10;
|
|
11950
|
+
var DEFAULT_VISIBILITY_TIMEOUT = 30;
|
|
11951
|
+
var DEFAULT_WAIT_TIME_SECONDS = 0;
|
|
11952
|
+
var DEFAULT_MESSAGE_GROUP_ID = "default";
|
|
11953
|
+
|
|
11954
|
+
// src/integration/amazon-sqs-client/index.ts
|
|
11955
|
+
var _AmazonSQSClient = class _AmazonSQSClient {
|
|
11956
|
+
/**
|
|
11957
|
+
* @param config - AWS region, IAM credentials, target queue URL, and optional
|
|
11958
|
+
* consumer/FIFO settings (visibilityTimeout, waitTimeSeconds, messageGroupId).
|
|
11959
|
+
*/
|
|
11960
|
+
constructor(config) {
|
|
11961
|
+
this.queueUrl = config.queueUrl;
|
|
11962
|
+
this.isFifo = config.queueUrl.endsWith(".fifo");
|
|
11963
|
+
this.visibilityTimeout = config.visibilityTimeout ?? DEFAULT_VISIBILITY_TIMEOUT;
|
|
11964
|
+
this.waitTimeSeconds = config.waitTimeSeconds ?? DEFAULT_WAIT_TIME_SECONDS;
|
|
11965
|
+
this.messageGroupId = config.messageGroupId ?? DEFAULT_MESSAGE_GROUP_ID;
|
|
11966
|
+
this.client = new import_client_sqs.SQSClient({
|
|
11967
|
+
region: config.region,
|
|
11968
|
+
credentials: {
|
|
11969
|
+
accessKeyId: config.accessKeyId,
|
|
11970
|
+
secretAccessKey: config.secretAccessKey
|
|
11971
|
+
}
|
|
11972
|
+
});
|
|
11973
|
+
}
|
|
11974
|
+
/**
|
|
11975
|
+
* Publishes all `payloads` to the bound queue in batches of 10 (the SQS hard limit
|
|
11976
|
+
* per `SendMessageBatch` call). Failed entries reported by SQS within a successful
|
|
11977
|
+
* batch response are tracked individually in `stats.errors`. Transport errors
|
|
11978
|
+
* (thrown exceptions) are captured per-batch so a single failing batch does not
|
|
11979
|
+
* abort the rest.
|
|
11980
|
+
*
|
|
11981
|
+
* For FIFO queues (URL ends in `.fifo`), every entry is stamped with:
|
|
11982
|
+
* - `MessageGroupId` — the value set at construction time (`config.messageGroupId`,
|
|
11983
|
+
* defaulting to `'default'`).
|
|
11984
|
+
* - `MessageDeduplicationId` — a unique `randomUUID()` per entry, ensuring
|
|
11985
|
+
* at-most-once delivery within the 5-minute SQS deduplication window regardless
|
|
11986
|
+
* of whether content-based deduplication is enabled on the queue.
|
|
11987
|
+
*
|
|
11988
|
+
* @param payloads - Array of string message bodies to send.
|
|
11989
|
+
* @returns Counts of published and failed messages plus per-failure details.
|
|
11990
|
+
*/
|
|
11991
|
+
async publish(payloads) {
|
|
11992
|
+
const stats = { published: 0, failed: 0, errors: [] };
|
|
11993
|
+
if (payloads.length === 0) return stats;
|
|
11994
|
+
const chunks = this.chunk(payloads, SQS_MAX_BATCH_SIZE);
|
|
11995
|
+
let globalIndex = 0;
|
|
11996
|
+
for (const chunk of chunks) {
|
|
11997
|
+
await this.sendBatch(chunk, globalIndex, stats);
|
|
11998
|
+
globalIndex += chunk.length;
|
|
11999
|
+
}
|
|
12000
|
+
return stats;
|
|
12001
|
+
}
|
|
12002
|
+
/**
|
|
12003
|
+
* Pulls up to `batchSize` messages from the bound queue and processes each
|
|
12004
|
+
* one via `handler`.
|
|
12005
|
+
*
|
|
12006
|
+
* Processing steps:
|
|
12007
|
+
* 1. Receive messages in ReceiveMessage loops (≤ 10 per call) until `batchSize`
|
|
12008
|
+
* messages are accumulated or the queue returns empty.
|
|
12009
|
+
* 2. Invoke `handler` concurrently for all received messages.
|
|
12010
|
+
* 3. Delete every message whose handler resolved successfully.
|
|
12011
|
+
* Messages whose handler threw are left in the queue and become visible again
|
|
12012
|
+
* after the configured `visibilityTimeout` (set at construction time).
|
|
12013
|
+
*
|
|
12014
|
+
* @param batchSize - Total number of messages to pull per invocation.
|
|
12015
|
+
* @param handler - Callback invoked with the SQS MessageId and raw body string.
|
|
12016
|
+
* @returns Receive / process / delete / fail counts plus per-error details.
|
|
12017
|
+
* @throws Propagates SQS transport errors (receive, delete) to the caller.
|
|
12018
|
+
*/
|
|
12019
|
+
async consume(batchSize, handler) {
|
|
12020
|
+
const stats = {
|
|
12021
|
+
received: 0,
|
|
12022
|
+
processed: 0,
|
|
12023
|
+
deleted: 0,
|
|
12024
|
+
failed: 0,
|
|
12025
|
+
errors: []
|
|
12026
|
+
};
|
|
12027
|
+
const messages = await this.receiveMessages(batchSize);
|
|
12028
|
+
stats.received = messages.length;
|
|
12029
|
+
if (messages.length === 0) return stats;
|
|
12030
|
+
const toDelete = [];
|
|
12031
|
+
await Promise.all(
|
|
12032
|
+
messages.map(async (msg) => {
|
|
12033
|
+
stats.processed++;
|
|
12034
|
+
try {
|
|
12035
|
+
await handler(msg.MessageId ?? "", msg.Body ?? "");
|
|
12036
|
+
toDelete.push(msg);
|
|
12037
|
+
} catch (error) {
|
|
12038
|
+
stats.failed++;
|
|
12039
|
+
stats.errors.push({ messageId: msg.MessageId ?? "", error });
|
|
12040
|
+
}
|
|
12041
|
+
})
|
|
12042
|
+
);
|
|
12043
|
+
if (toDelete.length > 0) {
|
|
12044
|
+
await this.deleteMessages(toDelete);
|
|
12045
|
+
stats.deleted += toDelete.length;
|
|
12046
|
+
}
|
|
12047
|
+
return stats;
|
|
12048
|
+
}
|
|
12049
|
+
/**
|
|
12050
|
+
* Loops ReceiveMessage calls until `batchSize` messages are accumulated
|
|
12051
|
+
* or the queue returns an empty response (queue drained).
|
|
12052
|
+
*
|
|
12053
|
+
* The first call uses `this.waitTimeSeconds` (enabling long polling when > 0).
|
|
12054
|
+
* Subsequent fill-up calls always use waitTimeSeconds = 0 to avoid blocking —
|
|
12055
|
+
* if the first call returned messages the queue is clearly non-empty.
|
|
12056
|
+
*/
|
|
12057
|
+
async receiveMessages(batchSize) {
|
|
12058
|
+
const messages = [];
|
|
12059
|
+
let isFirstCall = true;
|
|
12060
|
+
while (messages.length < batchSize) {
|
|
12061
|
+
const remaining = batchSize - messages.length;
|
|
12062
|
+
const maxMessages = Math.min(remaining, SQS_MAX_BATCH_SIZE);
|
|
12063
|
+
const response = await this.client.send(
|
|
12064
|
+
new import_client_sqs.ReceiveMessageCommand({
|
|
12065
|
+
QueueUrl: this.queueUrl,
|
|
12066
|
+
MaxNumberOfMessages: maxMessages,
|
|
12067
|
+
VisibilityTimeout: this.visibilityTimeout,
|
|
12068
|
+
WaitTimeSeconds: isFirstCall ? this.waitTimeSeconds : 0
|
|
12069
|
+
})
|
|
12070
|
+
);
|
|
12071
|
+
isFirstCall = false;
|
|
12072
|
+
const received = response.Messages ?? [];
|
|
12073
|
+
if (received.length === 0) break;
|
|
12074
|
+
messages.push(...received);
|
|
12075
|
+
if (received.length < maxMessages) break;
|
|
12076
|
+
}
|
|
12077
|
+
return messages;
|
|
12078
|
+
}
|
|
12079
|
+
/**
|
|
12080
|
+
* Deletes messages from the queue after successful processing.
|
|
12081
|
+
* Uses DeleteMessageBatch (≤ 10 per call).
|
|
12082
|
+
*/
|
|
12083
|
+
async deleteMessages(messages) {
|
|
12084
|
+
const chunks = this.chunk(messages, SQS_MAX_BATCH_SIZE);
|
|
12085
|
+
for (const chunk of chunks) {
|
|
12086
|
+
const entries = chunk.map((msg, i) => ({
|
|
12087
|
+
Id: String(i),
|
|
12088
|
+
ReceiptHandle: msg.ReceiptHandle ?? ""
|
|
12089
|
+
}));
|
|
12090
|
+
await this.client.send(
|
|
12091
|
+
new import_client_sqs.DeleteMessageBatchCommand({ QueueUrl: this.queueUrl, Entries: entries })
|
|
12092
|
+
);
|
|
12093
|
+
}
|
|
12094
|
+
}
|
|
12095
|
+
/**
|
|
12096
|
+
* Sends a single publish batch via `SendMessageBatchCommand`.
|
|
12097
|
+
* `globalOffset` generates unique, stable entry IDs across consecutive batches
|
|
12098
|
+
* (SQS requires unique IDs within each request, not globally).
|
|
12099
|
+
* For FIFO queues, each entry is stamped with a `MessageGroupId` and a unique
|
|
12100
|
+
* `MessageDeduplicationId` (randomUUID).
|
|
12101
|
+
* Per-entry SQS failures are captured in `stats.errors`; transport exceptions
|
|
12102
|
+
* mark all entries in the chunk as failed without re-throwing.
|
|
12103
|
+
*/
|
|
12104
|
+
async sendBatch(chunk, globalOffset, stats) {
|
|
12105
|
+
const entries = chunk.map((payload, i) => ({
|
|
12106
|
+
Id: String(globalOffset + i),
|
|
12107
|
+
MessageBody: payload,
|
|
12108
|
+
...this.isFifo && {
|
|
12109
|
+
MessageGroupId: this.messageGroupId,
|
|
12110
|
+
MessageDeduplicationId: (0, import_crypto5.randomUUID)()
|
|
12111
|
+
}
|
|
12112
|
+
}));
|
|
12113
|
+
try {
|
|
12114
|
+
const response = await this.client.send(
|
|
12115
|
+
new import_client_sqs.SendMessageBatchCommand({ QueueUrl: this.queueUrl, Entries: entries })
|
|
12116
|
+
);
|
|
12117
|
+
const successful = response.Successful ?? [];
|
|
12118
|
+
const failed = response.Failed ?? [];
|
|
12119
|
+
stats.published += successful.length;
|
|
12120
|
+
for (const failure of failed) {
|
|
12121
|
+
const entryIndex = Number(failure.Id) - globalOffset;
|
|
12122
|
+
const payload = chunk[entryIndex] ?? "";
|
|
12123
|
+
const error = new Error(
|
|
12124
|
+
`SQS batch entry failed [Id=${failure.Id}] Code=${failure.Code}: ${failure.Message ?? "unknown"}`
|
|
12125
|
+
);
|
|
12126
|
+
stats.failed++;
|
|
12127
|
+
stats.errors.push({ payload, error });
|
|
12128
|
+
}
|
|
12129
|
+
} catch (error) {
|
|
12130
|
+
for (const payload of chunk) {
|
|
12131
|
+
stats.failed++;
|
|
12132
|
+
stats.errors.push({ payload, error });
|
|
12133
|
+
}
|
|
12134
|
+
}
|
|
12135
|
+
}
|
|
12136
|
+
/**
|
|
12137
|
+
* Splits `items` into sequential chunks of at most `size` elements.
|
|
12138
|
+
*/
|
|
12139
|
+
chunk(items, size) {
|
|
12140
|
+
const chunks = [];
|
|
12141
|
+
for (let i = 0; i < items.length; i += size) {
|
|
12142
|
+
chunks.push(items.slice(i, i + size));
|
|
12143
|
+
}
|
|
12144
|
+
return chunks;
|
|
12145
|
+
}
|
|
12146
|
+
};
|
|
12147
|
+
__name(_AmazonSQSClient, "AmazonSQSClient");
|
|
12148
|
+
var AmazonSQSClient = _AmazonSQSClient;
|
|
12149
|
+
var amazon_sqs_client_default = AmazonSQSClient;
|
|
12150
|
+
|
|
11943
12151
|
// src/commerce/adobe-commerce-client/index.ts
|
|
11944
12152
|
var import_got = __toESM(require("got"));
|
|
11945
12153
|
var _AdobeCommerceClient = class _AdobeCommerceClient {
|
|
@@ -12934,6 +13142,7 @@ var AdminUiSdk = _AdminUiSdk;
|
|
|
12934
13142
|
AdminUiSdk,
|
|
12935
13143
|
AdobeAuth,
|
|
12936
13144
|
AdobeCommerceClient,
|
|
13145
|
+
AmazonSQSClient,
|
|
12937
13146
|
BasicAuthConnection,
|
|
12938
13147
|
BearerToken,
|
|
12939
13148
|
CreateEvents,
|