@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/index.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
@@ -1963,6 +1980,11 @@ var ProductsResource = class {
1963
1980
  * List approved products. Use `paginate()` from `@lonca/core` to iterate
1964
1981
  * lazily across pages.
1965
1982
  *
1983
+ * **Approved only:** this endpoint silently excludes products still in review
1984
+ * or rejected — use {@link listUnapproved} for those. Date fields on the
1985
+ * returned {@link Product} (`createdAt` / `updatedAt`) are ISO 8601 UTC
1986
+ * **strings**, not `Date` objects.
1987
+ *
1966
1988
  * Trendyol exposes both page-based and `nextPageToken`-based pagination
1967
1989
  * (the latter required when the dataset exceeds 10,000 items). The SDK
1968
1990
  * picks the right strategy automatically — pass our opaque `cursor` from
@@ -2398,6 +2420,9 @@ var QuestionsResource = class {
2398
2420
  * Reply to a question. Trendyol enforces 10–2000 characters on the
2399
2421
  * answer text; the SDK pre-validates client-side.
2400
2422
  *
2423
+ * Trendyol documents the response as `{ answerId: number }`; the SDK
2424
+ * surfaces it as `answerId` and keeps the untouched body on `raw`.
2425
+ *
2401
2426
  * @throws {ValidationError} when `text` is outside the 10–2000 char range.
2402
2427
  */
2403
2428
  async answer(questionId, text) {
@@ -2411,12 +2436,15 @@ var QuestionsResource = class {
2411
2436
  message: `questions.answer: text must be at most 2000 chars (got ${text.length})`
2412
2437
  });
2413
2438
  }
2414
- return this.transport.request({
2439
+ const raw = await this.transport.request({
2415
2440
  method: "POST",
2416
2441
  path: `/integration/qna/sellers/${this.transport.sellerId}/questions/${encodeURIComponent(String(questionId))}/answers`,
2417
2442
  body: { text },
2418
2443
  rateLimiter: this.limiter
2419
2444
  });
2445
+ const out = { raw };
2446
+ if (typeof raw?.answerId === "number") out.answerId = raw.answerId;
2447
+ return out;
2420
2448
  }
2421
2449
  };
2422
2450
  var VALID_TYPES = /* @__PURE__ */ new Set([
@@ -2509,6 +2537,9 @@ var TestOrdersResource = class {
2509
2537
  * SDK forwards the typed payload verbatim — drill into Trendyol's
2510
2538
  * `createTestOrder` doc for inner field rules.
2511
2539
  *
2540
+ * Trendyol documents the response as `{ orderNumber: string }`; the SDK
2541
+ * surfaces it as `orderNumber` and keeps the untouched body on `raw`.
2542
+ *
2512
2543
  * @throws {ValidationError} when required top-level fields are missing.
2513
2544
  */
2514
2545
  async create(input) {
@@ -2517,29 +2548,52 @@ var TestOrdersResource = class {
2517
2548
  throw new core.ValidationError({ message: `testOrders.create: ${k} is required` });
2518
2549
  }
2519
2550
  }
2520
- return this.transport.request({
2551
+ const raw = await this.transport.request({
2521
2552
  method: "POST",
2522
2553
  path: `/integration/test/order/orders/core`,
2523
2554
  body: input,
2524
2555
  rateLimiter: this.limiter
2525
2556
  });
2557
+ const out = { raw };
2558
+ if (typeof raw?.orderNumber === "string") out.orderNumber = raw.orderNumber;
2559
+ else if (typeof raw?.orderNumber === "number") out.orderNumber = String(raw.orderNumber);
2560
+ return out;
2526
2561
  }
2527
- /** Push a test shipment package to the given status. */
2528
- async updateStatus(packageId, status) {
2529
- return this.transport.request({
2562
+ /**
2563
+ * Push a test shipment package to the given status. Trendyol's
2564
+ * `status-updates-on-test-orders` doc shows a `{ lines, params, status }`
2565
+ * body — pass `options` to send the documented `lines` / `params`;
2566
+ * omitted, the body stays `{ status }` alone as before. Documented
2567
+ * response is a bare `200 OK` (no body), hence `MutationResult`.
2568
+ */
2569
+ async updateStatus(packageId, status, options = {}) {
2570
+ const raw = await this.transport.request({
2530
2571
  method: "PUT",
2531
2572
  path: `/integration/test/order/sellers/${this.transport.sellerId}/shipment-packages/${encodeURIComponent(String(packageId))}/status`,
2532
- body: { status },
2573
+ body: {
2574
+ ...options.lines !== void 0 ? { lines: options.lines } : {},
2575
+ ...options.params !== void 0 ? { params: options.params } : {},
2576
+ status
2577
+ },
2533
2578
  rateLimiter: this.limiter
2534
2579
  });
2580
+ return { raw };
2535
2581
  }
2536
- /** Move test claims to the `WaitingInAction` state. */
2537
- async setClaimsWaitingInAction() {
2538
- return this.transport.request({
2582
+ /**
2583
+ * Move test claims to the `WaitingInAction` state. Trendyol's
2584
+ * `updateTestOrderStatus` doc shows a `{ shipmentPackageId }` body (the
2585
+ * `orderShipmentPackageId` from `claims.list`); pass `input` to send it —
2586
+ * omitted, the request goes out body-less as before. Documented response
2587
+ * is a bare `200 OK` (no body), hence `MutationResult`.
2588
+ */
2589
+ async setClaimsWaitingInAction(input) {
2590
+ const raw = await this.transport.request({
2539
2591
  method: "PUT",
2540
2592
  path: `/integration/test/order/sellers/${this.transport.sellerId}/claims/waiting-in-action`,
2593
+ ...input ? { body: input } : {},
2541
2594
  rateLimiter: this.limiter
2542
2595
  });
2596
+ return { raw };
2543
2597
  }
2544
2598
  };
2545
2599
  var VideosResource = class {
@@ -2555,18 +2609,25 @@ var VideosResource = class {
2555
2609
  * Queue a video for upload. Trendyol downloads from the URL in the
2556
2610
  * body asynchronously; poll `list()` (filtered by id) for status.
2557
2611
  *
2612
+ * Trendyol documents the response as `{ videoId: string }`; the SDK
2613
+ * surfaces it as `videoId` (pass it to `list({ id })`) and keeps the
2614
+ * untouched body on `raw`.
2615
+ *
2558
2616
  * @throws {ValidationError} when `input` is empty / not an object.
2559
2617
  */
2560
2618
  async create(input) {
2561
2619
  if (!input || typeof input !== "object") {
2562
2620
  throw new core.ValidationError({ message: "videos.create: input is required" });
2563
2621
  }
2564
- return this.transport.request({
2622
+ const raw = await this.transport.request({
2565
2623
  method: "POST",
2566
2624
  path: `/integration/video/sellers/${this.transport.sellerId}/videos`,
2567
2625
  body: input,
2568
2626
  rateLimiter: this.createLimiter
2569
2627
  });
2628
+ const out = { raw };
2629
+ if (typeof raw?.videoId === "string") out.videoId = raw.videoId;
2630
+ return out;
2570
2631
  }
2571
2632
  /** List the seller's integration videos (optionally filtered by id / status). */
2572
2633
  async list(params = {}) {
@@ -2618,16 +2679,24 @@ var WebhooksResource = class {
2618
2679
  * per seller — the SDK does NOT pre-check (you'd need to call `list()`
2619
2680
  * first), but Trendyol returns 400 when the cap is exceeded.
2620
2681
  *
2682
+ * Trendyol documents the response as `{ id: string }` — the webhook ID
2683
+ * you need for `update` / `delete` / `activate` / `deactivate`. The SDK
2684
+ * surfaces it as `id` and keeps the untouched body on `raw`.
2685
+ *
2621
2686
  * @throws {ValidationError} when `url` or `authenticationType` is missing.
2622
2687
  */
2623
2688
  async create(input) {
2624
2689
  this.validateInput(input, "create");
2625
- return this.transport.request({
2690
+ const raw = await this.transport.request({
2626
2691
  method: "POST",
2627
2692
  path: `/integration/sellers/${this.transport.sellerId}/webhooks`,
2628
2693
  body: input,
2629
2694
  rateLimiter: this.limiter
2630
2695
  });
2696
+ const out = { raw };
2697
+ if (typeof raw?.id === "string") out.id = raw.id;
2698
+ else if (typeof raw?.id === "number") out.id = String(raw.id);
2699
+ return out;
2631
2700
  }
2632
2701
  /** List all registered webhook subscriptions. */
2633
2702
  async list() {
@@ -2642,43 +2711,57 @@ var WebhooksResource = class {
2642
2711
  /**
2643
2712
  * Update a webhook subscription. Same input shape as `create`; replaces
2644
2713
  * the whole subscription (Trendyol does NOT partially update).
2714
+ *
2715
+ * Documented response is a bare `200 OK` (no body), hence `MutationResult`.
2645
2716
  */
2646
2717
  async update(webhookId, input) {
2647
2718
  this.validateInput(input, "update");
2648
- return this.transport.request({
2719
+ const raw = await this.transport.request({
2649
2720
  method: "PUT",
2650
2721
  path: this.webhookPath(webhookId),
2651
2722
  body: input,
2652
2723
  rateLimiter: this.limiter
2653
2724
  });
2725
+ return { raw };
2654
2726
  }
2655
- /** Permanently delete a webhook subscription. */
2727
+ /**
2728
+ * Permanently delete a webhook subscription. Documented response is a
2729
+ * bare `200 OK` (no body), hence `MutationResult`.
2730
+ */
2656
2731
  async delete(webhookId) {
2657
- return this.transport.request({
2732
+ const raw = await this.transport.request({
2658
2733
  method: "DELETE",
2659
2734
  path: this.webhookPath(webhookId),
2660
2735
  rateLimiter: this.limiter
2661
2736
  });
2737
+ return { raw };
2662
2738
  }
2663
- /** Re-activate a previously-deactivated webhook subscription. */
2739
+ /**
2740
+ * Re-activate a previously-deactivated webhook subscription. Documented
2741
+ * response is a bare `200 OK` (no body), hence `MutationResult`.
2742
+ */
2664
2743
  async activate(webhookId) {
2665
- return this.transport.request({
2744
+ const raw = await this.transport.request({
2666
2745
  method: "PUT",
2667
2746
  path: `${this.webhookPath(webhookId)}/activate`,
2668
2747
  rateLimiter: this.limiter
2669
2748
  });
2749
+ return { raw };
2670
2750
  }
2671
2751
  /**
2672
2752
  * Deactivate a webhook subscription. Trendyol automatically deactivates
2673
2753
  * a subscription after persistent delivery failures (and sends 2 emails);
2674
2754
  * use `activate()` to bring it back online once your endpoint is healthy.
2755
+ *
2756
+ * Documented response is a bare `200 OK` (no body), hence `MutationResult`.
2675
2757
  */
2676
2758
  async deactivate(webhookId) {
2677
- return this.transport.request({
2759
+ const raw = await this.transport.request({
2678
2760
  method: "PUT",
2679
2761
  path: `${this.webhookPath(webhookId)}/deactivate`,
2680
2762
  rateLimiter: this.limiter
2681
2763
  });
2764
+ return { raw };
2682
2765
  }
2683
2766
  validateInput(input, method) {
2684
2767
  if (!input?.url || typeof input.url !== "string") {
@@ -2726,6 +2809,13 @@ function buildUserAgent(sellerId, integratorName) {
2726
2809
  return `${sellerId} - ${integratorName}`;
2727
2810
  }
2728
2811
  function mapHttpError(status, body, retryAfterMs) {
2812
+ if ((status === 401 || status === 403) && typeof body === "string") {
2813
+ return new core.AuthError({
2814
+ message: `Trendyol rejected the request before it reached the API (HTTP ${status}, non-JSON body) \u2014 check IP allowlisting / credentials / User-Agent`,
2815
+ status,
2816
+ data: { bodyKind: /^\s*</.test(body) ? "html" : "text", bodyLength: body.length }
2817
+ });
2818
+ }
2729
2819
  const data = { body };
2730
2820
  const issues = normalizeErrorIssues(body);
2731
2821
  switch (status) {