@yoryoboy/bi-mcp 1.10.0 → 1.13.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 (239) hide show
  1. package/README.md +4 -5
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/index.js +398 -8
  4. package/dist/index.js.map +2 -2
  5. package/dist/mcp-use.json +2 -2
  6. package/dist/src/config/__tests__/meta.test.js +35 -0
  7. package/dist/src/config/__tests__/meta.test.js.map +7 -0
  8. package/dist/src/config/mercadolibre-profile-store.js +25 -0
  9. package/dist/src/config/mercadolibre-profile-store.js.map +2 -2
  10. package/dist/src/config/meta-store.js +109 -0
  11. package/dist/src/config/meta-store.js.map +7 -0
  12. package/dist/src/config/meta.js +0 -2
  13. package/dist/src/config/meta.js.map +2 -2
  14. package/dist/src/meta/__tests__/meta-utils.test.js +155 -0
  15. package/dist/src/meta/__tests__/meta-utils.test.js.map +7 -0
  16. package/dist/src/services/mercadolibre/__tests__/mercadolibre-api.test.js +265 -0
  17. package/dist/src/services/mercadolibre/__tests__/mercadolibre-api.test.js.map +7 -0
  18. package/dist/src/services/mercadolibre/__tests__/mercadolibre-items.test.js +311 -0
  19. package/dist/src/services/mercadolibre/__tests__/mercadolibre-items.test.js.map +7 -0
  20. package/dist/src/services/mercadolibre/__tests__/mercadolibre-orders.test.js +220 -0
  21. package/dist/src/services/mercadolibre/__tests__/mercadolibre-orders.test.js.map +7 -0
  22. package/dist/src/services/meta/__tests__/meta-ads.test.js +126 -0
  23. package/dist/src/services/meta/__tests__/meta-ads.test.js.map +7 -0
  24. package/dist/src/services/meta/__tests__/meta-api.test.js +70 -0
  25. package/dist/src/services/meta/__tests__/meta-api.test.js.map +7 -0
  26. package/dist/src/services/meta/meta-ads.js +94 -40
  27. package/dist/src/services/meta/meta-ads.js.map +2 -2
  28. package/dist/src/services/meta/meta-api.js +8 -6
  29. package/dist/src/services/meta/meta-api.js.map +2 -2
  30. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +165 -0
  31. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +7 -0
  32. package/dist/src/services/vtex/__tests__/vtex-catalog-write-eans.test.js +92 -0
  33. package/dist/src/services/vtex/__tests__/vtex-catalog-write-eans.test.js.map +7 -0
  34. package/dist/src/services/vtex/__tests__/vtex-catalog-write-products.test.js +41 -0
  35. package/dist/src/services/vtex/__tests__/vtex-catalog-write-products.test.js.map +7 -0
  36. package/dist/src/services/vtex/__tests__/vtex-catalog.test.js +80 -0
  37. package/dist/src/services/vtex/__tests__/vtex-catalog.test.js.map +7 -0
  38. package/dist/src/services/vtex/__tests__/vtex-orders-write-http.test.js +85 -0
  39. package/dist/src/services/vtex/__tests__/vtex-orders-write-http.test.js.map +7 -0
  40. package/dist/src/services/vtex/__tests__/vtex-orders-write-state-validation.test.js +251 -0
  41. package/dist/src/services/vtex/__tests__/vtex-orders-write-state-validation.test.js.map +7 -0
  42. package/dist/src/services/vtex/__tests__/vtex-write.test.js +111 -0
  43. package/dist/src/services/vtex/__tests__/vtex-write.test.js.map +7 -0
  44. package/dist/src/services/vtex/vtex-catalog-write.js +194 -1
  45. package/dist/src/services/vtex/vtex-catalog-write.js.map +2 -2
  46. package/dist/src/services/vtex/vtex-catalog.js +118 -1
  47. package/dist/src/services/vtex/vtex-catalog.js.map +2 -2
  48. package/dist/src/services/vtex/vtex-pricing-write.js +5 -0
  49. package/dist/src/services/vtex/vtex-pricing-write.js.map +2 -2
  50. package/dist/src/services/vtex/vtex-write.js +67 -1
  51. package/dist/src/services/vtex/vtex-write.js.map +2 -2
  52. package/dist/src/tools/config/list-profiles.js +85 -11
  53. package/dist/src/tools/config/list-profiles.js.map +2 -2
  54. package/dist/src/tools/index.js.map +2 -2
  55. package/dist/src/tools/mercadolibre/__tests__/helpers.test.js +37 -0
  56. package/dist/src/tools/mercadolibre/__tests__/helpers.test.js.map +7 -0
  57. package/dist/src/tools/mercadolibre/__tests__/profile-resolution.test.js +30 -0
  58. package/dist/src/tools/mercadolibre/__tests__/profile-resolution.test.js.map +7 -0
  59. package/dist/src/tools/mercadolibre/profile-resolution.js +4 -50
  60. package/dist/src/tools/mercadolibre/profile-resolution.js.map +2 -2
  61. package/dist/src/tools/meta/__tests__/pagination.test.js +133 -0
  62. package/dist/src/tools/meta/__tests__/pagination.test.js.map +7 -0
  63. package/dist/src/tools/meta/__tests__/profile-access.test.js +262 -0
  64. package/dist/src/tools/meta/__tests__/profile-access.test.js.map +7 -0
  65. package/dist/src/tools/meta/__tests__/read-tools.test.js +722 -0
  66. package/dist/src/tools/meta/__tests__/read-tools.test.js.map +7 -0
  67. package/dist/src/tools/meta/__tests__/schemas.test.js +103 -0
  68. package/dist/src/tools/meta/__tests__/schemas.test.js.map +7 -0
  69. package/dist/src/tools/meta/account-overview.js +37 -19
  70. package/dist/src/tools/meta/account-overview.js.map +2 -2
  71. package/dist/src/tools/meta/ad-account-info.js +31 -6
  72. package/dist/src/tools/meta/ad-account-info.js.map +2 -2
  73. package/dist/src/tools/meta/ads-performance.js +35 -21
  74. package/dist/src/tools/meta/ads-performance.js.map +2 -2
  75. package/dist/src/tools/meta/campaign-performance.js +35 -18
  76. package/dist/src/tools/meta/campaign-performance.js.map +2 -2
  77. package/dist/src/tools/meta/list-accessible-ad-accounts.js +39 -10
  78. package/dist/src/tools/meta/list-accessible-ad-accounts.js.map +2 -2
  79. package/dist/src/tools/meta/list-accessible-businesses.js +37 -13
  80. package/dist/src/tools/meta/list-accessible-businesses.js.map +2 -2
  81. package/dist/src/tools/meta/placement-mix.js +37 -22
  82. package/dist/src/tools/meta/placement-mix.js.map +2 -2
  83. package/dist/src/tools/meta/profile-access.js +215 -0
  84. package/dist/src/tools/meta/profile-access.js.map +7 -0
  85. package/dist/src/tools/meta/schema-helpers.js +19 -0
  86. package/dist/src/tools/meta/schema-helpers.js.map +7 -0
  87. package/dist/src/tools/meta/time-series.js +40 -23
  88. package/dist/src/tools/meta/time-series.js.map +2 -2
  89. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +233 -0
  90. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +7 -0
  91. package/dist/src/tools/vtex/__tests__/catalog-admin-categories.test.js +649 -0
  92. package/dist/src/tools/vtex/__tests__/catalog-admin-categories.test.js.map +7 -0
  93. package/dist/src/tools/vtex/__tests__/catalog-admin-product-specifications.test.js +339 -0
  94. package/dist/src/tools/vtex/__tests__/catalog-admin-product-specifications.test.js.map +7 -0
  95. package/dist/src/tools/vtex/__tests__/catalog-admin-products-skus.test.js +235 -0
  96. package/dist/src/tools/vtex/__tests__/catalog-admin-products-skus.test.js.map +7 -0
  97. package/dist/src/tools/vtex/__tests__/catalog-navigation-reads.test.js +372 -0
  98. package/dist/src/tools/vtex/__tests__/catalog-navigation-reads.test.js.map +7 -0
  99. package/dist/src/tools/vtex/__tests__/catalog-navigation-surface.test.js +57 -0
  100. package/dist/src/tools/vtex/__tests__/catalog-navigation-surface.test.js.map +7 -0
  101. package/dist/src/tools/vtex/__tests__/write-helpers.test.js +97 -0
  102. package/dist/src/tools/vtex/__tests__/write-helpers.test.js.map +7 -0
  103. package/dist/src/tools/vtex/activate-sku.js +1 -48
  104. package/dist/src/tools/vtex/activate-sku.js.map +2 -2
  105. package/dist/src/tools/vtex/associate-specification.js +3 -54
  106. package/dist/src/tools/vtex/associate-specification.js.map +2 -2
  107. package/dist/src/tools/vtex/attach-catalog-image.js +3 -57
  108. package/dist/src/tools/vtex/attach-catalog-image.js.map +2 -2
  109. package/dist/src/tools/vtex/catalog-admin-batch.js +298 -0
  110. package/dist/src/tools/vtex/catalog-admin-batch.js.map +7 -0
  111. package/dist/src/tools/vtex/catalog-admin-categories.js +542 -0
  112. package/dist/src/tools/vtex/catalog-admin-categories.js.map +7 -0
  113. package/dist/src/tools/vtex/catalog-admin-product-specifications.js +275 -0
  114. package/dist/src/tools/vtex/catalog-admin-product-specifications.js.map +7 -0
  115. package/dist/src/tools/vtex/catalog-admin-products-skus.js +475 -0
  116. package/dist/src/tools/vtex/catalog-admin-products-skus.js.map +7 -0
  117. package/dist/src/tools/vtex/catalog-navigation-reads.js +430 -0
  118. package/dist/src/tools/vtex/catalog-navigation-reads.js.map +7 -0
  119. package/dist/src/tools/vtex/create-brand.js +1 -64
  120. package/dist/src/tools/vtex/create-brand.js.map +2 -2
  121. package/dist/src/tools/vtex/create-category.js +1 -76
  122. package/dist/src/tools/vtex/create-category.js.map +2 -2
  123. package/dist/src/tools/vtex/create-product-with-sku.js +3 -114
  124. package/dist/src/tools/vtex/create-product-with-sku.js.map +2 -2
  125. package/dist/src/tools/vtex/create-specification-value.js +3 -47
  126. package/dist/src/tools/vtex/create-specification-value.js.map +2 -2
  127. package/dist/src/tools/vtex/create-specification.js +1 -80
  128. package/dist/src/tools/vtex/create-specification.js.map +2 -2
  129. package/dist/src/tools/vtex/deactivate-sku.js +1 -48
  130. package/dist/src/tools/vtex/deactivate-sku.js.map +2 -2
  131. package/dist/src/tools/vtex/delete-all-product-specifications.js +9 -0
  132. package/dist/src/tools/vtex/delete-all-product-specifications.js.map +7 -0
  133. package/dist/src/tools/vtex/delete-all-sku-specifications.js +9 -0
  134. package/dist/src/tools/vtex/delete-all-sku-specifications.js.map +7 -0
  135. package/dist/src/tools/vtex/delete-brand.js +9 -0
  136. package/dist/src/tools/vtex/delete-brand.js.map +7 -0
  137. package/dist/src/tools/vtex/delete-catalog-image.js +9 -0
  138. package/dist/src/tools/vtex/delete-catalog-image.js.map +7 -0
  139. package/dist/src/tools/vtex/delete-product-specification.js +9 -0
  140. package/dist/src/tools/vtex/delete-product-specification.js.map +7 -0
  141. package/dist/src/tools/vtex/delete-sku-price.js +55 -0
  142. package/dist/src/tools/vtex/delete-sku-price.js.map +7 -0
  143. package/dist/src/tools/vtex/delete-sku-specification.js +9 -0
  144. package/dist/src/tools/vtex/delete-sku-specification.js.map +7 -0
  145. package/dist/src/tools/vtex/get-brand.js +6 -0
  146. package/dist/src/tools/vtex/get-brand.js.map +7 -0
  147. package/dist/src/tools/vtex/get-category-tree.js +6 -0
  148. package/dist/src/tools/vtex/get-category-tree.js.map +7 -0
  149. package/dist/src/tools/vtex/get-category.js +6 -0
  150. package/dist/src/tools/vtex/get-category.js.map +7 -0
  151. package/dist/src/tools/vtex/get-product-specifications.js +9 -0
  152. package/dist/src/tools/vtex/get-product-specifications.js.map +7 -0
  153. package/dist/src/tools/vtex/get-product.js +6 -0
  154. package/dist/src/tools/vtex/get-product.js.map +7 -0
  155. package/dist/src/tools/vtex/get-sku.js +6 -0
  156. package/dist/src/tools/vtex/get-sku.js.map +7 -0
  157. package/dist/src/tools/vtex/index.js +23 -1
  158. package/dist/src/tools/vtex/index.js.map +2 -2
  159. package/dist/src/tools/vtex/list-brands.js +6 -0
  160. package/dist/src/tools/vtex/list-brands.js.map +7 -0
  161. package/dist/src/tools/vtex/list-categories.js +6 -0
  162. package/dist/src/tools/vtex/list-categories.js.map +7 -0
  163. package/dist/src/tools/vtex/list-products-by-category.js +6 -0
  164. package/dist/src/tools/vtex/list-products-by-category.js.map +7 -0
  165. package/dist/src/tools/vtex/list-products.js +6 -0
  166. package/dist/src/tools/vtex/list-products.js.map +7 -0
  167. package/dist/src/tools/vtex/list-skus-by-product.js +6 -0
  168. package/dist/src/tools/vtex/list-skus-by-product.js.map +7 -0
  169. package/dist/src/tools/vtex/list-specification-groups.js +9 -0
  170. package/dist/src/tools/vtex/list-specification-groups.js.map +7 -0
  171. package/dist/src/tools/vtex/move-category.js +6 -0
  172. package/dist/src/tools/vtex/move-category.js.map +7 -0
  173. package/dist/src/tools/vtex/profile-resolution.js +4 -51
  174. package/dist/src/tools/vtex/profile-resolution.js.map +2 -2
  175. package/dist/src/tools/vtex/update-brand.js +6 -0
  176. package/dist/src/tools/vtex/update-brand.js.map +7 -0
  177. package/dist/src/tools/vtex/update-category.js +6 -0
  178. package/dist/src/tools/vtex/update-category.js.map +7 -0
  179. package/dist/src/tools/vtex/update-product-basic-fields.js +3 -65
  180. package/dist/src/tools/vtex/update-product-basic-fields.js.map +2 -2
  181. package/dist/src/tools/vtex/update-sku-basic-fields.js +1 -87
  182. package/dist/src/tools/vtex/update-sku-basic-fields.js.map +2 -2
  183. package/dist/src/tools/vtex/update-sku-price.js +21 -1
  184. package/dist/src/tools/vtex/update-sku-price.js.map +2 -2
  185. package/dist/src/tools/vtex/write-helpers.js +104 -14
  186. package/dist/src/tools/vtex/write-helpers.js.map +2 -2
  187. package/dist/src/utils/provider-profile-selection.js +117 -0
  188. package/dist/src/utils/provider-profile-selection.js.map +7 -0
  189. package/dist/tests/meli/mercadolibre-tool-handlers-medium-batch4.test.js +678 -0
  190. package/dist/tests/meli/mercadolibre-tool-handlers-medium-batch4.test.js.map +7 -0
  191. package/dist/tests/meli/mercadolibre-tool-handlers-monster-batch5.test.js +564 -0
  192. package/dist/tests/meli/mercadolibre-tool-handlers-monster-batch5.test.js.map +7 -0
  193. package/dist/tests/meli/mercadolibre-tool-handlers-monster-batch6.test.js +387 -0
  194. package/dist/tests/meli/mercadolibre-tool-handlers-monster-batch6.test.js.map +7 -0
  195. package/dist/tests/meli/mercadolibre-tool-handlers-monster-batch7.test.js +368 -0
  196. package/dist/tests/meli/mercadolibre-tool-handlers-monster-batch7.test.js.map +7 -0
  197. package/dist/tests/meli/mercadolibre-tool-handlers-small.test.js +626 -0
  198. package/dist/tests/meli/mercadolibre-tool-handlers-small.test.js.map +7 -0
  199. package/dist/tests/meli/mercadolibre-tool-handlers-write-batch8.test.js +480 -0
  200. package/dist/tests/meli/mercadolibre-tool-handlers-write-batch8.test.js.map +7 -0
  201. package/dist/tests/setup.js +2 -0
  202. package/dist/tests/setup.js.map +7 -0
  203. package/dist/tests/smoke/test-harness.test.js +7 -0
  204. package/dist/tests/smoke/test-harness.test.js.map +7 -0
  205. package/dist/tests/vtex/read-only-utils.test.js +161 -0
  206. package/dist/tests/vtex/read-only-utils.test.js.map +7 -0
  207. package/dist/tests/vtex/vtex-catalog-admin-docs.test.js +24 -0
  208. package/dist/tests/vtex/vtex-catalog-admin-docs.test.js.map +7 -0
  209. package/dist/tests/vtex/vtex-catalog-admin-surface.test.js +30 -0
  210. package/dist/tests/vtex/vtex-catalog-admin-surface.test.js.map +7 -0
  211. package/dist/tests/vtex/vtex-catalog-write-tools.test.js +712 -0
  212. package/dist/tests/vtex/vtex-catalog-write-tools.test.js.map +7 -0
  213. package/dist/tests/vtex/vtex-catalog.service.test.js +51 -0
  214. package/dist/tests/vtex/vtex-catalog.service.test.js.map +7 -0
  215. package/dist/tests/vtex/vtex-inventory-tools.test.js +201 -0
  216. package/dist/tests/vtex/vtex-inventory-tools.test.js.map +7 -0
  217. package/dist/tests/vtex/vtex-logistics.service.test.js +134 -0
  218. package/dist/tests/vtex/vtex-logistics.service.test.js.map +7 -0
  219. package/dist/tests/vtex/vtex-order-details.tool.test.js +141 -0
  220. package/dist/tests/vtex/vtex-order-details.tool.test.js.map +7 -0
  221. package/dist/tests/vtex/vtex-order-write-tools.test.js +483 -0
  222. package/dist/tests/vtex/vtex-order-write-tools.test.js.map +7 -0
  223. package/dist/tests/vtex/vtex-orders-summary.tool.test.js +185 -0
  224. package/dist/tests/vtex/vtex-orders-summary.tool.test.js.map +7 -0
  225. package/dist/tests/vtex/vtex-orders.service.test.js +120 -0
  226. package/dist/tests/vtex/vtex-orders.service.test.js.map +7 -0
  227. package/dist/tests/vtex/vtex-pricing-write-tools.test.js +202 -0
  228. package/dist/tests/vtex/vtex-pricing-write-tools.test.js.map +7 -0
  229. package/dist/tests/vtex/vtex-pricing-write.service.test.js +106 -0
  230. package/dist/tests/vtex/vtex-pricing-write.service.test.js.map +7 -0
  231. package/dist/tests/vtex/vtex-pricing.service.test.js +88 -0
  232. package/dist/tests/vtex/vtex-pricing.service.test.js.map +7 -0
  233. package/dist/tests/vtex/vtex-small-tools.test.js +190 -0
  234. package/dist/tests/vtex/vtex-small-tools.test.js.map +7 -0
  235. package/dist/tests/vtex/vtex-write-simple-tools.test.js +647 -0
  236. package/dist/tests/vtex/vtex-write-simple-tools.test.js.map +7 -0
  237. package/dist/vitest.config.js +15 -0
  238. package/dist/vitest.config.js.map +7 -0
  239. package/package.json +6 -2
@@ -0,0 +1,678 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { meliSearchItemsHandler } from "../../src/tools/mercadolibre/search-items.js";
3
+ import { meliGetStorePerformanceHandler } from "../../src/tools/mercadolibre/get-store-performance.js";
4
+ import { meliGetSalesByItemHandler } from "../../src/tools/mercadolibre/get-sales-by-item.js";
5
+ import { meliGetSalesTrendHandler } from "../../src/tools/mercadolibre/get-sales-trend.js";
6
+ import { meliGetOrderDetailsHandler } from "../../src/tools/mercadolibre/get-order-details.js";
7
+ import { resolveMercadoLibreProfileOrSelection } from "../../src/tools/mercadolibre/profile-resolution.js";
8
+ import { getMercadoLibreAccessForProfile } from "../../src/config/mercadolibre.js";
9
+ import {
10
+ formatMercadoLibreError,
11
+ normalizeMercadoLibrePaging
12
+ } from "../../src/services/mercadolibre/mercadolibre-api.js";
13
+ import {
14
+ getMercadoLibreItemDetailsBatch,
15
+ getMercadoLibreItemDetailsWithFallbackBatch,
16
+ getMercadoLibreUserItemsVisits,
17
+ searchMercadoLibreItems
18
+ } from "../../src/services/mercadolibre/mercadolibre-items.js";
19
+ import {
20
+ getMercadoLibreOrder,
21
+ getMercadoLibreOrderDetailsBatch,
22
+ searchMercadoLibreOrders,
23
+ searchMercadoLibreOrdersBatch
24
+ } from "../../src/services/mercadolibre/mercadolibre-orders.js";
25
+ vi.mock("mcp-use/server", () => ({
26
+ object: vi.fn((payload) => ({ kind: "object", payload })),
27
+ error: vi.fn((message) => ({ kind: "error", message }))
28
+ }));
29
+ vi.mock("../../src/tools/mercadolibre/profile-resolution.js", () => ({
30
+ resolveMercadoLibreProfileOrSelection: vi.fn()
31
+ }));
32
+ vi.mock("../../src/config/mercadolibre.js", () => ({
33
+ getMercadoLibreAccessForProfile: vi.fn()
34
+ }));
35
+ vi.mock("../../src/services/mercadolibre/mercadolibre-api.js", () => ({
36
+ formatMercadoLibreError: vi.fn(
37
+ (err, fallback) => `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`
38
+ ),
39
+ normalizeMercadoLibrePaging: vi.fn((paging) => paging)
40
+ }));
41
+ vi.mock("../../src/services/mercadolibre/mercadolibre-items.js", () => ({
42
+ searchMercadoLibreItems: vi.fn(),
43
+ searchMercadoLibreItemsBatch: vi.fn(),
44
+ getMercadoLibreItemDetailsBatch: vi.fn(),
45
+ getMercadoLibreItemDetailsWithFallbackBatch: vi.fn(),
46
+ getMercadoLibreUserItemsVisits: vi.fn()
47
+ }));
48
+ vi.mock("../../src/services/mercadolibre/mercadolibre-orders.js", () => ({
49
+ searchMercadoLibreOrders: vi.fn(),
50
+ searchMercadoLibreOrdersBatch: vi.fn(),
51
+ getMercadoLibreOrder: vi.fn(),
52
+ getMercadoLibreOrderDetailsBatch: vi.fn()
53
+ }));
54
+ describe("MercadoLibre medium tool handlers batch 4", () => {
55
+ beforeEach(() => {
56
+ vi.clearAllMocks();
57
+ vi.mocked(resolveMercadoLibreProfileOrSelection).mockResolvedValue({
58
+ ok: true,
59
+ value: { profileId: "meli-profile-1" }
60
+ });
61
+ vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({
62
+ sellerId: "seller-99",
63
+ scopes: ["read"],
64
+ expiresAt: "2026-07-01T00:00:00.000Z"
65
+ });
66
+ vi.mocked(normalizeMercadoLibrePaging).mockImplementation((paging) => paging);
67
+ });
68
+ it("searches items with the default active status and compact item rows", async () => {
69
+ vi.mocked(searchMercadoLibreItems).mockResolvedValue({
70
+ results: ["MLA1", "MLA2"],
71
+ paging: { total: 2, limit: 50, offset: 0 }
72
+ });
73
+ vi.mocked(getMercadoLibreItemDetailsBatch).mockResolvedValue([
74
+ {
75
+ id: "MLA1",
76
+ title: "Boots",
77
+ status: "active",
78
+ price: 100,
79
+ currency_id: "ARS",
80
+ available_quantity: 3,
81
+ sold_quantity: 8,
82
+ listing_type_id: "gold_special",
83
+ category_id: "MLA123"
84
+ },
85
+ {
86
+ id: "MLA2",
87
+ title: "Sneakers",
88
+ status: "paused",
89
+ price: 250,
90
+ currency_id: "USD",
91
+ available_quantity: 1,
92
+ sold_quantity: 2,
93
+ listing_type_id: "gold_pro",
94
+ category_id: "MLA456"
95
+ }
96
+ ]);
97
+ vi.mocked(getMercadoLibreItemDetailsWithFallbackBatch).mockResolvedValue({
98
+ successful: [],
99
+ failed: []
100
+ });
101
+ const result = await meliSearchItemsHandler({ profileId: "meli-profile-1" });
102
+ expect(searchMercadoLibreItems).toHaveBeenCalledWith("meli-profile-1", {
103
+ sellerId: "seller-99",
104
+ status: "active",
105
+ q: void 0,
106
+ category: void 0,
107
+ listingTypeId: void 0,
108
+ orders: void 0,
109
+ limit: 50,
110
+ offset: 0
111
+ });
112
+ expect(getMercadoLibreItemDetailsBatch).toHaveBeenCalledWith("meli-profile-1", ["MLA1", "MLA2"], [
113
+ "id",
114
+ "title",
115
+ "status",
116
+ "price",
117
+ "currency_id",
118
+ "available_quantity",
119
+ "sold_quantity",
120
+ "listing_type_id",
121
+ "category_id"
122
+ ]);
123
+ expect(result).toEqual({
124
+ kind: "object",
125
+ payload: {
126
+ profile_id: "meli-profile-1",
127
+ metadata: {
128
+ total: 2,
129
+ limit: 2,
130
+ offset: 0,
131
+ returned: 2,
132
+ has_more: false,
133
+ continuation: "No more pages for this query.",
134
+ applied_status: "active",
135
+ default_status_notice: "Solo se devolvieron publicaciones active por default. Tambi\xE9n se puede pedir status expl\xEDcito como paused, closed, under_review, inactive, not_yet_active, payment_required o deleted.",
136
+ available_status_filters: [
137
+ "active",
138
+ "paused",
139
+ "closed",
140
+ "under_review",
141
+ "inactive",
142
+ "not_yet_active",
143
+ "payment_required",
144
+ "deleted"
145
+ ],
146
+ detail_coverage: {
147
+ detail_failures: 0,
148
+ details_complete: true
149
+ },
150
+ pages_requested: 1,
151
+ pages_succeeded: 1,
152
+ pages_failed: 0,
153
+ universe_fully_fetched: true
154
+ },
155
+ items_schema: [
156
+ "item_id",
157
+ "title",
158
+ "status",
159
+ "price",
160
+ "currency_id",
161
+ "available_quantity",
162
+ "sold_quantity",
163
+ "listing_type_id",
164
+ "category_id"
165
+ ],
166
+ items: [
167
+ ["MLA1", "Boots", "active", 100, "ARS", 3, 8, "gold_special", "MLA123"],
168
+ ["MLA2", "Sneakers", "paused", 250, "USD", 1, 2, "gold_pro", "MLA456"]
169
+ ]
170
+ }
171
+ });
172
+ });
173
+ it("reports partial item detail coverage when fallback misses items", async () => {
174
+ vi.mocked(searchMercadoLibreItems).mockResolvedValue({
175
+ results: ["MLA1", "MLA2", "MLA3"],
176
+ paging: { total: 3, limit: 50, offset: 0 }
177
+ });
178
+ vi.mocked(getMercadoLibreItemDetailsBatch).mockResolvedValue([{ id: "MLA1", title: "Boots" }]);
179
+ vi.mocked(getMercadoLibreItemDetailsWithFallbackBatch).mockResolvedValue({
180
+ successful: [{ id: "MLA2", document: { id: "MLA2", title: "Sneakers" } }],
181
+ failed: [{ id: "MLA3", message: "missing", attempts: 2, retryable: false, statusCode: 404 }]
182
+ });
183
+ const result = await meliSearchItemsHandler({
184
+ profileId: "meli-profile-1",
185
+ status: "paused",
186
+ limit: 3,
187
+ offset: 0
188
+ });
189
+ expect(getMercadoLibreItemDetailsWithFallbackBatch).toHaveBeenCalledWith("meli-profile-1", ["MLA2", "MLA3"], {
190
+ maxConcurrency: 10,
191
+ maxRetries: 1
192
+ });
193
+ expect(result).toEqual({
194
+ kind: "object",
195
+ payload: {
196
+ profile_id: "meli-profile-1",
197
+ metadata: {
198
+ total: 3,
199
+ limit: 3,
200
+ offset: 0,
201
+ returned: 2,
202
+ has_more: true,
203
+ next_offset: 2,
204
+ continuation: "Se recuper\xF3 cobertura parcial. Reintentar la misma tool con offset=0 y limit=3. Luego continuar con offset=2 si hace falta.",
205
+ applied_status: "paused",
206
+ available_status_filters: [
207
+ "active",
208
+ "paused",
209
+ "closed",
210
+ "under_review",
211
+ "inactive",
212
+ "not_yet_active",
213
+ "payment_required",
214
+ "deleted"
215
+ ],
216
+ detail_coverage: {
217
+ detail_failures: 1,
218
+ details_complete: false
219
+ },
220
+ pages_requested: 1,
221
+ pages_succeeded: 1,
222
+ pages_failed: 0,
223
+ universe_fully_fetched: true
224
+ },
225
+ items_schema: [
226
+ "item_id",
227
+ "title",
228
+ "status",
229
+ "price",
230
+ "currency_id",
231
+ "available_quantity",
232
+ "sold_quantity",
233
+ "listing_type_id",
234
+ "category_id"
235
+ ],
236
+ items: [
237
+ ["MLA1", "Boots", "", 0, "UNKNOWN", 0, 0, "", ""],
238
+ ["MLA2", "Sneakers", "", 0, "UNKNOWN", 0, 0, "", ""]
239
+ ]
240
+ }
241
+ });
242
+ });
243
+ it("builds store performance summaries with service wiring, ordering, and warnings", async () => {
244
+ vi.mocked(searchMercadoLibreOrders).mockResolvedValue({
245
+ results: [
246
+ {
247
+ currency_id: "ARS",
248
+ total_amount: 200.5,
249
+ order_items: [
250
+ {
251
+ quantity: 2,
252
+ unit_price: 50.25,
253
+ item: { id: "MLA1", title: "Boots" }
254
+ }
255
+ ]
256
+ },
257
+ {
258
+ currency_id: "USD",
259
+ total_amount: 75.255,
260
+ order_items: [
261
+ {
262
+ quantity: 1,
263
+ unit_price: 75.255,
264
+ item: { id: "MLA2", title: "Sneakers" }
265
+ }
266
+ ]
267
+ }
268
+ ]
269
+ });
270
+ vi.mocked(searchMercadoLibreItems).mockResolvedValue({
271
+ results: ["MLA1", "MLA2", "MLA3"]
272
+ });
273
+ vi.mocked(getMercadoLibreUserItemsVisits).mockResolvedValue({ results: [] });
274
+ const result = await meliGetStorePerformanceHandler({
275
+ profileId: "meli-profile-1",
276
+ startDate: "2026-03-01",
277
+ endDate: "2026-03-31",
278
+ ordersLimit: 2,
279
+ itemsLimit: 5
280
+ });
281
+ expect(searchMercadoLibreOrders).toHaveBeenCalledWith("meli-profile-1", {
282
+ seller: "seller-99",
283
+ from: "2026-03-01",
284
+ to: "2026-03-31",
285
+ limit: 2,
286
+ offset: 0
287
+ });
288
+ expect(searchMercadoLibreItems).toHaveBeenCalledWith("meli-profile-1", {
289
+ sellerId: "seller-99",
290
+ limit: 5,
291
+ offset: 0
292
+ });
293
+ expect(getMercadoLibreUserItemsVisits).toHaveBeenCalledWith(
294
+ "meli-profile-1",
295
+ "seller-99",
296
+ "2026-03-01",
297
+ "2026-03-31"
298
+ );
299
+ expect(result).toEqual({
300
+ kind: "object",
301
+ payload: {
302
+ profile_id: "meli-profile-1",
303
+ seller_id: "seller-99",
304
+ executive_summary: {
305
+ orders_sampled: 2,
306
+ active_items_sampled: 3,
307
+ total_visits: 0,
308
+ revenue_by_currency: {
309
+ ARS: { orders: 1, revenue: 200.5 },
310
+ USD: { orders: 1, revenue: 75.25 }
311
+ }
312
+ },
313
+ top_items: [
314
+ { item_id: "MLA1", title: "Boots", units: 2, revenue: 100.5 },
315
+ { item_id: "MLA2", title: "Sneakers", units: 1, revenue: 75.25 }
316
+ ],
317
+ warnings: [
318
+ "La muestra de \xF3rdenes puede ser parcial. Si necesit\xE1s totales completos, reenviar con mayor rango paginado.",
319
+ "MercadoLibre no devolvi\xF3 filas de visitas para el rango indicado."
320
+ ]
321
+ }
322
+ });
323
+ });
324
+ it("aggregates sales by item across paginated order batches", async () => {
325
+ vi.mocked(searchMercadoLibreOrders).mockResolvedValue({
326
+ paging: { total: 3, limit: 2, offset: 0 },
327
+ results: [
328
+ {
329
+ currency_id: "ARS",
330
+ date_created: "2026-03-10T14:45:55.000Z",
331
+ order_items: [
332
+ {
333
+ quantity: 2,
334
+ unit_price: 100,
335
+ item: { id: "MLA1", title: "Boots", variation_id: "V1" }
336
+ }
337
+ ]
338
+ },
339
+ {
340
+ currency_id: "USD",
341
+ date_created: "2026-03-11T08:10:00.000Z",
342
+ order_items: [
343
+ {
344
+ quantity: 1,
345
+ unit_price: 50,
346
+ item: { id: "MLA2", title: "Sneakers" }
347
+ }
348
+ ]
349
+ }
350
+ ]
351
+ });
352
+ vi.mocked(searchMercadoLibreOrdersBatch).mockResolvedValue({
353
+ successful: [
354
+ {
355
+ id: "2",
356
+ document: {
357
+ results: [
358
+ {
359
+ currency_id: "ARS",
360
+ date_created: "2026-03-12T09:15:00.000Z",
361
+ order_items: [
362
+ {
363
+ quantity: 1,
364
+ unit_price: 120,
365
+ item: { id: "MLA1", title: "Boots", variation_id: "V1" }
366
+ }
367
+ ]
368
+ }
369
+ ]
370
+ }
371
+ }
372
+ ],
373
+ failed: []
374
+ });
375
+ const result = await meliGetSalesByItemHandler({
376
+ profileId: "meli-profile-1",
377
+ startDate: "2026-03-01",
378
+ endDate: "2026-03-31",
379
+ status: "paid",
380
+ limit: 2,
381
+ offset: 0
382
+ });
383
+ expect(searchMercadoLibreOrders).toHaveBeenCalledWith("meli-profile-1", {
384
+ seller: "",
385
+ from: "2026-03-01",
386
+ to: "2026-03-31",
387
+ status: "paid",
388
+ limit: 2,
389
+ offset: 0
390
+ });
391
+ expect(searchMercadoLibreOrdersBatch).toHaveBeenCalledWith(
392
+ "meli-profile-1",
393
+ {
394
+ seller: "",
395
+ from: "2026-03-01",
396
+ to: "2026-03-31",
397
+ status: "paid",
398
+ limit: 2
399
+ },
400
+ [2],
401
+ {
402
+ maxConcurrency: 15,
403
+ maxRetries: 2
404
+ }
405
+ );
406
+ expect(result).toEqual({
407
+ kind: "object",
408
+ payload: {
409
+ profile_id: "meli-profile-1",
410
+ metadata: {
411
+ total: 3,
412
+ limit: 2,
413
+ offset: 0,
414
+ returned: 3,
415
+ orders_aggregated: 3,
416
+ has_more: false,
417
+ continuation: "Agregado completo. No more pages for this query.",
418
+ fetch_mode: "full_aggregate",
419
+ pages_requested: 2,
420
+ pages_succeeded: 2,
421
+ pages_failed: 0,
422
+ universe_fully_fetched: true
423
+ },
424
+ sales_by_item_schema: [
425
+ "item_id",
426
+ "title",
427
+ "variation_id",
428
+ "orders",
429
+ "units",
430
+ "revenue",
431
+ "last_order_date"
432
+ ],
433
+ sales_by_currency: {
434
+ ARS: [["MLA1", "Boots", "V1", 2, 3, 320, "2026-03-12 09:15"]],
435
+ USD: [["MLA2", "Sneakers", "", 1, 1, 50, "2026-03-11 08:10"]]
436
+ }
437
+ }
438
+ });
439
+ });
440
+ it("reports partial weekly sales trends when follow-up pages fail", async () => {
441
+ vi.mocked(searchMercadoLibreOrders).mockResolvedValue({
442
+ paging: { total: 3, limit: 2, offset: 0 },
443
+ results: [
444
+ {
445
+ currency_id: "ARS",
446
+ total_amount: 100,
447
+ date_created: "2026-03-10T23:30:00.000Z"
448
+ },
449
+ {
450
+ currency_id: "ARS",
451
+ total_amount: 50,
452
+ date_created: "2026-03-13T03:00:00.000Z"
453
+ }
454
+ ]
455
+ });
456
+ vi.mocked(searchMercadoLibreOrdersBatch).mockResolvedValue({
457
+ successful: [],
458
+ failed: [{ id: "2", message: "timeout", attempts: 2, retryable: true, statusCode: 504 }]
459
+ });
460
+ const result = await meliGetSalesTrendHandler({
461
+ profileId: "meli-profile-1",
462
+ startDate: "2026-03-01",
463
+ endDate: "2026-03-31",
464
+ granularity: "week",
465
+ limit: 2,
466
+ offset: 0
467
+ });
468
+ expect(result).toEqual({
469
+ kind: "object",
470
+ payload: {
471
+ profile_id: "meli-profile-1",
472
+ granularity: "week",
473
+ trend_by_currency: {
474
+ ARS: [{ bucket: "2026-03-09", orders: 2, revenue: 150 }]
475
+ },
476
+ metadata: {
477
+ total_matching_orders: 3,
478
+ limit: 2,
479
+ offset: 0,
480
+ returned: 2,
481
+ orders_aggregated: 2,
482
+ continuation: "Agregado parcial por paginas fallidas. Reintentar la misma tool con los mismos filtros para recomputar el trend completo. Offsets fallidos: 2.",
483
+ fetch_mode: "full_aggregate",
484
+ pages_requested: 2,
485
+ pages_succeeded: 1,
486
+ pages_failed: 1,
487
+ universe_fully_fetched: false
488
+ },
489
+ failed_pages: [
490
+ {
491
+ offset: 2,
492
+ limit: 2,
493
+ page_number: 2,
494
+ message: "timeout",
495
+ status_code: 504,
496
+ attempts: 2,
497
+ retryable: true
498
+ }
499
+ ]
500
+ }
501
+ });
502
+ });
503
+ it("uses the single-order path when all requested order ids collapse to one unique id", async () => {
504
+ vi.mocked(getMercadoLibreOrder).mockResolvedValue({
505
+ id: 100,
506
+ status: "paid",
507
+ status_detail: "accredited",
508
+ date_created: "2026-03-10T14:45:55.000Z",
509
+ date_closed: "2026-03-10T15:00:00.000Z",
510
+ currency_id: "ARS",
511
+ total_amount: 200,
512
+ paid_amount: 200,
513
+ shipping: { id: 1, status: "ready_to_ship", logistic_type: "drop_off" },
514
+ buyer: { id: 10, nickname: "buyer-1" },
515
+ seller: { id: 20, nickname: "seller-1" },
516
+ order_items: [
517
+ {
518
+ quantity: 2,
519
+ unit_price: 100,
520
+ full_unit_price: 120,
521
+ item: { id: "MLA1", title: "Boots", variation_id: "V1" }
522
+ }
523
+ ],
524
+ payments: [
525
+ {
526
+ id: 999,
527
+ status: "approved",
528
+ payment_type: "credit_card",
529
+ installments: 3,
530
+ total_paid_amount: 200
531
+ }
532
+ ],
533
+ tags: ["packed"]
534
+ });
535
+ const result = await meliGetOrderDetailsHandler({
536
+ profileId: "meli-profile-1",
537
+ orderIds: ["100", "100"]
538
+ });
539
+ expect(getMercadoLibreOrder).toHaveBeenCalledWith("meli-profile-1", "100");
540
+ expect(getMercadoLibreOrderDetailsBatch).not.toHaveBeenCalled();
541
+ expect(result).toEqual({
542
+ kind: "object",
543
+ payload: {
544
+ metadata: {
545
+ profile_id: "meli-profile-1",
546
+ requested: 1,
547
+ successful: 1,
548
+ failed: 0
549
+ },
550
+ orders: [
551
+ {
552
+ buyer: { id: "", nickname: "buyer-1" },
553
+ currency_id: "ARS",
554
+ date_closed: "2026-03-10 15:00",
555
+ date_created: "2026-03-10 14:45",
556
+ items: [
557
+ {
558
+ item_id: "MLA1",
559
+ title: "Boots",
560
+ variation_id: "V1",
561
+ quantity: 2,
562
+ unit_price: 100,
563
+ full_unit_price: 120
564
+ }
565
+ ],
566
+ order_id: "",
567
+ total_amount: 200,
568
+ paid_amount: 200,
569
+ payments: [
570
+ {
571
+ id: "",
572
+ status: "approved",
573
+ payment_type: "credit_card",
574
+ installments: 3,
575
+ total_paid_amount: 200
576
+ }
577
+ ],
578
+ seller: { id: "", nickname: "seller-1" },
579
+ shipping: {
580
+ id: "",
581
+ status: "ready_to_ship",
582
+ substatus: "",
583
+ mode: "",
584
+ logistic_type: "drop_off"
585
+ },
586
+ status: "paid",
587
+ status_detail: "accredited",
588
+ tags: ["packed"]
589
+ }
590
+ ]
591
+ }
592
+ });
593
+ });
594
+ it("returns batch order details with normalized failures", async () => {
595
+ vi.mocked(getMercadoLibreOrderDetailsBatch).mockResolvedValue({
596
+ successful: [
597
+ {
598
+ id: "100",
599
+ document: {
600
+ id: "100",
601
+ status: "paid",
602
+ currency_id: "ARS",
603
+ total_amount: 100,
604
+ paid_amount: 100,
605
+ order_items: [],
606
+ payments: []
607
+ }
608
+ }
609
+ ],
610
+ failed: [{ id: "101", message: "not found", statusCode: 404, attempts: 2, retryable: false }]
611
+ });
612
+ const result = await meliGetOrderDetailsHandler({
613
+ profileId: "meli-profile-1",
614
+ orderIds: ["100", "101", "100"]
615
+ });
616
+ expect(getMercadoLibreOrderDetailsBatch).toHaveBeenCalledWith("meli-profile-1", ["100", "101"], {
617
+ maxConcurrency: 10,
618
+ maxRetries: 2
619
+ });
620
+ expect(result).toEqual({
621
+ kind: "object",
622
+ payload: {
623
+ metadata: {
624
+ profile_id: "meli-profile-1",
625
+ requested: 2,
626
+ successful: 1,
627
+ failed: 1,
628
+ has_failures: true
629
+ },
630
+ orders: [
631
+ {
632
+ buyer: { id: "", nickname: "" },
633
+ order_id: "100",
634
+ status: "paid",
635
+ status_detail: "",
636
+ currency_id: "ARS",
637
+ total_amount: 100,
638
+ paid_amount: 100,
639
+ shipping: {
640
+ id: "",
641
+ status: "",
642
+ substatus: "",
643
+ mode: "",
644
+ logistic_type: ""
645
+ },
646
+ seller: { id: "", nickname: "" }
647
+ }
648
+ ],
649
+ failures: [
650
+ {
651
+ order_id: "101",
652
+ message: "not found",
653
+ status_code: 404,
654
+ attempts: 2,
655
+ retryable: false
656
+ }
657
+ ]
658
+ }
659
+ });
660
+ });
661
+ it("formats medium-handler failures through MercadoLibre error helpers", async () => {
662
+ vi.mocked(searchMercadoLibreOrders).mockRejectedValue(new Error("orders-boom"));
663
+ const result = await meliGetSalesTrendHandler({
664
+ profileId: "meli-profile-1",
665
+ startDate: "2026-03-01",
666
+ endDate: "2026-03-31"
667
+ });
668
+ expect(formatMercadoLibreError).toHaveBeenCalledWith(
669
+ expect.any(Error),
670
+ "Failed to build MercadoLibre sales trend"
671
+ );
672
+ expect(result).toEqual({
673
+ kind: "error",
674
+ message: "formatted:Failed to build MercadoLibre sales trend:orders-boom"
675
+ });
676
+ });
677
+ });
678
+ //# sourceMappingURL=mercadolibre-tool-handlers-medium-batch4.test.js.map