@adobe-commerce/aio-toolkit 1.0.14 → 1.0.16
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 +90 -0
- package/README.md +218 -13
- package/dist/aio-toolkit-cursor-context/bin/cli.js +1168 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js.map +1 -0
- package/dist/aio-toolkit-onboard-events/bin/cli.js +14611 -0
- package/dist/aio-toolkit-onboard-events/bin/cli.js.map +1 -0
- package/files/cursor-context/commands/aio-toolkit-create-event-consumer-action.md +562 -0
- package/files/cursor-context/commands/aio-toolkit-create-graphql-action.md +531 -0
- package/files/cursor-context/commands/aio-toolkit-create-runtime-action.md +293 -0
- package/files/cursor-context/commands/aio-toolkit-create-webhook-action.md +439 -0
- package/files/cursor-context/rules/aio-toolkit-create-adobe-commerce-client.mdc +1321 -0
- package/files/cursor-context/rules/aio-toolkit-oop-best-practices.mdc +331 -0
- package/files/cursor-context/rules/aio-toolkit-setup-new-relic-telemetry.mdc +354 -0
- package/onboard.config.default.yaml +31 -0
- package/package.json +8 -1
|
@@ -0,0 +1,1321 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Creating Adobe Commerce Client Operations using @adobe-commerce/aio-toolkit
|
|
3
|
+
globs: '**/{actions,lib}/**/*.{ts,js},.env'
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Creating Adobe Commerce Client Operations
|
|
8
|
+
|
|
9
|
+
## Trigger Conditions
|
|
10
|
+
|
|
11
|
+
This rule applies when the user requests to integrate Adobe Commerce API into their actions using any of these phrases:
|
|
12
|
+
|
|
13
|
+
- "Create an Adobe Commerce client"
|
|
14
|
+
- "Make an API call to Commerce"
|
|
15
|
+
- "Add Commerce API to [action-name]"
|
|
16
|
+
- "Create a product in Commerce"
|
|
17
|
+
- "Create an order in Commerce"
|
|
18
|
+
- "Connect to Adobe Commerce"
|
|
19
|
+
- "Setup Commerce connection"
|
|
20
|
+
- "Call Commerce API"
|
|
21
|
+
- "Integrate Commerce with [action-name]"
|
|
22
|
+
- "Use Commerce REST API"
|
|
23
|
+
- "I need to interact with Commerce API"
|
|
24
|
+
- "Add Commerce client to my action"
|
|
25
|
+
|
|
26
|
+
**Important**: This rule does NOT create new actions. It integrates Commerce API into existing actions only.
|
|
27
|
+
|
|
28
|
+
**Integration with Other Action Creation Rules**:
|
|
29
|
+
|
|
30
|
+
When using action creation rules (RuntimeAction, WebhookAction, GraphQLAction, EventConsumerAction) and the developer mentions Commerce operations in the business logic:
|
|
31
|
+
|
|
32
|
+
- **Automatically trigger this rule** after the action is created
|
|
33
|
+
- Examples of Commerce operations: "create product", "get customer", "update order", "call Commerce API", "fetch products from Commerce"
|
|
34
|
+
- This rule handles all Commerce client setup, connection methods, and API integration
|
|
35
|
+
|
|
36
|
+
**If you need to create a new action first**:
|
|
37
|
+
|
|
38
|
+
- Use the "Create Runtime Action" rule to create the action
|
|
39
|
+
- Then this rule will add Commerce API integration to that action
|
|
40
|
+
|
|
41
|
+
**This rule offers two implementation approaches**:
|
|
42
|
+
|
|
43
|
+
**Approach A: Centralized Client Builder (Recommended)**
|
|
44
|
+
|
|
45
|
+
1. Creates a reusable `AdobeCommerceClientBuilder` class in `lib/adobe-commerce/client-builder/` (if not exists)
|
|
46
|
+
2. Integrates Commerce API calls into existing runtime actions using `getClient()` method
|
|
47
|
+
3. Uses singleton pattern to avoid creating multiple client instances
|
|
48
|
+
4. Best for: Multiple actions needing Commerce API
|
|
49
|
+
|
|
50
|
+
**Approach B: Direct Connection (Simpler)**
|
|
51
|
+
|
|
52
|
+
1. Creates connection and client directly in the runtime action
|
|
53
|
+
2. No shared client builder
|
|
54
|
+
3. Best for: Single action with Commerce API, one-off use cases
|
|
55
|
+
|
|
56
|
+
When any of these patterns are detected, follow this process:
|
|
57
|
+
|
|
58
|
+
## Step 1: Verify Prerequisites
|
|
59
|
+
|
|
60
|
+
Before proceeding, verify that `@adobe-commerce/aio-toolkit` is installed:
|
|
61
|
+
|
|
62
|
+
1. Check if the package exists in `package.json` dependencies
|
|
63
|
+
2. If NOT installed, inform the user and ask if they want to install it:
|
|
64
|
+
```bash
|
|
65
|
+
npm install @adobe-commerce/aio-toolkit
|
|
66
|
+
```
|
|
67
|
+
3. **Check Project Type**: Detect project structure
|
|
68
|
+
- Check for `application:` section in root `app.config.yaml` (standard actions)
|
|
69
|
+
- Check for `extensions:` section in root `app.config.yaml` (extension point actions)
|
|
70
|
+
- If extensions exist, parse the `$include` path to get extension directory
|
|
71
|
+
- Example: `$include: src/commerce-backend-ui-1/ext.config.yaml` → directory: `src/commerce-backend-ui-1`
|
|
72
|
+
- Example: `$include: extensions/my-ext/ext.config.yaml` → directory: `extensions/my-ext`
|
|
73
|
+
- Note: Projects can have BOTH standard actions AND extension point actions
|
|
74
|
+
|
|
75
|
+
4. **Detect Language (TypeScript vs JavaScript)**: Automatically determine the project language
|
|
76
|
+
|
|
77
|
+
**Check for TypeScript indicators (check ALL of these)**:
|
|
78
|
+
1. **Package Dependencies**: Look for `typescript` in `package.json` dependencies or devDependencies
|
|
79
|
+
2. **Config File**: Check if `tsconfig.json` exists in project root
|
|
80
|
+
3. **TypeScript Loaders**: Look for `ts-loader`, `ts-node`, or `@types/*` packages in `package.json`
|
|
81
|
+
4. **Build Scripts**: Check for TypeScript compilation in `package.json` scripts (e.g., `tsc`, `tsup`, `esbuild` with `.ts`)
|
|
82
|
+
5. **Existing Files**: Check for `.ts` or `.tsx` files in key directories (`actions/`, `src/`, `lib/`)
|
|
83
|
+
6. **Compiled Output**: Check `app.config.yaml` or `ext.config.yaml` for `build/` directory references (indicates TypeScript compilation)
|
|
84
|
+
|
|
85
|
+
**Detection Logic**:
|
|
86
|
+
- **If ANY of the following are true → TypeScript project**:
|
|
87
|
+
- `typescript` package installed AND `tsconfig.json` exists
|
|
88
|
+
- Multiple TypeScript indicators (2 or more from above list)
|
|
89
|
+
- Existing `.ts` files found in `actions/` or `lib/` directories
|
|
90
|
+
- **Otherwise → JavaScript project**
|
|
91
|
+
|
|
92
|
+
**Action**:
|
|
93
|
+
- **If TypeScript detected**: Use `.ts` extension and TypeScript syntax for all generated code
|
|
94
|
+
- **If JavaScript detected**: Use `.js` extension and JavaScript syntax for all generated code
|
|
95
|
+
- **Log the detection**: Inform user "✓ Detected [TypeScript/JavaScript] project"
|
|
96
|
+
- This eliminates the need to ask the developer about language preference
|
|
97
|
+
|
|
98
|
+
**Examples**:
|
|
99
|
+
- **TypeScript Project**: Has `typescript` + `tsconfig.json` → Generate `.ts` files
|
|
100
|
+
- **JavaScript Project**: No TypeScript indicators → Generate `.js` files
|
|
101
|
+
- **Ambiguous Case**: Has TypeScript setup but only `.js` files in actions/ → Generate `.js` to match existing
|
|
102
|
+
- **Migration Case**: Has both `.ts` and `.js` files → Use majority language (count files in `actions/` and `lib/`)
|
|
103
|
+
|
|
104
|
+
5. **Check for Existing Actions**: Verify that at least one runtime action exists
|
|
105
|
+
- List all existing actions from `actions/` directory (root application)
|
|
106
|
+
- List all existing actions from `[extension-path]/actions/` directory (extensions)
|
|
107
|
+
- If NO actions exist:
|
|
108
|
+
- Inform the user that this rule requires existing actions
|
|
109
|
+
- Recommend: "Please use the 'Create Runtime Action' rule first to create an action, then return to this rule to add Commerce API integration"
|
|
110
|
+
- Stop execution and wait for user to create an action
|
|
111
|
+
- If actions exist: Proceed to next step
|
|
112
|
+
|
|
113
|
+
6. **Check MCP Server Availability**: Verify commerce-extensibility MCP server is enabled
|
|
114
|
+
- Check if `search-commerce-docs` tool is available from the MCP server
|
|
115
|
+
- This provides RAG-based search for Commerce API patterns and documentation
|
|
116
|
+
- Example usage: `/search-commerce-docs "How to get list of products using REST endpoint?"`
|
|
117
|
+
- If available: Use it to search for relevant Commerce API patterns based on user's request
|
|
118
|
+
- If NOT available: Inform user that MCP server is not enabled, but proceed with rule execution
|
|
119
|
+
- Note: MCP server enhances the rule by providing Commerce-specific API guidance
|
|
120
|
+
|
|
121
|
+
7. Only proceed to Step 2 after confirming the toolkit is available and at least one action exists
|
|
122
|
+
|
|
123
|
+
## Step 2: Ask Required Questions
|
|
124
|
+
|
|
125
|
+
Before generating any code, ask the user the following questions:
|
|
126
|
+
|
|
127
|
+
**Important**:
|
|
128
|
+
|
|
129
|
+
- If any question is unclear or you need more information to proceed, continue asking follow-up questions until you have complete clarity on what to build. Do not make assumptions - keep the conversation going until all details are clear.
|
|
130
|
+
- Once all questions are clearly answered, move to Step 3 to get user confirmation before generating any code.
|
|
131
|
+
|
|
132
|
+
### Core Questions:
|
|
133
|
+
|
|
134
|
+
1. **Implementation Approach**: How do you want to implement the Commerce client?
|
|
135
|
+
- **Option A: Centralized Client Builder** (Recommended)
|
|
136
|
+
- Creates reusable `AdobeCommerceClientBuilder` class in `lib/adobe-commerce/client-builder/`
|
|
137
|
+
- Singleton pattern - client instance is reused across multiple actions
|
|
138
|
+
- Best for: Projects with multiple actions needing Commerce API
|
|
139
|
+
- Benefits: Code reusability, consistent configuration, easier maintenance
|
|
140
|
+
- **Option B: Direct Connection in Action**
|
|
141
|
+
- Creates connection and client directly in the runtime action
|
|
142
|
+
- No shared client builder
|
|
143
|
+
- Best for: Single action with Commerce API, one-off use cases
|
|
144
|
+
- Benefits: Simpler, all code in one place, no external dependencies
|
|
145
|
+
|
|
146
|
+
2. **Connection Method**: How do you want to connect to Adobe Commerce?
|
|
147
|
+
- **Option A: OAuth 1.0a Connection** (`Oauth1aConnection`)
|
|
148
|
+
- Use Case: Direct Commerce instance integration
|
|
149
|
+
- Authentication: OAuth 1.0a protocol
|
|
150
|
+
- Best for: On-premise or self-hosted Commerce instances
|
|
151
|
+
- **Option B: IMS Connection** (`ImsConnection`)
|
|
152
|
+
- Use Case: Adobe Commerce Cloud integration
|
|
153
|
+
- Authentication: Adobe Identity Management Services (IMS)
|
|
154
|
+
- Best for: Adobe Commerce Cloud with IMS authentication
|
|
155
|
+
- **Option C: Basic Auth Connection** (`BasicAuthConnection`)
|
|
156
|
+
- Use Case: Simple username/password authentication
|
|
157
|
+
- Authentication: HTTP Basic Authentication
|
|
158
|
+
- Best for: Development/testing environments (not recommended for production)
|
|
159
|
+
|
|
160
|
+
3. **Existing Action Selection**: Which existing action do you want to add Commerce API integration to?
|
|
161
|
+
|
|
162
|
+
**The rule will**:
|
|
163
|
+
- List all existing actions from root `actions/` directory (if root application exists)
|
|
164
|
+
- List all existing actions from `[extension-path]/actions/` directory (if extension exists)
|
|
165
|
+
- Include both simple actions and packaged actions
|
|
166
|
+
- Show action names and their file paths
|
|
167
|
+
|
|
168
|
+
**User selects**:
|
|
169
|
+
- Choose from the list of existing actions
|
|
170
|
+
- Example: `runtime-action`, `order-processor`, `product/created`
|
|
171
|
+
|
|
172
|
+
**Note**:
|
|
173
|
+
- If Centralized Client Builder: Action will use `AdobeCommerceClientBuilder.getClient()` for Commerce API calls
|
|
174
|
+
- If Direct Connection: Action will have direct connection and client initialization (no client builder)
|
|
175
|
+
|
|
176
|
+
**If you need a new action**: Use the "Create Runtime Action" rule first, then return to this rule
|
|
177
|
+
|
|
178
|
+
4. **Commerce Operation**: What Commerce operation do you want to perform in this action?
|
|
179
|
+
- **If MCP server is available**: Use `/search-commerce-docs` to find relevant API patterns
|
|
180
|
+
- Examples:
|
|
181
|
+
- Get list of products
|
|
182
|
+
- Create a product
|
|
183
|
+
- Update a product
|
|
184
|
+
- Delete a product
|
|
185
|
+
- Get customer by ID
|
|
186
|
+
- Create an order
|
|
187
|
+
- Update order status
|
|
188
|
+
- Get categories
|
|
189
|
+
- Custom REST API call
|
|
190
|
+
- Provide a brief description of what the operation should do
|
|
191
|
+
- Note: The MCP server can help identify the correct REST endpoint and parameters
|
|
192
|
+
|
|
193
|
+
**This operation logic will be added to the selected action**
|
|
194
|
+
|
|
195
|
+
## Step 3: Confirm Implementation Details
|
|
196
|
+
|
|
197
|
+
After receiving answers to ALL questions, present a comprehensive summary and **wait for user confirmation** before proceeding to Step 4:
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### 📋 Adobe Commerce Client Configuration Summary
|
|
202
|
+
|
|
203
|
+
**Implementation Approach:** [Centralized Client Builder (Recommended) / Direct Connection in Action]
|
|
204
|
+
|
|
205
|
+
**Connection Method:** [OAuth 1.0a / IMS / Basic Auth]
|
|
206
|
+
|
|
207
|
+
**Basic Configuration:**
|
|
208
|
+
|
|
209
|
+
- **Language:** [TypeScript/JavaScript] (auto-detected from project)
|
|
210
|
+
- **Selected Action:** `[action-name]`
|
|
211
|
+
- **Action Path:** `[path to action file]`
|
|
212
|
+
|
|
213
|
+
[If Centralized Client Builder:]
|
|
214
|
+
|
|
215
|
+
**Client Builder:**
|
|
216
|
+
|
|
217
|
+
- **Location:** [Automatically determined]
|
|
218
|
+
- If ONLY root application exists: `lib/adobe-commerce/client-builder/index.[js/ts]`
|
|
219
|
+
- If ONLY extension point exists: `[extension-path]/lib/adobe-commerce/client-builder/index.[js/ts]`
|
|
220
|
+
- If BOTH root and extension exist: `lib/adobe-commerce/client-builder/index.[js/ts]` (in root, reusable by both)
|
|
221
|
+
- **Status:** [Already exists - will reuse / Will create new]
|
|
222
|
+
|
|
223
|
+
[If Direct Connection:]
|
|
224
|
+
|
|
225
|
+
**Integration:** Direct connection and client initialization in action (no shared client builder)
|
|
226
|
+
|
|
227
|
+
**Commerce Operation:**
|
|
228
|
+
|
|
229
|
+
- **Description:** [what the operation does]
|
|
230
|
+
- **REST Endpoint:** [If found via MCP: show endpoint, method, parameters]
|
|
231
|
+
|
|
232
|
+
**Environment Variables:**
|
|
233
|
+
|
|
234
|
+
[If OAuth 1.0a Connection:]
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Adobe Commerce REST API Configuration (OAuth 1.0a)
|
|
238
|
+
COMMERCE_BASE_URL=https://your-commerce-store.com/rest
|
|
239
|
+
COMMERCE_CONSUMER_KEY=
|
|
240
|
+
COMMERCE_CONSUMER_SECRET=
|
|
241
|
+
COMMERCE_ACCESS_TOKEN=
|
|
242
|
+
COMMERCE_ACCESS_TOKEN_SECRET=
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
📍 **Source:** Commerce Admin > System > Extensions > Integrations
|
|
246
|
+
|
|
247
|
+
[If IMS Connection:]
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Adobe Commerce REST API Configuration (IMS)
|
|
251
|
+
COMMERCE_BASE_URL=https://your-commerce-cloud.adobe.com/rest
|
|
252
|
+
IMS_CLIENT_ID=
|
|
253
|
+
IMS_CLIENT_SECRET=
|
|
254
|
+
IMS_TECHNICAL_ACCOUNT_ID=
|
|
255
|
+
IMS_TECHNICAL_ACCOUNT_EMAIL=
|
|
256
|
+
IMS_ORD_ID=
|
|
257
|
+
IMS_SCOPES=openid,AdobeID,read_organizations
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
📍 **Source:** Adobe Developer Console
|
|
261
|
+
|
|
262
|
+
[If Basic Auth Connection:]
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# Adobe Commerce REST API Configuration (Basic Auth)
|
|
266
|
+
COMMERCE_BASE_URL=https://your-commerce-store.com/rest
|
|
267
|
+
COMMERCE_USERNAME=
|
|
268
|
+
COMMERCE_PASSWORD=
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
⚠️ **Warning:** Basic Auth is NOT recommended for production (security risk)
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### ✅ What Will Be Created
|
|
276
|
+
|
|
277
|
+
[If Centralized Client Builder Approach:]
|
|
278
|
+
|
|
279
|
+
[If client builder does NOT exist:]
|
|
280
|
+
|
|
281
|
+
**1. Client Builder (NEW)**
|
|
282
|
+
|
|
283
|
+
- 📄 Create `lib/adobe-commerce/client-builder/index.[js/ts]` (based on detected language)
|
|
284
|
+
- Implement `AdobeCommerceClientBuilder` class:
|
|
285
|
+
- Singleton pattern for reusable client instance
|
|
286
|
+
- `getClient()` method returning configured AdobeCommerceClient
|
|
287
|
+
- [Connection method] initialization (Oauth1aConnection / ImsConnection / BasicAuthConnection)
|
|
288
|
+
- Environment variable validation
|
|
289
|
+
- Error handling for connection failures
|
|
290
|
+
|
|
291
|
+
[If client builder already exists:]
|
|
292
|
+
|
|
293
|
+
**1. Client Builder (EXISTING)**
|
|
294
|
+
|
|
295
|
+
- ✅ Reuse existing `AdobeCommerceClientBuilder`
|
|
296
|
+
- No changes to client builder
|
|
297
|
+
|
|
298
|
+
**2. Action Integration**
|
|
299
|
+
|
|
300
|
+
- ✏️ Update `[action-path]/index.[js/ts]`
|
|
301
|
+
- Import `AdobeCommerceClientBuilder` from `lib/adobe-commerce/client-builder`
|
|
302
|
+
- Use `getClient()` method to get Commerce client instance
|
|
303
|
+
- Add Commerce API operation logic for [operation description]
|
|
304
|
+
- Add structured logging for Commerce API calls
|
|
305
|
+
- Add error handling for API failures
|
|
306
|
+
|
|
307
|
+
**3. Environment Variables**
|
|
308
|
+
|
|
309
|
+
- ✏️ Update project root `.env` file with placeholder environment variables (if not already present)
|
|
310
|
+
- If `.env` doesn't exist, create it in the project root directory
|
|
311
|
+
|
|
312
|
+
**Files to Create/Modify:**
|
|
313
|
+
|
|
314
|
+
[If client builder does NOT exist:]
|
|
315
|
+
|
|
316
|
+
- 📄 `lib/adobe-commerce/client-builder/index.[js/ts]` - NEW client builder
|
|
317
|
+
|
|
318
|
+
[Always:]
|
|
319
|
+
|
|
320
|
+
- ✏️ `[action-path]/index.[js/ts]` - Add Commerce API integration
|
|
321
|
+
- 📄/✏️ `.env` (project root) - Create or update with environment variable placeholders
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
[If Direct Connection Approach:]
|
|
326
|
+
|
|
327
|
+
**1. Action Implementation**
|
|
328
|
+
|
|
329
|
+
- ✏️ Update `[action-path]/index.[js/ts]`
|
|
330
|
+
- Import `AdobeCommerceClient` and connection class from `@adobe-commerce/aio-toolkit`
|
|
331
|
+
- Create connection instance ([Oauth1aConnection / ImsConnection / BasicAuthConnection])
|
|
332
|
+
- Initialize `AdobeCommerceClient` with connection
|
|
333
|
+
- Add Commerce API operation logic for [operation description]
|
|
334
|
+
- Add structured logging for Commerce API calls
|
|
335
|
+
- Add error handling for API and connection failures
|
|
336
|
+
- Add environment variable validation
|
|
337
|
+
|
|
338
|
+
**2. Environment Variables**
|
|
339
|
+
|
|
340
|
+
- ✏️ Update project root `.env` file with placeholder environment variables (if not already present)
|
|
341
|
+
- If `.env` doesn't exist, create it in the project root directory
|
|
342
|
+
|
|
343
|
+
**Files to Create/Modify:**
|
|
344
|
+
|
|
345
|
+
- ✏️ `[action-path]/index.[js/ts]` - Add direct Commerce API integration
|
|
346
|
+
- 📄/✏️ `.env` (project root) - Create or update with environment variable placeholders
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
**Should I proceed with this implementation?**
|
|
351
|
+
|
|
352
|
+
## Step 4: Generate Implementation
|
|
353
|
+
|
|
354
|
+
Once confirmed, follow the implementation path based on the chosen approach:
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
### Path A: Centralized Client Builder Approach (Recommended)
|
|
359
|
+
|
|
360
|
+
#### Step 4.1: Check for Existing Client Builder
|
|
361
|
+
|
|
362
|
+
1. Check if `lib/adobe-commerce/client-builder/index.[js/ts]` exists in root or extension
|
|
363
|
+
2. If exists: Skip to Step 4.3 (Action Integration)
|
|
364
|
+
3. If NOT exists: Continue to Step 4.2
|
|
365
|
+
|
|
366
|
+
#### Step 4.2: Create AdobeCommerceClientBuilder (if not exists)
|
|
367
|
+
|
|
368
|
+
**Directory Structure:**
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
lib/
|
|
372
|
+
└── adobe-commerce/
|
|
373
|
+
└── client-builder/
|
|
374
|
+
└── index.[js/ts] # Extension based on auto-detected language
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Create the centralized client builder class that will be reused across multiple actions.
|
|
378
|
+
|
|
379
|
+
**Note**: Use the language detected in Step 1 (TypeScript or JavaScript) for all code generation.
|
|
380
|
+
|
|
381
|
+
##### OAuth 1.0a Client Builder
|
|
382
|
+
|
|
383
|
+
**JavaScript Example:**
|
|
384
|
+
|
|
385
|
+
```javascript
|
|
386
|
+
/*
|
|
387
|
+
* <license header>
|
|
388
|
+
*/
|
|
389
|
+
|
|
390
|
+
const { Oauth1aConnection, AdobeCommerceClient } = require('@adobe-commerce/aio-toolkit');
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Centralized Adobe Commerce Client Builder (OAuth 1.0a)
|
|
394
|
+
*
|
|
395
|
+
* This class implements a singleton pattern to create and reuse
|
|
396
|
+
* a single AdobeCommerceClient instance across multiple action invocations.
|
|
397
|
+
*/
|
|
398
|
+
class AdobeCommerceClientBuilder {
|
|
399
|
+
// Commerce connection credentials
|
|
400
|
+
commerceBaseUrl = null;
|
|
401
|
+
commerceConsumerKey = null;
|
|
402
|
+
commerceConsumerSecret = null;
|
|
403
|
+
commerceAccessToken = null;
|
|
404
|
+
commerceAccessTokenSecret = null;
|
|
405
|
+
|
|
406
|
+
// Singleton client instance (reused across calls)
|
|
407
|
+
client = null;
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Initialize the client builder with OAuth 1.0a credentials
|
|
411
|
+
*
|
|
412
|
+
* @param {string} commerceBaseUrl - Commerce REST API base URL (e.g., https://your-store.com/rest/V1)
|
|
413
|
+
* @param {string} commerceConsumerKey - OAuth consumer key from Commerce Admin
|
|
414
|
+
* @param {string} commerceConsumerSecret - OAuth consumer secret from Commerce Admin
|
|
415
|
+
* @param {string} commerceAccessToken - OAuth access token from Commerce Admin
|
|
416
|
+
* @param {string} commerceAccessTokenSecret - OAuth access token secret from Commerce Admin
|
|
417
|
+
*/
|
|
418
|
+
constructor(
|
|
419
|
+
commerceBaseUrl,
|
|
420
|
+
commerceConsumerKey,
|
|
421
|
+
commerceConsumerSecret,
|
|
422
|
+
commerceAccessToken,
|
|
423
|
+
commerceAccessTokenSecret
|
|
424
|
+
) {
|
|
425
|
+
this.commerceBaseUrl = commerceBaseUrl;
|
|
426
|
+
this.commerceConsumerKey = commerceConsumerKey;
|
|
427
|
+
this.commerceConsumerSecret = commerceConsumerSecret;
|
|
428
|
+
this.commerceAccessToken = commerceAccessToken;
|
|
429
|
+
this.commerceAccessTokenSecret = commerceAccessTokenSecret;
|
|
430
|
+
this.client = null;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Get or create the Commerce client instance
|
|
435
|
+
*
|
|
436
|
+
* Returns the cached client if it exists, otherwise creates a new one.
|
|
437
|
+
* This implements the singleton pattern to avoid recreating the client on every call.
|
|
438
|
+
*
|
|
439
|
+
* @returns {AdobeCommerceClient} Configured Commerce API client
|
|
440
|
+
*/
|
|
441
|
+
getClient() {
|
|
442
|
+
// Return cached client if already created (singleton pattern)
|
|
443
|
+
if (this.client) {
|
|
444
|
+
return this.client;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Create OAuth 1.0a connection
|
|
448
|
+
const connection = new Oauth1aConnection(
|
|
449
|
+
this.commerceConsumerKey,
|
|
450
|
+
this.commerceConsumerSecret,
|
|
451
|
+
this.commerceAccessToken,
|
|
452
|
+
this.commerceAccessTokenSecret
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
// Create and cache the Commerce client
|
|
456
|
+
this.client = new AdobeCommerceClient(this.commerceBaseUrl, connection);
|
|
457
|
+
return this.client;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
module.exports = AdobeCommerceClientBuilder;
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**TypeScript Example:** Same as JavaScript with type annotations:
|
|
465
|
+
|
|
466
|
+
- Add `private` to all properties
|
|
467
|
+
- Add types to constructor parameters
|
|
468
|
+
- Add return type `: AdobeCommerceClient` to `getClient()`
|
|
469
|
+
- Use `export default` instead of `module.exports`
|
|
470
|
+
|
|
471
|
+
##### IMS Connection Client Builder
|
|
472
|
+
|
|
473
|
+
**JavaScript Example:**
|
|
474
|
+
|
|
475
|
+
```javascript
|
|
476
|
+
/*
|
|
477
|
+
* <license header>
|
|
478
|
+
*/
|
|
479
|
+
|
|
480
|
+
const { ImsConnection, AdobeCommerceClient, AdobeAuth } = require('@adobe-commerce/aio-toolkit');
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Centralized Adobe Commerce Client Builder (IMS Connection)
|
|
484
|
+
*
|
|
485
|
+
* This class implements a singleton pattern to create and reuse
|
|
486
|
+
* a single AdobeCommerceClient instance across multiple action invocations.
|
|
487
|
+
* Uses Adobe Identity Management Services (IMS) for authentication.
|
|
488
|
+
*/
|
|
489
|
+
class AdobeCommerceClientBuilder {
|
|
490
|
+
// Commerce base URL
|
|
491
|
+
commerceBaseUrl = null;
|
|
492
|
+
|
|
493
|
+
// IMS credentials for authentication
|
|
494
|
+
imsClientId = null;
|
|
495
|
+
imsClientSecret = null;
|
|
496
|
+
imsTechnicalAccountId = null;
|
|
497
|
+
imsTechnicalAccountEmail = null;
|
|
498
|
+
imsOrgId = null;
|
|
499
|
+
imsScopes = null;
|
|
500
|
+
|
|
501
|
+
// Singleton client instance (reused across calls)
|
|
502
|
+
client = null;
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Initialize the client builder with IMS credentials
|
|
506
|
+
*
|
|
507
|
+
* @param {string} commerceBaseUrl - Commerce REST API base URL (e.g., https://your-store.com/rest/V1)
|
|
508
|
+
* @param {string} imsClientId - IMS client ID from Adobe Developer Console
|
|
509
|
+
* @param {string} imsClientSecret - IMS client secret from Adobe Developer Console
|
|
510
|
+
* @param {string} imsTechnicalAccountId - IMS technical account ID
|
|
511
|
+
* @param {string} imsTechnicalAccountEmail - IMS technical account email
|
|
512
|
+
* @param {string} imsOrgId - IMS organization ID
|
|
513
|
+
* @param {string} imsScopes - Comma-separated list of IMS scopes
|
|
514
|
+
*/
|
|
515
|
+
constructor(
|
|
516
|
+
commerceBaseUrl,
|
|
517
|
+
imsClientId,
|
|
518
|
+
imsClientSecret,
|
|
519
|
+
imsTechnicalAccountId,
|
|
520
|
+
imsTechnicalAccountEmail,
|
|
521
|
+
imsOrgId,
|
|
522
|
+
imsScopes
|
|
523
|
+
) {
|
|
524
|
+
this.commerceBaseUrl = commerceBaseUrl;
|
|
525
|
+
this.imsClientId = imsClientId;
|
|
526
|
+
this.imsClientSecret = imsClientSecret;
|
|
527
|
+
this.imsTechnicalAccountId = imsTechnicalAccountId;
|
|
528
|
+
this.imsTechnicalAccountEmail = imsTechnicalAccountEmail;
|
|
529
|
+
this.imsOrgId = imsOrgId;
|
|
530
|
+
this.imsScopes = imsScopes;
|
|
531
|
+
this.client = null;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Get or create the Commerce client instance
|
|
536
|
+
*
|
|
537
|
+
* Returns the cached client if it exists, otherwise creates a new one.
|
|
538
|
+
* This implements the singleton pattern to avoid recreating the client on every call.
|
|
539
|
+
*
|
|
540
|
+
* Note: IMS tokens are fetched fresh on each getClient() call to ensure validity.
|
|
541
|
+
*
|
|
542
|
+
* @returns {Promise<AdobeCommerceClient>} Configured Commerce API client
|
|
543
|
+
*/
|
|
544
|
+
async getClient() {
|
|
545
|
+
// Return cached client if already created (singleton pattern)
|
|
546
|
+
if (this.client) {
|
|
547
|
+
return this.client;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Get IMS access token using Adobe Auth
|
|
551
|
+
const token = await AdobeAuth.getToken(
|
|
552
|
+
this.imsClientId,
|
|
553
|
+
this.imsClientSecret,
|
|
554
|
+
this.imsTechnicalAccountId,
|
|
555
|
+
this.imsTechnicalAccountEmail,
|
|
556
|
+
this.imsOrgId,
|
|
557
|
+
this.imsScopes.split(',')
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
// Create IMS connection with the token
|
|
561
|
+
const connection = new ImsConnection(token);
|
|
562
|
+
|
|
563
|
+
// Create and cache the Commerce client
|
|
564
|
+
this.client = new AdobeCommerceClient(this.commerceBaseUrl, connection);
|
|
565
|
+
return this.client;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
module.exports = AdobeCommerceClientBuilder;
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**TypeScript Example:** Same as JavaScript with type annotations:
|
|
573
|
+
|
|
574
|
+
- Add `private` to all properties
|
|
575
|
+
- Add types to constructor parameters (7 IMS params)
|
|
576
|
+
- Add return type `: Promise<AdobeCommerceClient>` to `getClient()`
|
|
577
|
+
- Use `export default` instead of `module.exports`
|
|
578
|
+
|
|
579
|
+
##### Basic Auth Connection Client Builder
|
|
580
|
+
|
|
581
|
+
**JavaScript Example:**
|
|
582
|
+
|
|
583
|
+
```javascript
|
|
584
|
+
/*
|
|
585
|
+
* <license header>
|
|
586
|
+
*/
|
|
587
|
+
|
|
588
|
+
const { BasicAuthConnection, AdobeCommerceClient } = require('@adobe-commerce/aio-toolkit');
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Centralized Adobe Commerce Client Builder (Basic Auth)
|
|
592
|
+
*
|
|
593
|
+
* This class implements a singleton pattern to create and reuse
|
|
594
|
+
* a single AdobeCommerceClient instance across multiple action invocations.
|
|
595
|
+
* Uses HTTP Basic Authentication (username/password).
|
|
596
|
+
*
|
|
597
|
+
* ⚠️ SECURITY WARNING: Basic Auth is less secure than OAuth or IMS.
|
|
598
|
+
* Only use for development/testing or when other methods are not available.
|
|
599
|
+
*/
|
|
600
|
+
class AdobeCommerceClientBuilder {
|
|
601
|
+
// Commerce connection credentials
|
|
602
|
+
commerceBaseUrl = null;
|
|
603
|
+
commerceUsername = null;
|
|
604
|
+
commercePassword = null;
|
|
605
|
+
|
|
606
|
+
// Singleton client instance (reused across calls)
|
|
607
|
+
client = null;
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Initialize the client builder with Basic Auth credentials
|
|
611
|
+
*
|
|
612
|
+
* @param {string} commerceBaseUrl - Commerce REST API base URL (e.g., https://your-store.com/rest/V1)
|
|
613
|
+
* @param {string} commerceUsername - Commerce admin username
|
|
614
|
+
* @param {string} commercePassword - Commerce admin password
|
|
615
|
+
*/
|
|
616
|
+
constructor(commerceBaseUrl, commerceUsername, commercePassword) {
|
|
617
|
+
this.commerceBaseUrl = commerceBaseUrl;
|
|
618
|
+
this.commerceUsername = commerceUsername;
|
|
619
|
+
this.commercePassword = commercePassword;
|
|
620
|
+
this.client = null;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Get or create the Commerce client instance
|
|
625
|
+
*
|
|
626
|
+
* Returns the cached client if it exists, otherwise creates a new one.
|
|
627
|
+
* This implements the singleton pattern to avoid recreating the client on every call.
|
|
628
|
+
*
|
|
629
|
+
* ⚠️ SECURITY NOTE: Credentials are sent with each request using HTTP Basic Auth.
|
|
630
|
+
*
|
|
631
|
+
* @returns {AdobeCommerceClient} Configured Commerce API client
|
|
632
|
+
*/
|
|
633
|
+
getClient() {
|
|
634
|
+
// Return cached client if already created (singleton pattern)
|
|
635
|
+
if (this.client) {
|
|
636
|
+
return this.client;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// Create Basic Auth connection
|
|
640
|
+
const connection = new BasicAuthConnection(this.commerceUsername, this.commercePassword);
|
|
641
|
+
|
|
642
|
+
// Create and cache the Commerce client
|
|
643
|
+
this.client = new AdobeCommerceClient(this.commerceBaseUrl, connection);
|
|
644
|
+
return this.client;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
module.exports = AdobeCommerceClientBuilder;
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
**TypeScript Example:** Same as JavaScript with type annotations:
|
|
652
|
+
|
|
653
|
+
- Add `private` to all properties
|
|
654
|
+
- Add types to constructor parameters (3 Basic Auth params)
|
|
655
|
+
- Add return type `: AdobeCommerceClient` to `getClient()`
|
|
656
|
+
- Use `export default` instead of `module.exports`
|
|
657
|
+
|
|
658
|
+
#### Step 4.3: Integrate Commerce Client into Existing Action
|
|
659
|
+
|
|
660
|
+
**Update the selected action to use the client builder:**
|
|
661
|
+
|
|
662
|
+
Add the following code to your existing action to use the centralized client builder.
|
|
663
|
+
|
|
664
|
+
##### For OAuth 1.0a Connection
|
|
665
|
+
|
|
666
|
+
**JavaScript Example:**
|
|
667
|
+
|
|
668
|
+
```javascript
|
|
669
|
+
// Import the centralized client builder
|
|
670
|
+
const AdobeCommerceClientBuilder = require('../../lib/adobe-commerce/client-builder');
|
|
671
|
+
|
|
672
|
+
// Inside your action logic (works in any action type: RuntimeAction, WebhookAction, EventConsumerAction, GraphQL, etc.)
|
|
673
|
+
|
|
674
|
+
// Step 1: Create client builder instance with OAuth 1.0a credentials from environment variables
|
|
675
|
+
const clientBuilder = new AdobeCommerceClientBuilder(
|
|
676
|
+
params.COMMERCE_BASE_URL,
|
|
677
|
+
params.COMMERCE_CONSUMER_KEY,
|
|
678
|
+
params.COMMERCE_CONSUMER_SECRET,
|
|
679
|
+
params.COMMERCE_ACCESS_TOKEN,
|
|
680
|
+
params.COMMERCE_ACCESS_TOKEN_SECRET
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
// Step 2: Get the Commerce client (cached after first call)
|
|
684
|
+
const client = clientBuilder.getClient();
|
|
685
|
+
|
|
686
|
+
// Step 3: Make API calls to Commerce
|
|
687
|
+
const products = await client.get('products');
|
|
688
|
+
const newProduct = await client.post('products', {}, productData);
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
**TypeScript:** Same as JavaScript, use `import` instead of `require`
|
|
692
|
+
|
|
693
|
+
##### For IMS Connection
|
|
694
|
+
|
|
695
|
+
**JavaScript Example:**
|
|
696
|
+
|
|
697
|
+
```javascript
|
|
698
|
+
// Import the centralized client builder
|
|
699
|
+
const AdobeCommerceClientBuilder = require('../../lib/adobe-commerce/client-builder');
|
|
700
|
+
|
|
701
|
+
// Inside your action logic (works in any action type: RuntimeAction, WebhookAction, EventConsumerAction, GraphQL, etc.)
|
|
702
|
+
|
|
703
|
+
// Step 1: Create client builder instance with IMS credentials from environment variables
|
|
704
|
+
const clientBuilder = new AdobeCommerceClientBuilder(
|
|
705
|
+
params.COMMERCE_BASE_URL,
|
|
706
|
+
params.IMS_CLIENT_ID,
|
|
707
|
+
params.IMS_CLIENT_SECRET,
|
|
708
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
709
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
710
|
+
params.IMS_ORD_ID,
|
|
711
|
+
params.IMS_SCOPES // Comma-separated scopes
|
|
712
|
+
);
|
|
713
|
+
|
|
714
|
+
// Step 2: Get the Commerce client (cached after first call)
|
|
715
|
+
// Note: IMS connection is async due to token fetching
|
|
716
|
+
const client = await clientBuilder.getClient();
|
|
717
|
+
|
|
718
|
+
// Step 3: Make API calls to Commerce
|
|
719
|
+
const customers = await client.get('customers/search');
|
|
720
|
+
const newCustomer = await client.post('customers', {}, customerData);
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**TypeScript:** Same as JavaScript, use `import` instead of `require`
|
|
724
|
+
|
|
725
|
+
##### For Basic Auth Connection
|
|
726
|
+
|
|
727
|
+
**JavaScript Example:**
|
|
728
|
+
|
|
729
|
+
```javascript
|
|
730
|
+
// Import the centralized client builder
|
|
731
|
+
const AdobeCommerceClientBuilder = require('../../lib/adobe-commerce/client-builder');
|
|
732
|
+
|
|
733
|
+
// Inside your action logic (works in any action type: RuntimeAction, WebhookAction, EventConsumerAction, GraphQL, etc.)
|
|
734
|
+
|
|
735
|
+
// Step 1: Create client builder instance with Basic Auth credentials from environment variables
|
|
736
|
+
// ⚠️ WARNING: Basic Auth is less secure - use only for development/testing
|
|
737
|
+
const clientBuilder = new AdobeCommerceClientBuilder(
|
|
738
|
+
params.COMMERCE_BASE_URL,
|
|
739
|
+
params.COMMERCE_USERNAME,
|
|
740
|
+
params.COMMERCE_PASSWORD
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
// Step 2: Get the Commerce client (cached after first call)
|
|
744
|
+
const client = clientBuilder.getClient();
|
|
745
|
+
|
|
746
|
+
// Step 3: Make API calls to Commerce
|
|
747
|
+
const orders = await client.get('orders');
|
|
748
|
+
const newOrder = await client.post('orders', {}, orderData);
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
**TypeScript:** Same as JavaScript, use `import` instead of `require`
|
|
752
|
+
|
|
753
|
+
**Benefits of Centralized Client Builder:**
|
|
754
|
+
|
|
755
|
+
- ✅ **Singleton Pattern**: Client instance is reused, not recreated on every call
|
|
756
|
+
- ✅ **Consistent Configuration**: All actions use the same client configuration
|
|
757
|
+
- ✅ **Easy Maintenance**: Update connection logic in one place
|
|
758
|
+
- ✅ **Reusable**: Can be used across RuntimeAction, WebhookAction, GraphQL resolvers, EventConsumerAction, etc.
|
|
759
|
+
|
|
760
|
+
#### Step 4.4: Add Environment Variables
|
|
761
|
+
|
|
762
|
+
**Update project root `.env` file with connection credentials:**
|
|
763
|
+
|
|
764
|
+
1. **Check for `.env` file**: Look for `.env` file in the project root directory (workspace root)
|
|
765
|
+
2. **Create if missing**: If `.env` doesn't exist, create it in the project root
|
|
766
|
+
3. **Add variables**: Add the appropriate environment variables based on connection method
|
|
767
|
+
|
|
768
|
+
The environment variables are the same as for Direct Connection. See **Path B: Step 4.2** for detailed instructions on setting up environment variables for each connection method (OAuth 1.0a, IMS, or Basic Auth).
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
### Path B: Direct Connection Approach
|
|
773
|
+
|
|
774
|
+
#### Step 4.1: Add Direct Commerce Client to Existing Action
|
|
775
|
+
|
|
776
|
+
**Update the selected action with direct connection and client:**
|
|
777
|
+
|
|
778
|
+
These implementations can be used in **any action type**: RuntimeAction, WebhookAction, GraphQL resolvers, EventConsumerAction, or OpenwhiskAction.
|
|
779
|
+
|
|
780
|
+
##### Template: OAuth 1.0a Connection (Direct Implementation)
|
|
781
|
+
|
|
782
|
+
**JavaScript Example:**
|
|
783
|
+
|
|
784
|
+
```javascript
|
|
785
|
+
const { AdobeCommerceClient, Oauth1aConnection } = require('@adobe-commerce/aio-toolkit');
|
|
786
|
+
|
|
787
|
+
// Create OAuth 1.0a connection
|
|
788
|
+
const connection = new Oauth1aConnection(
|
|
789
|
+
params.COMMERCE_CONSUMER_KEY,
|
|
790
|
+
params.COMMERCE_CONSUMER_SECRET,
|
|
791
|
+
params.COMMERCE_ACCESS_TOKEN,
|
|
792
|
+
params.COMMERCE_ACCESS_TOKEN_SECRET
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
// Create Commerce client
|
|
796
|
+
const client = new AdobeCommerceClient(params.COMMERCE_BASE_URL, connection);
|
|
797
|
+
|
|
798
|
+
// Make API calls
|
|
799
|
+
// GET request
|
|
800
|
+
const products = await client.get('products');
|
|
801
|
+
const product = await client.get('products/SKU123');
|
|
802
|
+
|
|
803
|
+
// POST request
|
|
804
|
+
const newProduct = await client.post(
|
|
805
|
+
'products',
|
|
806
|
+
{},
|
|
807
|
+
{
|
|
808
|
+
product: {
|
|
809
|
+
sku: 'NEW-SKU',
|
|
810
|
+
name: 'New Product',
|
|
811
|
+
price: 99.99,
|
|
812
|
+
// ... other product data
|
|
813
|
+
},
|
|
814
|
+
}
|
|
815
|
+
);
|
|
816
|
+
|
|
817
|
+
// PUT request
|
|
818
|
+
const updatedProduct = await client.put(
|
|
819
|
+
'products/SKU123',
|
|
820
|
+
{},
|
|
821
|
+
{
|
|
822
|
+
product: {
|
|
823
|
+
name: 'Updated Product Name',
|
|
824
|
+
price: 89.99,
|
|
825
|
+
},
|
|
826
|
+
}
|
|
827
|
+
);
|
|
828
|
+
|
|
829
|
+
// DELETE request
|
|
830
|
+
await client.delete('products/SKU123');
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
**TypeScript:** Same as JavaScript with type safety:
|
|
834
|
+
|
|
835
|
+
- Use `import` instead of `require`
|
|
836
|
+
- Define interfaces for entities (e.g., `interface Product { sku: string; name: string; price: number; }`)
|
|
837
|
+
- Use generics: `client.get<Product[]>('products')`, `client.post<Product>(...)`
|
|
838
|
+
|
|
839
|
+
##### Template: IMS Connection (Direct Implementation)
|
|
840
|
+
|
|
841
|
+
**JavaScript Example:**
|
|
842
|
+
|
|
843
|
+
```javascript
|
|
844
|
+
const { AdobeCommerceClient, ImsConnection, AdobeAuth } = require('@adobe-commerce/aio-toolkit');
|
|
845
|
+
|
|
846
|
+
// Get IMS token
|
|
847
|
+
const token = await AdobeAuth.getToken(
|
|
848
|
+
params.IMS_CLIENT_ID,
|
|
849
|
+
params.IMS_CLIENT_SECRET,
|
|
850
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
851
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
852
|
+
params.IMS_ORD_ID,
|
|
853
|
+
params.IMS_SCOPES.split(',')
|
|
854
|
+
);
|
|
855
|
+
|
|
856
|
+
// Create IMS connection
|
|
857
|
+
const connection = new ImsConnection(token);
|
|
858
|
+
|
|
859
|
+
// Create Commerce client
|
|
860
|
+
const client = new AdobeCommerceClient(params.COMMERCE_BASE_URL, connection);
|
|
861
|
+
|
|
862
|
+
// Make API calls
|
|
863
|
+
// GET request
|
|
864
|
+
const customers = await client.get('customers/search', { searchCriteria: {} });
|
|
865
|
+
const customer = await client.get('customers/123');
|
|
866
|
+
|
|
867
|
+
// POST request
|
|
868
|
+
const newCustomer = await client.post(
|
|
869
|
+
'customers',
|
|
870
|
+
{},
|
|
871
|
+
{
|
|
872
|
+
customer: {
|
|
873
|
+
email: 'customer@example.com',
|
|
874
|
+
firstname: 'John',
|
|
875
|
+
lastname: 'Doe',
|
|
876
|
+
},
|
|
877
|
+
}
|
|
878
|
+
);
|
|
879
|
+
|
|
880
|
+
// PUT request
|
|
881
|
+
const updatedCustomer = await client.put(
|
|
882
|
+
'customers/123',
|
|
883
|
+
{},
|
|
884
|
+
{
|
|
885
|
+
customer: {
|
|
886
|
+
firstname: 'Jane',
|
|
887
|
+
},
|
|
888
|
+
}
|
|
889
|
+
);
|
|
890
|
+
|
|
891
|
+
// DELETE request
|
|
892
|
+
await client.delete('customers/123');
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
**TypeScript:** Same as JavaScript with type safety (define `interface Customer` and use generics)
|
|
896
|
+
|
|
897
|
+
##### Template: Basic Auth Connection (Direct Implementation)
|
|
898
|
+
|
|
899
|
+
**JavaScript Example:**
|
|
900
|
+
|
|
901
|
+
```javascript
|
|
902
|
+
const { AdobeCommerceClient, BasicAuthConnection } = require('@adobe-commerce/aio-toolkit');
|
|
903
|
+
|
|
904
|
+
// Create Basic Auth connection
|
|
905
|
+
const connection = new BasicAuthConnection(params.COMMERCE_USERNAME, params.COMMERCE_PASSWORD);
|
|
906
|
+
|
|
907
|
+
// Create Commerce client
|
|
908
|
+
const client = new AdobeCommerceClient(params.COMMERCE_BASE_URL, connection);
|
|
909
|
+
|
|
910
|
+
// Make API calls
|
|
911
|
+
// GET request
|
|
912
|
+
const orders = await client.get('orders');
|
|
913
|
+
const order = await client.get('orders/123');
|
|
914
|
+
|
|
915
|
+
// POST request
|
|
916
|
+
const newOrder = await client.post(
|
|
917
|
+
'orders',
|
|
918
|
+
{},
|
|
919
|
+
{
|
|
920
|
+
entity: {
|
|
921
|
+
customer_email: 'customer@example.com',
|
|
922
|
+
items: [
|
|
923
|
+
{
|
|
924
|
+
sku: 'PRODUCT-SKU',
|
|
925
|
+
qty: 1,
|
|
926
|
+
price: 99.99,
|
|
927
|
+
},
|
|
928
|
+
],
|
|
929
|
+
},
|
|
930
|
+
}
|
|
931
|
+
);
|
|
932
|
+
|
|
933
|
+
// PUT request
|
|
934
|
+
const updatedOrder = await client.put(
|
|
935
|
+
'orders/123',
|
|
936
|
+
{},
|
|
937
|
+
{
|
|
938
|
+
entity: {
|
|
939
|
+
status: 'processing',
|
|
940
|
+
},
|
|
941
|
+
}
|
|
942
|
+
);
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
**TypeScript:** Same as JavaScript with type safety (define `interface Order` and use generics)
|
|
946
|
+
|
|
947
|
+
**⚠️ Security Warning:** Basic Auth is NOT recommended for production environments. Use OAuth 1.0a or IMS for production deployments.
|
|
948
|
+
|
|
949
|
+
#### Step 4.2: Add Environment Variables
|
|
950
|
+
|
|
951
|
+
**Update project root `.env` file with connection credentials:**
|
|
952
|
+
|
|
953
|
+
1. **Locate `.env` file**: Find the `.env` file in the project root directory (workspace root)
|
|
954
|
+
2. **Create if missing**: If `.env` doesn't exist, create it in the project root directory
|
|
955
|
+
3. **Add variables**: Add the appropriate environment variables based on the connection method chosen
|
|
956
|
+
|
|
957
|
+
**Important**: Always use the project's `.env` file located at the workspace root, NOT a global `.env` file.
|
|
958
|
+
|
|
959
|
+
##### For OAuth 1.0a Connection:
|
|
960
|
+
|
|
961
|
+
**Add to project root `.env` file:**
|
|
962
|
+
|
|
963
|
+
```bash
|
|
964
|
+
# Adobe Commerce REST API Configuration (OAuth 1.0a)
|
|
965
|
+
COMMERCE_BASE_URL=https://your-commerce-store.com/rest/V1
|
|
966
|
+
COMMERCE_CONSUMER_KEY=
|
|
967
|
+
COMMERCE_CONSUMER_SECRET=
|
|
968
|
+
COMMERCE_ACCESS_TOKEN=
|
|
969
|
+
COMMERCE_ACCESS_TOKEN_SECRET=
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
**How to get credentials:**
|
|
973
|
+
|
|
974
|
+
1. Log in to Commerce Admin
|
|
975
|
+
2. Navigate to **System** > **Extensions** > **Integrations**
|
|
976
|
+
3. Create a new integration or select an existing one
|
|
977
|
+
4. Copy the **Consumer Key**, **Consumer Secret**, **Access Token**, and **Access Token Secret**
|
|
978
|
+
5. Paste them into your project root `.env` file
|
|
979
|
+
|
|
980
|
+
##### For IMS Connection:
|
|
981
|
+
|
|
982
|
+
**Add to project root `.env` file:**
|
|
983
|
+
|
|
984
|
+
```bash
|
|
985
|
+
# Adobe Commerce REST API Configuration (IMS)
|
|
986
|
+
COMMERCE_BASE_URL=https://your-commerce-cloud.adobe.com/rest/V1
|
|
987
|
+
IMS_CLIENT_ID=
|
|
988
|
+
IMS_CLIENT_SECRET=
|
|
989
|
+
IMS_TECHNICAL_ACCOUNT_ID=
|
|
990
|
+
IMS_TECHNICAL_ACCOUNT_EMAIL=
|
|
991
|
+
IMS_ORD_ID=
|
|
992
|
+
IMS_SCOPES=openid,AdobeID,read_organizations
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
**How to get credentials:**
|
|
996
|
+
|
|
997
|
+
1. Log in to [Adobe Developer Console](https://developer.adobe.com/console)
|
|
998
|
+
2. Select your project or create a new one
|
|
999
|
+
3. Add Adobe Commerce API to your project
|
|
1000
|
+
4. Generate or use existing Service Account (JWT) credentials
|
|
1001
|
+
5. Copy the credentials and paste them into your project root `.env` file
|
|
1002
|
+
6. Adjust `IMS_SCOPES` as needed (comma-separated, no spaces)
|
|
1003
|
+
|
|
1004
|
+
##### For Basic Auth Connection:
|
|
1005
|
+
|
|
1006
|
+
**Add to project root `.env` file:**
|
|
1007
|
+
|
|
1008
|
+
```bash
|
|
1009
|
+
# Adobe Commerce REST API Configuration (Basic Auth)
|
|
1010
|
+
COMMERCE_BASE_URL=https://your-commerce-store.com/rest/V1
|
|
1011
|
+
COMMERCE_USERNAME=
|
|
1012
|
+
COMMERCE_PASSWORD=
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
**How to get credentials:**
|
|
1016
|
+
|
|
1017
|
+
1. Use Commerce admin username and password
|
|
1018
|
+
2. OR create a dedicated API user in Commerce Admin
|
|
1019
|
+
3. Paste credentials into your project root `.env` file
|
|
1020
|
+
|
|
1021
|
+
**⚠️ Security Warning:** Basic Auth is NOT recommended for production environments. Use OAuth 1.0a or IMS for production deployments.
|
|
1022
|
+
|
|
1023
|
+
**Important Notes:**
|
|
1024
|
+
|
|
1025
|
+
- The `.env` file should be in your project root directory (workspace root)
|
|
1026
|
+
- Never commit the `.env` file to version control
|
|
1027
|
+
- Ensure `.env` is in your `.gitignore` file
|
|
1028
|
+
- Keep credentials secure and rotate them regularly
|
|
1029
|
+
- Use different credentials for different environments (dev, staging, production)
|
|
1030
|
+
|
|
1031
|
+
## Step 5: Configuration and Additional Recommendations
|
|
1032
|
+
|
|
1033
|
+
### A. Action Configuration
|
|
1034
|
+
|
|
1035
|
+
Update action configuration to include Commerce credentials as inputs:
|
|
1036
|
+
|
|
1037
|
+
```yaml
|
|
1038
|
+
inputs:
|
|
1039
|
+
LOG_LEVEL: debug
|
|
1040
|
+
COMMERCE_BASE_URL: $COMMERCE_BASE_URL
|
|
1041
|
+
# For OAuth: Add COMMERCE_CONSUMER_KEY, COMMERCE_CONSUMER_SECRET, COMMERCE_ACCESS_TOKEN, COMMERCE_ACCESS_TOKEN_SECRET
|
|
1042
|
+
# For IMS: Add IMS_CLIENT_ID, IMS_CLIENT_SECRET, IMS_TECHNICAL_ACCOUNT_ID, IMS_TECHNICAL_ACCOUNT_EMAIL, IMS_ORD_ID, IMS_SCOPES
|
|
1043
|
+
# For Basic Auth: Add COMMERCE_USERNAME, COMMERCE_PASSWORD
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
### B. Testing & Error Handling
|
|
1047
|
+
|
|
1048
|
+
1. **Testing**: Create unit tests (`test/[action-name].test.[js/ts]`) and E2E tests (`e2e/[action-name].e2e.test.[js/ts]`)
|
|
1049
|
+
2. **Error Handling**: Wrap API calls in try-catch, check `error.response` for Commerce errors, use `RuntimeActionResponse.error()`
|
|
1050
|
+
3. **Local Testing**: Use `aio app dev` and MCP server (`/search-commerce-docs`) for API pattern verification
|
|
1051
|
+
|
|
1052
|
+
### C. Best Practices
|
|
1053
|
+
|
|
1054
|
+
- **Documentation**: Document operations, env vars, API responses, and error scenarios
|
|
1055
|
+
- **Performance**: Centralized Client Builder uses singleton pattern (better for multiple actions)
|
|
1056
|
+
- **Telemetry**: Recommend enabling New Relic telemetry for Commerce API observability
|
|
1057
|
+
- **Security**: Never commit `.env`, rotate credentials, use OAuth/IMS for production (not Basic Auth)
|
|
1058
|
+
|
|
1059
|
+
## Key Components from @adobe-commerce/aio-toolkit
|
|
1060
|
+
|
|
1061
|
+
### AdobeCommerceClient Class
|
|
1062
|
+
|
|
1063
|
+
Main class for interacting with Adobe Commerce REST API
|
|
1064
|
+
|
|
1065
|
+
- **Purpose**: Provides methods to interact with Adobe Commerce REST API
|
|
1066
|
+
- **Constructor**: `new AdobeCommerceClient(baseUrl, connection)`
|
|
1067
|
+
- `baseUrl`: Commerce REST API base URL (e.g., `https://your-store.com/rest/V1`)
|
|
1068
|
+
- `connection`: Connection instance (Oauth1aConnection, ImsConnection, or BasicAuthConnection)
|
|
1069
|
+
|
|
1070
|
+
**Available Methods:**
|
|
1071
|
+
|
|
1072
|
+
#### get(endpoint, queryParams?)
|
|
1073
|
+
|
|
1074
|
+
Perform GET request to Commerce API
|
|
1075
|
+
|
|
1076
|
+
- **Parameters**:
|
|
1077
|
+
- `endpoint` (string): API endpoint path (e.g., `'products'`, `'products/SKU123'`)
|
|
1078
|
+
- `queryParams` (object, optional): Query parameters for the request
|
|
1079
|
+
- **Returns**: Promise with response data
|
|
1080
|
+
- **Example**:
|
|
1081
|
+
```javascript
|
|
1082
|
+
const products = await client.get('products');
|
|
1083
|
+
const product = await client.get('products/SKU123');
|
|
1084
|
+
const searchResults = await client.get('products', { searchCriteria: { pageSize: 10 } });
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
#### post(endpoint, queryParams?, body?)
|
|
1088
|
+
|
|
1089
|
+
Perform POST request to Commerce API
|
|
1090
|
+
|
|
1091
|
+
- **Parameters**:
|
|
1092
|
+
- `endpoint` (string): API endpoint path
|
|
1093
|
+
- `queryParams` (object, optional): Query parameters
|
|
1094
|
+
- `body` (object, optional): Request body
|
|
1095
|
+
- **Returns**: Promise with response data
|
|
1096
|
+
- **Example**:
|
|
1097
|
+
```javascript
|
|
1098
|
+
const newProduct = await client.post(
|
|
1099
|
+
'products',
|
|
1100
|
+
{},
|
|
1101
|
+
{
|
|
1102
|
+
product: {
|
|
1103
|
+
sku: 'NEW-SKU',
|
|
1104
|
+
name: 'New Product',
|
|
1105
|
+
price: 99.99,
|
|
1106
|
+
},
|
|
1107
|
+
}
|
|
1108
|
+
);
|
|
1109
|
+
```
|
|
1110
|
+
|
|
1111
|
+
#### put(endpoint, queryParams?, body?)
|
|
1112
|
+
|
|
1113
|
+
Perform PUT request to Commerce API
|
|
1114
|
+
|
|
1115
|
+
- **Parameters**:
|
|
1116
|
+
- `endpoint` (string): API endpoint path
|
|
1117
|
+
- `queryParams` (object, optional): Query parameters
|
|
1118
|
+
- `body` (object, optional): Request body
|
|
1119
|
+
- **Returns**: Promise with response data
|
|
1120
|
+
- **Example**:
|
|
1121
|
+
```javascript
|
|
1122
|
+
const updated = await client.put(
|
|
1123
|
+
'products/SKU123',
|
|
1124
|
+
{},
|
|
1125
|
+
{
|
|
1126
|
+
product: {
|
|
1127
|
+
name: 'Updated Name',
|
|
1128
|
+
price: 89.99,
|
|
1129
|
+
},
|
|
1130
|
+
}
|
|
1131
|
+
);
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
#### delete(endpoint, queryParams?)
|
|
1135
|
+
|
|
1136
|
+
Perform DELETE request to Commerce API
|
|
1137
|
+
|
|
1138
|
+
- **Parameters**:
|
|
1139
|
+
- `endpoint` (string): API endpoint path
|
|
1140
|
+
- `queryParams` (object, optional): Query parameters
|
|
1141
|
+
- **Returns**: Promise with response data
|
|
1142
|
+
- **Example**:
|
|
1143
|
+
```javascript
|
|
1144
|
+
await client.delete('products/SKU123');
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
### Oauth1aConnection Class
|
|
1148
|
+
|
|
1149
|
+
OAuth 1.0a authentication for Commerce
|
|
1150
|
+
|
|
1151
|
+
- **Purpose**: Establishes connection using OAuth 1.0a credentials
|
|
1152
|
+
- **Use Case**: Direct Commerce instance integration (on-premise, self-hosted)
|
|
1153
|
+
- **Constructor**: `new Oauth1aConnection(consumerKey, consumerSecret, accessToken, accessTokenSecret)`
|
|
1154
|
+
- **Required Credentials**:
|
|
1155
|
+
- `consumerKey`: OAuth consumer key from Commerce Admin
|
|
1156
|
+
- `consumerSecret`: OAuth consumer secret from Commerce Admin
|
|
1157
|
+
- `accessToken`: OAuth access token from Commerce Admin
|
|
1158
|
+
- `accessTokenSecret`: OAuth access token secret from Commerce Admin
|
|
1159
|
+
- **How to Get**: Commerce Admin > System > Extensions > Integrations
|
|
1160
|
+
- **Security**: OAuth 1.0a is secure for production use
|
|
1161
|
+
|
|
1162
|
+
### ImsConnection Class
|
|
1163
|
+
|
|
1164
|
+
IMS (Identity Management Services) authentication
|
|
1165
|
+
|
|
1166
|
+
- **Purpose**: Establishes connection using Adobe IMS token
|
|
1167
|
+
- **Use Case**: Adobe Commerce Cloud integration
|
|
1168
|
+
- **Constructor**: `new ImsConnection(token)`
|
|
1169
|
+
- **Required Credentials**:
|
|
1170
|
+
- `token`: IMS access token (obtained via AdobeAuth.getToken())
|
|
1171
|
+
- **How to Get**: Adobe Developer Console > Service Account (JWT) credentials
|
|
1172
|
+
- **Security**: IMS is secure for production use
|
|
1173
|
+
- **Note**: Token must be fetched using `AdobeAuth.getToken()` before creating connection
|
|
1174
|
+
|
|
1175
|
+
### BasicAuthConnection Class
|
|
1176
|
+
|
|
1177
|
+
HTTP Basic Authentication for Commerce
|
|
1178
|
+
|
|
1179
|
+
- **Purpose**: Establishes connection using username/password
|
|
1180
|
+
- **Use Case**: Development/testing environments (NOT recommended for production)
|
|
1181
|
+
- **Constructor**: `new BasicAuthConnection(username, password)`
|
|
1182
|
+
- **Required Credentials**:
|
|
1183
|
+
- `username`: Commerce admin username or API user
|
|
1184
|
+
- `password`: Commerce admin password or API user password
|
|
1185
|
+
- **How to Get**: Use Commerce admin credentials or create dedicated API user
|
|
1186
|
+
- **Security**: ⚠️ **NOT secure for production** - credentials sent with every request
|
|
1187
|
+
- **Recommendation**: Use OAuth 1.0a or IMS for production environments
|
|
1188
|
+
|
|
1189
|
+
### AdobeAuth Class
|
|
1190
|
+
|
|
1191
|
+
Utility class for fetching IMS access tokens
|
|
1192
|
+
|
|
1193
|
+
- **Purpose**: Fetches IMS access tokens for ImsConnection
|
|
1194
|
+
- **Use Case**: Required when using ImsConnection for Commerce Cloud
|
|
1195
|
+
|
|
1196
|
+
#### getToken() Method
|
|
1197
|
+
|
|
1198
|
+
Fetch IMS access token using service account credentials
|
|
1199
|
+
|
|
1200
|
+
- **Parameters**:
|
|
1201
|
+
- `clientId` (string): IMS client ID
|
|
1202
|
+
- `clientSecret` (string): IMS client secret
|
|
1203
|
+
- `technicalAccountId` (string): IMS technical account ID
|
|
1204
|
+
- `technicalAccountEmail` (string): IMS technical account email
|
|
1205
|
+
- `orgId` (string): IMS organization ID
|
|
1206
|
+
- `scopes` (string[]): Array of IMS scopes (e.g., `['openid', 'AdobeID', 'read_organizations']`)
|
|
1207
|
+
- **Returns**: Promise<string> - IMS access token
|
|
1208
|
+
- **Example**:
|
|
1209
|
+
```javascript
|
|
1210
|
+
const token = await AdobeAuth.getToken(
|
|
1211
|
+
params.IMS_CLIENT_ID,
|
|
1212
|
+
params.IMS_CLIENT_SECRET,
|
|
1213
|
+
params.IMS_TECHNICAL_ACCOUNT_ID,
|
|
1214
|
+
params.IMS_TECHNICAL_ACCOUNT_EMAIL,
|
|
1215
|
+
params.IMS_ORD_ID,
|
|
1216
|
+
params.IMS_SCOPES.split(',')
|
|
1217
|
+
);
|
|
1218
|
+
```
|
|
1219
|
+
- **Note**: Tokens are temporary and should be fetched fresh when needed
|
|
1220
|
+
|
|
1221
|
+
## Important Notes
|
|
1222
|
+
|
|
1223
|
+
1. **Authentication Methods**: OAuth 1.0a (on-premise), IMS (Commerce Cloud), Basic Auth (dev/test only, NOT production)
|
|
1224
|
+
|
|
1225
|
+
2. **Credentials Management**: Store in `.env`, add to `.gitignore`, rotate regularly, use different creds per environment
|
|
1226
|
+
|
|
1227
|
+
3. **Implementation Approach**:
|
|
1228
|
+
- **Centralized Client Builder (Recommended)**: Singleton pattern, reusable across actions, in `lib/adobe-commerce/client-builder/`
|
|
1229
|
+
- **Direct Connection**: Simpler, for single-action use cases, connection created per invocation
|
|
1230
|
+
|
|
1231
|
+
4. **Client Builder Reusability**: If in root `lib/`, usable by both root and extension actions. Only create once, reuse everywhere.
|
|
1232
|
+
|
|
1233
|
+
5. **API Usage**: Use REST V1 endpoints (`/rest/V1/products`), wrap calls in try-catch, handle errors with `RuntimeActionResponse.error()`, respect rate limits
|
|
1234
|
+
|
|
1235
|
+
6. **No New Actions Created**: This rule only integrates Commerce API into existing actions. Use "Create Runtime Action" rule first if needed.
|
|
1236
|
+
|
|
1237
|
+
7. **MCP Server Integration**: Use `/search-commerce-docs "How to [operation]"` to discover API patterns, endpoints, and parameters
|
|
1238
|
+
|
|
1239
|
+
8. **Testing**: Create unit tests (`test/[action-name].test.[js/ts]`), E2E tests (`e2e/[action-name].e2e.test.[js/ts]`), use `aio app dev` locally
|
|
1240
|
+
|
|
1241
|
+
9. **Language Auto-Detection**: TypeScript or JavaScript is automatically detected using multiple indicators:
|
|
1242
|
+
- Package dependencies (`typescript`, `ts-loader`, `@types/*`)
|
|
1243
|
+
- Config files (`tsconfig.json`)
|
|
1244
|
+
- Build scripts (TypeScript compilation commands)
|
|
1245
|
+
- Existing `.ts`/`.tsx` files in `actions/`, `src/`, `lib/`
|
|
1246
|
+
- Compiled output paths (`build/` references in config)
|
|
1247
|
+
- **Detection Priority**: If `typescript` + `tsconfig.json` exist OR 2+ indicators found OR `.ts` files exist → TypeScript project
|
|
1248
|
+
- No need to ask developer. TypeScript provides type safety with interfaces (Product, Customer, Order) and generics: `client.get<Product[]>('products')`
|
|
1249
|
+
|
|
1250
|
+
10. **Performance**: Centralized Client Builder caches instance (singleton), better for high-frequency/multiple actions. IMS tokens fetched fresh per `getClient()` call.
|
|
1251
|
+
|
|
1252
|
+
11. **Action Configuration**: Add Commerce env vars as action inputs using `$VARIABLE_NAME` syntax in `app.config.yaml` or `ext.config.yaml`
|
|
1253
|
+
|
|
1254
|
+
12. **Compatibility**: Works with RuntimeAction, WebhookAction, EventConsumerAction, GraphQL resolvers, OpenwhiskAction. Supports root and extension points.
|
|
1255
|
+
|
|
1256
|
+
13. **Telemetry**: Recommend enabling New Relic for Commerce API observability (traces, metrics, logs). Refer to New Relic telemetry setup rule.
|
|
1257
|
+
|
|
1258
|
+
14. **Integration with Action Creation Rules**: This rule is designed to work seamlessly with RuntimeAction, WebhookAction, GraphQLAction, and EventConsumerAction rules. When developers mention Commerce operations during action creation, automatically suggest or trigger this rule for Commerce API integration.
|
|
1259
|
+
|
|
1260
|
+
15. **Edge Case - Ambiguous Language Detection**: If language detection is uncertain (e.g., TypeScript configured but no existing TypeScript files):
|
|
1261
|
+
|
|
1262
|
+
- **Default to JavaScript** if no `.ts` files exist in `actions/` or `lib/` directories
|
|
1263
|
+
- Inform user: "Detected TypeScript setup but no existing TypeScript files. Generating JavaScript code to match existing actions. To use TypeScript, add a `.ts` file first."
|
|
1264
|
+
- **Prefer consistency**: Match the language of existing action files in the project
|
|
1265
|
+
|
|
1266
|
+
## Integration with Other Rules
|
|
1267
|
+
|
|
1268
|
+
**This rule should be referenced in other action creation rules when Commerce operations are mentioned:**
|
|
1269
|
+
|
|
1270
|
+
### Trigger Patterns in Other Rules:
|
|
1271
|
+
|
|
1272
|
+
When developers mention these phrases during action creation in the "Business Logic" question:
|
|
1273
|
+
|
|
1274
|
+
- "Create a product in Commerce"
|
|
1275
|
+
- "Get customer from Commerce"
|
|
1276
|
+
- "Update order in Commerce"
|
|
1277
|
+
- "Call Commerce API"
|
|
1278
|
+
- "Fetch products from Commerce"
|
|
1279
|
+
- "Sync to Commerce"
|
|
1280
|
+
- "Make Commerce API call"
|
|
1281
|
+
- "Interact with Commerce"
|
|
1282
|
+
- Any phrase containing "Commerce" + "API"/"product"/"order"/"customer"
|
|
1283
|
+
|
|
1284
|
+
**Action to take:**
|
|
1285
|
+
|
|
1286
|
+
1. Complete the action creation first (in detected language: TypeScript or JavaScript)
|
|
1287
|
+
2. Then inform the user: "I see you need to integrate with Commerce API. Let me help you set up the Commerce client integration."
|
|
1288
|
+
3. Trigger/reference the "Creating Adobe Commerce Client Operations" rule
|
|
1289
|
+
4. This rule will:
|
|
1290
|
+
- Auto-detect language (already done in Step 1)
|
|
1291
|
+
- Use the same language for Commerce client code
|
|
1292
|
+
- Handle connection methods, client builder, and API integration
|
|
1293
|
+
|
|
1294
|
+
**Example Flow**:
|
|
1295
|
+
|
|
1296
|
+
```
|
|
1297
|
+
User: "Create a runtime action that fetches products from Commerce"
|
|
1298
|
+
AI: ✓ Detected TypeScript project
|
|
1299
|
+
AI: Creating runtime action... [generates .ts file]
|
|
1300
|
+
AI: I see you need to integrate with Commerce API. Let me set up the Commerce client.
|
|
1301
|
+
AI: [Creates TypeScript Commerce client builder in lib/adobe-commerce/client-builder/index.ts]
|
|
1302
|
+
AI: [Integrates Commerce API calls into the action]
|
|
1303
|
+
```
|
|
1304
|
+
|
|
1305
|
+
### Recommended Updates to Action Creation Rules:
|
|
1306
|
+
|
|
1307
|
+
Add this note to the "Business Logic" question in:
|
|
1308
|
+
|
|
1309
|
+
- `create-runtime-action.mdc`
|
|
1310
|
+
- `create-webhook-action.mdc`
|
|
1311
|
+
- `aio-toolkit-create-graphql-action.mdc`
|
|
1312
|
+
- `aio-toolkit-create-event-consumer-action.mdc`
|
|
1313
|
+
|
|
1314
|
+
**Note to add:**
|
|
1315
|
+
|
|
1316
|
+
```
|
|
1317
|
+
**If business logic requires Commerce API operations**:
|
|
1318
|
+
- Complete this action creation first
|
|
1319
|
+
- Then use "Creating Adobe Commerce Client Operations" rule to integrate Commerce API
|
|
1320
|
+
- That rule handles connection setup, client builder, and API calls
|
|
1321
|
+
```
|