@thorprovider/medusa-extended 1.4.0 → 1.6.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/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/dropshipper.live-smoke.test.ts +685 -0
- package/src/dropshipper.test.ts +40 -0
- package/src/dropshipper.ts +41 -0
- package/src/request-resilience.ts +12 -0
- package/.turbo/turbo-build.log +0 -18
- package/dist/.tsbuildinfo +0 -1
package/src/dropshipper.test.ts
CHANGED
|
@@ -484,6 +484,46 @@ describe('DropshipperClient.createOrder', () => {
|
|
|
484
484
|
expect(result.order.id).toBe('ord_new')
|
|
485
485
|
})
|
|
486
486
|
|
|
487
|
+
it('POST /admin/thor/dropshipper/orders forwards unit_price override per item', async () => {
|
|
488
|
+
server.use(
|
|
489
|
+
http.post(`${BASE}/admin/thor/dropshipper/orders`, async ({ request }) => {
|
|
490
|
+
requireBearerToken(request)
|
|
491
|
+
const body = await request.json() as any
|
|
492
|
+
expect(body.items).toEqual([
|
|
493
|
+
{ variant_id: 'var_1', quantity: 1, unit_price: 150 },
|
|
494
|
+
{ variant_id: 'var_2', quantity: 2, unit_price: 299.99 },
|
|
495
|
+
])
|
|
496
|
+
return HttpResponse.json({
|
|
497
|
+
order: {
|
|
498
|
+
id: 'ord_new',
|
|
499
|
+
display_id: 46,
|
|
500
|
+
status: 'pending',
|
|
501
|
+
subtotal: 749.98,
|
|
502
|
+
tax_total: 0,
|
|
503
|
+
shipping_total: 1000,
|
|
504
|
+
discount_total: 0,
|
|
505
|
+
total: 1749.98,
|
|
506
|
+
profit: 500,
|
|
507
|
+
created_at: '2026-01-01T00:00:00Z',
|
|
508
|
+
shipping_method: null,
|
|
509
|
+
},
|
|
510
|
+
})
|
|
511
|
+
}),
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
const result = await client().createOrder({
|
|
515
|
+
customer_id: 'cus_1',
|
|
516
|
+
currency_code: 'usd',
|
|
517
|
+
items: [
|
|
518
|
+
{ variant_id: 'var_1', quantity: 1, unit_price: 150 },
|
|
519
|
+
{ variant_id: 'var_2', quantity: 2, unit_price: 299.99 },
|
|
520
|
+
],
|
|
521
|
+
shipping_address: { full_name: 'John', address_1: '123 Main', city: 'NY', province: null, postal_code: '10001', country_code: 'us' },
|
|
522
|
+
payment_method_id: 'pm_1',
|
|
523
|
+
})
|
|
524
|
+
expect(result.order.id).toBe('ord_new')
|
|
525
|
+
})
|
|
526
|
+
|
|
487
527
|
it('createOrder with dropshipper-collected payment method', async () => {
|
|
488
528
|
server.use(
|
|
489
529
|
http.post(`${BASE}/admin/thor/dropshipper/orders`, async ({ request }) => {
|
package/src/dropshipper.ts
CHANGED
|
@@ -133,6 +133,10 @@ import type {
|
|
|
133
133
|
GetFinancialAnalysisResponse,
|
|
134
134
|
RegisterPaymentBody,
|
|
135
135
|
RegisterPaymentResponse,
|
|
136
|
+
// Geo-reference
|
|
137
|
+
GetGeoCountriesResponse,
|
|
138
|
+
GetGeoProvincesResponse,
|
|
139
|
+
GetGeoCitiesResponse,
|
|
136
140
|
// Dashboard Capabilities
|
|
137
141
|
DropshipperDashboardCapabilities,
|
|
138
142
|
// Inline return types
|
|
@@ -1451,6 +1455,43 @@ export class DropshipperClient {
|
|
|
1451
1455
|
'/store/thor/dropshipper-categories',
|
|
1452
1456
|
);
|
|
1453
1457
|
}
|
|
1458
|
+
|
|
1459
|
+
// -------------------------------------------------------------------------
|
|
1460
|
+
// Geo-reference
|
|
1461
|
+
// -------------------------------------------------------------------------
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* List all geo-reference countries.
|
|
1465
|
+
*
|
|
1466
|
+
* `GET /admin/geo-reference`
|
|
1467
|
+
*/
|
|
1468
|
+
async getGeoCountries(): Promise<GetGeoCountriesResponse> {
|
|
1469
|
+
return this.request<GetGeoCountriesResponse>('GET', '/admin/geo-reference');
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
/**
|
|
1473
|
+
* List provinces/states for a country.
|
|
1474
|
+
*
|
|
1475
|
+
* `GET /admin/geo-reference/countries/:iso_2/provinces`
|
|
1476
|
+
*/
|
|
1477
|
+
async getGeoProvinces(iso2: string): Promise<GetGeoProvincesResponse> {
|
|
1478
|
+
return this.request<GetGeoProvincesResponse>(
|
|
1479
|
+
'GET',
|
|
1480
|
+
`/admin/geo-reference/countries/${iso2}/provinces`,
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
/**
|
|
1485
|
+
* List cities for a province/state.
|
|
1486
|
+
*
|
|
1487
|
+
* `GET /admin/geo-reference/provinces/:code/cities`
|
|
1488
|
+
*/
|
|
1489
|
+
async getGeoCities(code: string): Promise<GetGeoCitiesResponse> {
|
|
1490
|
+
return this.request<GetGeoCitiesResponse>(
|
|
1491
|
+
'GET',
|
|
1492
|
+
`/admin/geo-reference/provinces/${code}/cities`,
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1454
1495
|
}
|
|
1455
1496
|
|
|
1456
1497
|
// Re-export types used by callers so they don't need to import from @thorprovider/types directly.
|
|
@@ -38,6 +38,8 @@ function isRetryableError(error: unknown, config: Required<RetryConfig>): boolea
|
|
|
38
38
|
|
|
39
39
|
async function fetchWithRetry(url: string, init: RequestInit, retryConfig?: RetryConfig): Promise<Response> {
|
|
40
40
|
const config = { ...DEFAULT_RETRY_CONFIG, ...retryConfig }
|
|
41
|
+
const method = (init.method || 'GET').toUpperCase()
|
|
42
|
+
const isMutation = ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)
|
|
41
43
|
let lastError: unknown
|
|
42
44
|
|
|
43
45
|
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
@@ -57,6 +59,16 @@ async function fetchWithRetry(url: string, init: RequestInit, retryConfig?: Retr
|
|
|
57
59
|
return response
|
|
58
60
|
} catch (error) {
|
|
59
61
|
lastError = error
|
|
62
|
+
|
|
63
|
+
// Never retry mutations (POST/PUT/PATCH/DELETE) on timeout/network error.
|
|
64
|
+
// The first request may have succeeded on the backend, and retrying would
|
|
65
|
+
// create duplicate resources (customers, orders, etc.).
|
|
66
|
+
const isTimeoutOrNetwork = error instanceof Error &&
|
|
67
|
+
(error.name === 'AbortError' || error.message?.includes('timeout') || error.message?.includes('fetch failed'))
|
|
68
|
+
if (isMutation && isTimeoutOrNetwork) {
|
|
69
|
+
break
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
const shouldRetry = attempt < config.maxRetries && isRetryableError(error, config)
|
|
61
73
|
|
|
62
74
|
if (shouldRetry) {
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
CLI Building entry: {"index":"src/index.ts"}
|
|
2
|
-
CLI Using tsconfig: tsconfig.json
|
|
3
|
-
CLI tsup v8.5.1
|
|
4
|
-
CLI Using tsup config: /home/nelson/dev/thorprovider/repos/thorcommerce/packages/medusa-extended/tsup.config.ts
|
|
5
|
-
CLI Target: esnext
|
|
6
|
-
CLI Cleaning output folder
|
|
7
|
-
CJS Build start
|
|
8
|
-
ESM Build start
|
|
9
|
-
ESM dist/index.mjs 40.61 KB
|
|
10
|
-
ESM dist/index.mjs.map 79.50 KB
|
|
11
|
-
ESM ⚡️ Build success in 72ms
|
|
12
|
-
CJS dist/index.js 41.69 KB
|
|
13
|
-
CJS dist/index.js.map 79.78 KB
|
|
14
|
-
CJS ⚡️ Build success in 73ms
|
|
15
|
-
DTS Build start
|
|
16
|
-
DTS ⚡️ Build success in 12343ms
|
|
17
|
-
DTS dist/index.d.ts 27.38 KB
|
|
18
|
-
DTS dist/index.d.mts 27.38 KB
|