@lonca/trendyol 0.13.0 → 0.15.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/README.md +26 -8
- package/dist/{client-DMndJSb0.d.cts → client-Dnfjvwah.d.cts} +173 -40
- package/dist/{client-DMndJSb0.d.ts → client-Dnfjvwah.d.ts} +173 -40
- package/dist/index.cjs +144 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +145 -55
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs +144 -54
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +145 -55
- package/dist/testing.js.map +1 -1
- package/package.json +6 -4
package/dist/testing.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as BatchRequestStatus, ba as TrendyolClient } from './client-Dnfjvwah.cjs';
|
|
2
2
|
import '@lonca/core';
|
|
3
3
|
|
|
4
4
|
/** A request the fake client received, normalized for matching in a `handler`. */
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as BatchRequestStatus, ba as TrendyolClient } from './client-Dnfjvwah.js';
|
|
2
2
|
import '@lonca/core';
|
|
3
3
|
|
|
4
4
|
/** A request the fake client received, normalized for matching in a `handler`. */
|
package/dist/testing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRequester, LoncaError, ServerError, RateLimitError, NotFoundError, ValidationError,
|
|
1
|
+
import { createRequester, AuthError, LoncaError, ServerError, RateLimitError, NotFoundError, ValidationError, TokenBucketRateLimiter, normalizeIssueEntries, TimeoutError } from '@lonca/core';
|
|
2
2
|
|
|
3
3
|
// src/resources/brands.ts
|
|
4
4
|
var DEFAULT_PAGE_SIZE = 1e3;
|
|
@@ -263,12 +263,14 @@ var ClaimsResource = class {
|
|
|
263
263
|
if (!Array.isArray(input?.claimItems) || input.claimItems.length === 0) {
|
|
264
264
|
throw new ValidationError({ message: "claims.create: claimItems must not be empty" });
|
|
265
265
|
}
|
|
266
|
-
return
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
266
|
+
return {
|
|
267
|
+
raw: await this.transport.request({
|
|
268
|
+
method: "POST",
|
|
269
|
+
path: `/integration/order/sellers/${this.transport.sellerId}/claims/create`,
|
|
270
|
+
body: input,
|
|
271
|
+
rateLimiter: this.limiter
|
|
272
|
+
})
|
|
273
|
+
};
|
|
272
274
|
}
|
|
273
275
|
/**
|
|
274
276
|
* File a seller-side rejection ("ret talebi") against a customer claim.
|
|
@@ -301,12 +303,14 @@ var ClaimsResource = class {
|
|
|
301
303
|
form.append("files", file);
|
|
302
304
|
}
|
|
303
305
|
}
|
|
304
|
-
return
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
306
|
+
return {
|
|
307
|
+
raw: await this.transport.request({
|
|
308
|
+
method: "POST",
|
|
309
|
+
path: `/integration/order/sellers/${this.transport.sellerId}/claims/${encodeURIComponent(claimId)}/issue`,
|
|
310
|
+
body: form,
|
|
311
|
+
rateLimiter: this.limiter
|
|
312
|
+
})
|
|
313
|
+
};
|
|
310
314
|
}
|
|
311
315
|
/**
|
|
312
316
|
* Approve specific claim line items. After approval, Trendyol moves
|
|
@@ -320,12 +324,14 @@ var ClaimsResource = class {
|
|
|
320
324
|
message: "claims.approveLineItems: claimLineItemIdList must not be empty"
|
|
321
325
|
});
|
|
322
326
|
}
|
|
323
|
-
return
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
return {
|
|
328
|
+
raw: await this.transport.request({
|
|
329
|
+
method: "PUT",
|
|
330
|
+
path: `/integration/order/sellers/${this.transport.sellerId}/claims/${encodeURIComponent(claimId)}/items/approve`,
|
|
331
|
+
body: input,
|
|
332
|
+
rateLimiter: this.limiter
|
|
333
|
+
})
|
|
334
|
+
};
|
|
329
335
|
}
|
|
330
336
|
/**
|
|
331
337
|
* List claims (page-based; SDK exposes opaque cursor convention).
|
|
@@ -899,33 +905,39 @@ var InvoicesResource = class {
|
|
|
899
905
|
if (input.invoiceNumber !== void 0) {
|
|
900
906
|
form.append("invoiceNumber", input.invoiceNumber);
|
|
901
907
|
}
|
|
902
|
-
return
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
+
return {
|
|
909
|
+
raw: await this.transport.request({
|
|
910
|
+
method: "POST",
|
|
911
|
+
path: `/integration/sellers/${this.transport.sellerId}/seller-invoice-file`,
|
|
912
|
+
body: form,
|
|
913
|
+
rateLimiter: this.limiter
|
|
914
|
+
})
|
|
915
|
+
};
|
|
908
916
|
}
|
|
909
917
|
/** Register an invoice URL with Trendyol (alternative to uploading the file). */
|
|
910
918
|
async sendLink(input) {
|
|
911
919
|
if (!input?.invoiceLink) {
|
|
912
920
|
throw new ValidationError({ message: "invoices.sendLink: invoiceLink is required" });
|
|
913
921
|
}
|
|
914
|
-
return
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
922
|
+
return {
|
|
923
|
+
raw: await this.transport.request({
|
|
924
|
+
method: "POST",
|
|
925
|
+
path: `/integration/sellers/${this.transport.sellerId}/seller-invoice-links`,
|
|
926
|
+
body: input,
|
|
927
|
+
rateLimiter: this.limiter
|
|
928
|
+
})
|
|
929
|
+
};
|
|
920
930
|
}
|
|
921
931
|
/** Remove a previously-registered invoice link. */
|
|
922
932
|
async deleteLink(input) {
|
|
923
|
-
return
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
933
|
+
return {
|
|
934
|
+
raw: await this.transport.request({
|
|
935
|
+
method: "POST",
|
|
936
|
+
path: `/integration/sellers/${this.transport.sellerId}/seller-invoice-links/delete`,
|
|
937
|
+
body: input,
|
|
938
|
+
rateLimiter: this.limiter
|
|
939
|
+
})
|
|
940
|
+
};
|
|
929
941
|
}
|
|
930
942
|
};
|
|
931
943
|
var LabelsResource = class {
|
|
@@ -940,18 +952,23 @@ var LabelsResource = class {
|
|
|
940
952
|
* returns, call `getCommon()` with the same `cargoTrackingNumber` to
|
|
941
953
|
* retrieve the generated label.
|
|
942
954
|
*
|
|
955
|
+
* Trendyol documents this endpoint (`createCommonLabel`) as a bare
|
|
956
|
+
* `200 OK` with no response body, so the SDK returns a `MutationResult`
|
|
957
|
+
* whose `raw` is whatever the gateway sent (normally `undefined`).
|
|
958
|
+
*
|
|
943
959
|
* @throws {ValidationError} when `format` is missing.
|
|
944
960
|
*/
|
|
945
961
|
async createCommon(cargoTrackingNumber, input) {
|
|
946
962
|
if (!input?.format) {
|
|
947
963
|
throw new ValidationError({ message: "labels.createCommon: format is required" });
|
|
948
964
|
}
|
|
949
|
-
|
|
965
|
+
const raw = await this.transport.request({
|
|
950
966
|
method: "POST",
|
|
951
967
|
path: `/integration/sellers/${this.transport.sellerId}/common-label/${encodeURIComponent(String(cargoTrackingNumber))}`,
|
|
952
968
|
body: input,
|
|
953
969
|
rateLimiter: this.limiter
|
|
954
970
|
});
|
|
971
|
+
return { raw };
|
|
955
972
|
}
|
|
956
973
|
/**
|
|
957
974
|
* Retrieve the previously-created common label. Trendyol returns
|
|
@@ -1958,6 +1975,11 @@ var ProductsResource = class {
|
|
|
1958
1975
|
* List approved products. Use `paginate()` from `@lonca/core` to iterate
|
|
1959
1976
|
* lazily across pages.
|
|
1960
1977
|
*
|
|
1978
|
+
* **Approved only:** this endpoint silently excludes products still in review
|
|
1979
|
+
* or rejected — use {@link listUnapproved} for those. Date fields on the
|
|
1980
|
+
* returned {@link Product} (`createdAt` / `updatedAt`) are ISO 8601 UTC
|
|
1981
|
+
* **strings**, not `Date` objects.
|
|
1982
|
+
*
|
|
1961
1983
|
* Trendyol exposes both page-based and `nextPageToken`-based pagination
|
|
1962
1984
|
* (the latter required when the dataset exceeds 10,000 items). The SDK
|
|
1963
1985
|
* picks the right strategy automatically — pass our opaque `cursor` from
|
|
@@ -2393,6 +2415,9 @@ var QuestionsResource = class {
|
|
|
2393
2415
|
* Reply to a question. Trendyol enforces 10–2000 characters on the
|
|
2394
2416
|
* answer text; the SDK pre-validates client-side.
|
|
2395
2417
|
*
|
|
2418
|
+
* Trendyol documents the response as `{ answerId: number }`; the SDK
|
|
2419
|
+
* surfaces it as `answerId` and keeps the untouched body on `raw`.
|
|
2420
|
+
*
|
|
2396
2421
|
* @throws {ValidationError} when `text` is outside the 10–2000 char range.
|
|
2397
2422
|
*/
|
|
2398
2423
|
async answer(questionId, text) {
|
|
@@ -2406,12 +2431,15 @@ var QuestionsResource = class {
|
|
|
2406
2431
|
message: `questions.answer: text must be at most 2000 chars (got ${text.length})`
|
|
2407
2432
|
});
|
|
2408
2433
|
}
|
|
2409
|
-
|
|
2434
|
+
const raw = await this.transport.request({
|
|
2410
2435
|
method: "POST",
|
|
2411
2436
|
path: `/integration/qna/sellers/${this.transport.sellerId}/questions/${encodeURIComponent(String(questionId))}/answers`,
|
|
2412
2437
|
body: { text },
|
|
2413
2438
|
rateLimiter: this.limiter
|
|
2414
2439
|
});
|
|
2440
|
+
const out = { raw };
|
|
2441
|
+
if (typeof raw?.answerId === "number") out.answerId = raw.answerId;
|
|
2442
|
+
return out;
|
|
2415
2443
|
}
|
|
2416
2444
|
};
|
|
2417
2445
|
var VALID_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -2504,6 +2532,9 @@ var TestOrdersResource = class {
|
|
|
2504
2532
|
* SDK forwards the typed payload verbatim — drill into Trendyol's
|
|
2505
2533
|
* `createTestOrder` doc for inner field rules.
|
|
2506
2534
|
*
|
|
2535
|
+
* Trendyol documents the response as `{ orderNumber: string }`; the SDK
|
|
2536
|
+
* surfaces it as `orderNumber` and keeps the untouched body on `raw`.
|
|
2537
|
+
*
|
|
2507
2538
|
* @throws {ValidationError} when required top-level fields are missing.
|
|
2508
2539
|
*/
|
|
2509
2540
|
async create(input) {
|
|
@@ -2512,29 +2543,52 @@ var TestOrdersResource = class {
|
|
|
2512
2543
|
throw new ValidationError({ message: `testOrders.create: ${k} is required` });
|
|
2513
2544
|
}
|
|
2514
2545
|
}
|
|
2515
|
-
|
|
2546
|
+
const raw = await this.transport.request({
|
|
2516
2547
|
method: "POST",
|
|
2517
2548
|
path: `/integration/test/order/orders/core`,
|
|
2518
2549
|
body: input,
|
|
2519
2550
|
rateLimiter: this.limiter
|
|
2520
2551
|
});
|
|
2552
|
+
const out = { raw };
|
|
2553
|
+
if (typeof raw?.orderNumber === "string") out.orderNumber = raw.orderNumber;
|
|
2554
|
+
else if (typeof raw?.orderNumber === "number") out.orderNumber = String(raw.orderNumber);
|
|
2555
|
+
return out;
|
|
2521
2556
|
}
|
|
2522
|
-
/**
|
|
2523
|
-
|
|
2524
|
-
|
|
2557
|
+
/**
|
|
2558
|
+
* Push a test shipment package to the given status. Trendyol's
|
|
2559
|
+
* `status-updates-on-test-orders` doc shows a `{ lines, params, status }`
|
|
2560
|
+
* body — pass `options` to send the documented `lines` / `params`;
|
|
2561
|
+
* omitted, the body stays `{ status }` alone as before. Documented
|
|
2562
|
+
* response is a bare `200 OK` (no body), hence `MutationResult`.
|
|
2563
|
+
*/
|
|
2564
|
+
async updateStatus(packageId, status, options = {}) {
|
|
2565
|
+
const raw = await this.transport.request({
|
|
2525
2566
|
method: "PUT",
|
|
2526
2567
|
path: `/integration/test/order/sellers/${this.transport.sellerId}/shipment-packages/${encodeURIComponent(String(packageId))}/status`,
|
|
2527
|
-
body: {
|
|
2568
|
+
body: {
|
|
2569
|
+
...options.lines !== void 0 ? { lines: options.lines } : {},
|
|
2570
|
+
...options.params !== void 0 ? { params: options.params } : {},
|
|
2571
|
+
status
|
|
2572
|
+
},
|
|
2528
2573
|
rateLimiter: this.limiter
|
|
2529
2574
|
});
|
|
2575
|
+
return { raw };
|
|
2530
2576
|
}
|
|
2531
|
-
/**
|
|
2532
|
-
|
|
2533
|
-
|
|
2577
|
+
/**
|
|
2578
|
+
* Move test claims to the `WaitingInAction` state. Trendyol's
|
|
2579
|
+
* `updateTestOrderStatus` doc shows a `{ shipmentPackageId }` body (the
|
|
2580
|
+
* `orderShipmentPackageId` from `claims.list`); pass `input` to send it —
|
|
2581
|
+
* omitted, the request goes out body-less as before. Documented response
|
|
2582
|
+
* is a bare `200 OK` (no body), hence `MutationResult`.
|
|
2583
|
+
*/
|
|
2584
|
+
async setClaimsWaitingInAction(input) {
|
|
2585
|
+
const raw = await this.transport.request({
|
|
2534
2586
|
method: "PUT",
|
|
2535
2587
|
path: `/integration/test/order/sellers/${this.transport.sellerId}/claims/waiting-in-action`,
|
|
2588
|
+
...input ? { body: input } : {},
|
|
2536
2589
|
rateLimiter: this.limiter
|
|
2537
2590
|
});
|
|
2591
|
+
return { raw };
|
|
2538
2592
|
}
|
|
2539
2593
|
};
|
|
2540
2594
|
var VideosResource = class {
|
|
@@ -2550,18 +2604,25 @@ var VideosResource = class {
|
|
|
2550
2604
|
* Queue a video for upload. Trendyol downloads from the URL in the
|
|
2551
2605
|
* body asynchronously; poll `list()` (filtered by id) for status.
|
|
2552
2606
|
*
|
|
2607
|
+
* Trendyol documents the response as `{ videoId: string }`; the SDK
|
|
2608
|
+
* surfaces it as `videoId` (pass it to `list({ id })`) and keeps the
|
|
2609
|
+
* untouched body on `raw`.
|
|
2610
|
+
*
|
|
2553
2611
|
* @throws {ValidationError} when `input` is empty / not an object.
|
|
2554
2612
|
*/
|
|
2555
2613
|
async create(input) {
|
|
2556
2614
|
if (!input || typeof input !== "object") {
|
|
2557
2615
|
throw new ValidationError({ message: "videos.create: input is required" });
|
|
2558
2616
|
}
|
|
2559
|
-
|
|
2617
|
+
const raw = await this.transport.request({
|
|
2560
2618
|
method: "POST",
|
|
2561
2619
|
path: `/integration/video/sellers/${this.transport.sellerId}/videos`,
|
|
2562
2620
|
body: input,
|
|
2563
2621
|
rateLimiter: this.createLimiter
|
|
2564
2622
|
});
|
|
2623
|
+
const out = { raw };
|
|
2624
|
+
if (typeof raw?.videoId === "string") out.videoId = raw.videoId;
|
|
2625
|
+
return out;
|
|
2565
2626
|
}
|
|
2566
2627
|
/** List the seller's integration videos (optionally filtered by id / status). */
|
|
2567
2628
|
async list(params = {}) {
|
|
@@ -2613,16 +2674,24 @@ var WebhooksResource = class {
|
|
|
2613
2674
|
* per seller — the SDK does NOT pre-check (you'd need to call `list()`
|
|
2614
2675
|
* first), but Trendyol returns 400 when the cap is exceeded.
|
|
2615
2676
|
*
|
|
2677
|
+
* Trendyol documents the response as `{ id: string }` — the webhook ID
|
|
2678
|
+
* you need for `update` / `delete` / `activate` / `deactivate`. The SDK
|
|
2679
|
+
* surfaces it as `id` and keeps the untouched body on `raw`.
|
|
2680
|
+
*
|
|
2616
2681
|
* @throws {ValidationError} when `url` or `authenticationType` is missing.
|
|
2617
2682
|
*/
|
|
2618
2683
|
async create(input) {
|
|
2619
2684
|
this.validateInput(input, "create");
|
|
2620
|
-
|
|
2685
|
+
const raw = await this.transport.request({
|
|
2621
2686
|
method: "POST",
|
|
2622
2687
|
path: `/integration/sellers/${this.transport.sellerId}/webhooks`,
|
|
2623
2688
|
body: input,
|
|
2624
2689
|
rateLimiter: this.limiter
|
|
2625
2690
|
});
|
|
2691
|
+
const out = { raw };
|
|
2692
|
+
if (typeof raw?.id === "string") out.id = raw.id;
|
|
2693
|
+
else if (typeof raw?.id === "number") out.id = String(raw.id);
|
|
2694
|
+
return out;
|
|
2626
2695
|
}
|
|
2627
2696
|
/** List all registered webhook subscriptions. */
|
|
2628
2697
|
async list() {
|
|
@@ -2637,43 +2706,57 @@ var WebhooksResource = class {
|
|
|
2637
2706
|
/**
|
|
2638
2707
|
* Update a webhook subscription. Same input shape as `create`; replaces
|
|
2639
2708
|
* the whole subscription (Trendyol does NOT partially update).
|
|
2709
|
+
*
|
|
2710
|
+
* Documented response is a bare `200 OK` (no body), hence `MutationResult`.
|
|
2640
2711
|
*/
|
|
2641
2712
|
async update(webhookId, input) {
|
|
2642
2713
|
this.validateInput(input, "update");
|
|
2643
|
-
|
|
2714
|
+
const raw = await this.transport.request({
|
|
2644
2715
|
method: "PUT",
|
|
2645
2716
|
path: this.webhookPath(webhookId),
|
|
2646
2717
|
body: input,
|
|
2647
2718
|
rateLimiter: this.limiter
|
|
2648
2719
|
});
|
|
2720
|
+
return { raw };
|
|
2649
2721
|
}
|
|
2650
|
-
/**
|
|
2722
|
+
/**
|
|
2723
|
+
* Permanently delete a webhook subscription. Documented response is a
|
|
2724
|
+
* bare `200 OK` (no body), hence `MutationResult`.
|
|
2725
|
+
*/
|
|
2651
2726
|
async delete(webhookId) {
|
|
2652
|
-
|
|
2727
|
+
const raw = await this.transport.request({
|
|
2653
2728
|
method: "DELETE",
|
|
2654
2729
|
path: this.webhookPath(webhookId),
|
|
2655
2730
|
rateLimiter: this.limiter
|
|
2656
2731
|
});
|
|
2732
|
+
return { raw };
|
|
2657
2733
|
}
|
|
2658
|
-
/**
|
|
2734
|
+
/**
|
|
2735
|
+
* Re-activate a previously-deactivated webhook subscription. Documented
|
|
2736
|
+
* response is a bare `200 OK` (no body), hence `MutationResult`.
|
|
2737
|
+
*/
|
|
2659
2738
|
async activate(webhookId) {
|
|
2660
|
-
|
|
2739
|
+
const raw = await this.transport.request({
|
|
2661
2740
|
method: "PUT",
|
|
2662
2741
|
path: `${this.webhookPath(webhookId)}/activate`,
|
|
2663
2742
|
rateLimiter: this.limiter
|
|
2664
2743
|
});
|
|
2744
|
+
return { raw };
|
|
2665
2745
|
}
|
|
2666
2746
|
/**
|
|
2667
2747
|
* Deactivate a webhook subscription. Trendyol automatically deactivates
|
|
2668
2748
|
* a subscription after persistent delivery failures (and sends 2 emails);
|
|
2669
2749
|
* use `activate()` to bring it back online once your endpoint is healthy.
|
|
2750
|
+
*
|
|
2751
|
+
* Documented response is a bare `200 OK` (no body), hence `MutationResult`.
|
|
2670
2752
|
*/
|
|
2671
2753
|
async deactivate(webhookId) {
|
|
2672
|
-
|
|
2754
|
+
const raw = await this.transport.request({
|
|
2673
2755
|
method: "PUT",
|
|
2674
2756
|
path: `${this.webhookPath(webhookId)}/deactivate`,
|
|
2675
2757
|
rateLimiter: this.limiter
|
|
2676
2758
|
});
|
|
2759
|
+
return { raw };
|
|
2677
2760
|
}
|
|
2678
2761
|
validateInput(input, method) {
|
|
2679
2762
|
if (!input?.url || typeof input.url !== "string") {
|
|
@@ -2721,6 +2804,13 @@ function buildUserAgent(sellerId, integratorName) {
|
|
|
2721
2804
|
return `${sellerId} - ${integratorName}`;
|
|
2722
2805
|
}
|
|
2723
2806
|
function mapHttpError(status, body, retryAfterMs) {
|
|
2807
|
+
if ((status === 401 || status === 403) && typeof body === "string") {
|
|
2808
|
+
return new AuthError({
|
|
2809
|
+
message: `Trendyol rejected the request before it reached the API (HTTP ${status}, non-JSON body) \u2014 check IP allowlisting / credentials / User-Agent`,
|
|
2810
|
+
status,
|
|
2811
|
+
data: { bodyKind: /^\s*</.test(body) ? "html" : "text", bodyLength: body.length }
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2724
2814
|
const data = { body };
|
|
2725
2815
|
const issues = normalizeErrorIssues(body);
|
|
2726
2816
|
switch (status) {
|