@lonca/trendyol 0.4.0 → 0.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.js CHANGED
@@ -232,6 +232,254 @@ function extractAttributeList(data) {
232
232
  }
233
233
  return null;
234
234
  }
235
+ function toIso(epochMs) {
236
+ if (typeof epochMs !== "number" || !Number.isFinite(epochMs) || epochMs === 0) {
237
+ return void 0;
238
+ }
239
+ return new Date(epochMs).toISOString();
240
+ }
241
+ function normalizeClaim(node) {
242
+ const out = {
243
+ id: node.id ?? node.claimId ?? "",
244
+ orderNumber: node.orderNumber ?? "",
245
+ raw: node
246
+ };
247
+ const orderDate = toIso(node.orderDate);
248
+ if (orderDate) out.orderDate = orderDate;
249
+ const claimDate = toIso(node.claimDate);
250
+ if (claimDate) out.claimDate = claimDate;
251
+ if (node.customerFirstName !== void 0) out.customerFirstName = node.customerFirstName;
252
+ if (node.customerLastName !== void 0) out.customerLastName = node.customerLastName;
253
+ return out;
254
+ }
255
+ var ClaimsResource = class {
256
+ constructor(transport, sellerId, limiter) {
257
+ this.transport = transport;
258
+ this.sellerId = sellerId;
259
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 1e3, intervalMs: 6e4 });
260
+ }
261
+ transport;
262
+ sellerId;
263
+ limiter;
264
+ /**
265
+ * Create a return claim against an order. Use this to file a return on
266
+ * behalf of a customer (e.g. when they called your CS line). For
267
+ * customer-initiated returns coming from trendyol.com, you receive them
268
+ * via `claims.list()` — no need to call `create`.
269
+ *
270
+ * Returns whatever Trendyol returns (typically the new claim's identifier).
271
+ *
272
+ * @throws {ValidationError} when `claimItems` is empty.
273
+ */
274
+ async create(input) {
275
+ if (!Array.isArray(input?.claimItems) || input.claimItems.length === 0) {
276
+ throw new ValidationError({ message: "claims.create: claimItems must not be empty" });
277
+ }
278
+ return this.transport.request({
279
+ method: "POST",
280
+ path: `/integration/order/sellers/${this.sellerId}/claims/create`,
281
+ body: input,
282
+ rateLimiter: this.limiter
283
+ });
284
+ }
285
+ /**
286
+ * File a seller-side rejection ("ret talebi") against a customer claim.
287
+ *
288
+ * **Wire format: `multipart/form-data`** — the SDK builds the FormData
289
+ * internally from the typed input. `claimItemIdList` is joined with
290
+ * commas (Trendyol expects a single comma-separated string field).
291
+ * Attach supporting docs (PDF / JPEG) via `files: [Blob, ...]`.
292
+ */
293
+ async createIssue(claimId, input) {
294
+ if (!Array.isArray(input?.claimItemIdList) || input.claimItemIdList.length === 0) {
295
+ throw new ValidationError({
296
+ message: "claims.createIssue: claimItemIdList must not be empty"
297
+ });
298
+ }
299
+ if (typeof input.description !== "string" || input.description.length === 0) {
300
+ throw new ValidationError({ message: "claims.createIssue: description is required" });
301
+ }
302
+ if (input.description.length > 500) {
303
+ throw new ValidationError({
304
+ message: `claims.createIssue: description must be \u2264500 chars (got ${input.description.length})`
305
+ });
306
+ }
307
+ const form = new FormData();
308
+ form.append("claimIssueReasonId", String(input.claimIssueReasonId));
309
+ form.append("claimItemIdList", input.claimItemIdList.join(","));
310
+ form.append("description", input.description);
311
+ if (input.files) {
312
+ for (const file of input.files) {
313
+ form.append("files", file);
314
+ }
315
+ }
316
+ return this.transport.request({
317
+ method: "POST",
318
+ path: `/integration/order/sellers/${this.sellerId}/claims/${encodeURIComponent(claimId)}/issue`,
319
+ body: form,
320
+ rateLimiter: this.limiter
321
+ });
322
+ }
323
+ /**
324
+ * Approve specific claim line items. After approval, Trendyol moves
325
+ * those line items into the post-approval refund / return-shipping flow.
326
+ *
327
+ * @throws {ValidationError} when `claimLineItemIdList` is empty.
328
+ */
329
+ async approveLineItems(claimId, input) {
330
+ if (!Array.isArray(input?.claimLineItemIdList) || input.claimLineItemIdList.length === 0) {
331
+ throw new ValidationError({
332
+ message: "claims.approveLineItems: claimLineItemIdList must not be empty"
333
+ });
334
+ }
335
+ return this.transport.request({
336
+ method: "PUT",
337
+ path: `/integration/order/sellers/${this.sellerId}/claims/${encodeURIComponent(claimId)}/items/approve`,
338
+ body: input,
339
+ rateLimiter: this.limiter
340
+ });
341
+ }
342
+ /**
343
+ * List claims (page-based; SDK exposes opaque cursor convention).
344
+ *
345
+ * @example
346
+ * ```ts
347
+ * import { paginate } from '@lonca/core';
348
+ * for await (const c of paginate((p) =>
349
+ * client.claims.list({ ...p, claimItemStatus: 'WaitingInAction' }),
350
+ * )) {
351
+ * console.log(c.id, c.orderNumber, c.claimDate);
352
+ * }
353
+ * ```
354
+ */
355
+ async list(params = {}) {
356
+ const size = Math.min(params.limit ?? 50, 200);
357
+ const page = params.cursor ? Number.parseInt(params.cursor, 10) : 0;
358
+ const query = { page, size };
359
+ if (params.startDate) query.startDate = params.startDate.getTime();
360
+ if (params.endDate) query.endDate = params.endDate.getTime();
361
+ if (params.claimItemStatus) query.claimItemStatus = params.claimItemStatus;
362
+ const data = await this.transport.request({
363
+ method: "GET",
364
+ path: `/integration/order/sellers/${this.sellerId}/claims`,
365
+ query,
366
+ rateLimiter: this.limiter
367
+ });
368
+ const items = (data.content ?? []).map(normalizeClaim);
369
+ const result = { items };
370
+ const totalPages = typeof data.totalPages === "number" ? data.totalPages : 0;
371
+ if (page + 1 < totalPages) {
372
+ result.nextCursor = String(page + 1);
373
+ }
374
+ return result;
375
+ }
376
+ /**
377
+ * Fetch the catalog of rejection-reason IDs the seller can use on
378
+ * `claims.createIssue()`. Cache the result — it changes rarely.
379
+ *
380
+ * Note: this endpoint is **not seller-scoped** (no `sellerId` in path).
381
+ */
382
+ async getIssueReasons() {
383
+ const data = await this.transport.request({
384
+ method: "GET",
385
+ path: `/integration/order/claim-issue-reasons`,
386
+ rateLimiter: this.limiter
387
+ });
388
+ return (data ?? []).map((r) => ({
389
+ id: typeof r.id === "number" ? r.id : 0,
390
+ name: r.name ?? ""
391
+ }));
392
+ }
393
+ /**
394
+ * Fetch the audit log for a single claim item (state transitions,
395
+ * actor, timestamp). Trendyol's response shape varies — the SDK
396
+ * surfaces each row as `{ raw }` and leaves field extraction to the
397
+ * caller until we observe a stable shape on the wire.
398
+ */
399
+ async getItemAudits(claimItemId) {
400
+ const data = await this.transport.request({
401
+ method: "GET",
402
+ path: `/integration/order/sellers/${this.sellerId}/claims/items/${encodeURIComponent(claimItemId)}/audit`,
403
+ rateLimiter: this.limiter
404
+ });
405
+ const rows = Array.isArray(data) ? data : Array.isArray(data?.content) ? data.content : [];
406
+ return rows.map((row) => ({ raw: row }));
407
+ }
408
+ };
409
+ function toIso2(epochMs) {
410
+ if (typeof epochMs !== "number" || !Number.isFinite(epochMs) || epochMs === 0) {
411
+ return void 0;
412
+ }
413
+ return new Date(epochMs).toISOString();
414
+ }
415
+ function normalizeRow(row) {
416
+ const out = {
417
+ id: row.id !== void 0 ? String(row.id) : "",
418
+ raw: row
419
+ };
420
+ const tx = toIso2(row.transactionDate);
421
+ if (tx) out.transactionDate = tx;
422
+ if (row.barcode !== void 0) out.barcode = row.barcode;
423
+ if (row.transactionType !== void 0) out.transactionType = row.transactionType;
424
+ if (row.receiptId !== void 0) out.receiptId = row.receiptId;
425
+ if (row.description !== void 0) out.description = row.description;
426
+ if (typeof row.debt === "number") out.debt = row.debt;
427
+ if (typeof row.credit === "number") out.credit = row.credit;
428
+ if (row.paymentPeriod !== void 0) out.paymentPeriod = row.paymentPeriod;
429
+ if (row.commissionRate !== void 0) out.commissionRate = row.commissionRate;
430
+ if (row.commissionAmount !== void 0) out.commissionAmount = row.commissionAmount;
431
+ if (row.commissionInvoiceSerialNumber !== void 0) {
432
+ out.commissionInvoiceSerialNumber = row.commissionInvoiceSerialNumber;
433
+ }
434
+ if (row.sellerRevenue !== void 0) out.sellerRevenue = row.sellerRevenue;
435
+ if (row.orderNumber !== void 0) out.orderNumber = row.orderNumber;
436
+ if (row.paymentOrderId !== void 0) out.paymentOrderId = row.paymentOrderId;
437
+ const pay = toIso2(row.paymentDate);
438
+ if (pay) out.paymentDate = pay;
439
+ if (typeof row.sellerId === "number") out.sellerId = row.sellerId;
440
+ if (row.storeId !== void 0) out.storeId = row.storeId;
441
+ if (row.storeName !== void 0) out.storeName = row.storeName;
442
+ if (row.storeAddress !== void 0) out.storeAddress = row.storeAddress;
443
+ if (row.country !== void 0) out.country = row.country;
444
+ return out;
445
+ }
446
+ var FinanceResource = class {
447
+ constructor(transport, sellerId, limiter) {
448
+ this.transport = transport;
449
+ this.sellerId = sellerId;
450
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 100, intervalMs: 6e4 });
451
+ }
452
+ transport;
453
+ sellerId;
454
+ limiter;
455
+ async getSettlements(params = {}) {
456
+ return this.queryPage(`/integration/sellers/${this.sellerId}/settlements`, params);
457
+ }
458
+ async getOtherFinancials(params = {}) {
459
+ return this.queryPage(`/integration/sellers/${this.sellerId}/otherfinancials`, params);
460
+ }
461
+ async queryPage(path, params) {
462
+ const size = Math.min(params.limit ?? 50, 200);
463
+ const page = params.cursor ? Number.parseInt(params.cursor, 10) : 0;
464
+ const query = { page, size };
465
+ if (params.startDate) query.startDate = params.startDate.getTime();
466
+ if (params.endDate) query.endDate = params.endDate.getTime();
467
+ if (params.transactionType) query.transactionType = params.transactionType;
468
+ const data = await this.transport.request({
469
+ method: "GET",
470
+ path,
471
+ query,
472
+ rateLimiter: this.limiter
473
+ });
474
+ const items = (data.content ?? []).map(normalizeRow);
475
+ const result = { items };
476
+ const totalPages = typeof data.totalPages === "number" ? data.totalPages : 0;
477
+ if (page + 1 < totalPages) {
478
+ result.nextCursor = String(page + 1);
479
+ }
480
+ return result;
481
+ }
482
+ };
235
483
  var MAX_ITEMS_PER_REQUEST = 1e3;
236
484
  var InventoryResource = class {
237
485
  constructor(transport, sellerId) {
@@ -271,9 +519,212 @@ var InventoryResource = class {
271
519
  return { batchRequestId: data.batchRequestId ?? "" };
272
520
  }
273
521
  };
522
+ var InvoicesResource = class {
523
+ constructor(transport, sellerId, limiter) {
524
+ this.transport = transport;
525
+ this.sellerId = sellerId;
526
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 500, intervalMs: 6e4 });
527
+ }
528
+ transport;
529
+ sellerId;
530
+ limiter;
531
+ /**
532
+ * Upload an invoice file for a shipment package. **Multipart**: the
533
+ * SDK builds the FormData internally from the typed input.
534
+ *
535
+ * Max 10 MB. Accepted formats: PDF, JPEG, PNG.
536
+ */
537
+ async uploadFile(input) {
538
+ if (!input?.file) {
539
+ throw new ValidationError({ message: "invoices.uploadFile: file is required" });
540
+ }
541
+ if (!input.shipmentPackageId) {
542
+ throw new ValidationError({ message: "invoices.uploadFile: shipmentPackageId is required" });
543
+ }
544
+ const form = new FormData();
545
+ form.append("shipmentPackageId", String(input.shipmentPackageId));
546
+ form.append("file", input.file);
547
+ if (input.invoiceDateTime !== void 0) {
548
+ form.append("invoiceDateTime", String(input.invoiceDateTime));
549
+ }
550
+ if (input.invoiceNumber !== void 0) {
551
+ form.append("invoiceNumber", input.invoiceNumber);
552
+ }
553
+ return this.transport.request({
554
+ method: "POST",
555
+ path: `/integration/sellers/${this.sellerId}/seller-invoice-file`,
556
+ body: form,
557
+ rateLimiter: this.limiter
558
+ });
559
+ }
560
+ /** Register an invoice URL with Trendyol (alternative to uploading the file). */
561
+ async sendLink(input) {
562
+ if (!input?.invoiceLink) {
563
+ throw new ValidationError({ message: "invoices.sendLink: invoiceLink is required" });
564
+ }
565
+ return this.transport.request({
566
+ method: "POST",
567
+ path: `/integration/sellers/${this.sellerId}/seller-invoice-links`,
568
+ body: input,
569
+ rateLimiter: this.limiter
570
+ });
571
+ }
572
+ /** Remove a previously-registered invoice link. */
573
+ async deleteLink(input) {
574
+ return this.transport.request({
575
+ method: "POST",
576
+ path: `/integration/sellers/${this.sellerId}/seller-invoice-links/delete`,
577
+ body: input,
578
+ rateLimiter: this.limiter
579
+ });
580
+ }
581
+ };
582
+ var LabelsResource = class {
583
+ constructor(transport, sellerId, limiter) {
584
+ this.transport = transport;
585
+ this.sellerId = sellerId;
586
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 100, intervalMs: 6e4 });
587
+ }
588
+ transport;
589
+ sellerId;
590
+ limiter;
591
+ /**
592
+ * Request a common ZPL label for a cargo tracking number. After this
593
+ * returns, call `getCommon()` with the same `cargoTrackingNumber` to
594
+ * retrieve the generated label.
595
+ *
596
+ * @throws {ValidationError} when `format` is missing.
597
+ */
598
+ async createCommon(cargoTrackingNumber, input) {
599
+ if (!input?.format) {
600
+ throw new ValidationError({ message: "labels.createCommon: format is required" });
601
+ }
602
+ return this.transport.request({
603
+ method: "POST",
604
+ path: `/integration/sellers/${this.sellerId}/common-label/${encodeURIComponent(String(cargoTrackingNumber))}`,
605
+ body: input,
606
+ rateLimiter: this.limiter
607
+ });
608
+ }
609
+ /**
610
+ * Retrieve the previously-created common label. Trendyol returns
611
+ * `{ data: [{ label, format }] }`; the SDK surfaces the array as
612
+ * `labels[]` for ergonomic access.
613
+ *
614
+ * Typically `labels.length === 1` per tracking number, but kept as an
615
+ * array to match the wire shape.
616
+ */
617
+ async getCommon(cargoTrackingNumber) {
618
+ const raw = await this.transport.request({
619
+ method: "GET",
620
+ path: `/integration/sellers/${this.sellerId}/common-label/${encodeURIComponent(String(cargoTrackingNumber))}`,
621
+ rateLimiter: this.limiter
622
+ });
623
+ const labels = (raw?.data ?? []).map((row) => ({
624
+ label: row.label ?? "",
625
+ format: row.format ?? "ZPL"
626
+ }));
627
+ return { labels, raw: raw ?? {} };
628
+ }
629
+ };
630
+ function n(rows, extract) {
631
+ const list = Array.isArray(rows) ? rows : [];
632
+ return list.map((r) => {
633
+ const node = r;
634
+ return { ...extract(node), raw: node };
635
+ });
636
+ }
637
+ var LocationsResource = class {
638
+ constructor(transport, limiter) {
639
+ this.transport = transport;
640
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 60, intervalMs: 6e4 });
641
+ }
642
+ transport;
643
+ limiter;
644
+ /** List all supported countries (Türkiye + AZ + GULF + CEE). */
645
+ async getCountries() {
646
+ const data = await this.transport.request({
647
+ method: "GET",
648
+ path: `/integration/member/countries`,
649
+ rateLimiter: this.limiter
650
+ });
651
+ return n(data, (node) => ({
652
+ code: String(node.code ?? node.id ?? ""),
653
+ name: node.name
654
+ }));
655
+ }
656
+ // ─── Domestic (TR / AZ) ───────────────────────────────────────────────
657
+ async getTurkeyCities() {
658
+ return this.cities(`/integration/member/countries/domestic/TR/cities`);
659
+ }
660
+ async getTurkeyDistricts(cityCode) {
661
+ return this.districts(
662
+ `/integration/member/countries/domestic/TR/cities/${encodeURIComponent(String(cityCode))}/districts`
663
+ );
664
+ }
665
+ async getTurkeyNeighborhoods(cityCode, districtCode) {
666
+ return this.neighborhoods(
667
+ `/integration/member/countries/domestic/TR/cities/${encodeURIComponent(String(cityCode))}/districts/${encodeURIComponent(String(districtCode))}/neighborhoods`
668
+ );
669
+ }
670
+ async getAzerbaijanCities() {
671
+ return this.cities(`/integration/member/countries/domestic/AZ/cities`);
672
+ }
673
+ async getAzerbaijanDistricts(cityCode) {
674
+ return this.districts(
675
+ `/integration/member/countries/domestic/AZ/cities/${encodeURIComponent(String(cityCode))}/districts`
676
+ );
677
+ }
678
+ // ─── International (GULF / CEE) ───────────────────────────────────────
679
+ async getCitiesByCountry(countryCode) {
680
+ return this.cities(`/integration/member/countries/${encodeURIComponent(countryCode)}/cities`);
681
+ }
682
+ async getDistrictsByCity(countryCode, cityId) {
683
+ return this.districts(
684
+ `/integration/member/countries/${encodeURIComponent(countryCode)}/cities/${encodeURIComponent(String(cityId))}/districts`
685
+ );
686
+ }
687
+ // ─── Shared paginators ────────────────────────────────────────────────
688
+ async cities(path) {
689
+ const data = await this.transport.request({
690
+ method: "GET",
691
+ path,
692
+ rateLimiter: this.limiter
693
+ });
694
+ return n(data, (node) => ({
695
+ code: String(node.code ?? node.id ?? ""),
696
+ name: node.name,
697
+ countryCode: node.countryCode
698
+ }));
699
+ }
700
+ async districts(path) {
701
+ const data = await this.transport.request({
702
+ method: "GET",
703
+ path,
704
+ rateLimiter: this.limiter
705
+ });
706
+ return n(data, (node) => ({
707
+ code: String(node.code ?? node.id ?? ""),
708
+ name: node.name,
709
+ cityCode: node.cityCode !== void 0 ? String(node.cityCode) : void 0
710
+ }));
711
+ }
712
+ async neighborhoods(path) {
713
+ const data = await this.transport.request({
714
+ method: "GET",
715
+ path,
716
+ rateLimiter: this.limiter
717
+ });
718
+ return n(data, (node) => ({
719
+ code: String(node.code ?? node.id ?? ""),
720
+ name: node.name,
721
+ districtCode: node.districtCode !== void 0 ? String(node.districtCode) : void 0
722
+ }));
723
+ }
724
+ };
274
725
  var MAX_PAGE_SIZE = 200;
275
726
  var DEFAULT_PAGE_SIZE2 = 50;
276
- function toIso(epochMs) {
727
+ function toIso3(epochMs) {
277
728
  if (typeof epochMs !== "number" || !Number.isFinite(epochMs) || epochMs === 0) {
278
729
  return void 0;
279
730
  }
@@ -341,7 +792,7 @@ function normalizeLine(node) {
341
792
  function normalizeHistory(node) {
342
793
  const out = { raw: node };
343
794
  if (node.status !== void 0) out.status = node.status;
344
- const createdAt = toIso(node.createdDate);
795
+ const createdAt = toIso3(node.createdDate);
345
796
  if (createdAt) out.createdAt = createdAt;
346
797
  return out;
347
798
  }
@@ -356,6 +807,9 @@ function normalizeCustomer(node) {
356
807
  if (node.identityNumber !== void 0) out.identityNumber = node.identityNumber;
357
808
  return out;
358
809
  }
810
+ function normalizeShipmentPackage(rawNode) {
811
+ return normalizePackage(rawNode ?? {});
812
+ }
359
813
  function normalizePackage(node) {
360
814
  const pkgId = node.shipmentPackageId ?? node.id;
361
815
  const out = {
@@ -363,8 +817,8 @@ function normalizePackage(node) {
363
817
  orderNumber: node.orderNumber ?? "",
364
818
  status: node.status ?? "",
365
819
  customer: normalizeCustomer(node),
366
- orderDate: toIso(node.orderDate) ?? "",
367
- lastModifiedDate: toIso(node.lastModifiedDate) ?? "",
820
+ orderDate: toIso3(node.orderDate) ?? "",
821
+ lastModifiedDate: toIso3(node.lastModifiedDate) ?? "",
368
822
  currencyCode: node.currencyCode ?? "",
369
823
  packageTotalPrice: typeof node.packageTotalPrice === "number" ? node.packageTotalPrice : 0,
370
824
  packageGrossAmount: typeof node.packageGrossAmount === "number" ? node.packageGrossAmount : 0,
@@ -384,13 +838,13 @@ function normalizePackage(node) {
384
838
  if (node.shipmentPackageStatus !== void 0) {
385
839
  out.shipmentPackageStatus = node.shipmentPackageStatus;
386
840
  }
387
- const agreed = toIso(node.agreedDeliveryDate);
841
+ const agreed = toIso3(node.agreedDeliveryDate);
388
842
  if (agreed) out.agreedDeliveryDate = agreed;
389
- const estStart = toIso(node.estimatedDeliveryStartDate);
843
+ const estStart = toIso3(node.estimatedDeliveryStartDate);
390
844
  if (estStart) out.estimatedDeliveryStartDate = estStart;
391
- const estEnd = toIso(node.estimatedDeliveryEndDate);
845
+ const estEnd = toIso3(node.estimatedDeliveryEndDate);
392
846
  if (estEnd) out.estimatedDeliveryEndDate = estEnd;
393
- const origin = toIso(node.originShipmentDate);
847
+ const origin = toIso3(node.originShipmentDate);
394
848
  if (origin) out.originShipmentDate = origin;
395
849
  const invoice = normalizeAddress(node.invoiceAddress);
396
850
  if (invoice) out.invoiceAddress = invoice;
@@ -800,6 +1254,101 @@ var OrdersResource = class {
800
1254
  }
801
1255
  return result;
802
1256
  }
1257
+ /**
1258
+ * Notify Trendyol that a shipped package was returned to you (manual
1259
+ * return flow, e.g. customer dropped it at your address or you got the
1260
+ * package back without going through Trendyol's return cargo).
1261
+ *
1262
+ * No body; Trendyol responds with 200 + empty body on success.
1263
+ */
1264
+ async manualReturnByPackageId(packageId) {
1265
+ await this.transport.request({
1266
+ method: "PUT",
1267
+ path: `${this.packagePath(packageId)}/manual-return`,
1268
+ rateLimiter: this.limiter
1269
+ });
1270
+ }
1271
+ /**
1272
+ * Manual-return variant that takes the cargo tracking number instead of
1273
+ * the package ID. Useful when the cargo provider's webhook only carries
1274
+ * the tracking number.
1275
+ *
1276
+ * Sibling path (not under `/{packageId}/...`).
1277
+ */
1278
+ async manualReturnByTrackingNumber(cargoTrackingNumber) {
1279
+ await this.transport.request({
1280
+ method: "PUT",
1281
+ path: `/integration/order/sellers/${this.sellerId}/shipment-packages/manual-return-by-tracking-number/${encodeURIComponent(String(cargoTrackingNumber))}`,
1282
+ rateLimiter: this.limiter
1283
+ });
1284
+ }
1285
+ /**
1286
+ * Fetch Trendyol Express compensation tickets (claims filed when a
1287
+ * shipment is lost or damaged in transit). Page-based pagination
1288
+ * internally; the SDK exposes the cursor convention.
1289
+ *
1290
+ * Note the different base path — `/integration/tex/compensation/...`,
1291
+ * not the regular `/integration/order/...`.
1292
+ *
1293
+ * @example
1294
+ * ```ts
1295
+ * import { paginate } from '@lonca/core';
1296
+ * const tickets = await client.orders.getCompensationTickets({
1297
+ * startDate: new Date('2026-01-01'),
1298
+ * endDate: new Date('2026-02-01'),
1299
+ * });
1300
+ * for (const t of tickets.items) {
1301
+ * console.log(t.orderNumber, t.currentState, t.stateMessage);
1302
+ * }
1303
+ * ```
1304
+ */
1305
+ async getCompensationTickets(params = {}) {
1306
+ const size = Math.min(params.limit ?? 200, 200);
1307
+ const page = params.cursor ? Number.parseInt(params.cursor, 10) : 0;
1308
+ const query = { page, size };
1309
+ if (params.startDate) query.startDate = params.startDate.getTime();
1310
+ if (params.endDate) query.endDate = params.endDate.getTime();
1311
+ const res = await this.transport.request({
1312
+ method: "GET",
1313
+ path: `/integration/tex/compensation/sellers/${this.sellerId}/tickets`,
1314
+ query,
1315
+ rateLimiter: this.limiter
1316
+ });
1317
+ const tickets = Array.isArray(res.data) ? res.data : res.data?.items ?? res.data?.content ?? res.content ?? [];
1318
+ const items = tickets.map((t) => {
1319
+ const itemDetails = (t.itemDetails ?? []).map((d) => {
1320
+ const out2 = {};
1321
+ if (typeof d.itemAmount === "number") out2.itemAmount = d.itemAmount;
1322
+ if (d.itemCode !== void 0) out2.itemCode = d.itemCode;
1323
+ if (typeof d.itemCount === "number") out2.itemCount = d.itemCount;
1324
+ if (d.itemName !== void 0) out2.itemName = d.itemName;
1325
+ return out2;
1326
+ });
1327
+ const out = {
1328
+ itemDetails,
1329
+ raw: t
1330
+ };
1331
+ if (t.cargoProvider !== void 0) out.cargoProvider = t.cargoProvider;
1332
+ if (t.compensateReason !== void 0) out.compensateReason = t.compensateReason;
1333
+ const createdAt = toIso3(t.createDate);
1334
+ if (createdAt) out.createdAt = createdAt;
1335
+ if (t.currentState !== void 0) {
1336
+ out.currentState = t.currentState;
1337
+ }
1338
+ if (t.deliveryNumber !== void 0) out.deliveryNumber = t.deliveryNumber;
1339
+ if (t.orderNumber !== void 0) out.orderNumber = t.orderNumber;
1340
+ if (t.requestedBy !== void 0) out.requestedBy = t.requestedBy;
1341
+ if (t.stateMessage !== void 0) out.stateMessage = t.stateMessage;
1342
+ if (t.totalItemsAmount !== void 0) out.totalItemsAmount = t.totalItemsAmount;
1343
+ return out;
1344
+ });
1345
+ const result = { items };
1346
+ const total = typeof res.totalCount === "number" ? res.totalCount : 0;
1347
+ if ((page + 1) * size < total) {
1348
+ result.nextCursor = String(page + 1);
1349
+ }
1350
+ return result;
1351
+ }
803
1352
  packagePath(packageId) {
804
1353
  return `/integration/order/sellers/${this.sellerId}/shipment-packages/${encodeURIComponent(String(packageId))}`;
805
1354
  }
@@ -849,7 +1398,7 @@ function normalizeVariant(variant) {
849
1398
  if (stock !== void 0) out.stock = stock;
850
1399
  return out;
851
1400
  }
852
- function toIso2(epochMs) {
1401
+ function toIso4(epochMs) {
853
1402
  if (typeof epochMs !== "number" || !Number.isFinite(epochMs)) return void 0;
854
1403
  return new Date(epochMs).toISOString();
855
1404
  }
@@ -863,8 +1412,8 @@ function normalizeProduct(node) {
863
1412
  images: normalizeImages(node.images),
864
1413
  attributes: (node.attributes ?? []).map(normalizeAttribute2),
865
1414
  variants: (node.variants ?? []).map(normalizeVariant),
866
- createdAt: toIso2(node.creationDate) ?? "",
867
- updatedAt: toIso2(node.lastModifiedDate) ?? "",
1415
+ createdAt: toIso4(node.creationDate) ?? "",
1416
+ updatedAt: toIso4(node.lastModifiedDate) ?? "",
868
1417
  raw: node
869
1418
  };
870
1419
  if (node.description !== void 0) out.description = node.description;
@@ -910,13 +1459,13 @@ function normalizeUnapproved(node) {
910
1459
  out.specialConsumptionTax = node.specialConsumptionTax;
911
1460
  }
912
1461
  if (node.sgrPrice !== void 0) out.sgrPrice = node.sgrPrice;
913
- const createdAt = toIso2(node.createDateTime);
1462
+ const createdAt = toIso4(node.createDateTime);
914
1463
  if (createdAt) out.createdAt = createdAt;
915
- const updatedAt = toIso2(node.lastUpdateDate);
1464
+ const updatedAt = toIso4(node.lastUpdateDate);
916
1465
  if (updatedAt) out.updatedAt = updatedAt;
917
- const priceChanged = toIso2(node.lastPriceChangeDate);
1466
+ const priceChanged = toIso4(node.lastPriceChangeDate);
918
1467
  if (priceChanged) out.lastPriceChangedAt = priceChanged;
919
- const stockChanged = toIso2(node.lastStockChangeDate);
1468
+ const stockChanged = toIso4(node.lastStockChangeDate);
920
1469
  if (stockChanged) out.lastStockChangedAt = stockChanged;
921
1470
  return out;
922
1471
  }
@@ -941,7 +1490,7 @@ function normalizeProductBase(data) {
941
1490
  archived: !!data.archived,
942
1491
  raw: data
943
1492
  };
944
- const approvedAt = toIso2(data.approvedDate);
1493
+ const approvedAt = toIso4(data.approvedDate);
945
1494
  if (approvedAt) out.approvedAt = approvedAt;
946
1495
  if (data.listingId !== void 0) out.listingId = data.listingId;
947
1496
  if (data.contentId !== void 0) out.contentId = String(data.contentId);
@@ -963,9 +1512,9 @@ function normalizeBatchResult(data) {
963
1512
  };
964
1513
  if (typeof data.itemCount === "number") out.itemCount = data.itemCount;
965
1514
  if (typeof data.failedItemCount === "number") out.failedItemCount = data.failedItemCount;
966
- const createdAt = toIso2(data.creationDate);
1515
+ const createdAt = toIso4(data.creationDate);
967
1516
  if (createdAt) out.createdAt = createdAt;
968
- const lastModifiedAt = toIso2(data.lastModification);
1517
+ const lastModifiedAt = toIso4(data.lastModification);
969
1518
  if (lastModifiedAt) out.lastModifiedAt = lastModifiedAt;
970
1519
  if (data.sourceType !== void 0) out.sourceType = data.sourceType;
971
1520
  if (data.batchRequestType !== void 0) out.batchRequestType = data.batchRequestType;
@@ -1311,6 +1860,120 @@ var ProductsResource = class {
1311
1860
  return { batchRequestId: data?.batchRequestId ?? "" };
1312
1861
  }
1313
1862
  };
1863
+ function toIso5(epochMs) {
1864
+ if (typeof epochMs !== "number" || !Number.isFinite(epochMs) || epochMs === 0) {
1865
+ return void 0;
1866
+ }
1867
+ return new Date(epochMs).toISOString();
1868
+ }
1869
+ function normalizeAnswer(a) {
1870
+ if (!a) return void 0;
1871
+ const out = {};
1872
+ if (a.text !== void 0) out.text = a.text;
1873
+ const createdAt = toIso5(a.creationDate);
1874
+ if (createdAt) out.createdAt = createdAt;
1875
+ if (a.status !== void 0) out.status = a.status;
1876
+ return out;
1877
+ }
1878
+ function normalizeQuestion(node) {
1879
+ const out = {
1880
+ id: node.id !== void 0 ? String(node.id) : "",
1881
+ raw: node
1882
+ };
1883
+ if (node.text !== void 0) out.text = node.text;
1884
+ if (node.customerId !== void 0) out.customerId = String(node.customerId);
1885
+ if (node.userName !== void 0) out.userName = node.userName;
1886
+ if (typeof node.showUserName === "boolean") out.showUserName = node.showUserName;
1887
+ if (node.status !== void 0) out.status = node.status;
1888
+ if (typeof node.public === "boolean") out.public = node.public;
1889
+ if (node.productMainId !== void 0) out.productMainId = node.productMainId;
1890
+ if (node.productName !== void 0) out.productName = node.productName;
1891
+ if (node.imageUrl !== void 0) out.imageUrl = node.imageUrl;
1892
+ if (node.webUrl !== void 0) out.webUrl = node.webUrl;
1893
+ const createdAt = toIso5(node.creationDate);
1894
+ if (createdAt) out.createdAt = createdAt;
1895
+ if (node.answeredDateMessage !== void 0) out.answeredDateMessage = node.answeredDateMessage;
1896
+ const answer = normalizeAnswer(node.answer);
1897
+ if (answer) out.answer = answer;
1898
+ const rejectedAnswer = normalizeAnswer(node.rejectedAnswer);
1899
+ if (rejectedAnswer) out.rejectedAnswer = rejectedAnswer;
1900
+ const rejectedAt = toIso5(node.rejectedDate);
1901
+ if (rejectedAt) out.rejectedAt = rejectedAt;
1902
+ if (node.reason !== void 0) out.reason = node.reason;
1903
+ if (node.reportReason !== void 0) out.reportReason = node.reportReason;
1904
+ const reportedAt = toIso5(node.reportedDate);
1905
+ if (reportedAt) out.reportedAt = reportedAt;
1906
+ return out;
1907
+ }
1908
+ var QuestionsResource = class {
1909
+ constructor(transport, sellerId, limiter) {
1910
+ this.transport = transport;
1911
+ this.sellerId = sellerId;
1912
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 500, intervalMs: 6e4 });
1913
+ }
1914
+ transport;
1915
+ sellerId;
1916
+ limiter;
1917
+ /** Fetch a single question by its numeric ID. */
1918
+ async get(questionId) {
1919
+ const data = await this.transport.request({
1920
+ method: "GET",
1921
+ path: `/integration/qna/sellers/${this.sellerId}/questions/${encodeURIComponent(String(questionId))}`,
1922
+ rateLimiter: this.limiter
1923
+ });
1924
+ return normalizeQuestion(data);
1925
+ }
1926
+ /**
1927
+ * Filter questions by barcode / date range / status. Page-based
1928
+ * pagination internally; SDK exposes the opaque-cursor convention.
1929
+ */
1930
+ async list(params = {}) {
1931
+ const size = Math.min(params.limit ?? 50, 200);
1932
+ const page = params.cursor ? Number.parseInt(params.cursor, 10) : 0;
1933
+ const query = { page, size };
1934
+ if (params.barcode) query.barcode = params.barcode;
1935
+ if (params.startDate) query.startDate = params.startDate.getTime();
1936
+ if (params.endDate) query.endDate = params.endDate.getTime();
1937
+ if (params.status) query.status = params.status;
1938
+ const data = await this.transport.request({
1939
+ method: "GET",
1940
+ path: `/integration/qna/sellers/${this.sellerId}/questions/filter`,
1941
+ query,
1942
+ rateLimiter: this.limiter
1943
+ });
1944
+ const items = (data.content ?? []).map(normalizeQuestion);
1945
+ const result = { items };
1946
+ const totalPages = typeof data.totalPages === "number" ? data.totalPages : 0;
1947
+ if (page + 1 < totalPages) {
1948
+ result.nextCursor = String(page + 1);
1949
+ }
1950
+ return result;
1951
+ }
1952
+ /**
1953
+ * Reply to a question. Trendyol enforces 10–2000 characters on the
1954
+ * answer text; the SDK pre-validates client-side.
1955
+ *
1956
+ * @throws {ValidationError} when `text` is outside the 10–2000 char range.
1957
+ */
1958
+ async answer(questionId, text) {
1959
+ if (typeof text !== "string" || text.length < 10) {
1960
+ throw new ValidationError({
1961
+ message: `questions.answer: text must be at least 10 chars (got ${text?.length ?? 0})`
1962
+ });
1963
+ }
1964
+ if (text.length > 2e3) {
1965
+ throw new ValidationError({
1966
+ message: `questions.answer: text must be at most 2000 chars (got ${text.length})`
1967
+ });
1968
+ }
1969
+ return this.transport.request({
1970
+ method: "POST",
1971
+ path: `/integration/qna/sellers/${this.sellerId}/questions/${encodeURIComponent(String(questionId))}/answers`,
1972
+ body: { text },
1973
+ rateLimiter: this.limiter
1974
+ });
1975
+ }
1976
+ };
1314
1977
  var VALID_TYPES = /* @__PURE__ */ new Set([
1315
1978
  "SHIPMENT",
1316
1979
  "RETURNING",
@@ -1391,6 +2054,170 @@ var SuppliersResource = class {
1391
2054
  return items;
1392
2055
  }
1393
2056
  };
2057
+ var TestOrdersResource = class {
2058
+ constructor(transport, sellerId, limiter) {
2059
+ this.transport = transport;
2060
+ this.sellerId = sellerId;
2061
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 60, intervalMs: 6e4 });
2062
+ }
2063
+ transport;
2064
+ sellerId;
2065
+ limiter;
2066
+ /**
2067
+ * Create a test order with the given customer / addresses / lines. The
2068
+ * SDK forwards the typed payload verbatim — drill into Trendyol's
2069
+ * `createTestOrder` doc for inner field rules.
2070
+ *
2071
+ * @throws {ValidationError} when required top-level fields are missing.
2072
+ */
2073
+ async create(input) {
2074
+ for (const k of ["customer", "invoiceAddress", "shippingAddress", "seller", "lines"]) {
2075
+ if (!input?.[k]) {
2076
+ throw new ValidationError({ message: `testOrders.create: ${k} is required` });
2077
+ }
2078
+ }
2079
+ return this.transport.request({
2080
+ method: "POST",
2081
+ path: `/integration/test/order/orders/core`,
2082
+ body: input,
2083
+ rateLimiter: this.limiter
2084
+ });
2085
+ }
2086
+ /** Push a test shipment package to the given status. */
2087
+ async updateStatus(packageId, status) {
2088
+ return this.transport.request({
2089
+ method: "PUT",
2090
+ path: `/integration/test/order/sellers/${this.sellerId}/shipment-packages/${encodeURIComponent(String(packageId))}/status`,
2091
+ body: { status },
2092
+ rateLimiter: this.limiter
2093
+ });
2094
+ }
2095
+ /** Move test claims to the `WaitingInAction` state. */
2096
+ async setClaimsWaitingInAction() {
2097
+ return this.transport.request({
2098
+ method: "PUT",
2099
+ path: `/integration/test/order/sellers/${this.sellerId}/claims/waiting-in-action`,
2100
+ rateLimiter: this.limiter
2101
+ });
2102
+ }
2103
+ };
2104
+ function normalizeWebhook(node) {
2105
+ const out = {
2106
+ id: node.id !== void 0 ? String(node.id) : "",
2107
+ raw: node
2108
+ };
2109
+ if (node.url !== void 0) out.url = node.url;
2110
+ if (node.authenticationType !== void 0) out.authenticationType = node.authenticationType;
2111
+ if (node.username !== void 0) out.username = node.username;
2112
+ if (node.apiKey !== void 0) out.apiKey = node.apiKey;
2113
+ if (node.subscribedStatuses !== void 0) out.subscribedStatuses = node.subscribedStatuses;
2114
+ if (typeof node.active === "boolean") out.active = node.active;
2115
+ else if (typeof node.isActive === "boolean") out.active = node.isActive;
2116
+ else if (typeof node.status === "string") out.active = node.status.toUpperCase() === "ACTIVE";
2117
+ return out;
2118
+ }
2119
+ var WebhooksResource = class {
2120
+ constructor(transport, sellerId, limiter) {
2121
+ this.transport = transport;
2122
+ this.sellerId = sellerId;
2123
+ this.limiter = limiter ?? new TokenBucketRateLimiter({ capacity: 50, intervalMs: 6e4 });
2124
+ }
2125
+ transport;
2126
+ sellerId;
2127
+ limiter;
2128
+ /**
2129
+ * Create a new webhook subscription. Trendyol caps subscriptions at 15
2130
+ * per seller — the SDK does NOT pre-check (you'd need to call `list()`
2131
+ * first), but Trendyol returns 400 when the cap is exceeded.
2132
+ *
2133
+ * @throws {ValidationError} when `url` or `authenticationType` is missing.
2134
+ */
2135
+ async create(input) {
2136
+ this.validateInput(input, "create");
2137
+ return this.transport.request({
2138
+ method: "POST",
2139
+ path: `/integration/sellers/${this.sellerId}/webhooks`,
2140
+ body: input,
2141
+ rateLimiter: this.limiter
2142
+ });
2143
+ }
2144
+ /** List all registered webhook subscriptions. */
2145
+ async list() {
2146
+ const data = await this.transport.request({
2147
+ method: "GET",
2148
+ path: `/integration/sellers/${this.sellerId}/webhooks`,
2149
+ rateLimiter: this.limiter
2150
+ });
2151
+ const rows = Array.isArray(data) ? data : Array.isArray(data?.webhooks) ? data.webhooks : Array.isArray(data?.content) ? data.content : [];
2152
+ return rows.map((r) => normalizeWebhook(r));
2153
+ }
2154
+ /**
2155
+ * Update a webhook subscription. Same input shape as `create`; replaces
2156
+ * the whole subscription (Trendyol does NOT partially update).
2157
+ */
2158
+ async update(webhookId, input) {
2159
+ this.validateInput(input, "update");
2160
+ return this.transport.request({
2161
+ method: "PUT",
2162
+ path: this.webhookPath(webhookId),
2163
+ body: input,
2164
+ rateLimiter: this.limiter
2165
+ });
2166
+ }
2167
+ /** Permanently delete a webhook subscription. */
2168
+ async delete(webhookId) {
2169
+ return this.transport.request({
2170
+ method: "DELETE",
2171
+ path: this.webhookPath(webhookId),
2172
+ rateLimiter: this.limiter
2173
+ });
2174
+ }
2175
+ /** Re-activate a previously-deactivated webhook subscription. */
2176
+ async activate(webhookId) {
2177
+ return this.transport.request({
2178
+ method: "PUT",
2179
+ path: `${this.webhookPath(webhookId)}/activate`,
2180
+ rateLimiter: this.limiter
2181
+ });
2182
+ }
2183
+ /**
2184
+ * Deactivate a webhook subscription. Trendyol automatically deactivates
2185
+ * a subscription after persistent delivery failures (and sends 2 emails);
2186
+ * use `activate()` to bring it back online once your endpoint is healthy.
2187
+ */
2188
+ async deactivate(webhookId) {
2189
+ return this.transport.request({
2190
+ method: "PUT",
2191
+ path: `${this.webhookPath(webhookId)}/deactivate`,
2192
+ rateLimiter: this.limiter
2193
+ });
2194
+ }
2195
+ validateInput(input, method) {
2196
+ if (!input?.url || typeof input.url !== "string") {
2197
+ throw new ValidationError({ message: `webhooks.${method}: url is required` });
2198
+ }
2199
+ if (input.authenticationType !== "BASIC_AUTHENTICATION" && input.authenticationType !== "API_KEY") {
2200
+ throw new ValidationError({
2201
+ message: `webhooks.${method}: authenticationType must be 'BASIC_AUTHENTICATION' or 'API_KEY'`
2202
+ });
2203
+ }
2204
+ if (input.authenticationType === "BASIC_AUTHENTICATION") {
2205
+ if (!input.username || !input.password) {
2206
+ throw new ValidationError({
2207
+ message: `webhooks.${method}: BASIC_AUTHENTICATION requires username + password`
2208
+ });
2209
+ }
2210
+ } else if (!input.apiKey) {
2211
+ throw new ValidationError({
2212
+ message: `webhooks.${method}: API_KEY requires apiKey`
2213
+ });
2214
+ }
2215
+ if (input.subscribedStatuses && input.subscribedStatuses.length === 0) ;
2216
+ }
2217
+ webhookPath(webhookId) {
2218
+ return `/integration/sellers/${this.sellerId}/webhooks/${encodeURIComponent(String(webhookId))}`;
2219
+ }
2220
+ };
1394
2221
 
1395
2222
  // src/auth.ts
1396
2223
  function buildAuthHeader(apiKey, apiSecret) {
@@ -1483,7 +2310,12 @@ var TrendyolTransport = class {
1483
2310
  signal: this.composeSignal(opts.signal)
1484
2311
  };
1485
2312
  if (opts.body !== void 0 && opts.method !== "GET") {
1486
- init.body = JSON.stringify(opts.body);
2313
+ if (opts.body instanceof FormData) {
2314
+ init.body = opts.body;
2315
+ delete headers["Content-Type"];
2316
+ } else {
2317
+ init.body = JSON.stringify(opts.body);
2318
+ }
1487
2319
  }
1488
2320
  this.logger.debug("trendyol.request", {
1489
2321
  method: opts.method,
@@ -1598,10 +2430,52 @@ function createTrendyolClient(opts) {
1598
2430
  suppliers: new SuppliersResource(transport, opts.sellerId),
1599
2431
  products: new ProductsResource(transport, opts.sellerId),
1600
2432
  inventory: new InventoryResource(transport, opts.sellerId),
1601
- orders: new OrdersResource(transport, opts.sellerId)
2433
+ orders: new OrdersResource(transport, opts.sellerId),
2434
+ claims: new ClaimsResource(transport, opts.sellerId),
2435
+ webhooks: new WebhooksResource(transport, opts.sellerId),
2436
+ questions: new QuestionsResource(transport, opts.sellerId),
2437
+ invoices: new InvoicesResource(transport, opts.sellerId),
2438
+ finance: new FinanceResource(transport, opts.sellerId),
2439
+ labels: new LabelsResource(transport, opts.sellerId),
2440
+ testOrders: new TestOrdersResource(transport, opts.sellerId),
2441
+ locations: new LocationsResource(transport)
2442
+ };
2443
+ }
2444
+ function parseWebhookEvent(rawBody) {
2445
+ let body;
2446
+ if (typeof rawBody === "string") {
2447
+ try {
2448
+ body = JSON.parse(rawBody);
2449
+ } catch {
2450
+ throw new ValidationError({
2451
+ message: "parseWebhookEvent: rawBody is not valid JSON"
2452
+ });
2453
+ }
2454
+ } else if (rawBody && typeof rawBody === "object") {
2455
+ body = rawBody;
2456
+ } else {
2457
+ throw new ValidationError({
2458
+ message: "parseWebhookEvent: rawBody must be an object or JSON string"
2459
+ });
2460
+ }
2461
+ const content = body.content;
2462
+ if (!Array.isArray(content)) {
2463
+ throw new ValidationError({
2464
+ message: "parseWebhookEvent: body.content must be an array"
2465
+ });
2466
+ }
2467
+ return {
2468
+ packages: content.map(normalizeShipmentPackage),
2469
+ pageInfo: {
2470
+ totalElements: typeof body.totalElements === "number" ? body.totalElements : void 0,
2471
+ totalPages: typeof body.totalPages === "number" ? body.totalPages : void 0,
2472
+ page: typeof body.page === "number" ? body.page : void 0,
2473
+ size: typeof body.size === "number" ? body.size : void 0
2474
+ },
2475
+ raw: body
1602
2476
  };
1603
2477
  }
1604
2478
 
1605
- export { BrandsResource, CategoriesResource, InventoryResource, OrdersResource, ProductsResource, SuppliersResource, createTrendyolClient };
2479
+ export { BrandsResource, CategoriesResource, ClaimsResource, FinanceResource, InventoryResource, InvoicesResource, LabelsResource, LocationsResource, OrdersResource, ProductsResource, QuestionsResource, SuppliersResource, TestOrdersResource, WebhooksResource, createTrendyolClient, normalizeShipmentPackage, parseWebhookEvent };
1606
2480
  //# sourceMappingURL=index.js.map
1607
2481
  //# sourceMappingURL=index.js.map