@yoryoboy/bi-mcp 1.16.0 → 1.19.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.
Files changed (158) hide show
  1. package/README.md +12 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/index.js +179 -6
  4. package/dist/index.js.map +2 -2
  5. package/dist/mcp-use.json +3 -6
  6. package/dist/src/config/__tests__/google-store.test.js +30 -0
  7. package/dist/src/config/__tests__/google-store.test.js.map +7 -0
  8. package/dist/src/config/__tests__/mcp-tool-deadline.test.js +64 -0
  9. package/dist/src/config/__tests__/mcp-tool-deadline.test.js.map +7 -0
  10. package/dist/src/config/google-store.js +18 -0
  11. package/dist/src/config/google-store.js.map +2 -2
  12. package/dist/src/config/mcp-tool-deadline-context.js +34 -0
  13. package/dist/src/config/mcp-tool-deadline-context.js.map +7 -0
  14. package/dist/src/config/mcp-tool-deadline.js +67 -0
  15. package/dist/src/config/mcp-tool-deadline.js.map +7 -0
  16. package/dist/src/services/mercadolibre/__tests__/mercadolibre-api.test.js +38 -3
  17. package/dist/src/services/mercadolibre/__tests__/mercadolibre-api.test.js.map +2 -2
  18. package/dist/src/services/mercadolibre/__tests__/mercadolibre-buyer-reconciliation.test.js +226 -0
  19. package/dist/src/services/mercadolibre/__tests__/mercadolibre-buyer-reconciliation.test.js.map +7 -0
  20. package/dist/src/services/mercadolibre/__tests__/mercadolibre-claim-reconciliation.test.js +127 -0
  21. package/dist/src/services/mercadolibre/__tests__/mercadolibre-claim-reconciliation.test.js.map +7 -0
  22. package/dist/src/services/mercadolibre/__tests__/mercadolibre-kits.test.js +103 -0
  23. package/dist/src/services/mercadolibre/__tests__/mercadolibre-kits.test.js.map +7 -0
  24. package/dist/src/services/mercadolibre/__tests__/mercadolibre-order-billing-info.test.js +582 -0
  25. package/dist/src/services/mercadolibre/__tests__/mercadolibre-order-billing-info.test.js.map +7 -0
  26. package/dist/src/services/mercadolibre/__tests__/mercadolibre-orders.test.js +10 -0
  27. package/dist/src/services/mercadolibre/__tests__/mercadolibre-orders.test.js.map +2 -2
  28. package/dist/src/services/mercadolibre/__tests__/mercadolibre-packs.test.js +36 -0
  29. package/dist/src/services/mercadolibre/__tests__/mercadolibre-packs.test.js.map +7 -0
  30. package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js +137 -0
  31. package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js.map +7 -0
  32. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-group-ads.test.js +105 -0
  33. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-group-ads.test.js.map +7 -0
  34. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-groups.test.js +143 -0
  35. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-groups.test.js.map +7 -0
  36. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-campaigns.test.js +100 -0
  37. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-campaigns.test.js.map +7 -0
  38. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads.test.js +350 -0
  39. package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads.test.js.map +7 -0
  40. package/dist/src/services/mercadolibre/__tests__/mercadolibre-return-reconciliation.test.js +228 -0
  41. package/dist/src/services/mercadolibre/__tests__/mercadolibre-return-reconciliation.test.js.map +7 -0
  42. package/dist/src/services/mercadolibre/__tests__/mercadolibre-shipping.test.js +58 -0
  43. package/dist/src/services/mercadolibre/__tests__/mercadolibre-shipping.test.js.map +7 -0
  44. package/dist/src/services/mercadolibre/mercadolibre-api.js +15 -3
  45. package/dist/src/services/mercadolibre/mercadolibre-api.js.map +2 -2
  46. package/dist/src/services/mercadolibre/mercadolibre-billing.js +110 -3
  47. package/dist/src/services/mercadolibre/mercadolibre-billing.js.map +2 -2
  48. package/dist/src/services/mercadolibre/mercadolibre-buyer-reconciliation.js +368 -0
  49. package/dist/src/services/mercadolibre/mercadolibre-buyer-reconciliation.js.map +7 -0
  50. package/dist/src/services/mercadolibre/mercadolibre-claim-reconciliation.js +399 -0
  51. package/dist/src/services/mercadolibre/mercadolibre-claim-reconciliation.js.map +7 -0
  52. package/dist/src/services/mercadolibre/mercadolibre-kits.js +55 -0
  53. package/dist/src/services/mercadolibre/mercadolibre-kits.js.map +7 -0
  54. package/dist/src/services/mercadolibre/mercadolibre-order-billing-info.js +392 -0
  55. package/dist/src/services/mercadolibre/mercadolibre-order-billing-info.js.map +7 -0
  56. package/dist/src/services/mercadolibre/mercadolibre-orders.js +8 -8
  57. package/dist/src/services/mercadolibre/mercadolibre-orders.js.map +2 -2
  58. package/dist/src/services/mercadolibre/mercadolibre-packs.js +21 -0
  59. package/dist/src/services/mercadolibre/mercadolibre-packs.js.map +7 -0
  60. package/dist/src/services/mercadolibre/mercadolibre-payments.js +60 -0
  61. package/dist/src/services/mercadolibre/mercadolibre-payments.js.map +7 -0
  62. package/dist/src/services/mercadolibre/mercadolibre-product-ads.js +429 -0
  63. package/dist/src/services/mercadolibre/mercadolibre-product-ads.js.map +7 -0
  64. package/dist/src/services/mercadolibre/mercadolibre-return-reconciliation.js +436 -0
  65. package/dist/src/services/mercadolibre/mercadolibre-return-reconciliation.js.map +7 -0
  66. package/dist/src/services/mercadolibre/mercadolibre-shipping.js +35 -0
  67. package/dist/src/services/mercadolibre/mercadolibre-shipping.js.map +7 -0
  68. package/dist/src/services/vtex/__tests__/vtex-api.test.js +67 -0
  69. package/dist/src/services/vtex/__tests__/vtex-api.test.js.map +7 -0
  70. package/dist/src/services/vtex/vtex-api.js +6 -0
  71. package/dist/src/services/vtex/vtex-api.js.map +2 -2
  72. package/dist/src/tools/config/__tests__/list-profiles.test.js +154 -0
  73. package/dist/src/tools/config/__tests__/list-profiles.test.js.map +7 -0
  74. package/dist/src/tools/config/list-profiles.js +39 -3
  75. package/dist/src/tools/config/list-profiles.js.map +2 -2
  76. package/dist/src/tools/mercadolibre/__tests__/get-order-billing-info.test.js +339 -0
  77. package/dist/src/tools/mercadolibre/__tests__/get-order-billing-info.test.js.map +7 -0
  78. package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-group-ads.test.js +225 -0
  79. package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-group-ads.test.js.map +7 -0
  80. package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-groups.test.js +148 -0
  81. package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-groups.test.js.map +7 -0
  82. package/dist/src/tools/mercadolibre/__tests__/product-ads-campaigns.test.js +60 -0
  83. package/dist/src/tools/mercadolibre/__tests__/product-ads-campaigns.test.js.map +7 -0
  84. package/dist/src/tools/mercadolibre/__tests__/product-ads-helpers.test.js +128 -0
  85. package/dist/src/tools/mercadolibre/__tests__/product-ads-helpers.test.js.map +7 -0
  86. package/dist/src/tools/mercadolibre/__tests__/product-ads-tools.test.js +435 -0
  87. package/dist/src/tools/mercadolibre/__tests__/product-ads-tools.test.js.map +7 -0
  88. package/dist/src/tools/mercadolibre/__tests__/reconcile-buyer-data.test.js +31 -0
  89. package/dist/src/tools/mercadolibre/__tests__/reconcile-buyer-data.test.js.map +7 -0
  90. package/dist/src/tools/mercadolibre/__tests__/reconcile-claim-data.test.js +36 -0
  91. package/dist/src/tools/mercadolibre/__tests__/reconcile-claim-data.test.js.map +7 -0
  92. package/dist/src/tools/mercadolibre/__tests__/validate-connection.test.js +205 -0
  93. package/dist/src/tools/mercadolibre/__tests__/validate-connection.test.js.map +7 -0
  94. package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js +313 -0
  95. package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js.map +7 -0
  96. package/dist/src/tools/mercadolibre/get-bundle-context-by-item.js +176 -0
  97. package/dist/src/tools/mercadolibre/get-bundle-context-by-item.js.map +7 -0
  98. package/dist/src/tools/mercadolibre/get-full-storage-charges.js +183 -0
  99. package/dist/src/tools/mercadolibre/get-full-storage-charges.js.map +7 -0
  100. package/dist/src/tools/mercadolibre/get-order-billing-info.js +189 -0
  101. package/dist/src/tools/mercadolibre/get-order-billing-info.js.map +7 -0
  102. package/dist/src/tools/mercadolibre/get-pack-context-by-order.js +150 -0
  103. package/dist/src/tools/mercadolibre/get-pack-context-by-order.js.map +7 -0
  104. package/dist/src/tools/mercadolibre/get-payment-details.js +322 -0
  105. package/dist/src/tools/mercadolibre/get-payment-details.js.map +7 -0
  106. package/dist/src/tools/mercadolibre/get-product-ads-ad-group-ads.js +144 -0
  107. package/dist/src/tools/mercadolibre/get-product-ads-ad-group-ads.js.map +7 -0
  108. package/dist/src/tools/mercadolibre/get-product-ads-advertisers.js +59 -0
  109. package/dist/src/tools/mercadolibre/get-product-ads-advertisers.js.map +7 -0
  110. package/dist/src/tools/mercadolibre/get-shipping-quote-by-declared-dimensions.js +104 -0
  111. package/dist/src/tools/mercadolibre/get-shipping-quote-by-declared-dimensions.js.map +7 -0
  112. package/dist/src/tools/mercadolibre/index.js +32 -0
  113. package/dist/src/tools/mercadolibre/index.js.map +2 -2
  114. package/dist/src/tools/mercadolibre/product-ads-helpers.js +130 -0
  115. package/dist/src/tools/mercadolibre/product-ads-helpers.js.map +7 -0
  116. package/dist/src/tools/mercadolibre/reconcile-buyer-data.js +27 -0
  117. package/dist/src/tools/mercadolibre/reconcile-buyer-data.js.map +7 -0
  118. package/dist/src/tools/mercadolibre/reconcile-claim-data.js +46 -0
  119. package/dist/src/tools/mercadolibre/reconcile-claim-data.js.map +7 -0
  120. package/dist/src/tools/mercadolibre/reconcile-return-data.js +25 -0
  121. package/dist/src/tools/mercadolibre/reconcile-return-data.js.map +7 -0
  122. package/dist/src/tools/mercadolibre/search-product-ads-ad-groups.js +162 -0
  123. package/dist/src/tools/mercadolibre/search-product-ads-ad-groups.js.map +7 -0
  124. package/dist/src/tools/mercadolibre/search-product-ads-ads.js +216 -0
  125. package/dist/src/tools/mercadolibre/search-product-ads-ads.js.map +7 -0
  126. package/dist/src/tools/mercadolibre/search-product-ads-campaigns.js +116 -0
  127. package/dist/src/tools/mercadolibre/search-product-ads-campaigns.js.map +7 -0
  128. package/dist/src/tools/mercadolibre/validate-connection.js +40 -12
  129. package/dist/src/tools/mercadolibre/validate-connection.js.map +2 -2
  130. package/dist/tests/meli/mercadolibre-billing-provisions.test.js +378 -0
  131. package/dist/tests/meli/mercadolibre-billing-provisions.test.js.map +2 -2
  132. package/dist/tests/meli/mercadolibre-order-billing-info-surface.test.js +123 -0
  133. package/dist/tests/meli/mercadolibre-order-billing-info-surface.test.js.map +7 -0
  134. package/dist/tests/meli/mercadolibre-payment-details.test.js +356 -0
  135. package/dist/tests/meli/mercadolibre-payment-details.test.js.map +7 -0
  136. package/dist/tests/meli/mercadolibre-payments.test.js +62 -0
  137. package/dist/tests/meli/mercadolibre-payments.test.js.map +7 -0
  138. package/dist/tests/meli/mercadolibre-product-ads-ad-groups-surface.test.js +90 -0
  139. package/dist/tests/meli/mercadolibre-product-ads-ad-groups-surface.test.js.map +7 -0
  140. package/dist/tests/meli/mercadolibre-product-ads-campaigns-surface.test.js +72 -0
  141. package/dist/tests/meli/mercadolibre-product-ads-campaigns-surface.test.js.map +7 -0
  142. package/dist/tests/meli/mercadolibre-tool-handlers-pack-kit-shipping.test.js +400 -0
  143. package/dist/tests/meli/mercadolibre-tool-handlers-pack-kit-shipping.test.js.map +7 -0
  144. package/dist/tests/meli/mercadolibre-tool-handlers-small.test.js +31 -12
  145. package/dist/tests/meli/mercadolibre-tool-handlers-small.test.js.map +2 -2
  146. package/dist/tests/vtex/vtex-commercial-conditions-docs.test.js +1 -1
  147. package/dist/tests/vtex/vtex-commercial-conditions-docs.test.js.map +1 -1
  148. package/package.json +1 -1
  149. package/dist/src/google-ads/report-utils.js +0 -78
  150. package/dist/src/google-ads/report-utils.js.map +0 -7
  151. package/dist/src/search-console/search-console-utils.js +0 -275
  152. package/dist/src/search-console/search-console-utils.js.map +0 -7
  153. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +0 -165
  154. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +0 -7
  155. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +0 -233
  156. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +0 -7
  157. package/dist/src/tools/vtex/catalog-admin-batch.js +0 -298
  158. package/dist/src/tools/vtex/catalog-admin-batch.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-order-billing-info.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { getMercadoLibreOrderBillingInfo, getMercadoLibreSaleBillingInfo } from \"../mercadolibre-order-billing-info.js\";\nimport { createMercadoLibreClient, MercadoLibreApiError } from \"../mercadolibre-api.js\";\nimport { getMercadoLibreConnectionRow } from \"../../../config/mercadolibre-profile-store.js\";\nimport { assertActiveProfile } from \"../../../config/profile-store.js\";\nimport { decryptSecret } from \"../../../config/vtex-crypto.js\";\n\nvi.mock(\"../mercadolibre-api.js\", () => ({\n createMercadoLibreClient: vi.fn(),\n isRetryableMercadoLibreError: (error: unknown) =>\n error instanceof MercadoLibreApiError && Boolean(error.status && [408, 429, 500, 502, 503, 504].includes(error.status)),\n MercadoLibreApiError: class MercadoLibreApiError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly code?: string,\n public readonly retryAfterMs?: number\n ) {\n super(message);\n }\n },\n}));\nvi.mock(\"../../../config/mercadolibre-profile-store.js\", () => ({ getMercadoLibreConnectionRow: vi.fn() }));\nvi.mock(\"../../../config/profile-store.js\", () => ({ assertActiveProfile: vi.fn() }));\nvi.mock(\"../../../config/vtex-crypto.js\", () => ({ decryptSecret: vi.fn() }));\n\ndescribe(\"getMercadoLibreOrderBillingInfo\", () => {\n const getMock = vi.fn();\n const completeBillingInfo = () => ({\n buyer: {\n billing_info: {\n name: \"Ada\",\n last_name: \"Lovelace\",\n identification: { type: \"CUIT\", number: \"20123456789\" },\n address: {\n street_name: \"Main\",\n street_number: \"10\",\n city_name: \"Buenos Aires\",\n state: \"CABA\",\n zip_code: \"1000\",\n country_id: \"AR\",\n },\n taxes: { taxpayer_type: { id: \"responsable_inscripto\", description: \"Responsable Inscripto\" } },\n },\n },\n });\n\n function createDeferred<T>() {\n let resolve!: (value: T) => void;\n const promise = new Promise<T>((resolvePromise) => {\n resolve = resolvePromise;\n });\n return { promise, resolve };\n }\n\n function setFiscalField(billingInfo: Record<string, unknown>, path: string[], value: unknown) {\n let current = billingInfo.buyer as Record<string, unknown>;\n for (const key of [\"billing_info\", ...path.slice(0, -1)]) {\n current = current[key] as Record<string, unknown>;\n }\n current[path.at(-1)!] = value;\n }\n\n beforeEach(() => {\n vi.clearAllMocks();\n vi.mocked(assertActiveProfile).mockResolvedValue({ id: \"triplim\" } as never);\n vi.mocked(getMercadoLibreConnectionRow).mockResolvedValue({\n sellerId: \"seller-1\",\n encryptedAccessToken: \"stored-token\",\n expiresAt: new Date(\"2099-01-01T00:00:00.000Z\"),\n status: \"active\",\n } as never);\n vi.mocked(decryptSecret).mockReturnValue(\"stored-access-token\");\n vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock } as never);\n });\n\n it(\"reads the order before requesting billing info with its site and billing info IDs\", async () => {\n const order = { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"billing/123\" } } };\n const billingInfo = completeBillingInfo();\n getMock\n .mockResolvedValueOnce({ data: order })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"order/456\")).resolves.toEqual({\n available: true,\n order,\n billingInfo,\n });\n expect(getMock).toHaveBeenNthCalledWith(1, \"/orders/order%2F456\");\n expect(getMock).toHaveBeenNthCalledWith(2, \"/users/seller-1\");\n expect(getMock).toHaveBeenNthCalledWith(3, \"/orders/billing-info/MLA/billing%2F123\");\n });\n\n it(\"returns an explicit unavailable result when the order has no buyer billing info\", async () => {\n getMock.mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: {} } });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"order_buyer_billing_info_missing\",\n });\n expect(getMock).toHaveBeenCalledTimes(1);\n });\n\n it(\"does not request fiscal data when the order belongs to another seller\", async () => {\n getMock.mockResolvedValueOnce({\n data: { seller: { id: \"other-seller\" }, buyer: { billing_info: { id: \"billing/123\" } } },\n });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"order_seller_ownership_mismatch\",\n });\n expect(getMock).toHaveBeenCalledTimes(1);\n expect(getMock).not.toHaveBeenCalledWith(expect.stringContaining(\"/orders/billing-info/\"));\n });\n\n it(\"accepts a numeric order seller ID for the selected string seller ID\", async () => {\n vi.mocked(getMercadoLibreConnectionRow).mockResolvedValue({\n sellerId: \"123\",\n encryptedAccessToken: \"stored-token\",\n expiresAt: new Date(\"2099-01-01T00:00:00.000Z\"),\n status: \"active\",\n } as never);\n const order = { seller: { id: 123 }, buyer: { billing_info: { id: \"billing/123\" } } };\n const billingInfo = completeBillingInfo();\n getMock\n .mockResolvedValueOnce({ data: order })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: true,\n order,\n billingInfo,\n });\n expect(getMock).toHaveBeenNthCalledWith(2, \"/users/123\");\n expect(getMock).toHaveBeenNthCalledWith(3, \"/orders/billing-info/MLA/billing%2F123\");\n });\n\n it(\"normalizes surrounding whitespace before checking seller ownership\", async () => {\n vi.mocked(getMercadoLibreConnectionRow).mockResolvedValue({\n sellerId: \" seller-1 \",\n encryptedAccessToken: \"stored-token\",\n expiresAt: new Date(\"2099-01-01T00:00:00.000Z\"),\n status: \"active\",\n } as never);\n const order = { seller: { id: \" seller-1 \" }, buyer: { billing_info: { id: \"billing/123\" } } };\n getMock\n .mockResolvedValueOnce({ data: order })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: completeBillingInfo() });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toMatchObject({ available: true });\n expect(getMock).toHaveBeenNthCalledWith(2, \"/users/%20seller-1%20\");\n expect(getMock).toHaveBeenNthCalledWith(3, \"/orders/billing-info/MLA/billing%2F123\");\n });\n\n it(\"does not request fiscal data when the order seller data is malformed\", async () => {\n getMock.mockResolvedValueOnce({\n data: { seller: { id: { unexpected: \"value\" } }, buyer: { billing_info: { id: \"billing/123\" } } },\n });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"order_seller_id_missing_or_malformed\",\n });\n expect(getMock).toHaveBeenCalledTimes(1);\n expect(getMock).not.toHaveBeenCalledWith(expect.stringContaining(\"/orders/billing-info/\"));\n });\n\n it.each([\n [\"null\", null],\n [\"array\", []],\n [\"empty string\", \"\"],\n [\"whitespace-only string\", \" \"],\n ])(\"fails closed for a %s seller ID\", async (_description, sellerId) => {\n getMock.mockResolvedValueOnce({\n data: { seller: { id: sellerId }, buyer: { billing_info: { id: \"billing/123\" } } },\n });\n\n const result = await getMercadoLibreOrderBillingInfo(\"triplim\", \"456\");\n\n expect(result).toEqual({\n available: false,\n reason: \"order_seller_id_missing_or_malformed\",\n });\n expect(result).not.toHaveProperty(\"billingInfo\");\n expect(result).not.toHaveProperty(\"fiscal\");\n expect(getMock).toHaveBeenCalledTimes(1);\n expect(getMock).not.toHaveBeenCalledWith(expect.stringContaining(\"/orders/billing-info/\"));\n });\n\n it(\"preserves upstream errors from the order or billing-info request\", async () => {\n const upstreamError = new Error(\"MercadoLibre API request failed (403): forbidden\");\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockRejectedValueOnce(upstreamError);\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).rejects.toMatchObject({\n message: \"MercadoLibre billing info request unavailable\",\n });\n });\n\n it(\"returns credential maintenance required without refreshing or persisting credentials\", async () => {\n vi.mocked(getMercadoLibreConnectionRow).mockResolvedValue({\n sellerId: \"seller-1\",\n encryptedAccessToken: \"stored-token\",\n expiresAt: new Date(\"2000-01-01T00:00:00.000Z\"),\n status: \"active\",\n } as never);\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"credential_maintenance_required\",\n });\n expect(decryptSecret).not.toHaveBeenCalled();\n expect(createMercadoLibreClient).not.toHaveBeenCalled();\n expect(getMock).not.toHaveBeenCalled();\n });\n\n it(\"retries a transient order request with deterministic backoff\", async () => {\n const transient = new MercadoLibreApiError(\"temporary\", 503);\n const pause = vi.fn().mockResolvedValue(undefined);\n getMock\n .mockRejectedValueOnce(transient)\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: completeBillingInfo() });\n\n await expect(\n getMercadoLibreOrderBillingInfo(\"triplim\", \"456\", { baseRetryDelayMs: 1, sleep: pause })\n ).resolves.toMatchObject({ available: true });\n expect(pause).toHaveBeenCalledWith(1);\n expect(getMock).toHaveBeenCalledTimes(4);\n });\n\n it(\"retries transient account and billing-info requests\", async () => {\n const pause = vi.fn().mockResolvedValue(undefined);\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockRejectedValueOnce(new MercadoLibreApiError(\"temporary account\", 503))\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockRejectedValueOnce(new MercadoLibreApiError(\"temporary billing\", 429))\n .mockResolvedValueOnce({ data: completeBillingInfo() });\n\n await expect(\n getMercadoLibreOrderBillingInfo(\"triplim\", \"456\", { baseRetryDelayMs: 1, sleep: pause })\n ).resolves.toMatchObject({ available: true });\n expect(pause).toHaveBeenCalledTimes(2);\n expect(getMock).toHaveBeenCalledTimes(5);\n });\n\n it(\"preserves terminal retryable classification after bounded retry exhaustion without leaking upstream details\", async () => {\n const pause = vi.fn().mockResolvedValue(undefined);\n getMock.mockRejectedValue(new MercadoLibreApiError(\"buyer-tax-id-should-not-leak\", 503, \"internal_error\"));\n\n await expect(\n getMercadoLibreOrderBillingInfo(\"triplim\", \"456\", { maxRetries: 1, sleep: pause })\n ).rejects.toMatchObject({\n message: \"MercadoLibre billing info request unavailable\",\n status: 503,\n code: \"internal_error\",\n resource: \"order\",\n attempts: 2,\n retryable: true,\n });\n expect(pause).toHaveBeenCalledTimes(1);\n expect(getMock).toHaveBeenCalledTimes(2);\n });\n\n it.each([\n [404, \"not_found\", \"order\"],\n [403, \"forbidden\", \"order\"],\n ])(\"preserves terminal %i non-retryable classification without retrying\", async (status, code, resource) => {\n const pause = vi.fn().mockResolvedValue(undefined);\n getMock.mockRejectedValue(new MercadoLibreApiError(\"buyer-tax-id-should-not-leak\", status, code));\n\n await expect(\n getMercadoLibreOrderBillingInfo(\"triplim\", \"456\", { sleep: pause })\n ).rejects.toMatchObject({\n message: \"MercadoLibre billing info request unavailable\",\n status,\n code,\n resource,\n attempts: 1,\n retryable: false,\n });\n expect(pause).not.toHaveBeenCalled();\n expect(getMock).toHaveBeenCalledTimes(1);\n });\n\n it(\"fails closed when intermediary or billing payloads are malformed\", async () => {\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: [] });\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"account_payload_malformed\",\n });\n\n getMock.mockReset();\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: { buyer: {} } });\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"billing_info_payload_malformed\",\n });\n });\n\n it.each([\n [\"buyer name\", { name: true }],\n [\"buyer last name\", { last_name: true }],\n [\"identification type\", { identification: { type: true } }],\n [\"identification number\", { identification: { number: true } }],\n [\"address street name\", { address: { street_name: true } }],\n [\"address street number\", { address: { street_number: true } }],\n [\"address city\", { address: { city_name: true } }],\n [\"address state\", { address: { state: true } }],\n [\"address zip code\", { address: { zip_code: true } }],\n [\"address country\", { address: { country_id: true } }],\n [\"taxpayer type ID\", { taxes: { taxpayer_type: { id: true } } }],\n [\"taxpayer type description\", { taxes: { taxpayer_type: { description: true } } }],\n ])(\"fails closed when %s is a boolean\", async (_field, fiscalFields) => {\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: { buyer: { billing_info: fiscalFields } } });\n\n const result = await getMercadoLibreOrderBillingInfo(\"triplim\", \"456\");\n\n expect(result).toEqual({\n available: false,\n reason: \"billing_info_fiscal_fields_malformed\",\n });\n expect(result).not.toHaveProperty(\"billingInfo\");\n });\n\n it.each([\n [\"buyer name\", [\"name\"]],\n [\"buyer last name\", [\"last_name\"]],\n [\"identification type\", [\"identification\", \"type\"]],\n [\"identification number\", [\"identification\", \"number\"]],\n [\"address street name\", [\"address\", \"street_name\"]],\n [\"address street number\", [\"address\", \"street_number\"]],\n [\"address city\", [\"address\", \"city_name\"]],\n [\"address state\", [\"address\", \"state\"]],\n [\"address zip code\", [\"address\", \"zip_code\"]],\n [\"address country\", [\"address\", \"country_id\"]],\n [\"taxpayer type ID\", [\"taxes\", \"taxpayer_type\", \"id\"]],\n [\"taxpayer type description\", [\"taxes\", \"taxpayer_type\", \"description\"]],\n ])(\"fails closed without a fiscal projection when required %s is null or blank\", async (_field, path) => {\n for (const value of [null, \" \"]) {\n const billingInfo = completeBillingInfo();\n setFiscalField(billingInfo, path, value);\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n const result = await getMercadoLibreOrderBillingInfo(\"triplim\", \"456\");\n\n expect(result).toEqual({ available: false, reason: \"billing_info_fiscal_fields_missing\" });\n expect(result).not.toHaveProperty(\"billingInfo\");\n expect(result).not.toHaveProperty(\"fiscal\");\n getMock.mockReset();\n }\n });\n\n it.each([\n [\"array\", []],\n [\"object\", { unexpected: \"value\" }],\n ])(\"fails closed when a fiscal field is a malformed %s\", async (_type, value) => {\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: { buyer: { billing_info: { name: value } } } });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"billing_info_fiscal_fields_malformed\",\n });\n });\n\n it(\"allows a valid numeric street number in a complete fiscal record\", async () => {\n const billingInfo = completeBillingInfo();\n setFiscalField(billingInfo, [\"address\", \"street_number\"], 123);\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: true,\n order: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } },\n billingInfo,\n });\n });\n\n it(\"normalizes a complete Mercado Libre state object to the report display state\", async () => {\n const billingInfo = completeBillingInfo();\n setFiscalField(billingInfo, [\"address\", \"state\"], { code: \"AR-C\", name: \"Ciudad Aut\u00F3noma de Buenos Aires\" });\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: true,\n order: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } },\n billingInfo: expect.objectContaining({\n buyer: expect.objectContaining({\n billing_info: expect.objectContaining({\n address: expect.objectContaining({ state: \"Ciudad Aut\u00F3noma de Buenos Aires\" }),\n }),\n }),\n }),\n });\n });\n\n it.each([\n [\"missing code\", { name: \"Ciudad Aut\u00F3noma de Buenos Aires\" }],\n [\"missing name\", { code: \"AR-C\" }],\n [\"blank name\", { code: \"AR-C\", name: \" \" }],\n ])(\"fails closed for a state object with %s\", async (_description, state) => {\n const billingInfo = completeBillingInfo();\n setFiscalField(billingInfo, [\"address\", \"state\"], state);\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: false,\n reason: \"billing_info_fiscal_fields_malformed\",\n });\n });\n\n it(\"retains scalar state compatibility\", async () => {\n const billingInfo = completeBillingInfo();\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: billingInfo });\n\n await expect(getMercadoLibreOrderBillingInfo(\"triplim\", \"456\")).resolves.toEqual({\n available: true,\n order: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } },\n billingInfo,\n });\n });\n\n it(\"resolves a direct sale reference as an order without querying packs\", async () => {\n getMock\n .mockResolvedValueOnce({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"123\" } } } })\n .mockResolvedValueOnce({ data: { site_id: \"MLA\" } })\n .mockResolvedValueOnce({ data: completeBillingInfo() });\n\n await expect(getMercadoLibreSaleBillingInfo(\"triplim\", \"order-1\")).resolves.toMatchObject({\n resolutionKind: \"order\",\n orderId: \"order-1\",\n result: { available: true },\n });\n expect(getMock).not.toHaveBeenCalledWith(\"/packs/order-1\");\n });\n\n it(\"falls back to a pack only after an order 404 and independently resolves every member\", async () => {\n const completeFor = (id: string) => ({ seller: { id: \"seller-1\" }, buyer: { billing_info: { id } } });\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n if (path === \"/packs/pack-1\") return Promise.resolve({ data: { orders: [{ id: \"order-1\" }, { id: \"order-2\" }] } });\n if (path === \"/orders/order-1\") return Promise.resolve({ data: completeFor(\"bill-1\") });\n if (path === \"/orders/order-2\") return Promise.resolve({ data: completeFor(\"bill-2\") });\n if (path === \"/users/seller-1\") return Promise.resolve({ data: { site_id: \"MLA\" } });\n if (path === \"/orders/billing-info/MLA/bill-1\" || path === \"/orders/billing-info/MLA/bill-2\") return Promise.resolve({ data: completeBillingInfo() });\n throw new Error(`unexpected path ${path}`);\n });\n\n const result = await getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\", { maxConcurrency: 2 });\n\n expect(result).toMatchObject({\n resolutionKind: \"pack\",\n packId: \"pack-1\",\n metadata: { memberCount: 2, accessibleCount: 2, availableCount: 2, unavailableCount: 0, failedCount: 0, partialCoverage: false },\n members: [expect.objectContaining({ orderId: \"order-1\", accessible: true }), expect.objectContaining({ orderId: \"order-2\", accessible: true })],\n });\n });\n\n it(\"keeps pack member failures and ownership mismatches scoped to their members\", async () => {\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n if (path === \"/packs/pack-1\") return Promise.resolve({ data: { orders: [{ id: \"foreign\" }, { id: \"missing\" }] } });\n if (path === \"/orders/foreign\") return Promise.resolve({ data: { seller: { id: \"other-seller\" }, buyer: { billing_info: { id: \"do-not-read\" } } } });\n if (path === \"/orders/missing\") return Promise.reject(new MercadoLibreApiError(\"missing\", 404));\n throw new Error(`unexpected path ${path}`);\n });\n\n await expect(getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\")).resolves.toMatchObject({\n resolutionKind: \"pack\",\n metadata: { memberCount: 2, accessibleCount: 1, availableCount: 0, unavailableCount: 1, failedCount: 1, partialCoverage: true },\n members: [\n { orderId: \"foreign\", accessible: true, result: { available: false, reason: \"order_seller_ownership_mismatch\" } },\n { orderId: \"missing\", accessible: false, failureReason: \"order_not_found\" },\n ],\n });\n expect(getMock).not.toHaveBeenCalledWith(expect.stringContaining(\"billing-info\"));\n });\n\n it(\"keeps valid pack members when other pack entries do not contain an order ID\", async () => {\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n if (path === \"/packs/pack-1\") return Promise.resolve({ data: { orders: [{ id: \"order-1\" }, {}, { id: \" \" }] } });\n if (path === \"/orders/order-1\") return Promise.resolve({ data: { seller: { id: \"seller-1\" }, buyer: { billing_info: { id: \"bill-1\" } } } });\n if (path === \"/users/seller-1\") return Promise.resolve({ data: { site_id: \"MLA\" } });\n if (path === \"/orders/billing-info/MLA/bill-1\") return Promise.resolve({ data: completeBillingInfo() });\n throw new Error(`unexpected path ${path}`);\n });\n\n await expect(getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\")).resolves.toMatchObject({\n resolutionKind: \"pack\",\n metadata: {\n memberCount: 3,\n validMemberCount: 1,\n invalidMemberCount: 2,\n accessibleCount: 1,\n availableCount: 1,\n unavailableCount: 0,\n failedCount: 2,\n partialCoverage: true,\n },\n members: [\n { orderId: \"order-1\", accessible: true, result: { available: true } },\n { memberIndex: 1, accessible: false, failureReason: \"invalid_member\" },\n { memberIndex: 2, accessible: false, failureReason: \"invalid_member\" },\n ],\n });\n });\n\n it(\"keeps pack member resolution at the configured concurrency ceiling\", async () => {\n let activeMembers = 0;\n let maxActiveMembers = 0;\n const firstWaveStarted = createDeferred<void>();\n const thirdMemberStarted = createDeferred<void>();\n const fourthMemberStarted = createDeferred<void>();\n const memberRequests = new Map<string, ReturnType<typeof createDeferred<{ data: Record<string, unknown> }>>>();\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n if (path === \"/packs/pack-1\") return Promise.resolve({ data: { orders: [{ id: \"one\" }, { id: \"two\" }, { id: \"three\" }, { id: \"four\" }] } });\n if (path.startsWith(\"/orders/\") && !path.startsWith(\"/orders/billing-info/\")) {\n activeMembers += 1;\n maxActiveMembers = Math.max(maxActiveMembers, activeMembers);\n if (activeMembers === 2) firstWaveStarted.resolve();\n const request = createDeferred<{ data: Record<string, unknown> }>();\n memberRequests.set(path, request);\n if (memberRequests.size === 3) thirdMemberStarted.resolve();\n if (memberRequests.size === 4) fourthMemberStarted.resolve();\n return request.promise.finally(() => {\n activeMembers -= 1;\n });\n }\n throw new Error(`unexpected path ${path}`);\n });\n\n const result = getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\", { maxConcurrency: 2 });\n await firstWaveStarted.promise;\n expect(maxActiveMembers).toBe(2);\n\n memberRequests.get(\"/orders/one\")!.resolve({ data: { seller: { id: \"seller-1\" }, buyer: {} } });\n await thirdMemberStarted.promise;\n expect(maxActiveMembers).toBe(2);\n\n for (const path of [\"/orders/two\", \"/orders/three\"]) {\n memberRequests.get(path)!.resolve({ data: { seller: { id: \"seller-1\" }, buyer: {} } });\n }\n await fourthMemberStarted.promise;\n memberRequests.get(\"/orders/four\")!.resolve({ data: { seller: { id: \"seller-1\" }, buyer: {} } });\n\n await result;\n\n expect(maxActiveMembers).toBe(2);\n });\n\n it(\"reports a retry-exhausted member without losing pack aggregate coverage\", async () => {\n const pause = vi.fn().mockResolvedValue(undefined);\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n if (path === \"/packs/pack-1\") return Promise.resolve({ data: { orders: [{ id: \"unavailable\" }] } });\n if (path === \"/orders/unavailable\") {\n return Promise.reject(new MercadoLibreApiError(\"buyer-tax-id-should-not-leak https://api.example/orders/unavailable\", 503));\n }\n throw new Error(`unexpected path ${path}`);\n });\n\n const result = await getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\", { maxRetries: 1, sleep: pause });\n expect(result).toMatchObject({\n resolutionKind: \"pack\",\n metadata: {\n memberCount: 1,\n accessibleCount: 0,\n availableCount: 0,\n unavailableCount: 0,\n failedCount: 1,\n partialCoverage: true,\n },\n members: [{ orderId: \"unavailable\", accessible: false, failureReason: \"upstream_unavailable\", attempts: 2, retryable: true }],\n });\n expect(JSON.stringify(result)).not.toContain(\"buyer-tax-id-should-not-leak\");\n expect(JSON.stringify(result)).not.toContain(\"api.example\");\n expect(pause).toHaveBeenCalledTimes(1);\n expect(getMock).toHaveBeenCalledWith(\"/orders/unavailable\", expect.anything());\n expect(getMock.mock.calls.filter(([path]) => path === \"/orders/unavailable\")).toHaveLength(2);\n });\n\n it(\"stops member retries when the feature-scoped pack deadline is exhausted\", async () => {\n const pause = vi.fn().mockResolvedValue(undefined);\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n if (path === \"/packs/pack-1\") return Promise.resolve({ data: { orders: [{ id: \"slow\" }] } });\n if (path === \"/orders/slow\") return Promise.reject(new MercadoLibreApiError(\"temporary\", 503));\n throw new Error(`unexpected path ${path}`);\n });\n\n await expect(\n getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\", {\n maxRetries: 2,\n baseRetryDelayMs: 10,\n packOperationDeadlineMs: 5,\n now: () => 0,\n sleep: pause,\n })\n ).resolves.toMatchObject({\n resolutionKind: \"pack\",\n metadata: { failedCount: 1, partialCoverage: true, deadlineExceeded: true },\n members: [{ orderId: \"slow\", accessible: false, failureReason: \"operation_deadline_exceeded\" }],\n });\n expect(pause).not.toHaveBeenCalled();\n expect(getMock.mock.calls.filter(([path]) => path === \"/orders/slow\")).toHaveLength(1);\n });\n\n it(\"keeps an initial order deadline unavailable and does not fall back after it expires\", async () => {\n const initialOrder = createDeferred<{ data: unknown }>();\n const initialRequestStarted = createDeferred<void>();\n let now = 0;\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") {\n initialRequestStarted.resolve();\n return initialOrder.promise;\n }\n throw new Error(`unexpected path ${path}`);\n });\n\n const result = getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\", {\n packOperationDeadlineMs: 5,\n now: () => now,\n });\n await initialRequestStarted.promise;\n now = 5;\n\n await expect(result).rejects.toThrow(\"MercadoLibre pack billing info operation deadline exceeded\");\n expect(getMock).toHaveBeenCalledWith(\"/orders/pack-1\", expect.objectContaining({ signal: expect.any(AbortSignal) }));\n expect(getMock).not.toHaveBeenCalledWith(\"/packs/pack-1\", expect.anything());\n });\n\n it(\"does not start fallback pack resolution after the initial order lookup exhausts the shared deadline\", async () => {\n let now = 0;\n getMock.mockImplementation((path: string) => {\n if (path === \"/orders/pack-1\") {\n now = 5;\n return Promise.reject(new MercadoLibreApiError(\"not found\", 404));\n }\n throw new Error(`unexpected path ${path}`);\n });\n\n await expect(\n getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\", {\n packOperationDeadlineMs: 5,\n now: () => now,\n })\n ).resolves.toMatchObject({\n resolutionKind: \"pack\",\n unavailableReason: \"pack_operation_deadline_exceeded\",\n metadata: { deadlineExceeded: true, partialCoverage: true },\n members: [],\n });\n expect(getMock).toHaveBeenCalledTimes(1);\n expect(getMock).not.toHaveBeenCalledWith(\"/packs/pack-1\", expect.anything());\n });\n\n it.each([\n [\"empty\", { orders: [] }, \"pack_orders_empty\"],\n [\"malformed envelope\", { orders: null }, \"pack_payload_malformed\"],\n ])(\"fails safely for a %s pack payload\", async (_description, payload, reason) => {\n getMock\n .mockRejectedValueOnce(new MercadoLibreApiError(\"not found\", 404))\n .mockResolvedValueOnce({ data: payload });\n\n await expect(getMercadoLibreSaleBillingInfo(\"triplim\", \"pack-1\")).resolves.toMatchObject({\n resolutionKind: \"pack\",\n members: [],\n unavailableReason: reason,\n metadata: { partialCoverage: true },\n });\n });\n\n it(\"does not attempt pack resolution for an order permission failure\", async () => {\n getMock.mockRejectedValueOnce(new MercadoLibreApiError(\"forbidden\", 403));\n\n await expect(getMercadoLibreSaleBillingInfo(\"triplim\", \"reference-1\")).rejects.toMatchObject({ status: 403, resource: \"order\" });\n expect(getMock).not.toHaveBeenCalledWith(\"/packs/reference-1\");\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -179,6 +179,16 @@ describe("mercadolibre-orders service", () => {
179
179
  await expect(call()).resolves.toEqual(data);
180
180
  expect(getMock).toHaveBeenCalledWith(path);
181
181
  });
182
+ it("passes the documented new shipment response header", async () => {
183
+ getMock.mockResolvedValueOnce({ data: { destination: { shipping_address: {} } } });
184
+ await getMercadoLibreShipment("profile-1", "ship-1", {
185
+ signal: new AbortController().signal,
186
+ headers: { "x-format-new": "true" }
187
+ });
188
+ expect(getMock).toHaveBeenCalledWith("/shipments/ship-1", expect.objectContaining({
189
+ headers: { "x-format-new": "true" }
190
+ }));
191
+ });
182
192
  it.each([
183
193
  {
184
194
  label: "shipment details batch",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-orders.test.ts"],
4
- "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport {\n getMercadoLibreOrder,\n getMercadoLibreOrderDetailsBatch,\n getMercadoLibreOrderShipments,\n getMercadoLibreShipment,\n getMercadoLibreShipmentBatch,\n getMercadoLibreShipmentCosts,\n getMercadoLibreShipmentCostsBatch,\n getMercadoLibreShipmentItems,\n searchMercadoLibreOrders,\n searchMercadoLibreOrdersBatch,\n} from \"../mercadolibre-orders.js\";\nimport { getMercadoLibreApiContext, runMercadoLibreBatch } from \"../mercadolibre-api.js\";\n\nvi.mock(\"../mercadolibre-api.js\", () => ({\n getMercadoLibreApiContext: vi.fn(),\n runMercadoLibreBatch: vi.fn(),\n}));\n\ndescribe(\"mercadolibre-orders service\", () => {\n const getMock = vi.fn();\n\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(getMercadoLibreApiContext).mockResolvedValue({\n api: { get: getMock },\n sellerId: \"seller-from-profile\",\n accessToken: \"token\",\n } as never);\n });\n\n it(\"uses the orders search endpoint with seller fallback and normalized dates\", async () => {\n getMock.mockResolvedValueOnce({ data: { results: [{ id: 1 }] } });\n\n const result = await searchMercadoLibreOrders(\"profile-1\", {\n seller: \"\",\n from: \"2026-01-01\",\n to: \"2026-01-31\",\n status: \"paid\",\n limit: 25,\n offset: 50,\n });\n\n expect(result).toEqual({ results: [{ id: 1 }] });\n expect(getMock).toHaveBeenCalledWith(\"/orders/search\", {\n params: {\n seller: \"seller-from-profile\",\n \"order.date_created.from\": \"2026-01-01T00:00:00.000-00:00\",\n \"order.date_created.to\": \"2026-01-31T23:59:59.999-00:00\",\n \"order.status\": \"paid\",\n q: undefined,\n sort: undefined,\n offset: 50,\n limit: 25,\n },\n });\n });\n\n it(\"preserves explicit seller, q and sort filters in order searches\", async () => {\n getMock.mockResolvedValueOnce({ data: { results: [{ id: 2 }] } });\n\n await searchMercadoLibreOrders(\"profile-1\", {\n seller: \"seller-override\",\n from: \"2026-02-01\",\n to: \"2026-02-02\",\n q: \"SKU-123\",\n sort: \"date_desc\",\n });\n\n expect(getMock).toHaveBeenCalledWith(\"/orders/search\", {\n params: {\n seller: \"seller-override\",\n \"order.date_created.from\": \"2026-02-01T00:00:00.000-00:00\",\n \"order.date_created.to\": \"2026-02-02T23:59:59.999-00:00\",\n \"order.status\": undefined,\n q: \"SKU-123\",\n sort: \"date_desc\",\n offset: 0,\n limit: 50,\n },\n });\n });\n\n it(\"builds batch order searches from offset ids\", async () => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: [],\n }));\n getMock.mockResolvedValueOnce({ data: { results: [], paging: { total: 0 } } });\n\n const result = await searchMercadoLibreOrdersBatch(\n \"profile-1\",\n {\n seller: \"\",\n from: \"2026-02-01\",\n to: \"2026-02-28\",\n },\n [100],\n { maxConcurrency: 2 }\n );\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([\"100\"], expect.any(Function), {\n maxConcurrency: 2,\n });\n expect(getMock).toHaveBeenCalledWith(\"/orders/search\", {\n params: {\n seller: \"seller-from-profile\",\n \"order.date_created.from\": \"2026-02-01T00:00:00.000-00:00\",\n \"order.date_created.to\": \"2026-02-28T23:59:59.999-00:00\",\n \"order.status\": undefined,\n q: undefined,\n sort: undefined,\n offset: 100,\n limit: 50,\n },\n });\n expect(result).toEqual({\n successful: [{ id: \"100\", document: { results: [], paging: { total: 0 } } }],\n failed: [],\n });\n });\n\n it(\"passes explicit seller and empty offsets through the shared batch order search runner\", async () => {\n vi.mocked(runMercadoLibreBatch).mockResolvedValue({ successful: [], failed: [] } as never);\n\n const result = await searchMercadoLibreOrdersBatch(\n \"profile-1\",\n {\n seller: \"seller-explicit\",\n from: \"2026-03-01\",\n to: \"2026-03-31\",\n status: \"confirmed\",\n },\n [],\n { maxRetries: 1 }\n );\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([], expect.any(Function), { maxRetries: 1 });\n expect(getMock).not.toHaveBeenCalled();\n expect(result).toEqual({ successful: [], failed: [] });\n });\n\n it(\"loads order details in batch through the shared batch runner\", async () => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher, options) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: options?.maxRetries ? [] : [],\n }));\n getMock.mockResolvedValueOnce({ data: { id: \"2001\", status: \"paid\" } });\n\n const result = await getMercadoLibreOrderDetailsBatch(\"profile-1\", [\"2001\"], {\n maxRetries: 1,\n });\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([\"2001\"], expect.any(Function), {\n maxRetries: 1,\n });\n expect(getMock).toHaveBeenCalledWith(\"/orders/2001\");\n expect(result).toEqual({\n successful: [{ id: \"2001\", document: { id: \"2001\", status: \"paid\" } }],\n failed: [],\n });\n });\n\n it.each([\n {\n label: \"single order\",\n call: () => getMercadoLibreOrder(\"profile-1\", \"2001\"),\n path: \"/orders/2001\",\n data: { id: \"2001\" },\n },\n {\n label: \"order shipments\",\n call: () => getMercadoLibreOrderShipments(\"profile-1\", \"2001\"),\n path: \"/orders/2001/shipments\",\n data: { shipments: [] },\n },\n {\n label: \"single shipment\",\n call: () => getMercadoLibreShipment(\"profile-1\", \"ship-1\"),\n path: \"/shipments/ship-1\",\n data: { id: \"ship-1\" },\n },\n {\n label: \"shipment items\",\n call: () => getMercadoLibreShipmentItems(\"profile-1\", \"ship-1\"),\n path: \"/shipments/ship-1/items\",\n data: { items: [] },\n },\n {\n label: \"shipment costs\",\n call: () => getMercadoLibreShipmentCosts(\"profile-1\", \"ship-1\"),\n path: \"/shipments/ship-1/costs\",\n data: { gross_amount: 99 },\n },\n ])(\"fetches $label from the expected MercadoLibre endpoint\", async ({ call, path, data }) => {\n getMock.mockResolvedValueOnce({ data });\n\n await expect(call()).resolves.toEqual(data);\n expect(getMock).toHaveBeenCalledWith(path);\n });\n\n it.each([\n {\n label: \"shipment details batch\",\n call: () => getMercadoLibreShipmentBatch(\"profile-1\", [\"ship-1\"], { maxConcurrency: 3 }),\n expectedIds: [\"ship-1\"],\n expectedOptions: { maxConcurrency: 3 },\n responsePath: \"/shipments/ship-1\",\n data: { id: \"ship-1\", status: \"ready_to_ship\" },\n },\n {\n label: \"shipment costs batch\",\n call: () => getMercadoLibreShipmentCostsBatch(\"profile-1\", [\"ship-2\"], { maxRetries: 2 }),\n expectedIds: [\"ship-2\"],\n expectedOptions: { maxRetries: 2 },\n responsePath: \"/shipments/ship-2/costs\",\n data: { id: \"ship-2\", gross_amount: 15 },\n },\n ])(\"delegates $label to the shared batch runner with the right fetcher\", async ({\n call,\n expectedIds,\n expectedOptions,\n responsePath,\n data,\n }) => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: [],\n }));\n getMock.mockResolvedValueOnce({ data });\n\n const result = await call();\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith(expectedIds, expect.any(Function), expectedOptions);\n expect(getMock).toHaveBeenCalledWith(responsePath);\n expect(result).toEqual({\n successful: [{ id: expectedIds[0], document: data }],\n failed: [],\n });\n });\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport {\n getMercadoLibreOrder,\n getMercadoLibreOrderDetailsBatch,\n getMercadoLibreOrderShipments,\n getMercadoLibreShipment,\n getMercadoLibreShipmentBatch,\n getMercadoLibreShipmentCosts,\n getMercadoLibreShipmentCostsBatch,\n getMercadoLibreShipmentItems,\n searchMercadoLibreOrders,\n searchMercadoLibreOrdersBatch,\n} from \"../mercadolibre-orders.js\";\nimport { getMercadoLibreApiContext, runMercadoLibreBatch } from \"../mercadolibre-api.js\";\n\nvi.mock(\"../mercadolibre-api.js\", () => ({\n getMercadoLibreApiContext: vi.fn(),\n runMercadoLibreBatch: vi.fn(),\n}));\n\ndescribe(\"mercadolibre-orders service\", () => {\n const getMock = vi.fn();\n\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(getMercadoLibreApiContext).mockResolvedValue({\n api: { get: getMock },\n sellerId: \"seller-from-profile\",\n accessToken: \"token\",\n } as never);\n });\n\n it(\"uses the orders search endpoint with seller fallback and normalized dates\", async () => {\n getMock.mockResolvedValueOnce({ data: { results: [{ id: 1 }] } });\n\n const result = await searchMercadoLibreOrders(\"profile-1\", {\n seller: \"\",\n from: \"2026-01-01\",\n to: \"2026-01-31\",\n status: \"paid\",\n limit: 25,\n offset: 50,\n });\n\n expect(result).toEqual({ results: [{ id: 1 }] });\n expect(getMock).toHaveBeenCalledWith(\"/orders/search\", {\n params: {\n seller: \"seller-from-profile\",\n \"order.date_created.from\": \"2026-01-01T00:00:00.000-00:00\",\n \"order.date_created.to\": \"2026-01-31T23:59:59.999-00:00\",\n \"order.status\": \"paid\",\n q: undefined,\n sort: undefined,\n offset: 50,\n limit: 25,\n },\n });\n });\n\n it(\"preserves explicit seller, q and sort filters in order searches\", async () => {\n getMock.mockResolvedValueOnce({ data: { results: [{ id: 2 }] } });\n\n await searchMercadoLibreOrders(\"profile-1\", {\n seller: \"seller-override\",\n from: \"2026-02-01\",\n to: \"2026-02-02\",\n q: \"SKU-123\",\n sort: \"date_desc\",\n });\n\n expect(getMock).toHaveBeenCalledWith(\"/orders/search\", {\n params: {\n seller: \"seller-override\",\n \"order.date_created.from\": \"2026-02-01T00:00:00.000-00:00\",\n \"order.date_created.to\": \"2026-02-02T23:59:59.999-00:00\",\n \"order.status\": undefined,\n q: \"SKU-123\",\n sort: \"date_desc\",\n offset: 0,\n limit: 50,\n },\n });\n });\n\n it(\"builds batch order searches from offset ids\", async () => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: [],\n }));\n getMock.mockResolvedValueOnce({ data: { results: [], paging: { total: 0 } } });\n\n const result = await searchMercadoLibreOrdersBatch(\n \"profile-1\",\n {\n seller: \"\",\n from: \"2026-02-01\",\n to: \"2026-02-28\",\n },\n [100],\n { maxConcurrency: 2 }\n );\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([\"100\"], expect.any(Function), {\n maxConcurrency: 2,\n });\n expect(getMock).toHaveBeenCalledWith(\"/orders/search\", {\n params: {\n seller: \"seller-from-profile\",\n \"order.date_created.from\": \"2026-02-01T00:00:00.000-00:00\",\n \"order.date_created.to\": \"2026-02-28T23:59:59.999-00:00\",\n \"order.status\": undefined,\n q: undefined,\n sort: undefined,\n offset: 100,\n limit: 50,\n },\n });\n expect(result).toEqual({\n successful: [{ id: \"100\", document: { results: [], paging: { total: 0 } } }],\n failed: [],\n });\n });\n\n it(\"passes explicit seller and empty offsets through the shared batch order search runner\", async () => {\n vi.mocked(runMercadoLibreBatch).mockResolvedValue({ successful: [], failed: [] } as never);\n\n const result = await searchMercadoLibreOrdersBatch(\n \"profile-1\",\n {\n seller: \"seller-explicit\",\n from: \"2026-03-01\",\n to: \"2026-03-31\",\n status: \"confirmed\",\n },\n [],\n { maxRetries: 1 }\n );\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([], expect.any(Function), { maxRetries: 1 });\n expect(getMock).not.toHaveBeenCalled();\n expect(result).toEqual({ successful: [], failed: [] });\n });\n\n it(\"loads order details in batch through the shared batch runner\", async () => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher, options) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: options?.maxRetries ? [] : [],\n }));\n getMock.mockResolvedValueOnce({ data: { id: \"2001\", status: \"paid\" } });\n\n const result = await getMercadoLibreOrderDetailsBatch(\"profile-1\", [\"2001\"], {\n maxRetries: 1,\n });\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([\"2001\"], expect.any(Function), {\n maxRetries: 1,\n });\n expect(getMock).toHaveBeenCalledWith(\"/orders/2001\");\n expect(result).toEqual({\n successful: [{ id: \"2001\", document: { id: \"2001\", status: \"paid\" } }],\n failed: [],\n });\n });\n\n it.each([\n {\n label: \"single order\",\n call: () => getMercadoLibreOrder(\"profile-1\", \"2001\"),\n path: \"/orders/2001\",\n data: { id: \"2001\" },\n },\n {\n label: \"order shipments\",\n call: () => getMercadoLibreOrderShipments(\"profile-1\", \"2001\"),\n path: \"/orders/2001/shipments\",\n data: { shipments: [] },\n },\n {\n label: \"single shipment\",\n call: () => getMercadoLibreShipment(\"profile-1\", \"ship-1\"),\n path: \"/shipments/ship-1\",\n data: { id: \"ship-1\" },\n },\n {\n label: \"shipment items\",\n call: () => getMercadoLibreShipmentItems(\"profile-1\", \"ship-1\"),\n path: \"/shipments/ship-1/items\",\n data: { items: [] },\n },\n {\n label: \"shipment costs\",\n call: () => getMercadoLibreShipmentCosts(\"profile-1\", \"ship-1\"),\n path: \"/shipments/ship-1/costs\",\n data: { gross_amount: 99 },\n },\n ])(\"fetches $label from the expected MercadoLibre endpoint\", async ({ call, path, data }) => {\n getMock.mockResolvedValueOnce({ data });\n\n await expect(call()).resolves.toEqual(data);\n expect(getMock).toHaveBeenCalledWith(path);\n });\n\n it(\"passes the documented new shipment response header\", async () => {\n getMock.mockResolvedValueOnce({ data: { destination: { shipping_address: {} } } });\n\n await getMercadoLibreShipment(\"profile-1\", \"ship-1\", {\n signal: new AbortController().signal,\n headers: { \"x-format-new\": \"true\" },\n });\n\n expect(getMock).toHaveBeenCalledWith(\"/shipments/ship-1\", expect.objectContaining({\n headers: { \"x-format-new\": \"true\" },\n }));\n });\n\n it.each([\n {\n label: \"shipment details batch\",\n call: () => getMercadoLibreShipmentBatch(\"profile-1\", [\"ship-1\"], { maxConcurrency: 3 }),\n expectedIds: [\"ship-1\"],\n expectedOptions: { maxConcurrency: 3 },\n responsePath: \"/shipments/ship-1\",\n data: { id: \"ship-1\", status: \"ready_to_ship\" },\n },\n {\n label: \"shipment costs batch\",\n call: () => getMercadoLibreShipmentCostsBatch(\"profile-1\", [\"ship-2\"], { maxRetries: 2 }),\n expectedIds: [\"ship-2\"],\n expectedOptions: { maxRetries: 2 },\n responsePath: \"/shipments/ship-2/costs\",\n data: { id: \"ship-2\", gross_amount: 15 },\n },\n ])(\"delegates $label to the shared batch runner with the right fetcher\", async ({\n call,\n expectedIds,\n expectedOptions,\n responsePath,\n data,\n }) => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: [],\n }));\n getMock.mockResolvedValueOnce({ data });\n\n const result = await call();\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith(expectedIds, expect.any(Function), expectedOptions);\n expect(getMock).toHaveBeenCalledWith(responsePath);\n expect(result).toEqual({\n successful: [{ id: expectedIds[0], document: data }],\n failed: [],\n });\n });\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,36 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { getMercadoLibreApiContext, runMercadoLibreBatch } from "../mercadolibre-api.js";
3
+ import { getMercadoLibrePack, getMercadoLibrePackBatch } from "../mercadolibre-packs.js";
4
+ vi.mock("../mercadolibre-api.js", () => ({
5
+ getMercadoLibreApiContext: vi.fn(),
6
+ runMercadoLibreBatch: vi.fn()
7
+ }));
8
+ describe("mercadolibre-packs service", () => {
9
+ const getMock = vi.fn();
10
+ beforeEach(() => {
11
+ vi.clearAllMocks();
12
+ vi.mocked(getMercadoLibreApiContext).mockResolvedValue({
13
+ api: { get: getMock },
14
+ sellerId: "seller-from-profile",
15
+ accessToken: "token"
16
+ });
17
+ });
18
+ it("fetches pack context from the official packs endpoint", async () => {
19
+ getMock.mockResolvedValueOnce({ data: { id: "PACK-1", orders: [{ id: "ORD-1" }] } });
20
+ const result = await getMercadoLibrePack("profile-1", "PACK-1");
21
+ expect(getMock).toHaveBeenCalledWith("/packs/PACK-1");
22
+ expect(result).toEqual({ id: "PACK-1", orders: [{ id: "ORD-1" }] });
23
+ });
24
+ it("delegates pack batch fetching through the shared batch runner", async () => {
25
+ vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher) => ({
26
+ successful: [{ id: ids[0], document: await fetcher(ids[0]) }],
27
+ failed: []
28
+ }));
29
+ getMock.mockResolvedValueOnce({ data: { id: "PACK-2" } });
30
+ const result = await getMercadoLibrePackBatch("profile-1", ["PACK-2"], { maxRetries: 1 });
31
+ expect(runMercadoLibreBatch).toHaveBeenCalledWith(["PACK-2"], expect.any(Function), { maxRetries: 1 });
32
+ expect(getMock).toHaveBeenCalledWith("/packs/PACK-2");
33
+ expect(result).toEqual({ successful: [{ id: "PACK-2", document: { id: "PACK-2" } }], failed: [] });
34
+ });
35
+ });
36
+ //# sourceMappingURL=mercadolibre-packs.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-packs.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { getMercadoLibreApiContext, runMercadoLibreBatch } from \"../mercadolibre-api.js\";\nimport { getMercadoLibrePack, getMercadoLibrePackBatch } from \"../mercadolibre-packs.js\";\n\nvi.mock(\"../mercadolibre-api.js\", () => ({\n getMercadoLibreApiContext: vi.fn(),\n runMercadoLibreBatch: vi.fn(),\n}));\n\ndescribe(\"mercadolibre-packs service\", () => {\n const getMock = vi.fn();\n\n beforeEach(() => {\n vi.clearAllMocks();\n vi.mocked(getMercadoLibreApiContext).mockResolvedValue({\n api: { get: getMock },\n sellerId: \"seller-from-profile\",\n accessToken: \"token\",\n } as never);\n });\n\n it(\"fetches pack context from the official packs endpoint\", async () => {\n getMock.mockResolvedValueOnce({ data: { id: \"PACK-1\", orders: [{ id: \"ORD-1\" }] } });\n\n const result = await getMercadoLibrePack(\"profile-1\", \"PACK-1\");\n\n expect(getMock).toHaveBeenCalledWith(\"/packs/PACK-1\");\n expect(result).toEqual({ id: \"PACK-1\", orders: [{ id: \"ORD-1\" }] });\n });\n\n it(\"delegates pack batch fetching through the shared batch runner\", async () => {\n vi.mocked(runMercadoLibreBatch).mockImplementation(async (ids, fetcher) => ({\n successful: [{ id: ids[0], document: await fetcher(ids[0]) }],\n failed: [],\n }));\n getMock.mockResolvedValueOnce({ data: { id: \"PACK-2\" } });\n\n const result = await getMercadoLibrePackBatch(\"profile-1\", [\"PACK-2\"], { maxRetries: 1 });\n\n expect(runMercadoLibreBatch).toHaveBeenCalledWith([\"PACK-2\"], expect.any(Function), { maxRetries: 1 });\n expect(getMock).toHaveBeenCalledWith(\"/packs/PACK-2\");\n expect(result).toEqual({ successful: [{ id: \"PACK-2\", document: { id: \"PACK-2\" } }], failed: [] });\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,YAAY,UAAU,QAAQ,IAAI,UAAU;AAErD,SAAS,2BAA2B,4BAA4B;AAChE,SAAS,qBAAqB,gCAAgC;AAE9D,GAAG,KAAK,0BAA0B,OAAO;AAAA,EACvC,2BAA2B,GAAG,GAAG;AAAA,EACjC,sBAAsB,GAAG,GAAG;AAC9B,EAAE;AAEF,SAAS,8BAA8B,MAAM;AAC3C,QAAM,UAAU,GAAG,GAAG;AAEtB,aAAW,MAAM;AACf,OAAG,cAAc;AACjB,OAAG,OAAO,yBAAyB,EAAE,kBAAkB;AAAA,MACrD,KAAK,EAAE,KAAK,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,aAAa;AAAA,IACf,CAAU;AAAA,EACZ,CAAC;AAED,KAAG,yDAAyD,YAAY;AACtE,YAAQ,sBAAsB,EAAE,MAAM,EAAE,IAAI,UAAU,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;AAEnF,UAAM,SAAS,MAAM,oBAAoB,aAAa,QAAQ;AAE9D,WAAO,OAAO,EAAE,qBAAqB,eAAe;AACpD,WAAO,MAAM,EAAE,QAAQ,EAAE,IAAI,UAAU,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,CAAC;AAAA,EACpE,CAAC;AAED,KAAG,iEAAiE,YAAY;AAC9E,OAAG,OAAO,oBAAoB,EAAE,mBAAmB,OAAO,KAAK,aAAa;AAAA,MAC1E,YAAY,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,UAAU,MAAM,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC;AAAA,MAC5D,QAAQ,CAAC;AAAA,IACX,EAAE;AACF,YAAQ,sBAAsB,EAAE,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;AAExD,UAAM,SAAS,MAAM,yBAAyB,aAAa,CAAC,QAAQ,GAAG,EAAE,YAAY,EAAE,CAAC;AAExF,WAAO,oBAAoB,EAAE,qBAAqB,CAAC,QAAQ,GAAG,OAAO,IAAI,QAAQ,GAAG,EAAE,YAAY,EAAE,CAAC;AACrG,WAAO,OAAO,EAAE,qBAAqB,eAAe;AACpD,WAAO,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,IAAI,UAAU,UAAU,EAAE,IAAI,SAAS,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;AAAA,EACnG,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,137 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { createMercadoLibreClient } from "../../../services/mercadolibre/mercadolibre-api.js";
3
+ import { getMercadoLibreAccessForProfile } from "../../../config/mercadolibre.js";
4
+ import { getMercadoLibrePaymentDetails, getMercadoLibrePaymentDetailsBatch } from "../mercadolibre-payments.js";
5
+ vi.mock("../../../services/mercadolibre/mercadolibre-api.js", async (importOriginal) => {
6
+ const actual = await importOriginal();
7
+ return {
8
+ ...actual,
9
+ createMercadoLibreClient: vi.fn()
10
+ };
11
+ });
12
+ vi.mock("../../../config/mercadolibre.js", () => ({
13
+ getMercadoLibreAccessForProfile: vi.fn()
14
+ }));
15
+ describe("mercadolibre payments service", () => {
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+ it("fetches payment details from the official payments endpoint", async () => {
20
+ const getMock = vi.fn().mockResolvedValue({
21
+ data: {
22
+ id: 28382111111,
23
+ status: "approved",
24
+ transaction_amount: 100
25
+ }
26
+ });
27
+ vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({
28
+ accessToken: "stored-token"
29
+ });
30
+ vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock });
31
+ await expect(getMercadoLibrePaymentDetails("profile-1", "28382111111")).resolves.toEqual({
32
+ id: 28382111111,
33
+ status: "approved",
34
+ transaction_amount: 100
35
+ });
36
+ expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith("profile-1");
37
+ expect(createMercadoLibreClient).toHaveBeenCalledWith("stored-token", "https://api.mercadopago.com");
38
+ expect(getMock).toHaveBeenCalledWith("/v1/payments/28382111111");
39
+ });
40
+ it("fetches payment details in parallel for batch requests and keeps failures isolated", async () => {
41
+ const deferredByPaymentId = /* @__PURE__ */ new Map();
42
+ const getMock = vi.fn().mockImplementation((path) => {
43
+ const paymentId = path.split("/").pop() ?? "";
44
+ if (paymentId === "28382111113") {
45
+ return Promise.reject(new Error("Request failed with status code 404"));
46
+ }
47
+ let resolvePromise;
48
+ const promise = new Promise((resolveFn) => {
49
+ resolvePromise = resolveFn;
50
+ });
51
+ deferredByPaymentId.set(paymentId, { resolve: resolvePromise });
52
+ return promise;
53
+ });
54
+ vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({
55
+ accessToken: "stored-token"
56
+ });
57
+ vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock });
58
+ const batchPromise = getMercadoLibrePaymentDetailsBatch("profile-1", [
59
+ "28382111111",
60
+ "28382111112",
61
+ "28382111113"
62
+ ]);
63
+ await Promise.resolve();
64
+ expect(getMock).toHaveBeenCalledTimes(3);
65
+ deferredByPaymentId.get("28382111111")?.resolve({
66
+ data: { id: "28382111111", status: "approved" }
67
+ });
68
+ deferredByPaymentId.get("28382111112")?.resolve({
69
+ data: { id: "28382111112", status: "pending" }
70
+ });
71
+ await expect(batchPromise).resolves.toEqual({
72
+ successful: [
73
+ { paymentId: "28382111111", payment: { id: "28382111111", status: "approved" } },
74
+ { paymentId: "28382111112", payment: { id: "28382111112", status: "pending" } }
75
+ ],
76
+ failed: [
77
+ {
78
+ paymentId: "28382111113",
79
+ message: "Request failed with status code 404",
80
+ statusCode: void 0,
81
+ attempts: 1,
82
+ retryable: false
83
+ }
84
+ ]
85
+ });
86
+ expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith("profile-1");
87
+ expect(createMercadoLibreClient).toHaveBeenCalledWith("stored-token", "https://api.mercadopago.com");
88
+ expect(getMock).toHaveBeenNthCalledWith(1, "/v1/payments/28382111111");
89
+ expect(getMock).toHaveBeenNthCalledWith(2, "/v1/payments/28382111112");
90
+ expect(getMock).toHaveBeenNthCalledWith(3, "/v1/payments/28382111113");
91
+ });
92
+ it("continues processing later chunks when earlier chunks contain failures", async () => {
93
+ const getMock = vi.fn().mockImplementation(async (path) => {
94
+ const paymentId = path.split("/").pop() ?? "";
95
+ if (paymentId === "pay-17" || paymentId === "pay-63") {
96
+ throw new Error(`Request failed with status code 404 for ${paymentId}`);
97
+ }
98
+ return { data: { id: paymentId } };
99
+ });
100
+ vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({
101
+ accessToken: "stored-token"
102
+ });
103
+ vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock });
104
+ const paymentIds = Array.from({ length: 101 }, (_, index) => `pay-${index + 1}`);
105
+ const batchPromise = getMercadoLibrePaymentDetailsBatch("profile-1", paymentIds);
106
+ await expect(batchPromise).resolves.toEqual({
107
+ successful: expect.arrayContaining([
108
+ { paymentId: "pay-1", payment: { id: "pay-1" } },
109
+ { paymentId: "pay-101", payment: { id: "pay-101" } }
110
+ ]),
111
+ failed: [
112
+ {
113
+ paymentId: "pay-17",
114
+ message: "Request failed with status code 404 for pay-17",
115
+ statusCode: void 0,
116
+ attempts: 1,
117
+ retryable: false
118
+ },
119
+ {
120
+ paymentId: "pay-63",
121
+ message: "Request failed with status code 404 for pay-63",
122
+ statusCode: void 0,
123
+ attempts: 1,
124
+ retryable: false
125
+ }
126
+ ]
127
+ });
128
+ expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith("profile-1");
129
+ expect(createMercadoLibreClient).toHaveBeenCalledWith("stored-token", "https://api.mercadopago.com");
130
+ expect(getMock).toHaveBeenCalledTimes(101);
131
+ expect(getMock).toHaveBeenNthCalledWith(1, "/v1/payments/pay-1");
132
+ expect(getMock).toHaveBeenNthCalledWith(50, "/v1/payments/pay-50");
133
+ expect(getMock).toHaveBeenNthCalledWith(51, "/v1/payments/pay-51");
134
+ expect(getMock).toHaveBeenNthCalledWith(101, "/v1/payments/pay-101");
135
+ });
136
+ });
137
+ //# sourceMappingURL=mercadolibre-payments.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-payments.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { createMercadoLibreClient } from \"../../../services/mercadolibre/mercadolibre-api.js\";\nimport { getMercadoLibreAccessForProfile } from \"../../../config/mercadolibre.js\";\nimport { getMercadoLibrePaymentDetails, getMercadoLibrePaymentDetailsBatch } from \"../mercadolibre-payments.js\";\n\nvi.mock(\"../../../services/mercadolibre/mercadolibre-api.js\", async (importOriginal) => {\n const actual = await importOriginal<typeof import(\"../../../services/mercadolibre/mercadolibre-api.js\")>();\n\n return {\n ...actual,\n createMercadoLibreClient: vi.fn(),\n };\n});\n\nvi.mock(\"../../../config/mercadolibre.js\", () => ({\n getMercadoLibreAccessForProfile: vi.fn(),\n}));\n\ndescribe(\"mercadolibre payments service\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it(\"fetches payment details from the official payments endpoint\", async () => {\n const getMock = vi.fn().mockResolvedValue({\n data: {\n id: 28382111111,\n status: \"approved\",\n transaction_amount: 100,\n },\n });\n\n vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({\n accessToken: \"stored-token\",\n } as never);\n vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock } as never);\n\n await expect(getMercadoLibrePaymentDetails(\"profile-1\", \"28382111111\")).resolves.toEqual({\n id: 28382111111,\n status: \"approved\",\n transaction_amount: 100,\n });\n\n expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith(\"profile-1\");\n expect(createMercadoLibreClient).toHaveBeenCalledWith(\"stored-token\", \"https://api.mercadopago.com\");\n expect(getMock).toHaveBeenCalledWith(\"/v1/payments/28382111111\");\n });\n\n it(\"fetches payment details in parallel for batch requests and keeps failures isolated\", async () => {\n const deferredByPaymentId = new Map<string, { resolve: (value: { data: Record<string, unknown> }) => void }>();\n const getMock = vi.fn().mockImplementation((path: string) => {\n const paymentId = path.split(\"/\").pop() ?? \"\";\n if (paymentId === \"28382111113\") {\n return Promise.reject(new Error(\"Request failed with status code 404\"));\n }\n\n let resolvePromise!: (value: { data: Record<string, unknown> }) => void;\n\n const promise = new Promise<{ data: Record<string, unknown> }>((resolveFn) => {\n resolvePromise = resolveFn;\n });\n\n deferredByPaymentId.set(paymentId, { resolve: resolvePromise });\n return promise;\n });\n\n vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({\n accessToken: \"stored-token\",\n } as never);\n vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock } as never);\n\n const batchPromise = getMercadoLibrePaymentDetailsBatch(\"profile-1\", [\n \"28382111111\",\n \"28382111112\",\n \"28382111113\",\n ]);\n\n await Promise.resolve();\n expect(getMock).toHaveBeenCalledTimes(3);\n\n deferredByPaymentId.get(\"28382111111\")?.resolve({\n data: { id: \"28382111111\", status: \"approved\" },\n });\n deferredByPaymentId.get(\"28382111112\")?.resolve({\n data: { id: \"28382111112\", status: \"pending\" },\n });\n\n await expect(batchPromise).resolves.toEqual({\n successful: [\n { paymentId: \"28382111111\", payment: { id: \"28382111111\", status: \"approved\" } },\n { paymentId: \"28382111112\", payment: { id: \"28382111112\", status: \"pending\" } },\n ],\n failed: [\n {\n paymentId: \"28382111113\",\n message: \"Request failed with status code 404\",\n statusCode: undefined,\n attempts: 1,\n retryable: false,\n },\n ],\n });\n\n expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith(\"profile-1\");\n expect(createMercadoLibreClient).toHaveBeenCalledWith(\"stored-token\", \"https://api.mercadopago.com\");\n expect(getMock).toHaveBeenNthCalledWith(1, \"/v1/payments/28382111111\");\n expect(getMock).toHaveBeenNthCalledWith(2, \"/v1/payments/28382111112\");\n expect(getMock).toHaveBeenNthCalledWith(3, \"/v1/payments/28382111113\");\n });\n\n it(\"continues processing later chunks when earlier chunks contain failures\", async () => {\n const getMock = vi.fn().mockImplementation(async (path: string) => {\n const paymentId = path.split(\"/\").pop() ?? \"\";\n\n if (paymentId === \"pay-17\" || paymentId === \"pay-63\") {\n throw new Error(`Request failed with status code 404 for ${paymentId}`);\n }\n\n return { data: { id: paymentId } };\n });\n\n vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({\n accessToken: \"stored-token\",\n } as never);\n vi.mocked(createMercadoLibreClient).mockReturnValue({ get: getMock } as never);\n\n const paymentIds = Array.from({ length: 101 }, (_, index) => `pay-${index + 1}`);\n const batchPromise = getMercadoLibrePaymentDetailsBatch(\"profile-1\", paymentIds);\n\n await expect(batchPromise).resolves.toEqual({\n successful: expect.arrayContaining([\n { paymentId: \"pay-1\", payment: { id: \"pay-1\" } },\n { paymentId: \"pay-101\", payment: { id: \"pay-101\" } },\n ]),\n failed: [\n {\n paymentId: \"pay-17\",\n message: \"Request failed with status code 404 for pay-17\",\n statusCode: undefined,\n attempts: 1,\n retryable: false,\n },\n {\n paymentId: \"pay-63\",\n message: \"Request failed with status code 404 for pay-63\",\n statusCode: undefined,\n attempts: 1,\n retryable: false,\n },\n ],\n });\n\n expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith(\"profile-1\");\n expect(createMercadoLibreClient).toHaveBeenCalledWith(\"stored-token\", \"https://api.mercadopago.com\");\n expect(getMock).toHaveBeenCalledTimes(101);\n expect(getMock).toHaveBeenNthCalledWith(1, \"/v1/payments/pay-1\");\n expect(getMock).toHaveBeenNthCalledWith(50, \"/v1/payments/pay-50\");\n expect(getMock).toHaveBeenNthCalledWith(51, \"/v1/payments/pay-51\");\n expect(getMock).toHaveBeenNthCalledWith(101, \"/v1/payments/pay-101\");\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,105 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { searchMercadoLibreProductAdsAdGroupAds } from "../mercadolibre-product-ads.js";
3
+ import { getMercadoLibreApiContext, MercadoLibreApiError } from "../mercadolibre-api.js";
4
+ vi.mock("../mercadolibre-api.js", async () => {
5
+ const actual = await vi.importActual("../mercadolibre-api.js");
6
+ return {
7
+ ...actual,
8
+ getMercadoLibreApiContext: vi.fn()
9
+ };
10
+ });
11
+ describe("mercadolibre product ads ad group ads service", () => {
12
+ const getMock = vi.fn();
13
+ beforeEach(() => {
14
+ vi.clearAllMocks();
15
+ vi.mocked(getMercadoLibreApiContext).mockResolvedValue({
16
+ api: { get: getMock },
17
+ sellerId: "seller-1",
18
+ accessToken: "token-1"
19
+ });
20
+ });
21
+ afterEach(() => {
22
+ vi.useRealTimers();
23
+ vi.restoreAllMocks();
24
+ });
25
+ it("retries 429 responses and succeeds on the next attempt", async () => {
26
+ vi.useFakeTimers();
27
+ getMock.mockRejectedValueOnce(new MercadoLibreApiError("rate limited", 429)).mockResolvedValueOnce({
28
+ data: {
29
+ paging: { total: 1, limit: 50, offset: 0 },
30
+ results: [{ item_id: "item-1" }]
31
+ }
32
+ });
33
+ const promise = searchMercadoLibreProductAdsAdGroupAds("profile-1", {
34
+ siteId: "MLA",
35
+ adGroupId: "ad-group-1",
36
+ dateFrom: "2026-06-01",
37
+ dateTo: "2026-06-30",
38
+ metrics: ["direct_amount"]
39
+ });
40
+ await vi.advanceTimersByTimeAsync(250);
41
+ await expect(promise).resolves.toEqual({
42
+ paging: { total: 1, limit: 50, offset: 0 },
43
+ results: [{ item_id: "item-1" }]
44
+ });
45
+ expect(getMock).toHaveBeenCalledTimes(2);
46
+ });
47
+ it("retries retryable 5xx responses and succeeds on the next attempt", async () => {
48
+ vi.useFakeTimers();
49
+ getMock.mockRejectedValueOnce(new MercadoLibreApiError("upstream unavailable", 503)).mockResolvedValueOnce({
50
+ data: {
51
+ paging: { total: 1, limit: 50, offset: 0 },
52
+ results: [{ item_id: "item-2" }]
53
+ }
54
+ });
55
+ const promise = searchMercadoLibreProductAdsAdGroupAds("profile-1", {
56
+ siteId: "MLA",
57
+ adGroupId: "ad-group-1",
58
+ dateFrom: "2026-06-01",
59
+ dateTo: "2026-06-30",
60
+ metrics: ["direct_amount"]
61
+ });
62
+ await vi.advanceTimersByTimeAsync(250);
63
+ await expect(promise).resolves.toEqual({
64
+ paging: { total: 1, limit: 50, offset: 0 },
65
+ results: [{ item_id: "item-2" }]
66
+ });
67
+ expect(getMock).toHaveBeenCalledTimes(2);
68
+ });
69
+ it("stops after the third attempt when retryable failures keep happening", async () => {
70
+ vi.useFakeTimers();
71
+ getMock.mockRejectedValueOnce(new MercadoLibreApiError("still broken", 503)).mockRejectedValueOnce(new MercadoLibreApiError("still broken", 503)).mockRejectedValueOnce(new MercadoLibreApiError("still broken", 503));
72
+ const promise = searchMercadoLibreProductAdsAdGroupAds("profile-1", {
73
+ siteId: "MLA",
74
+ adGroupId: "ad-group-1",
75
+ dateFrom: "2026-06-01",
76
+ dateTo: "2026-06-30",
77
+ metrics: ["direct_amount"]
78
+ });
79
+ const rejection = promise.catch((error) => error);
80
+ await vi.advanceTimersByTimeAsync(750);
81
+ await expect(rejection).resolves.toMatchObject({
82
+ name: "MercadoLibreApiError",
83
+ status: 503,
84
+ message: "still broken"
85
+ });
86
+ expect(getMock).toHaveBeenCalledTimes(3);
87
+ });
88
+ it("wraps unexpected upstream failures in a MercadoLibreApiError contract", async () => {
89
+ getMock.mockRejectedValueOnce(new Error("boom"));
90
+ await expect(
91
+ searchMercadoLibreProductAdsAdGroupAds("profile-1", {
92
+ siteId: "MLA",
93
+ adGroupId: "ad-group-1",
94
+ dateFrom: "2026-06-01",
95
+ dateTo: "2026-06-30",
96
+ metrics: ["direct_amount"]
97
+ })
98
+ ).rejects.toMatchObject({
99
+ name: "MercadoLibreApiError",
100
+ message: "boom"
101
+ });
102
+ expect(getMock).toHaveBeenCalledTimes(1);
103
+ });
104
+ });
105
+ //# sourceMappingURL=mercadolibre-product-ads-ad-group-ads.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-group-ads.test.ts"],
4
+ "sourcesContent": ["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { searchMercadoLibreProductAdsAdGroupAds } from \"../mercadolibre-product-ads.js\";\nimport { getMercadoLibreApiContext, MercadoLibreApiError } from \"../mercadolibre-api.js\";\n\nvi.mock(\"../mercadolibre-api.js\", async () => {\n const actual = await vi.importActual<typeof import(\"../mercadolibre-api.js\")>(\"../mercadolibre-api.js\");\n\n return {\n ...actual,\n getMercadoLibreApiContext: vi.fn(),\n };\n});\n\ndescribe(\"mercadolibre product ads ad group ads service\", () => {\n const getMock = vi.fn();\n\n beforeEach(() => {\n vi.clearAllMocks();\n vi.mocked(getMercadoLibreApiContext).mockResolvedValue({\n api: { get: getMock },\n sellerId: \"seller-1\",\n accessToken: \"token-1\",\n } as never);\n });\n\n afterEach(() => {\n vi.useRealTimers();\n vi.restoreAllMocks();\n });\n\n it(\"retries 429 responses and succeeds on the next attempt\", async () => {\n vi.useFakeTimers();\n\n getMock\n .mockRejectedValueOnce(new MercadoLibreApiError(\"rate limited\", 429))\n .mockResolvedValueOnce({\n data: {\n paging: { total: 1, limit: 50, offset: 0 },\n results: [{ item_id: \"item-1\" }],\n },\n });\n\n const promise = searchMercadoLibreProductAdsAdGroupAds(\"profile-1\", {\n siteId: \"MLA\",\n adGroupId: \"ad-group-1\",\n dateFrom: \"2026-06-01\",\n dateTo: \"2026-06-30\",\n metrics: [\"direct_amount\"],\n });\n\n await vi.advanceTimersByTimeAsync(250);\n\n await expect(promise).resolves.toEqual({\n paging: { total: 1, limit: 50, offset: 0 },\n results: [{ item_id: \"item-1\" }],\n });\n expect(getMock).toHaveBeenCalledTimes(2);\n });\n\n it(\"retries retryable 5xx responses and succeeds on the next attempt\", async () => {\n vi.useFakeTimers();\n\n getMock\n .mockRejectedValueOnce(new MercadoLibreApiError(\"upstream unavailable\", 503))\n .mockResolvedValueOnce({\n data: {\n paging: { total: 1, limit: 50, offset: 0 },\n results: [{ item_id: \"item-2\" }],\n },\n });\n\n const promise = searchMercadoLibreProductAdsAdGroupAds(\"profile-1\", {\n siteId: \"MLA\",\n adGroupId: \"ad-group-1\",\n dateFrom: \"2026-06-01\",\n dateTo: \"2026-06-30\",\n metrics: [\"direct_amount\"],\n });\n\n await vi.advanceTimersByTimeAsync(250);\n\n await expect(promise).resolves.toEqual({\n paging: { total: 1, limit: 50, offset: 0 },\n results: [{ item_id: \"item-2\" }],\n });\n expect(getMock).toHaveBeenCalledTimes(2);\n });\n\n it(\"stops after the third attempt when retryable failures keep happening\", async () => {\n vi.useFakeTimers();\n\n getMock\n .mockRejectedValueOnce(new MercadoLibreApiError(\"still broken\", 503))\n .mockRejectedValueOnce(new MercadoLibreApiError(\"still broken\", 503))\n .mockRejectedValueOnce(new MercadoLibreApiError(\"still broken\", 503));\n\n const promise = searchMercadoLibreProductAdsAdGroupAds(\"profile-1\", {\n siteId: \"MLA\",\n adGroupId: \"ad-group-1\",\n dateFrom: \"2026-06-01\",\n dateTo: \"2026-06-30\",\n metrics: [\"direct_amount\"],\n });\n const rejection = promise.catch((error) => error);\n\n await vi.advanceTimersByTimeAsync(750);\n\n await expect(rejection).resolves.toMatchObject({\n name: \"MercadoLibreApiError\",\n status: 503,\n message: \"still broken\",\n });\n expect(getMock).toHaveBeenCalledTimes(3);\n });\n\n it(\"wraps unexpected upstream failures in a MercadoLibreApiError contract\", async () => {\n getMock.mockRejectedValueOnce(new Error(\"boom\"));\n\n await expect(\n searchMercadoLibreProductAdsAdGroupAds(\"profile-1\", {\n siteId: \"MLA\",\n adGroupId: \"ad-group-1\",\n dateFrom: \"2026-06-01\",\n dateTo: \"2026-06-30\",\n metrics: [\"direct_amount\"],\n })\n ).rejects.toMatchObject({\n name: \"MercadoLibreApiError\",\n message: \"boom\",\n });\n\n expect(getMock).toHaveBeenCalledTimes(1);\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }