@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.
Files changed (31) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/README.md +169 -0
  3. package/dist/aio-toolkit-cli-workflow/bin/cli.js +2048 -0
  4. package/dist/aio-toolkit-cli-workflow/bin/cli.js.map +1 -0
  5. package/dist/aio-toolkit-cursor-context/bin/cli.js +16 -0
  6. package/dist/aio-toolkit-cursor-context/bin/cli.js.map +1 -1
  7. package/dist/index.d.mts +51 -6
  8. package/dist/index.d.ts +51 -6
  9. package/dist/index.js +209 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +213 -0
  12. package/dist/index.mjs.map +1 -1
  13. package/files/cursor-context/commands/aio-toolkit-analyze-adobe-commerce-module.md +612 -0
  14. package/files/cursor-context/commands/aio-toolkit-create-amazon-sqs-consumer.md +445 -0
  15. package/files/cursor-context/commands/aio-toolkit-create-event-consumer-action.md +6 -0
  16. package/files/cursor-context/commands/aio-toolkit-create-graphql-action.md +21 -7
  17. package/files/cursor-context/commands/aio-toolkit-create-openwhisk-action.md +326 -0
  18. package/files/cursor-context/commands/aio-toolkit-create-runtime-action.md +15 -5
  19. package/files/cursor-context/commands/aio-toolkit-create-shipping-carrier.md +681 -0
  20. package/files/cursor-context/commands/aio-toolkit-create-webhook-action.md +22 -9
  21. package/files/cursor-context/rules/aio-toolkit-create-adobe-commerce-client.mdc +252 -116
  22. package/files/cursor-context/rules/aio-toolkit-oop-best-practices.mdc +10 -4
  23. package/files/cursor-context/rules/aio-toolkit-setup-new-relic-telemetry.mdc +167 -2
  24. package/files/cursor-context/rules/aio-toolkit-use-abdb-collection.mdc +610 -0
  25. package/files/cursor-context/rules/aio-toolkit-use-abdb-repository.mdc +705 -0
  26. package/files/cursor-context/rules/aio-toolkit-use-adobe-auth.mdc +442 -0
  27. package/files/cursor-context/rules/aio-toolkit-use-amazon-sqs-publish.mdc +397 -0
  28. package/files/cursor-context/rules/aio-toolkit-use-file-repository.mdc +502 -0
  29. package/files/cursor-context/rules/aio-toolkit-use-publish-event.mdc +510 -0
  30. package/files/cursor-context/rules/aio-toolkit-use-runtime-api-gateway-service.mdc +542 -0
  31. package/package.json +4 -2
@@ -0,0 +1,542 @@
1
+ ---
2
+ description: Adding RuntimeApiGatewayService to Adobe I/O Runtime actions using @adobe-commerce/aio-toolkit
3
+ globs: '**/{actions,lib}/**/*.{ts,js}'
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Using RuntimeApiGatewayService
8
+
9
+ ## Trigger Conditions
10
+
11
+ This rule applies when the user requests to call a web-exposed Adobe I/O Runtime action from within another action using any of these phrases:
12
+
13
+ - "Call a web action from another action"
14
+ - "Invoke action via API Gateway"
15
+ - "HTTP call to a Runtime action"
16
+ - "Use RuntimeApiGatewayService"
17
+ - "Call another action over HTTP"
18
+ - "Orchestrate actions via API Gateway"
19
+ - "Call [action-name] from [action-name]"
20
+ - "Add API Gateway client to [action-name]"
21
+ - "Invoke a web action with IMS auth"
22
+ - "Call Runtime endpoint from my action"
23
+
24
+ **Important**: This rule does NOT create new actions. It integrates `RuntimeApiGatewayService` into existing actions only.
25
+
26
+ **Integration with Other Action Creation Rules:**
27
+
28
+ When using action creation rules (RuntimeAction, WebhookAction, EventConsumerAction, GraphQlAction, OpenwhiskAction) and the developer mentions calling another web action or API Gateway endpoint in the business logic:
29
+
30
+ - **Automatically trigger this rule** after the action is created
31
+ - Examples: "call the product-service action", "invoke another web action", "call action via API Gateway", "HTTP request to runtime endpoint"
32
+ - This rule handles service construction, token generation, response handling, and config wiring
33
+
34
+ **RuntimeApiGatewayService vs the Openwhisk client:**
35
+
36
+ Both call one action from another — choose based on what the target action looks like:
37
+
38
+ | | `Openwhisk` client | `RuntimeApiGatewayService` |
39
+ |---|---|---|
40
+ | Protocol | OpenWhisk API (internal) | HTTP via API Gateway |
41
+ | Target must be `web: 'yes'` | No | Yes |
42
+ | Auth | `API_HOST` + `API_AUTH` (auto-injected) | IMS Bearer token (must be generated) |
43
+ | Returns | Full activation result | Raw `node-fetch` Response |
44
+ | Blocking / non-blocking | Configurable | Always async HTTP |
45
+ | Token management | None needed | Must generate + optionally cache |
46
+ | Best for | Internal sub-actions, fan-out pipelines | Web actions, HTTP-level response control |
47
+
48
+ **Use `RuntimeApiGatewayService` when:**
49
+ - The target action is `web: 'yes'`
50
+ - You need full HTTP response control (`response.ok`, headers, status codes)
51
+ - The target is in a different namespace
52
+ - You need IMS-authenticated HTTP calls to public endpoints
53
+
54
+ **Use `Openwhisk` client when:**
55
+ - The target action is `web: 'no'` (internal)
56
+ - You need blocking/non-blocking control
57
+ - You're routing within the same namespace
58
+ - Simplicity matters more than HTTP-level control
59
+
60
+ ---
61
+
62
+ ## Step 1: Verify Prerequisites
63
+
64
+ Before proceeding, verify:
65
+
66
+ 1. **Toolkit installed**: Check `@adobe-commerce/aio-toolkit` in `package.json`
67
+ - If NOT installed: `npm install @adobe-commerce/aio-toolkit`
68
+
69
+ 2. **Detect Language (TypeScript vs JavaScript)**:
70
+
71
+ **Check for TypeScript indicators (check ALL of these)**:
72
+ 1. **Package Dependencies**: Look for `typescript` in `package.json` dependencies or devDependencies
73
+ 2. **Config File**: Check if `tsconfig.json` exists in project root
74
+ 3. **TypeScript Loaders**: Look for `ts-loader`, `ts-node`, or `@types/*` packages
75
+ 4. **Existing Files**: Check for `.ts` files in `actions/` or `lib/`
76
+
77
+ **Detection Logic**:
78
+ - **TypeScript** if: `typescript` + `tsconfig.json` exist, OR 2+ indicators found, OR `.ts` files in `actions/`/`lib/`
79
+ - **Otherwise**: JavaScript
80
+
81
+ 3. **Detect Project Structure**:
82
+ - Check `app.config.yaml` for `application:` (root actions) or `extensions:` (extension points)
83
+
84
+ 4. **Check Existing Actions**: List all actions from `actions/` and `[extension-path]/actions/`
85
+ - If NO actions exist: stop and recommend creating an action first
86
+
87
+ 5. Only proceed to Step 2 after confirming all prerequisites
88
+
89
+ ---
90
+
91
+ ## Step 2: Ask Required Questions
92
+
93
+ Before generating any code, ask the user:
94
+
95
+ **Important**: Do not make assumptions — clarify all details before writing code.
96
+
97
+ 1. **Target Action**: Which existing action should receive the `RuntimeApiGatewayService` integration?
98
+ - List discovered actions for the user to choose from
99
+
100
+ 2. **Endpoint(s) to Call**: What API Gateway endpoint(s) will this action call?
101
+ - Format: `v1/web/{package}/{action-name}` (e.g. `v1/web/my-package/process-order`)
102
+ - Note: The namespace is handled automatically — only provide the path after it
103
+
104
+ 3. **HTTP Method(s)**: Which HTTP methods are needed?
105
+ - GET (read data, no payload)
106
+ - POST (send payload, create/trigger)
107
+ - PUT (update with payload)
108
+ - DELETE (remove by path)
109
+ - Multiple methods if the action calls different endpoints differently
110
+
111
+ 4. **Payload Structure** (for POST / PUT only):
112
+ - What data is sent in the request body?
113
+ - Example: `{ orderId, customerId, action }`
114
+
115
+ 5. **Token Caching Strategy**: How should the IMS token be managed?
116
+ - **Simple** (default, recommended for low-volume actions): generate a fresh token on every invocation using `AdobeAuth.getToken()`
117
+ - **Cached** (recommended for high-frequency actions): check token validity with `BearerToken.info()` before generating; cache with a TTL in-memory or via an external store
118
+
119
+ 6. **Additional Headers** (optional): Does any call need custom headers beyond the defaults?
120
+ - Defaults: `Authorization`, `x-gw-ims-org-id`, `Content-Type: application/json`
121
+ - Examples: `x-request-id`, `x-correlation-id`, `x-custom-header`
122
+
123
+ ---
124
+
125
+ ## Step 3: Confirm Implementation Details
126
+
127
+ After receiving answers to ALL questions, present a comprehensive summary and **wait for user confirmation** before proceeding to Step 4:
128
+
129
+ ---
130
+
131
+ ### 📋 RuntimeApiGatewayService Integration Summary
132
+
133
+ **Target Action:** `[action-name]`
134
+ **Action Path:** `[path to action file]`
135
+ **Language:** [TypeScript/JavaScript] (auto-detected)
136
+
137
+ **API Gateway Calls:**
138
+
139
+ | Method | Endpoint | Payload |
140
+ |---|---|---|
141
+ | [GET/POST/PUT/DELETE] | `v1/web/[package]/[action]` | `{ [fields] }` or — |
142
+
143
+ **Token Strategy:** [Simple (fresh per invocation) / Cached with BearerToken.info()]
144
+
145
+ **URL Pattern:** `https://adobeioruntime.net/apis/{namespace}/v1/web/[package]/[action]`
146
+
147
+ **Environment Variables:**
148
+
149
+ ```bash
150
+ # RuntimeApiGatewayService — IMS credentials
151
+ NAMESPACE=$AIO_runtime_namespace # auto-available in App Builder
152
+ IMS_ORG_ID=
153
+ CLIENT_ID=
154
+ CLIENT_SECRET=
155
+ TECHNICAL_ACCOUNT_ID=
156
+ TECHNICAL_ACCOUNT_EMAIL=
157
+ ```
158
+
159
+ 📍 **Source:** Adobe Developer Console → Your project → Credentials
160
+
161
+ ---
162
+
163
+ ### ✅ What Will Be Changed
164
+
165
+ **1. Action Implementation**
166
+ - ✏️ `[action-path]/index.[js/ts]`
167
+ - Import `RuntimeApiGatewayService`, `AdobeAuth` [, `BearerToken` if caching]
168
+ - Generate IMS token via `AdobeAuth.getToken()`
169
+ - Construct `new RuntimeApiGatewayService(params.NAMESPACE, params.IMS_ORG_ID, token, logger)`
170
+ - Call `service.[method](endpoint [, payload])` for each configured call
171
+ - Check `response.ok` and parse with `response.json()` / `response.text()`
172
+
173
+ **2. Action Configuration**
174
+ - ✏️ `app.config.yaml`, `ext.config.yaml`, or `actions.config.yaml`
175
+ - Add `NAMESPACE: $AIO_runtime_namespace`
176
+ - Add IMS credential inputs: `IMS_ORG_ID`, `CLIENT_ID`, `CLIENT_SECRET`, `TECHNICAL_ACCOUNT_ID`, `TECHNICAL_ACCOUNT_EMAIL`
177
+
178
+ **3. Environment Variables**
179
+ - 📄/✏️ `.env` (project root) — add placeholder variables if not already present
180
+
181
+ ---
182
+
183
+ **Should I proceed with this implementation?**
184
+
185
+ ---
186
+
187
+ ## Step 4: Generate Implementation
188
+
189
+ ### Step 4.1: Update the Action Code
190
+
191
+ #### Simple Pattern (fresh token per invocation)
192
+
193
+ **JavaScript:**
194
+
195
+ ```javascript
196
+ const {
197
+ RuntimeApiGatewayService,
198
+ AdobeAuth,
199
+ } = require('@adobe-commerce/aio-toolkit');
200
+
201
+ // Inside your action handler (params, ctx):
202
+ const { logger } = ctx;
203
+
204
+ // Step 1: Generate IMS access token
205
+ const token = await AdobeAuth.getToken(
206
+ params.CLIENT_ID,
207
+ params.CLIENT_SECRET,
208
+ params.TECHNICAL_ACCOUNT_ID,
209
+ params.TECHNICAL_ACCOUNT_EMAIL,
210
+ params.IMS_ORG_ID,
211
+ ['openid', 'AdobeID', 'adobeio_api']
212
+ );
213
+
214
+ // Step 2: Construct the service
215
+ const service = new RuntimeApiGatewayService(
216
+ params.NAMESPACE,
217
+ params.IMS_ORG_ID,
218
+ token,
219
+ logger // optional: enables request/error logging
220
+ );
221
+
222
+ // Step 3: Make the call — method throws on network failure, so wrap in try/catch
223
+ const response = await service.get('v1/web/[package]/[action]');
224
+
225
+ // Step 4: Check HTTP result — response body is NOT auto-parsed
226
+ if (!response.ok) {
227
+ const errorBody = await response.text();
228
+ logger.error({ message: '[action-name]-call-failed', status: response.status, errorBody });
229
+ return RuntimeActionResponse.error(response.status, `Downstream call failed: ${response.status}`);
230
+ }
231
+
232
+ const result = await response.json();
233
+ logger.info({ message: '[action-name]-call-success' });
234
+ ```
235
+
236
+ #### Simple Pattern — POST with payload
237
+
238
+ ```javascript
239
+ const response = await service.post(
240
+ 'v1/web/[package]/[action]',
241
+ { /* payload fields */ }
242
+ );
243
+
244
+ if (!response.ok) {
245
+ const errorBody = await response.text();
246
+ throw new Error(`POST failed ${response.status}: ${errorBody}`);
247
+ }
248
+
249
+ const result = await response.json();
250
+ ```
251
+
252
+ #### Cached Token Pattern (recommended for high-frequency actions)
253
+
254
+ ```javascript
255
+ const {
256
+ RuntimeApiGatewayService,
257
+ AdobeAuth,
258
+ BearerToken,
259
+ } = require('@adobe-commerce/aio-toolkit');
260
+
261
+ // Inside your action handler (params, ctx):
262
+ const { logger } = ctx;
263
+
264
+ // Check cache first (replace with your preferred cache — module-level Map, Redis, etc.)
265
+ let token = tokenCache.get('ims_token');
266
+
267
+ if (!token || !BearerToken.info(token).isValid) {
268
+ token = await AdobeAuth.getToken(
269
+ params.CLIENT_ID,
270
+ params.CLIENT_SECRET,
271
+ params.TECHNICAL_ACCOUNT_ID,
272
+ params.TECHNICAL_ACCOUNT_EMAIL,
273
+ params.IMS_ORG_ID,
274
+ ['openid', 'AdobeID', 'adobeio_api']
275
+ );
276
+
277
+ const tokenInfo = BearerToken.info(token);
278
+ if (tokenInfo.isValid && tokenInfo.timeUntilExpiry) {
279
+ // Cache with 10-minute safety buffer
280
+ const ttlMs = tokenInfo.timeUntilExpiry - 600_000;
281
+ tokenCache.set('ims_token', token, ttlMs);
282
+ }
283
+ }
284
+
285
+ const service = new RuntimeApiGatewayService(
286
+ params.NAMESPACE,
287
+ params.IMS_ORG_ID,
288
+ token,
289
+ logger
290
+ );
291
+
292
+ // Make calls as normal
293
+ const response = await service.get('v1/web/[package]/[action]');
294
+ ```
295
+
296
+ #### With additional headers
297
+
298
+ ```javascript
299
+ // Override or extend default headers for a specific call
300
+ const response = await service.get(
301
+ 'v1/web/[package]/[action]',
302
+ { 'x-correlation-id': params.correlationId }
303
+ );
304
+ ```
305
+
306
+ **TypeScript:** Same with `import` syntax:
307
+ ```typescript
308
+ import { RuntimeApiGatewayService, AdobeAuth, BearerToken } from '@adobe-commerce/aio-toolkit';
309
+ ```
310
+
311
+ ### Step 4.2: Update Action Configuration
312
+
313
+ Add the required inputs to the action's YAML configuration:
314
+
315
+ ```yaml
316
+ [action-name]:
317
+ function: [action-path]/index.[js/ts]
318
+ web: 'yes' # or 'no' for event consumers / internal actions
319
+ runtime: nodejs:22
320
+ annotations:
321
+ require-adobe-auth: [true/false]
322
+ final: true
323
+ inputs:
324
+ LOG_LEVEL: debug
325
+ # RuntimeApiGatewayService inputs
326
+ NAMESPACE: $AIO_runtime_namespace # auto-available — no .env entry needed
327
+ IMS_ORG_ID: $IMS_ORG_ID
328
+ CLIENT_ID: $CLIENT_ID
329
+ CLIENT_SECRET: $CLIENT_SECRET
330
+ TECHNICAL_ACCOUNT_ID: $TECHNICAL_ACCOUNT_ID
331
+ TECHNICAL_ACCOUNT_EMAIL: $TECHNICAL_ACCOUNT_EMAIL
332
+ ```
333
+
334
+ > `$AIO_runtime_namespace` is automatically available in every App Builder project — it resolves to the current workspace namespace without any manual configuration. Do NOT add it to `.env`.
335
+
336
+ ### Step 4.3: Add Environment Variables
337
+
338
+ Update the project root `.env` with credential placeholders (skip `NAMESPACE` — it's auto-provided):
339
+
340
+ ```bash
341
+ # RuntimeApiGatewayService — IMS credentials
342
+ IMS_ORG_ID=your-org@AdobeOrg
343
+ CLIENT_ID=
344
+ CLIENT_SECRET=
345
+ TECHNICAL_ACCOUNT_ID=
346
+ TECHNICAL_ACCOUNT_EMAIL=
347
+ ```
348
+
349
+ **How to get credentials:**
350
+ 1. Log in to [Adobe Developer Console](https://developer.adobe.com/console)
351
+ 2. Open your App Builder project
352
+ 3. Go to **Credentials** → Service Account (OAuth S2S) or JWT
353
+ 4. Copy `Client ID` → `CLIENT_ID`, `Client Secret` → `CLIENT_SECRET`
354
+ 5. Copy `Technical Account ID` and `Technical Account Email`
355
+ 6. Copy `Organization ID` → `IMS_ORG_ID`
356
+
357
+ **Security Notes:**
358
+ - Never commit `.env` — confirm it is in `.gitignore`
359
+ - `CLIENT_SECRET` is a secret — treat it with the same care as a password
360
+ - Use different credentials per environment (dev / staging / production)
361
+
362
+ ---
363
+
364
+ ## Step 5: Recommendations
365
+
366
+ ### A. Response Handling Strategy
367
+
368
+ `RuntimeApiGatewayService` methods throw on **network-level failure** but return normally for HTTP error status codes. Always check both:
369
+
370
+ ```javascript
371
+ try {
372
+ const response = await service.post('v1/web/[package]/[action]', payload);
373
+
374
+ // HTTP-level check
375
+ if (!response.ok) {
376
+ const errorBody = await response.text();
377
+ logger.error({ message: '[action]-downstream-http-error', status: response.status, errorBody });
378
+ return RuntimeActionResponse.error(response.status, `Downstream action returned ${response.status}`);
379
+ }
380
+
381
+ const result = await response.json();
382
+ return RuntimeActionResponse.success(result);
383
+
384
+ } catch (error) {
385
+ // Network/connection failure
386
+ logger.error({ message: '[action]-downstream-network-error', error: error.message });
387
+ return RuntimeActionResponse.error(HttpStatus.INTERNAL_ERROR, `Gateway call failed: ${error.message}`);
388
+ }
389
+ ```
390
+
391
+ ### B. Token Caching Decision
392
+
393
+ | Scenario | Strategy |
394
+ |---|---|
395
+ | Action invoked infrequently (< 1 req/min) | **Simple** — generate fresh token per invocation |
396
+ | Action invoked frequently or in a loop | **Cached** — use `BearerToken.info()` + module-level cache |
397
+ | Action runs in a stateful process | **Cached** — share token across invocations |
398
+
399
+ > OpenWhisk actions are cold-started per request — module-level variables do NOT persist between invocations unless the same container is reused. For reliable caching, use an external store (`@adobe/aio-lib-state`, Redis, etc.).
400
+
401
+ ### C. No Retries or Timeouts
402
+
403
+ `RuntimeApiGatewayService` has no built-in retry or timeout logic. For reliability-sensitive paths:
404
+
405
+ ```javascript
406
+ // Simple retry with exponential backoff
407
+ async function callWithRetry(service, endpoint, retries = 3) {
408
+ for (let i = 0; i < retries; i++) {
409
+ try {
410
+ const response = await service.get(endpoint);
411
+ if (response.ok) return response;
412
+ } catch (error) {
413
+ if (i === retries - 1) throw error;
414
+ await new Promise(r => setTimeout(r, 2 ** i * 1000));
415
+ }
416
+ }
417
+ }
418
+ ```
419
+
420
+ ### D. URL Construction
421
+
422
+ Endpoint is appended as-is — no leading slash normalization:
423
+
424
+ ```javascript
425
+ // ✅ Correct
426
+ await service.get('v1/web/my-package/my-action');
427
+ // → https://adobeioruntime.net/apis/{namespace}/v1/web/my-package/my-action
428
+
429
+ // ⚠️ Extra leading slash produces double slash in URL
430
+ await service.get('/v1/web/my-package/my-action');
431
+ // → https://adobeioruntime.net/apis/{namespace}//v1/web/...
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Key Components from @adobe-commerce/aio-toolkit
437
+
438
+ ### RuntimeApiGatewayService Constructor
439
+
440
+ ```typescript
441
+ new RuntimeApiGatewayService(
442
+ namespace: string, // Adobe I/O Runtime namespace — use params.NAMESPACE
443
+ imsOrgId: string, // IMS Org ID — use params.IMS_ORG_ID
444
+ imsToken: string, // Bearer token — from AdobeAuth.getToken()
445
+ logger?: any // optional: enables request/error logging
446
+ )
447
+ ```
448
+
449
+ > **No constructor validation** — invalid credentials are only detected when the first request is made.
450
+
451
+ ### Methods (all return `Promise<Response>`)
452
+
453
+ ```typescript
454
+ service.get(endpoint, additionalHeaders?)
455
+ service.post(endpoint, payload, additionalHeaders?)
456
+ service.put(endpoint, payload, additionalHeaders?)
457
+ service.delete(endpoint, additionalHeaders?)
458
+ ```
459
+
460
+ - All methods **throw** on network failure (after logging if a logger is provided)
461
+ - All methods return the **raw `node-fetch` Response** — you must call `.json()` / `.text()` and check `response.ok`
462
+ - `additionalHeaders` are merged after the defaults and can override `Authorization`, `x-gw-ims-org-id`, or `Content-Type`
463
+
464
+ ### Default Headers (sent on every request)
465
+
466
+ ```
467
+ Authorization: Bearer <imsToken>
468
+ x-gw-ims-org-id: <imsOrgId>
469
+ Content-Type: application/json
470
+ ```
471
+
472
+ ### AdobeAuth.getToken() — generate IMS token
473
+
474
+ ```typescript
475
+ const token = await AdobeAuth.getToken(
476
+ clientId, // params.CLIENT_ID
477
+ clientSecret, // params.CLIENT_SECRET
478
+ technicalAccountId, // params.TECHNICAL_ACCOUNT_ID
479
+ technicalAccountEmail, // params.TECHNICAL_ACCOUNT_EMAIL
480
+ orgId, // params.IMS_ORG_ID
481
+ scopes // ['openid', 'AdobeID', 'adobeio_api']
482
+ );
483
+ ```
484
+
485
+ ### BearerToken.info() — inspect token validity (for caching)
486
+
487
+ ```typescript
488
+ const { isValid, timeUntilExpiry } = BearerToken.info(token);
489
+ // isValid: boolean — false if expired or invalid
490
+ // timeUntilExpiry: number (ms) — time until expiry; 0 or undefined if expired
491
+ ```
492
+
493
+ ---
494
+
495
+ ## Important Notes
496
+
497
+ 1. **No constructor validation**: Invalid credentials fail on first request, not at construction time — verify credentials are set before constructing
498
+ 2. **Raw Response returned**: Always call `.json()` or `.text()` and check `response.ok` — nothing is auto-parsed
499
+ 3. **Methods throw on network failure**: Wrap in try/catch to handle connection errors separately from HTTP errors
500
+ 4. **No built-in retries or timeouts**: Implement your own retry logic for reliability-sensitive paths
501
+ 5. **`NAMESPACE` is auto-provided**: `$AIO_runtime_namespace` is always available in App Builder — do not manually add it to `.env`
502
+ 6. **Token caching is application-level**: OpenWhisk containers may not persist module-level state — use external storage for reliable cross-invocation caching
503
+ 7. **Endpoint appended as-is**: No leading slash normalization — omit the leading `/` in endpoint strings
504
+ 8. **Additional headers override defaults**: Can override `Authorization`, `x-gw-ims-org-id`, and `Content-Type` per-request via `additionalHeaders`
505
+ 9. **vs Openwhisk client**: Use `RuntimeApiGatewayService` for `web: 'yes'` targets needing HTTP-level control; use `Openwhisk` client for `web: 'no'` internal actions
506
+ 10. **Works with any action type**: RuntimeAction, WebhookAction, EventConsumerAction, GraphQlAction, OpenwhiskAction
507
+
508
+ ## Integration with Action Creation Rules
509
+
510
+ **This rule should be triggered when developers mention calling web actions in their business logic:**
511
+
512
+ ### Trigger Patterns in Other Rules
513
+
514
+ When developers mention these phrases during action creation:
515
+
516
+ - "Call the [action-name] action"
517
+ - "Invoke web action from my action"
518
+ - "HTTP request to another Runtime action"
519
+ - "Call via API Gateway"
520
+ - "Orchestrate actions with HTTP"
521
+ - Any phrase involving "RuntimeApiGatewayService" or "API Gateway" + "call"/"invoke"/"request"
522
+
523
+ **Action to take:**
524
+
525
+ 1. Complete the action creation first
526
+ 2. Inform the user: "I see you need to call a web action via API Gateway. Let me integrate RuntimeApiGatewayService."
527
+ 3. Trigger/reference the "Using RuntimeApiGatewayService" rule
528
+ 4. This rule handles token generation, service construction, response handling, and config wiring
529
+
530
+ **Example Flow:**
531
+
532
+ ```
533
+ User: "Create a runtime action that calls the product-service web action to fetch product data"
534
+ AI: ✓ Detected TypeScript project
535
+ AI: Creating runtime action... [generates .ts file]
536
+ AI: I see you need to call a web action. Let me integrate RuntimeApiGatewayService.
537
+ AI: [Adds token generation, service construction, GET call, response handling, and config inputs]
538
+ ```
539
+
540
+ ## Related Rules
541
+
542
+ - **"Using AdobeAuth"** (`aio-toolkit-use-adobe-auth.mdc`) — primary reference for `AdobeAuth.getToken()` usage, caching patterns, scope selection, and error handling for the IMS token this service requires
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe-commerce/aio-toolkit",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "A comprehensive TypeScript toolkit for Adobe App Builder applications providing standardized Adobe Commerce integrations, I/O Events orchestration, file storage utilities, authentication helpers, and robust backend development tools with 100% test coverage.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -22,7 +22,8 @@
22
22
  ],
23
23
  "bin": {
24
24
  "aio-toolkit-cursor-context": "dist/aio-toolkit-cursor-context/bin/cli.js",
25
- "aio-toolkit-onboard-events": "dist/aio-toolkit-onboard-events/bin/cli.js"
25
+ "aio-toolkit-onboard-events": "dist/aio-toolkit-onboard-events/bin/cli.js",
26
+ "aio-toolkit-cli-workflow": "dist/aio-toolkit-cli-workflow/bin/cli.js"
26
27
  },
27
28
  "scripts": {
28
29
  "build": "tsup",
@@ -60,6 +61,7 @@
60
61
  "license": "SEE LICENSE IN LICENSE",
61
62
  "dependencies": {
62
63
  "@adobe-commerce/aio-services-kit": "^1.0.0",
64
+ "@aws-sdk/client-sqs": "^3.1045.0",
63
65
  "amqplib": "^1.0.3",
64
66
  "cloudevents": "^8.0.2",
65
67
  "dotenv": "^17.3.1",