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