@operor/testing 0.1.0
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/API_VALIDATION.md +572 -0
- package/dist/index.d.ts +414 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1608 -0
- package/dist/index.js.map +1 -0
- package/fixtures/sample-tests.csv +10 -0
- package/package.json +31 -0
- package/src/CSVLoader.ts +83 -0
- package/src/ConversationEvaluator.ts +254 -0
- package/src/ConversationRunner.ts +267 -0
- package/src/CustomerSimulator.ts +106 -0
- package/src/MockShopifySkill.ts +336 -0
- package/src/SimulationRunner.ts +425 -0
- package/src/SkillTestHarness.ts +220 -0
- package/src/TestCaseEvaluator.ts +296 -0
- package/src/TestSuiteRunner.ts +151 -0
- package/src/__tests__/CSVLoader.test.ts +122 -0
- package/src/__tests__/ConversationEvaluator.test.ts +221 -0
- package/src/__tests__/ConversationRunner.test.ts +270 -0
- package/src/__tests__/CustomerSimulator.test.ts +160 -0
- package/src/__tests__/SimulationRunner.test.ts +281 -0
- package/src/__tests__/SkillTestHarness.test.ts +181 -0
- package/src/__tests__/scenarios.test.ts +71 -0
- package/src/index.ts +32 -0
- package/src/scenarios/edge-cases.ts +52 -0
- package/src/scenarios/general.ts +37 -0
- package/src/scenarios/index.ts +32 -0
- package/src/scenarios/order-tracking.ts +56 -0
- package/src/scenarios.ts +142 -0
- package/src/types.ts +133 -0
- package/src/utils.ts +6 -0
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +10 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
# API Validation Report
|
|
2
|
+
|
|
3
|
+
**Generated:** 2026-02-15
|
|
4
|
+
**Purpose:** Validate integration API usage against current documentation (2025-2026)
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Executive Summary
|
|
9
|
+
|
|
10
|
+
This report validates the API usage patterns across all integrations in Operor against current vendor documentation. Key findings:
|
|
11
|
+
|
|
12
|
+
- **Shopify**: CRITICAL - Using deprecated REST API (2024-01) that reached EOL on 2025-01-01. Price Rules API deprecated. Migration to GraphQL required.
|
|
13
|
+
- **Stripe**: LEGACY - Using deprecated Charges API. Should migrate to Payment Intents API.
|
|
14
|
+
- **Salesforce**: CURRENT - jsforce patterns are valid, but API versions 21.0-30.0 retired in 2025.
|
|
15
|
+
- **Zendesk**: CURRENT - API v2 endpoints are current and stable.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. Shopify Integration
|
|
20
|
+
|
|
21
|
+
**File:** `packages/integrations/shopify/src/ShopifyIntegration.ts`
|
|
22
|
+
|
|
23
|
+
### Current Implementation
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
apiVersion: '2024-01'
|
|
27
|
+
baseUrl: `https://${shopDomain}/admin/api/${apiVersion}`
|
|
28
|
+
|
|
29
|
+
Endpoints used:
|
|
30
|
+
- GET /admin/api/2024-01/shop.json (authentication)
|
|
31
|
+
- GET /admin/api/2024-01/orders.json?name=X&status=any
|
|
32
|
+
- GET /admin/api/2024-01/orders/{id}.json
|
|
33
|
+
- POST /admin/api/2024-01/price_rules.json
|
|
34
|
+
- POST /admin/api/2024-01/price_rules/{id}/discount_codes.json
|
|
35
|
+
- GET /admin/api/2024-01/products.json?limit=X&title=Y
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Validation Results
|
|
39
|
+
|
|
40
|
+
#### ❌ CRITICAL: API Version Deprecated
|
|
41
|
+
- **Status:** REST Admin API version 2024-01 reached **end-of-life on January 1, 2025**
|
|
42
|
+
- **Impact:** API version no longer supported
|
|
43
|
+
- **Timeline:**
|
|
44
|
+
- October 1, 2024: Entire REST Admin API became "legacy" (no updates/features)
|
|
45
|
+
- February 1, 2025: Critical REST endpoints (products/variants) ceased functioning
|
|
46
|
+
- April 1, 2025: All new apps must use GraphQL exclusively
|
|
47
|
+
- 2026+: GraphQL will be the only supported API
|
|
48
|
+
|
|
49
|
+
#### ❌ CRITICAL: Price Rules API Deprecated
|
|
50
|
+
- **Status:** Price Rules REST API deprecated in favor of GraphQL discounts
|
|
51
|
+
- **Timeline:**
|
|
52
|
+
- February/March 2023: `priceRule` GraphQL queries/mutations deprecated
|
|
53
|
+
- April 2024: Access to priceRule resources removed
|
|
54
|
+
- Current: REST Price Rules API is legacy, no longer receives updates
|
|
55
|
+
|
|
56
|
+
### Recommendations
|
|
57
|
+
|
|
58
|
+
**Priority 1: Migrate to GraphQL Admin API**
|
|
59
|
+
```graphql
|
|
60
|
+
# Replace REST orders endpoint
|
|
61
|
+
query {
|
|
62
|
+
orders(first: 10, query: "name:#1001") {
|
|
63
|
+
edges {
|
|
64
|
+
node {
|
|
65
|
+
id
|
|
66
|
+
name
|
|
67
|
+
displayFinancialStatus
|
|
68
|
+
displayFulfillmentStatus
|
|
69
|
+
createdAt
|
|
70
|
+
totalPriceSet { shopMoney { amount currencyCode } }
|
|
71
|
+
lineItems(first: 10) {
|
|
72
|
+
edges {
|
|
73
|
+
node {
|
|
74
|
+
title
|
|
75
|
+
quantity
|
|
76
|
+
originalUnitPriceSet { shopMoney { amount } }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Replace Price Rules with Discount API
|
|
86
|
+
mutation discountCodeBasicCreate($basicCodeDiscount: DiscountCodeBasicInput!) {
|
|
87
|
+
discountCodeBasicCreate(basicCodeDiscount: $basicCodeDiscount) {
|
|
88
|
+
codeDiscountNode {
|
|
89
|
+
id
|
|
90
|
+
codeDiscount {
|
|
91
|
+
... on DiscountCodeBasic {
|
|
92
|
+
title
|
|
93
|
+
codes(first: 1) {
|
|
94
|
+
edges {
|
|
95
|
+
node {
|
|
96
|
+
code
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
userErrors {
|
|
104
|
+
field
|
|
105
|
+
message
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Priority 2: Update API Version**
|
|
112
|
+
- If continuing with REST temporarily, upgrade to latest stable version (2025-01 or later)
|
|
113
|
+
- Note: REST API will eventually be fully deprecated
|
|
114
|
+
|
|
115
|
+
**Breaking Changes:**
|
|
116
|
+
- GraphQL uses different data structures (edges/nodes pattern)
|
|
117
|
+
- Discount creation requires different parameters
|
|
118
|
+
- Authentication headers remain the same (`X-Shopify-Access-Token`)
|
|
119
|
+
|
|
120
|
+
**Sources:**
|
|
121
|
+
- [Shopify API Versioning](https://shopify.dev)
|
|
122
|
+
- [REST to GraphQL Migration Guide](https://shopify.dev)
|
|
123
|
+
- [Discount API Documentation](https://digitalsuits.co)
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 2. Stripe Integration
|
|
128
|
+
|
|
129
|
+
**File:** `packages/integrations/stripe/src/StripeIntegration.ts`
|
|
130
|
+
|
|
131
|
+
### Current Implementation
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
Endpoints used:
|
|
135
|
+
- stripe.balance.retrieve() (authentication)
|
|
136
|
+
- stripe.customers.retrieve(id)
|
|
137
|
+
- stripe.customers.list({ email })
|
|
138
|
+
- stripe.charges.list({ customer, limit })
|
|
139
|
+
- stripe.paymentIntents.retrieve(id)
|
|
140
|
+
- stripe.refunds.create({ charge, payment_intent, amount, reason })
|
|
141
|
+
- stripe.products.create()
|
|
142
|
+
- stripe.prices.create()
|
|
143
|
+
- stripe.paymentLinks.create()
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Validation Results
|
|
147
|
+
|
|
148
|
+
#### ⚠️ WARNING: Charges API is Legacy
|
|
149
|
+
- **Status:** Charges API is a **legacy feature** as of 2025
|
|
150
|
+
- **Recommendation:** Stripe strongly recommends using **Payment Intents API** for new integrations
|
|
151
|
+
- **Impact:** Limited access to newer Stripe features when using Charges API
|
|
152
|
+
- **Current Support:** Still functional but not recommended for new code
|
|
153
|
+
|
|
154
|
+
#### ✅ CURRENT: Other APIs Valid
|
|
155
|
+
- **Customers API:** Current and stable
|
|
156
|
+
- **Payment Intents API:** Current (already used for `stripe_get_payment_intent`)
|
|
157
|
+
- **Refunds API:** Current and stable
|
|
158
|
+
- **Payment Links API:** Current and stable
|
|
159
|
+
|
|
160
|
+
### Recommendations
|
|
161
|
+
|
|
162
|
+
**Priority 1: Migrate from Charges to Payment Intents**
|
|
163
|
+
|
|
164
|
+
Current implementation:
|
|
165
|
+
```typescript
|
|
166
|
+
stripe_get_charges: {
|
|
167
|
+
execute: async (params) => {
|
|
168
|
+
const charges = await this.stripe.charges.list({
|
|
169
|
+
customer: params.customerId,
|
|
170
|
+
limit: params.limit || 10,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Recommended implementation:
|
|
177
|
+
```typescript
|
|
178
|
+
stripe_get_payment_intents: {
|
|
179
|
+
execute: async (params) => {
|
|
180
|
+
const paymentIntents = await this.stripe.paymentIntents.list({
|
|
181
|
+
customer: params.customerId,
|
|
182
|
+
limit: params.limit || 10,
|
|
183
|
+
});
|
|
184
|
+
// Payment Intents provide more context and support modern features
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Priority 2: Update Refund Tool**
|
|
190
|
+
- Current implementation correctly supports both `charge` and `payment_intent` parameters
|
|
191
|
+
- Consider deprecating `chargeId` parameter in favor of `paymentIntentId` only
|
|
192
|
+
|
|
193
|
+
**API Versioning:**
|
|
194
|
+
- Current API version: `2026-01-28.clover` (as of late 2024)
|
|
195
|
+
- Stripe uses date-based versioning (e.g., `2024-10-01`)
|
|
196
|
+
- SDK automatically handles version compatibility
|
|
197
|
+
- **Important:** Certificate trust chain changes effective February 1, 2026
|
|
198
|
+
|
|
199
|
+
**Sources:**
|
|
200
|
+
- [Stripe API Documentation](https://stripe.com)
|
|
201
|
+
- [Payment Intents vs Charges](https://stripe.com)
|
|
202
|
+
- [Stripe Node.js SDK](https://github.com)
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 3. Salesforce Integration
|
|
207
|
+
|
|
208
|
+
**File:** `packages/integrations/salesforce/src/SalesforceIntegration.ts`
|
|
209
|
+
|
|
210
|
+
### Current Implementation
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
Library: jsforce
|
|
214
|
+
Authentication: OAuth2 + username/password login
|
|
215
|
+
API calls:
|
|
216
|
+
- conn.sobject('Contact').retrieve(id)
|
|
217
|
+
- conn.query(SOQL) for Contact, Case queries
|
|
218
|
+
- conn.sobject('Contact').update({ Id, ...fields })
|
|
219
|
+
- conn.sobject('Case').create({ ContactId, Subject, Description, Priority, Status })
|
|
220
|
+
- conn.sobject('Note').create({ ParentId, Title, Body })
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Validation Results
|
|
224
|
+
|
|
225
|
+
#### ✅ CURRENT: jsforce Patterns Valid
|
|
226
|
+
- **Status:** jsforce library and SOQL patterns are current for 2025
|
|
227
|
+
- **API Version:** Summer '25 release (API version 64.0) is current
|
|
228
|
+
- **Authentication:** OAuth 2.0 and username-password flows supported
|
|
229
|
+
|
|
230
|
+
#### ⚠️ WARNING: API Version Retirements
|
|
231
|
+
- **Retired:** API versions 21.0 through 30.0 (REST, SOAP, Bulk APIs)
|
|
232
|
+
- **Impact:** Applications using old versions will experience "endpoint not found" errors
|
|
233
|
+
- **Action:** Ensure using API version 31.0 or higher
|
|
234
|
+
|
|
235
|
+
#### ⚠️ WARNING: SOAP login() Retirement
|
|
236
|
+
- **Timeline:** SOAP `login()` API retiring in Summer '27 (API version 65.0)
|
|
237
|
+
- **Current Impact:** None (still functional)
|
|
238
|
+
- **Future Action:** Migrate to OAuth 2.0 Username-Password Flow
|
|
239
|
+
|
|
240
|
+
### Recommendations
|
|
241
|
+
|
|
242
|
+
**Priority 1: Verify API Version**
|
|
243
|
+
- jsforce defaults to latest API version, but verify configuration
|
|
244
|
+
- Ensure not pinned to versions 21.0-30.0
|
|
245
|
+
|
|
246
|
+
**Priority 2: Update Authentication (Future)**
|
|
247
|
+
- Current username/password login via jsforce is acceptable for 2025-2026
|
|
248
|
+
- Plan migration to OAuth 2.0 Username-Password Flow before Summer 2027
|
|
249
|
+
|
|
250
|
+
**Priority 3: Security Best Practices**
|
|
251
|
+
- ✅ Already using SOQL escaping (`escapeSoql` function)
|
|
252
|
+
- ✅ Using parameterized queries
|
|
253
|
+
- Consider: My Domain URL requirement (all API calls must use org-specific My Domain URL)
|
|
254
|
+
|
|
255
|
+
**New Features Available:**
|
|
256
|
+
- OpenAPI Specification for sObjects REST API (Beta) - can generate client SDKs
|
|
257
|
+
- Reduced Outbound Message timeout (60s → 20s)
|
|
258
|
+
|
|
259
|
+
**Note Object:**
|
|
260
|
+
- Current implementation uses `Note` object
|
|
261
|
+
- Consider: `ContentNote` may be more appropriate for newer implementations
|
|
262
|
+
- Current usage is valid but verify against org's object model
|
|
263
|
+
|
|
264
|
+
**Sources:**
|
|
265
|
+
- [Salesforce Summer '25 Release Notes](https://salesforce.com)
|
|
266
|
+
- [jsforce Documentation](https://github.io)
|
|
267
|
+
- [Salesforce REST API Best Practices](https://integrate.io)
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 4. Zendesk Integration
|
|
272
|
+
|
|
273
|
+
**File:** `packages/integrations/zendesk/src/ZendeskIntegration.ts`
|
|
274
|
+
|
|
275
|
+
### Current Implementation
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
Library: axios
|
|
279
|
+
Base URL: https://{subdomain}.zendesk.com/api/v2
|
|
280
|
+
Authentication: Basic auth with {email}/token and API token
|
|
281
|
+
|
|
282
|
+
Endpoints used:
|
|
283
|
+
- GET /api/v2/users/me.json (authentication)
|
|
284
|
+
- POST /api/v2/tickets.json
|
|
285
|
+
- GET /api/v2/tickets/{id}.json
|
|
286
|
+
- PUT /api/v2/tickets/{id}.json
|
|
287
|
+
- GET /api/v2/search.json?query=type:ticket {query}&per_page={limit}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Validation Results
|
|
291
|
+
|
|
292
|
+
#### ✅ CURRENT: All Endpoints Valid
|
|
293
|
+
- **Status:** Zendesk API v2 is current and stable for 2025-2026
|
|
294
|
+
- **Authentication:** Basic auth with email/token is current standard
|
|
295
|
+
- **Endpoints:** All ticket, search, and comment endpoints are current
|
|
296
|
+
|
|
297
|
+
#### ✅ CURRENT: Search API Implementation
|
|
298
|
+
- **Query Syntax:** Correctly using `type:ticket` prefix
|
|
299
|
+
- **Pagination:** Using `per_page` parameter (correct)
|
|
300
|
+
- **Limits:** API returns up to 1,000 results (100 per page max)
|
|
301
|
+
|
|
302
|
+
### Recommendations
|
|
303
|
+
|
|
304
|
+
**Priority 1: Consider Pagination Limits**
|
|
305
|
+
- Current implementation doesn't handle the 1,000 result limit
|
|
306
|
+
- For large datasets, consider:
|
|
307
|
+
- Breaking searches into date ranges
|
|
308
|
+
- Using Export Search Results endpoint
|
|
309
|
+
- Using Incremental Export endpoints for changes
|
|
310
|
+
|
|
311
|
+
**Priority 2: Add Side-loading Support (Optional)**
|
|
312
|
+
- Zendesk supports side-loading related records
|
|
313
|
+
- Example: `GET /api/v2/tickets/{id}.json?include=users,groups`
|
|
314
|
+
- Could reduce API calls for ticket details
|
|
315
|
+
|
|
316
|
+
**Priority 3: Error Handling Enhancement**
|
|
317
|
+
- Current error handling is basic
|
|
318
|
+
- Consider handling specific Zendesk error codes:
|
|
319
|
+
- 422: Insufficient Resource Error (pagination beyond limit)
|
|
320
|
+
- 429: Rate limiting
|
|
321
|
+
- 401: Authentication failures
|
|
322
|
+
|
|
323
|
+
**Best Practices:**
|
|
324
|
+
- ✅ Using correct authentication method
|
|
325
|
+
- ✅ Proper Content-Type headers
|
|
326
|
+
- ✅ URL encoding for search queries (handled by axios)
|
|
327
|
+
|
|
328
|
+
**Sources:**
|
|
329
|
+
- [Zendesk API v2 Documentation](https://zendesk.com)
|
|
330
|
+
- [Search API Reference](https://zendesk.com)
|
|
331
|
+
- [Zendesk Developer Docs](https://zendesk.com)
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Library Usage Validation
|
|
336
|
+
|
|
337
|
+
### 1. vitest
|
|
338
|
+
|
|
339
|
+
**Files:** `packages/core/test/integration.test.ts`, `packages/memory/src/memory.test.ts`
|
|
340
|
+
|
|
341
|
+
#### ✅ CURRENT: Test Patterns Valid
|
|
342
|
+
|
|
343
|
+
**Patterns Used:**
|
|
344
|
+
```typescript
|
|
345
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
|
|
346
|
+
|
|
347
|
+
describe('Test Suite', () => {
|
|
348
|
+
beforeAll(async () => { /* setup */ });
|
|
349
|
+
afterAll(async () => { /* cleanup */ });
|
|
350
|
+
|
|
351
|
+
it('should test something', () => {
|
|
352
|
+
expect(value).toBe(expected);
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Validation:**
|
|
358
|
+
- ✅ Correct import pattern
|
|
359
|
+
- ✅ Proper use of `describe`, `it`, `expect`
|
|
360
|
+
- ✅ Async test support with `async/await`
|
|
361
|
+
- ✅ Setup/teardown with `beforeAll`/`afterAll`
|
|
362
|
+
- ✅ Timeout configuration (15000ms) for long-running tests
|
|
363
|
+
- ✅ Using `--run` flag to avoid watch mode (per CLAUDE.md)
|
|
364
|
+
|
|
365
|
+
**Best Practices Followed:**
|
|
366
|
+
- Proper cleanup in `afterAll`
|
|
367
|
+
- Async setup with proper awaits
|
|
368
|
+
- Clear test descriptions
|
|
369
|
+
- Appropriate timeout for integration tests
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### 2. commander
|
|
374
|
+
|
|
375
|
+
**File:** `packages/cli/src/index.ts`
|
|
376
|
+
|
|
377
|
+
#### ✅ CURRENT: Command Registration Patterns Valid
|
|
378
|
+
|
|
379
|
+
**Patterns Used:**
|
|
380
|
+
```typescript
|
|
381
|
+
import { Command } from 'commander';
|
|
382
|
+
|
|
383
|
+
const program = new Command();
|
|
384
|
+
|
|
385
|
+
program
|
|
386
|
+
.name('operor')
|
|
387
|
+
.description('Operor - AI Agent Operating System')
|
|
388
|
+
.version('0.1.0');
|
|
389
|
+
|
|
390
|
+
program
|
|
391
|
+
.command('setup')
|
|
392
|
+
.description('Run the interactive setup wizard')
|
|
393
|
+
.action(async () => { /* ... */ });
|
|
394
|
+
|
|
395
|
+
const configCmd = program.command('config').description('View and modify configuration');
|
|
396
|
+
configCmd
|
|
397
|
+
.command('set <key> <value>')
|
|
398
|
+
.action(async (k, v) => { /* ... */ });
|
|
399
|
+
|
|
400
|
+
program.parse();
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Validation:**
|
|
404
|
+
- ✅ Correct import pattern (ESM)
|
|
405
|
+
- ✅ Proper command registration with `.command()`
|
|
406
|
+
- ✅ Descriptions for help generation
|
|
407
|
+
- ✅ Action handlers with async support
|
|
408
|
+
- ✅ Subcommands (config subcommands)
|
|
409
|
+
- ✅ Required arguments (`<key> <value>`)
|
|
410
|
+
- ✅ Final `program.parse()` call
|
|
411
|
+
|
|
412
|
+
**Alignment with 2025 Best Practices:**
|
|
413
|
+
- ✅ Using ESM syntax
|
|
414
|
+
- ✅ Async action handlers
|
|
415
|
+
- ✅ Proper metadata (name, description, version)
|
|
416
|
+
- ✅ Modular command structure
|
|
417
|
+
|
|
418
|
+
**Note:** Commander v14 (May 2025) requires Node.js v20+. Verify package.json engines field.
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
### 3. tsup
|
|
423
|
+
|
|
424
|
+
**Files:** Multiple `tsup.config.ts` files across packages
|
|
425
|
+
|
|
426
|
+
#### ✅ CURRENT: Build Configuration Valid
|
|
427
|
+
|
|
428
|
+
**Pattern Used:**
|
|
429
|
+
```typescript
|
|
430
|
+
import { defineConfig } from 'tsup';
|
|
431
|
+
|
|
432
|
+
export default defineConfig({
|
|
433
|
+
entry: ['src/index.ts'],
|
|
434
|
+
format: ['esm'],
|
|
435
|
+
dts: true,
|
|
436
|
+
clean: true,
|
|
437
|
+
sourcemap: true,
|
|
438
|
+
banner: {
|
|
439
|
+
js: '#!/usr/bin/env node', // CLI package only
|
|
440
|
+
},
|
|
441
|
+
});
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Validation:**
|
|
445
|
+
- ✅ Using `defineConfig` for type safety
|
|
446
|
+
- ✅ ESM format specified
|
|
447
|
+
- ✅ TypeScript declarations enabled (`dts: true`)
|
|
448
|
+
- ✅ Clean builds (`clean: true`)
|
|
449
|
+
- ✅ Sourcemaps enabled (`sourcemap: true`)
|
|
450
|
+
- ✅ Banner for CLI executables (CLI package only)
|
|
451
|
+
|
|
452
|
+
**Best Practices:**
|
|
453
|
+
- ✅ Consistent configuration across packages
|
|
454
|
+
- ✅ Proper entry point specification
|
|
455
|
+
- ✅ Type-safe configuration
|
|
456
|
+
- ✅ Development-friendly sourcemaps
|
|
457
|
+
|
|
458
|
+
**Recommendations:**
|
|
459
|
+
- Consider adding `splitting: true` for code splitting (defaults to true for ESM)
|
|
460
|
+
- Consider `minify: true` for production builds (optional)
|
|
461
|
+
- Consider `target: 'node18'` or higher to match Node.js requirements
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
### 4. @clack/prompts
|
|
466
|
+
|
|
467
|
+
**Files:** `packages/cli/src/setup.ts`, `packages/cli/src/commands/doctor.ts`
|
|
468
|
+
|
|
469
|
+
#### ✅ CURRENT: Prompt Usage Patterns Valid
|
|
470
|
+
|
|
471
|
+
**Patterns Used:**
|
|
472
|
+
```typescript
|
|
473
|
+
import * as clack from '@clack/prompts';
|
|
474
|
+
|
|
475
|
+
// Intro/Outro
|
|
476
|
+
clack.intro('Operor - Setup');
|
|
477
|
+
clack.outro('Config saved to .env');
|
|
478
|
+
|
|
479
|
+
// Select
|
|
480
|
+
const provider = await clack.select({
|
|
481
|
+
message: 'Choose your LLM provider',
|
|
482
|
+
options: [
|
|
483
|
+
{ value: 'openai', label: 'OpenAI' },
|
|
484
|
+
{ value: 'anthropic', label: 'Anthropic (Claude)' },
|
|
485
|
+
],
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// Confirm
|
|
489
|
+
const useDetected = await clack.confirm({
|
|
490
|
+
message: `Found API key. Use it?`,
|
|
491
|
+
initialValue: true,
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// Cancel handling
|
|
495
|
+
if (clack.isCancel(provider)) {
|
|
496
|
+
clack.cancel('Setup cancelled');
|
|
497
|
+
process.exit(0);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Spinner
|
|
501
|
+
const spinner = clack.spinner();
|
|
502
|
+
spinner.start('Validating credentials');
|
|
503
|
+
spinner.stop('Validation complete');
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
**Validation:**
|
|
507
|
+
- ✅ Correct import pattern
|
|
508
|
+
- ✅ Proper use of `select`, `confirm`, `multiselect`
|
|
509
|
+
- ✅ Cancel detection with `isCancel()`
|
|
510
|
+
- ✅ Graceful exit on cancel
|
|
511
|
+
- ✅ Spinner for async operations
|
|
512
|
+
- ✅ Intro/outro for session management
|
|
513
|
+
- ✅ Validation functions in prompts
|
|
514
|
+
|
|
515
|
+
**Best Practices Followed:**
|
|
516
|
+
- ✅ Consistent cancel handling across all prompts
|
|
517
|
+
- ✅ User-friendly messages
|
|
518
|
+
- ✅ Visual feedback with spinners
|
|
519
|
+
- ✅ Input validation
|
|
520
|
+
- ✅ Proper error handling
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Summary of Findings
|
|
525
|
+
|
|
526
|
+
### Critical Issues (Immediate Action Required)
|
|
527
|
+
|
|
528
|
+
1. **Shopify Integration**
|
|
529
|
+
- API version 2024-01 reached EOL on 2025-01-01
|
|
530
|
+
- Price Rules API deprecated
|
|
531
|
+
- **Action:** Migrate to GraphQL Admin API
|
|
532
|
+
|
|
533
|
+
### Warnings (Plan for Migration)
|
|
534
|
+
|
|
535
|
+
2. **Stripe Integration**
|
|
536
|
+
- Charges API is legacy
|
|
537
|
+
- **Action:** Migrate to Payment Intents API
|
|
538
|
+
|
|
539
|
+
3. **Salesforce Integration**
|
|
540
|
+
- SOAP login() retiring in Summer 2027
|
|
541
|
+
- **Action:** Plan OAuth 2.0 migration
|
|
542
|
+
|
|
543
|
+
### Current and Valid
|
|
544
|
+
|
|
545
|
+
4. **Zendesk Integration** - All endpoints current ✅
|
|
546
|
+
5. **vitest** - Test patterns valid ✅
|
|
547
|
+
6. **commander** - CLI patterns valid ✅
|
|
548
|
+
7. **tsup** - Build configuration valid ✅
|
|
549
|
+
8. **@clack/prompts** - Prompt usage valid ✅
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## Recommended Action Plan
|
|
554
|
+
|
|
555
|
+
### Phase 1: Critical (Q1 2026)
|
|
556
|
+
1. Migrate Shopify to GraphQL Admin API
|
|
557
|
+
2. Update Shopify API version to 2025-01 or later (if staying on REST temporarily)
|
|
558
|
+
|
|
559
|
+
### Phase 2: Important (Q2 2026)
|
|
560
|
+
3. Migrate Stripe from Charges API to Payment Intents API
|
|
561
|
+
4. Verify Salesforce API version configuration
|
|
562
|
+
|
|
563
|
+
### Phase 3: Future (2026-2027)
|
|
564
|
+
5. Plan Salesforce OAuth 2.0 migration (before Summer 2027)
|
|
565
|
+
6. Consider Zendesk pagination enhancements
|
|
566
|
+
7. Review tsup configuration for production optimizations
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
**Report Generated:** 2026-02-15
|
|
571
|
+
**Validation Method:** Web search against current vendor documentation (2025-2026)
|
|
572
|
+
**Next Review:** Q3 2026
|