@thorprovider/medusa-extended 1.5.0 → 1.7.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/CHANGELOG.md +14 -0
- package/dist/index.d.mts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +88 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/dropshipper.test.ts +40 -0
- package/src/dropshipper.ts +116 -0
- package/src/request-resilience.ts +12 -0
package/src/dropshipper.ts
CHANGED
|
@@ -55,6 +55,16 @@ import type {
|
|
|
55
55
|
CreateOrderNoteBody,
|
|
56
56
|
GetOrderNotesResponse,
|
|
57
57
|
DeleteOrderNoteResponse,
|
|
58
|
+
// Draft Orders
|
|
59
|
+
GetDropshipperDraftOrdersOptions,
|
|
60
|
+
GetDropshipperDraftOrdersResponse,
|
|
61
|
+
GetDropshipperDraftOrderDetailResponse,
|
|
62
|
+
CreateDropshipperDraftOrderBody,
|
|
63
|
+
CreateDropshipperDraftOrderResponse,
|
|
64
|
+
UpdateDropshipperDraftOrderBody,
|
|
65
|
+
UpdateDropshipperDraftOrderResponse,
|
|
66
|
+
ConvertDropshipperDraftOrderBody,
|
|
67
|
+
ConvertDropshipperDraftOrderResponse,
|
|
58
68
|
// Dropshipper Addresses
|
|
59
69
|
DropshipperAddressBody,
|
|
60
70
|
DropshipperAddressResponse,
|
|
@@ -77,6 +87,8 @@ import type {
|
|
|
77
87
|
GetDropshipperCustomerDetailResponse,
|
|
78
88
|
CreateDropshipperCustomerBody,
|
|
79
89
|
CreateDropshipperCustomerResponse,
|
|
90
|
+
UpdateDropshipperCustomerBody,
|
|
91
|
+
UpdateDropshipperCustomerResponse,
|
|
80
92
|
// Account & Settlements (Y)
|
|
81
93
|
GetDropshipperAccountResponse,
|
|
82
94
|
GetDropshipperPayableResponse,
|
|
@@ -809,6 +821,22 @@ export class DropshipperClient {
|
|
|
809
821
|
);
|
|
810
822
|
}
|
|
811
823
|
|
|
824
|
+
/**
|
|
825
|
+
* Update a customer scoped to Y's channel.
|
|
826
|
+
*
|
|
827
|
+
* `POST /admin/thor/dropshipper/customers/:id`
|
|
828
|
+
*/
|
|
829
|
+
async updateCustomer(
|
|
830
|
+
customerId: string,
|
|
831
|
+
body: UpdateDropshipperCustomerBody,
|
|
832
|
+
): Promise<UpdateDropshipperCustomerResponse> {
|
|
833
|
+
return this.request<UpdateDropshipperCustomerResponse>(
|
|
834
|
+
'POST',
|
|
835
|
+
`/admin/thor/dropshipper/customers/${customerId}`,
|
|
836
|
+
body,
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
|
|
812
840
|
// -------------------------------------------------------------------------
|
|
813
841
|
// Customer Addresses (Solo Y) — B-06
|
|
814
842
|
// -------------------------------------------------------------------------
|
|
@@ -1456,6 +1484,94 @@ export class DropshipperClient {
|
|
|
1456
1484
|
);
|
|
1457
1485
|
}
|
|
1458
1486
|
|
|
1487
|
+
// -------------------------------------------------------------------------
|
|
1488
|
+
// Draft Orders
|
|
1489
|
+
// -------------------------------------------------------------------------
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* List all draft orders in the dropshipper's channel.
|
|
1493
|
+
*
|
|
1494
|
+
* `GET /admin/thor/dropshipper/draft-orders`
|
|
1495
|
+
*/
|
|
1496
|
+
async getDraftOrders(
|
|
1497
|
+
options: GetDropshipperDraftOrdersOptions = {},
|
|
1498
|
+
): Promise<GetDropshipperDraftOrdersResponse> {
|
|
1499
|
+
const { customer_id, from, to, q, limit = 20, offset = 0 } = options;
|
|
1500
|
+
const qs = new URLSearchParams({
|
|
1501
|
+
limit: String(limit),
|
|
1502
|
+
offset: String(offset),
|
|
1503
|
+
...(customer_id ? { customer_id } : {}),
|
|
1504
|
+
...(from ? { from } : {}),
|
|
1505
|
+
...(to ? { to } : {}),
|
|
1506
|
+
...(q ? { q } : {}),
|
|
1507
|
+
});
|
|
1508
|
+
return this.request<GetDropshipperDraftOrdersResponse>(
|
|
1509
|
+
'GET',
|
|
1510
|
+
`/admin/thor/dropshipper/draft-orders?${qs}`,
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
/**
|
|
1515
|
+
* Get a specific draft order by ID.
|
|
1516
|
+
*
|
|
1517
|
+
* `GET /admin/thor/dropshipper/draft-orders/:id`
|
|
1518
|
+
*/
|
|
1519
|
+
async getDraftOrder(
|
|
1520
|
+
draftOrderId: string,
|
|
1521
|
+
): Promise<GetDropshipperDraftOrderDetailResponse> {
|
|
1522
|
+
return this.request<GetDropshipperDraftOrderDetailResponse>(
|
|
1523
|
+
'GET',
|
|
1524
|
+
`/admin/thor/dropshipper/draft-orders/${draftOrderId}`,
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
/**
|
|
1529
|
+
* Create a new draft order.
|
|
1530
|
+
*
|
|
1531
|
+
* `POST /admin/thor/dropshipper/draft-orders`
|
|
1532
|
+
*/
|
|
1533
|
+
async createDraftOrder(
|
|
1534
|
+
body: CreateDropshipperDraftOrderBody,
|
|
1535
|
+
): Promise<CreateDropshipperDraftOrderResponse> {
|
|
1536
|
+
return this.request<CreateDropshipperDraftOrderResponse>(
|
|
1537
|
+
'POST',
|
|
1538
|
+
'/admin/thor/dropshipper/draft-orders',
|
|
1539
|
+
body,
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
/**
|
|
1544
|
+
* Update a draft order.
|
|
1545
|
+
*
|
|
1546
|
+
* `POST /admin/thor/dropshipper/draft-orders/:id`
|
|
1547
|
+
*/
|
|
1548
|
+
async updateDraftOrder(
|
|
1549
|
+
draftOrderId: string,
|
|
1550
|
+
body: UpdateDropshipperDraftOrderBody,
|
|
1551
|
+
): Promise<UpdateDropshipperDraftOrderResponse> {
|
|
1552
|
+
return this.request<UpdateDropshipperDraftOrderResponse>(
|
|
1553
|
+
'POST',
|
|
1554
|
+
`/admin/thor/dropshipper/draft-orders/${draftOrderId}`,
|
|
1555
|
+
body,
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
/**
|
|
1560
|
+
* Convert a draft order to a real order.
|
|
1561
|
+
*
|
|
1562
|
+
* `POST /admin/thor/dropshipper/draft-orders/:id/convert`
|
|
1563
|
+
*/
|
|
1564
|
+
async convertDraftOrder(
|
|
1565
|
+
draftOrderId: string,
|
|
1566
|
+
body: ConvertDropshipperDraftOrderBody,
|
|
1567
|
+
): Promise<ConvertDropshipperDraftOrderResponse> {
|
|
1568
|
+
return this.request<ConvertDropshipperDraftOrderResponse>(
|
|
1569
|
+
'POST',
|
|
1570
|
+
`/admin/thor/dropshipper/draft-orders/${draftOrderId}/convert`,
|
|
1571
|
+
body,
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1459
1575
|
// -------------------------------------------------------------------------
|
|
1460
1576
|
// Geo-reference
|
|
1461
1577
|
// -------------------------------------------------------------------------
|
|
@@ -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) {
|