@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,356 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ const {
3
+ errorMock,
4
+ objectMock,
5
+ resolveProfileMock,
6
+ formatErrorMock,
7
+ paymentDetailsMock,
8
+ paymentDetailsBatchMock
9
+ } = vi.hoisted(
10
+ () => ({
11
+ errorMock: vi.fn((message) => ({ kind: "error", message })),
12
+ objectMock: vi.fn((payload) => ({ kind: "object", payload })),
13
+ resolveProfileMock: vi.fn(),
14
+ formatErrorMock: vi.fn(
15
+ (err, fallback) => `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`
16
+ ),
17
+ paymentDetailsMock: vi.fn(),
18
+ paymentDetailsBatchMock: vi.fn()
19
+ })
20
+ );
21
+ vi.mock("mcp-use/server", () => ({
22
+ object: objectMock,
23
+ error: errorMock
24
+ }));
25
+ vi.mock("../../src/tools/mercadolibre/profile-resolution.js", () => ({
26
+ resolveMercadoLibreProfileOrSelection: resolveProfileMock
27
+ }));
28
+ vi.mock("../../src/services/mercadolibre/mercadolibre-api.js", () => ({
29
+ formatMercadoLibreError: formatErrorMock
30
+ }));
31
+ vi.mock("../../src/services/mercadolibre/mercadolibre-payments.js", () => ({
32
+ getMercadoLibrePaymentDetails: paymentDetailsMock,
33
+ getMercadoLibrePaymentDetailsBatch: paymentDetailsBatchMock
34
+ }));
35
+ import {
36
+ meliGetPaymentDetailsHandler,
37
+ meliGetPaymentDetailsSchema
38
+ } from "../../src/tools/mercadolibre/get-payment-details.js";
39
+ describe("meli_get_payment_details handler", () => {
40
+ beforeEach(() => {
41
+ vi.clearAllMocks();
42
+ vi.mocked(resolveProfileMock).mockResolvedValue({
43
+ ok: true,
44
+ value: { profileId: "meli-profile-1" }
45
+ });
46
+ vi.mocked(paymentDetailsMock).mockResolvedValue({
47
+ id: 28382111111,
48
+ status: "approved",
49
+ status_detail: "accredited",
50
+ currency_id: "ARS",
51
+ transaction_amount: 100,
52
+ date_created: "2023-10-27T10:00:00.000-04:00",
53
+ date_last_updated: "2023-10-27T10:05:00.000-04:00",
54
+ payment_method_id: "credit_card",
55
+ payment_type_id: "credit_card",
56
+ installments: 1,
57
+ description: "Payment for order #12345",
58
+ order: {
59
+ id: 1234567890
60
+ },
61
+ payer: {
62
+ id: 987654321,
63
+ email: "buyer@example.com",
64
+ first_name: "Test",
65
+ last_name: "User",
66
+ type: "customer"
67
+ },
68
+ transaction_details: {
69
+ total_paid_amount: 100,
70
+ net_received_amount: 95,
71
+ overpaid_amount: 0,
72
+ external_reference: "order_12345"
73
+ },
74
+ fee_details: [{ type: "MERCHANT_FEES", amount: 5 }]
75
+ });
76
+ vi.mocked(paymentDetailsBatchMock).mockResolvedValue({
77
+ successful: [],
78
+ failed: []
79
+ });
80
+ });
81
+ it("returns a compact single-payment payload with summary and breakdowns", async () => {
82
+ const result = await meliGetPaymentDetailsHandler({
83
+ profileId: "custom-profile",
84
+ paymentId: "28382111111"
85
+ });
86
+ expect(resolveProfileMock).toHaveBeenCalledWith("custom-profile");
87
+ expect(paymentDetailsMock).toHaveBeenCalledWith("meli-profile-1", "28382111111");
88
+ expect(result).toEqual({
89
+ kind: "object",
90
+ payload: {
91
+ metadata: {
92
+ profile_id: "meli-profile-1",
93
+ mode: "single",
94
+ requested_count: 1,
95
+ successful_count: 1,
96
+ failed_count: 0,
97
+ coverage_complete: true,
98
+ requested_payment_ids: ["28382111111"],
99
+ successful_payment_ids: ["28382111111"],
100
+ endpoint: "/v1/payments/{payment_id}"
101
+ },
102
+ summary: {
103
+ requested_count: 1,
104
+ successful_count: 1,
105
+ failed_count: 0,
106
+ payments_with_order_count: 1,
107
+ payments_without_order_count: 0,
108
+ payments_without_payer_count: 0,
109
+ currency_totals: {
110
+ ARS: {
111
+ count: 1,
112
+ transaction_amount: 100,
113
+ total_paid_amount: 100,
114
+ net_received_amount: 95,
115
+ overpaid_amount: 0,
116
+ fee_total: 5
117
+ }
118
+ },
119
+ status_counts: { approved: 1 },
120
+ payment_method_counts: { credit_card: 1 },
121
+ payment_type_counts: { credit_card: 1 }
122
+ },
123
+ breakdowns: {
124
+ by_currency: [
125
+ {
126
+ currency_id: "ARS",
127
+ count: 1,
128
+ transaction_amount: 100,
129
+ total_paid_amount: 100,
130
+ net_received_amount: 95,
131
+ overpaid_amount: 0,
132
+ fee_total: 5
133
+ }
134
+ ],
135
+ by_status: [{ key: "approved", count: 1, rate: 1 }],
136
+ by_payment_method: [{ key: "credit_card", count: 1, rate: 1 }],
137
+ by_payment_type: [{ key: "credit_card", count: 1, rate: 1 }]
138
+ },
139
+ payments_schema: [
140
+ "payment_id",
141
+ "status",
142
+ "status_detail",
143
+ "currency_id",
144
+ "transaction_amount",
145
+ "total_paid_amount",
146
+ "net_received_amount",
147
+ "overpaid_amount",
148
+ "payment_method_id",
149
+ "payment_type_id",
150
+ "installments",
151
+ "date_created",
152
+ "date_last_updated",
153
+ "description",
154
+ "order_id",
155
+ "payer_id",
156
+ "payer_email",
157
+ "payer_type",
158
+ "payer_first_name",
159
+ "payer_last_name",
160
+ "fee_count",
161
+ "fee_total",
162
+ "external_reference"
163
+ ],
164
+ payments: [
165
+ [
166
+ "28382111111",
167
+ "approved",
168
+ "accredited",
169
+ "ARS",
170
+ 100,
171
+ 100,
172
+ 95,
173
+ 0,
174
+ "credit_card",
175
+ "credit_card",
176
+ 1,
177
+ "2023-10-27 10:00",
178
+ "2023-10-27 10:05",
179
+ "Payment for order #12345",
180
+ "1234567890",
181
+ "987654321",
182
+ "buyer@example.com",
183
+ "customer",
184
+ "Test",
185
+ "User",
186
+ 1,
187
+ 5,
188
+ "order_12345"
189
+ ]
190
+ ],
191
+ payment_fee_details_schema: ["payment_id", "fee_type", "fee_amount"],
192
+ payment_fee_details: [["28382111111", "MERCHANT_FEES", 5]]
193
+ }
194
+ });
195
+ });
196
+ it("accepts the exact 250-payment boundary and rejects invalid selector combinations", () => {
197
+ const exactBoundaryPaymentIds = Array.from({ length: 250 }, (_, index) => `p-${index + 1}`);
198
+ expect(
199
+ meliGetPaymentDetailsSchema.safeParse({
200
+ profileId: "custom-profile",
201
+ paymentIds: exactBoundaryPaymentIds
202
+ }).success
203
+ ).toBe(true);
204
+ expect(
205
+ () => meliGetPaymentDetailsSchema.parse({
206
+ profileId: "custom-profile"
207
+ })
208
+ ).toThrow(/paymentId|paymentIds/);
209
+ expect(
210
+ () => meliGetPaymentDetailsSchema.parse({
211
+ profileId: "custom-profile",
212
+ paymentId: "28382111111",
213
+ paymentIds: ["28382111112"]
214
+ })
215
+ ).toThrow(/paymentId|paymentIds/);
216
+ expect(
217
+ () => meliGetPaymentDetailsSchema.parse({
218
+ profileId: "custom-profile",
219
+ paymentIds: Array.from({ length: 251 }, (_, index) => `p-${index + 1}`)
220
+ })
221
+ ).toThrow(/250/);
222
+ });
223
+ it("returns the selection payload unchanged when the profile cannot be resolved", async () => {
224
+ vi.mocked(resolveProfileMock).mockResolvedValue({
225
+ ok: false,
226
+ response: { selection_required: true }
227
+ });
228
+ const result = await meliGetPaymentDetailsHandler({
229
+ profileId: "unknown-profile",
230
+ paymentId: "28382111111"
231
+ });
232
+ expect(result).toEqual({ selection_required: true });
233
+ expect(paymentDetailsMock).not.toHaveBeenCalled();
234
+ });
235
+ it("returns a compact batch payload with partial failures", async () => {
236
+ vi.mocked(paymentDetailsBatchMock).mockResolvedValue({
237
+ successful: [
238
+ {
239
+ paymentId: "28382111111",
240
+ payment: {
241
+ id: 28382111111,
242
+ status: "approved",
243
+ status_detail: "accredited",
244
+ currency_id: "ARS",
245
+ transaction_amount: 100,
246
+ date_created: "2023-10-27T10:00:00.000-04:00",
247
+ date_last_updated: "2023-10-27T10:05:00.000-04:00",
248
+ payment_method_id: "credit_card",
249
+ payment_type_id: "credit_card",
250
+ installments: 1,
251
+ order: { id: 1234567890 },
252
+ payer: { id: 987654321, email: "buyer@example.com", type: "customer" },
253
+ transaction_details: {
254
+ total_paid_amount: 100,
255
+ net_received_amount: 95,
256
+ overpaid_amount: 0
257
+ },
258
+ fee_details: [{ type: "MERCHANT_FEES", amount: 5 }]
259
+ }
260
+ },
261
+ {
262
+ paymentId: "28382111112",
263
+ payment: {
264
+ id: 28382111112,
265
+ status: "pending",
266
+ currency_id: "USD",
267
+ transaction_amount: 50,
268
+ date_created: "2023-10-27T11:00:00.000-04:00",
269
+ date_last_updated: "2023-10-27T11:05:00.000-04:00",
270
+ payment_method_id: "debit_card",
271
+ payment_type_id: "debit_card",
272
+ installments: 1,
273
+ transaction_details: {
274
+ total_paid_amount: 50,
275
+ net_received_amount: 48,
276
+ overpaid_amount: 0
277
+ },
278
+ fee_details: []
279
+ }
280
+ }
281
+ ],
282
+ failed: [
283
+ {
284
+ paymentId: "28382111113",
285
+ message: "formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404",
286
+ statusCode: 404,
287
+ attempts: 1,
288
+ retryable: false
289
+ }
290
+ ]
291
+ });
292
+ const result = await meliGetPaymentDetailsHandler({
293
+ profileId: "custom-profile",
294
+ paymentIds: ["28382111111", "28382111112", "28382111113"]
295
+ });
296
+ expect(paymentDetailsBatchMock).toHaveBeenCalledWith("meli-profile-1", [
297
+ "28382111111",
298
+ "28382111112",
299
+ "28382111113"
300
+ ]);
301
+ expect(result).toEqual({
302
+ kind: "object",
303
+ payload: expect.objectContaining({
304
+ metadata: expect.objectContaining({
305
+ mode: "batch",
306
+ requested_count: 3,
307
+ successful_count: 2,
308
+ failed_count: 1,
309
+ coverage_complete: false,
310
+ requested_payment_ids: ["28382111111", "28382111112", "28382111113"],
311
+ successful_payment_ids: ["28382111111", "28382111112"],
312
+ failed_payment_ids: ["28382111113"]
313
+ }),
314
+ failures: [
315
+ {
316
+ paymentId: "28382111113",
317
+ message: "formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404",
318
+ statusCode: 404,
319
+ attempts: 1,
320
+ retryable: false
321
+ }
322
+ ]
323
+ })
324
+ });
325
+ const [firstRow, secondRow] = result.payload.payments;
326
+ expect(firstRow).toHaveLength(23);
327
+ expect(secondRow).toHaveLength(23);
328
+ expect(secondRow[2]).toBeNull();
329
+ expect(secondRow[13]).toBeNull();
330
+ expect(secondRow[14]).toBeNull();
331
+ expect(secondRow[15]).toBeNull();
332
+ expect(secondRow[16]).toBeNull();
333
+ expect(secondRow[17]).toBeNull();
334
+ expect(secondRow[18]).toBeNull();
335
+ expect(secondRow[19]).toBeNull();
336
+ expect(secondRow[22]).toBeNull();
337
+ });
338
+ it("returns a formatted error when the payment lookup fails", async () => {
339
+ vi.mocked(paymentDetailsMock).mockRejectedValueOnce(
340
+ new Error("Request failed with status code 404")
341
+ );
342
+ const result = await meliGetPaymentDetailsHandler({
343
+ profileId: "custom-profile",
344
+ paymentId: "28382111111"
345
+ });
346
+ expect(formatErrorMock).toHaveBeenCalledWith(
347
+ expect.any(Error),
348
+ "Failed to fetch MercadoLibre payment details"
349
+ );
350
+ expect(result).toEqual({
351
+ kind: "error",
352
+ message: "formatted:Failed to fetch MercadoLibre payment details:Request failed with status code 404"
353
+ });
354
+ });
355
+ });
356
+ //# sourceMappingURL=mercadolibre-payment-details.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/meli/mercadolibre-payment-details.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst {\n errorMock,\n objectMock,\n resolveProfileMock,\n formatErrorMock,\n paymentDetailsMock,\n paymentDetailsBatchMock,\n} = vi.hoisted(\n () => ({\n errorMock: vi.fn((message: string) => ({ kind: \"error\", message })),\n objectMock: vi.fn((payload: unknown) => ({ kind: \"object\", payload })),\n resolveProfileMock: vi.fn(),\n formatErrorMock: vi.fn(\n (err: unknown, fallback: string) =>\n `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`\n ),\n paymentDetailsMock: vi.fn(),\n paymentDetailsBatchMock: vi.fn(),\n })\n);\n\nvi.mock(\"mcp-use/server\", () => ({\n object: objectMock,\n error: errorMock,\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/profile-resolution.js\", () => ({\n resolveMercadoLibreProfileOrSelection: resolveProfileMock,\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-api.js\", () => ({\n formatMercadoLibreError: formatErrorMock,\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-payments.js\", () => ({\n getMercadoLibrePaymentDetails: paymentDetailsMock,\n getMercadoLibrePaymentDetailsBatch: paymentDetailsBatchMock,\n}));\n\nimport {\n meliGetPaymentDetailsHandler,\n meliGetPaymentDetailsSchema,\n} from \"../../src/tools/mercadolibre/get-payment-details.js\";\n\ndescribe(\"meli_get_payment_details handler\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(resolveProfileMock).mockResolvedValue({\n ok: true,\n value: { profileId: \"meli-profile-1\" },\n });\n\n vi.mocked(paymentDetailsMock).mockResolvedValue({\n id: 28382111111,\n status: \"approved\",\n status_detail: \"accredited\",\n currency_id: \"ARS\",\n transaction_amount: 100,\n date_created: \"2023-10-27T10:00:00.000-04:00\",\n date_last_updated: \"2023-10-27T10:05:00.000-04:00\",\n payment_method_id: \"credit_card\",\n payment_type_id: \"credit_card\",\n installments: 1,\n description: \"Payment for order #12345\",\n order: {\n id: 1234567890,\n },\n payer: {\n id: 987654321,\n email: \"buyer@example.com\",\n first_name: \"Test\",\n last_name: \"User\",\n type: \"customer\",\n },\n transaction_details: {\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n external_reference: \"order_12345\",\n },\n fee_details: [{ type: \"MERCHANT_FEES\", amount: 5 }],\n } as never);\n\n vi.mocked(paymentDetailsBatchMock).mockResolvedValue({\n successful: [],\n failed: [],\n });\n });\n\n it(\"returns a compact single-payment payload with summary and breakdowns\", async () => {\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"custom-profile\",\n paymentId: \"28382111111\",\n });\n\n expect(resolveProfileMock).toHaveBeenCalledWith(\"custom-profile\");\n expect(paymentDetailsMock).toHaveBeenCalledWith(\"meli-profile-1\", \"28382111111\");\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n metadata: {\n profile_id: \"meli-profile-1\",\n mode: \"single\",\n requested_count: 1,\n successful_count: 1,\n failed_count: 0,\n coverage_complete: true,\n requested_payment_ids: [\"28382111111\"],\n successful_payment_ids: [\"28382111111\"],\n endpoint: \"/v1/payments/{payment_id}\",\n },\n summary: {\n requested_count: 1,\n successful_count: 1,\n failed_count: 0,\n payments_with_order_count: 1,\n payments_without_order_count: 0,\n payments_without_payer_count: 0,\n currency_totals: {\n ARS: {\n count: 1,\n transaction_amount: 100,\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n fee_total: 5,\n },\n },\n status_counts: { approved: 1 },\n payment_method_counts: { credit_card: 1 },\n payment_type_counts: { credit_card: 1 },\n },\n breakdowns: {\n by_currency: [\n {\n currency_id: \"ARS\",\n count: 1,\n transaction_amount: 100,\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n fee_total: 5,\n },\n ],\n by_status: [{ key: \"approved\", count: 1, rate: 1 }],\n by_payment_method: [{ key: \"credit_card\", count: 1, rate: 1 }],\n by_payment_type: [{ key: \"credit_card\", count: 1, rate: 1 }],\n },\n payments_schema: [\n \"payment_id\",\n \"status\",\n \"status_detail\",\n \"currency_id\",\n \"transaction_amount\",\n \"total_paid_amount\",\n \"net_received_amount\",\n \"overpaid_amount\",\n \"payment_method_id\",\n \"payment_type_id\",\n \"installments\",\n \"date_created\",\n \"date_last_updated\",\n \"description\",\n \"order_id\",\n \"payer_id\",\n \"payer_email\",\n \"payer_type\",\n \"payer_first_name\",\n \"payer_last_name\",\n \"fee_count\",\n \"fee_total\",\n \"external_reference\",\n ],\n payments: [\n [\n \"28382111111\",\n \"approved\",\n \"accredited\",\n \"ARS\",\n 100,\n 100,\n 95,\n 0,\n \"credit_card\",\n \"credit_card\",\n 1,\n \"2023-10-27 10:00\",\n \"2023-10-27 10:05\",\n \"Payment for order #12345\",\n \"1234567890\",\n \"987654321\",\n \"buyer@example.com\",\n \"customer\",\n \"Test\",\n \"User\",\n 1,\n 5,\n \"order_12345\",\n ],\n ],\n payment_fee_details_schema: [\"payment_id\", \"fee_type\", \"fee_amount\"],\n payment_fee_details: [[\"28382111111\", \"MERCHANT_FEES\", 5]],\n },\n });\n });\n\n it(\"accepts the exact 250-payment boundary and rejects invalid selector combinations\", () => {\n const exactBoundaryPaymentIds = Array.from({ length: 250 }, (_, index) => `p-${index + 1}`);\n\n expect(\n meliGetPaymentDetailsSchema.safeParse({\n profileId: \"custom-profile\",\n paymentIds: exactBoundaryPaymentIds,\n }).success\n ).toBe(true);\n\n expect(() =>\n meliGetPaymentDetailsSchema.parse({\n profileId: \"custom-profile\",\n })\n ).toThrow(/paymentId|paymentIds/);\n\n expect(() =>\n meliGetPaymentDetailsSchema.parse({\n profileId: \"custom-profile\",\n paymentId: \"28382111111\",\n paymentIds: [\"28382111112\"],\n })\n ).toThrow(/paymentId|paymentIds/);\n\n expect(() =>\n meliGetPaymentDetailsSchema.parse({\n profileId: \"custom-profile\",\n paymentIds: Array.from({ length: 251 }, (_, index) => `p-${index + 1}`),\n })\n ).toThrow(/250/);\n });\n\n it(\"returns the selection payload unchanged when the profile cannot be resolved\", async () => {\n vi.mocked(resolveProfileMock).mockResolvedValue({\n ok: false,\n response: { selection_required: true },\n } as never);\n\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"unknown-profile\",\n paymentId: \"28382111111\",\n });\n\n expect(result).toEqual({ selection_required: true });\n expect(paymentDetailsMock).not.toHaveBeenCalled();\n });\n\n it(\"returns a compact batch payload with partial failures\", async () => {\n vi.mocked(paymentDetailsBatchMock).mockResolvedValue({\n successful: [\n {\n paymentId: \"28382111111\",\n payment: {\n id: 28382111111,\n status: \"approved\",\n status_detail: \"accredited\",\n currency_id: \"ARS\",\n transaction_amount: 100,\n date_created: \"2023-10-27T10:00:00.000-04:00\",\n date_last_updated: \"2023-10-27T10:05:00.000-04:00\",\n payment_method_id: \"credit_card\",\n payment_type_id: \"credit_card\",\n installments: 1,\n order: { id: 1234567890 },\n payer: { id: 987654321, email: \"buyer@example.com\", type: \"customer\" },\n transaction_details: {\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n },\n fee_details: [{ type: \"MERCHANT_FEES\", amount: 5 }],\n },\n },\n {\n paymentId: \"28382111112\",\n payment: {\n id: 28382111112,\n status: \"pending\",\n currency_id: \"USD\",\n transaction_amount: 50,\n date_created: \"2023-10-27T11:00:00.000-04:00\",\n date_last_updated: \"2023-10-27T11:05:00.000-04:00\",\n payment_method_id: \"debit_card\",\n payment_type_id: \"debit_card\",\n installments: 1,\n transaction_details: {\n total_paid_amount: 50,\n net_received_amount: 48,\n overpaid_amount: 0,\n },\n fee_details: [],\n },\n },\n ],\n failed: [\n {\n paymentId: \"28382111113\",\n message: \"formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404\",\n statusCode: 404,\n attempts: 1,\n retryable: false,\n },\n ],\n });\n\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"custom-profile\",\n paymentIds: [\"28382111111\", \"28382111112\", \"28382111113\"],\n });\n\n expect(paymentDetailsBatchMock).toHaveBeenCalledWith(\"meli-profile-1\", [\n \"28382111111\",\n \"28382111112\",\n \"28382111113\",\n ]);\n expect(result).toEqual({\n kind: \"object\",\n payload: expect.objectContaining({\n metadata: expect.objectContaining({\n mode: \"batch\",\n requested_count: 3,\n successful_count: 2,\n failed_count: 1,\n coverage_complete: false,\n requested_payment_ids: [\"28382111111\", \"28382111112\", \"28382111113\"],\n successful_payment_ids: [\"28382111111\", \"28382111112\"],\n failed_payment_ids: [\"28382111113\"],\n }),\n failures: [\n {\n paymentId: \"28382111113\",\n message: \"formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404\",\n statusCode: 404,\n attempts: 1,\n retryable: false,\n },\n ],\n }),\n });\n\n const [firstRow, secondRow] = (result as unknown as {\n payload: { payments: Array<(string | number | null)[]> };\n }).payload.payments;\n\n expect(firstRow).toHaveLength(23);\n expect(secondRow).toHaveLength(23);\n expect(secondRow[2]).toBeNull();\n expect(secondRow[13]).toBeNull();\n expect(secondRow[14]).toBeNull();\n expect(secondRow[15]).toBeNull();\n expect(secondRow[16]).toBeNull();\n expect(secondRow[17]).toBeNull();\n expect(secondRow[18]).toBeNull();\n expect(secondRow[19]).toBeNull();\n expect(secondRow[22]).toBeNull();\n });\n\n it(\"returns a formatted error when the payment lookup fails\", async () => {\n vi.mocked(paymentDetailsMock).mockRejectedValueOnce(\n new Error(\"Request failed with status code 404\")\n );\n\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"custom-profile\",\n paymentId: \"28382111111\",\n });\n\n expect(formatErrorMock).toHaveBeenCalledWith(\n expect.any(Error),\n \"Failed to fetch MercadoLibre payment details\"\n );\n expect(result).toEqual({\n kind: \"error\",\n message:\n \"formatted:Failed to fetch MercadoLibre payment details:Request failed with status code 404\",\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,62 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ const { accessProfileMock, createClientMock, getPaymentMock } = vi.hoisted(() => ({
3
+ accessProfileMock: vi.fn(),
4
+ createClientMock: vi.fn(),
5
+ getPaymentMock: vi.fn()
6
+ }));
7
+ vi.mock("../../src/config/mercadolibre.js", () => ({
8
+ getMercadoLibreAccessForProfile: accessProfileMock
9
+ }));
10
+ vi.mock("../../src/services/mercadolibre/mercadolibre-api.js", () => ({
11
+ createMercadoLibreClient: createClientMock
12
+ }));
13
+ import {
14
+ getMercadoLibrePaymentDetails,
15
+ getMercadoLibrePaymentDetailsBatch
16
+ } from "../../src/services/mercadolibre/mercadolibre-payments.js";
17
+ describe("getMercadoLibrePaymentDetails", () => {
18
+ beforeEach(() => {
19
+ vi.clearAllMocks();
20
+ vi.mocked(accessProfileMock).mockResolvedValue({
21
+ accessToken: "meli-token"
22
+ });
23
+ vi.mocked(createClientMock).mockReturnValue({
24
+ get: getPaymentMock
25
+ });
26
+ });
27
+ it("encodes the payment id in the request path", async () => {
28
+ vi.mocked(getPaymentMock).mockResolvedValueOnce({ data: { id: "ok" } });
29
+ const result = await getMercadoLibrePaymentDetails("meli-profile-1", "pay/ment id?=1");
30
+ expect(accessProfileMock).toHaveBeenCalledWith("meli-profile-1");
31
+ expect(createClientMock).toHaveBeenCalledWith("meli-token", "https://api.mercadopago.com");
32
+ expect(getPaymentMock).toHaveBeenCalledWith("/v1/payments/pay%2Fment%20id%3F%3D1");
33
+ expect(result).toEqual({ id: "ok" });
34
+ });
35
+ it("propagates upstream failures", async () => {
36
+ const upstreamError = new Error("Request failed with status code 401");
37
+ vi.mocked(getPaymentMock).mockRejectedValueOnce(upstreamError);
38
+ await expect(
39
+ getMercadoLibrePaymentDetails("meli-profile-1", "28382111111")
40
+ ).rejects.toBe(upstreamError);
41
+ });
42
+ it("chunks payment batches in groups of 50", async () => {
43
+ vi.mocked(getPaymentMock).mockImplementation(async (path) => ({
44
+ data: { id: path.split("/").pop() }
45
+ }));
46
+ const paymentIds = Array.from({ length: 101 }, (_, index) => `pay-${index + 1}`);
47
+ const originalAllSettled = Promise.allSettled.bind(Promise);
48
+ const allSettledSpy = vi.spyOn(Promise, "allSettled").mockImplementation(((iterable) => originalAllSettled(iterable)));
49
+ const result = await getMercadoLibrePaymentDetailsBatch("meli-profile-1", paymentIds);
50
+ expect(accessProfileMock).toHaveBeenCalledWith("meli-profile-1");
51
+ expect(allSettledSpy).toHaveBeenCalledTimes(3);
52
+ expect(allSettledSpy.mock.calls[0]?.[0]).toHaveLength(50);
53
+ expect(allSettledSpy.mock.calls[1]?.[0]).toHaveLength(50);
54
+ expect(allSettledSpy.mock.calls[2]?.[0]).toHaveLength(1);
55
+ expect(result.successful).toHaveLength(101);
56
+ expect(result.failed).toHaveLength(0);
57
+ expect(result.successful[0]).toEqual({ paymentId: "pay-1", payment: { id: "pay-1" } });
58
+ expect(result.successful[100]).toEqual({ paymentId: "pay-101", payment: { id: "pay-101" } });
59
+ allSettledSpy.mockRestore();
60
+ });
61
+ });
62
+ //# sourceMappingURL=mercadolibre-payments.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/meli/mercadolibre-payments.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst { accessProfileMock, createClientMock, getPaymentMock } = vi.hoisted(() => ({\n accessProfileMock: vi.fn(),\n createClientMock: vi.fn(),\n getPaymentMock: vi.fn(),\n}));\n\nvi.mock(\"../../src/config/mercadolibre.js\", () => ({\n getMercadoLibreAccessForProfile: accessProfileMock,\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-api.js\", () => ({\n createMercadoLibreClient: createClientMock,\n}));\n\nimport {\n getMercadoLibrePaymentDetails,\n getMercadoLibrePaymentDetailsBatch,\n} from \"../../src/services/mercadolibre/mercadolibre-payments.js\";\n\ndescribe(\"getMercadoLibrePaymentDetails\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(accessProfileMock).mockResolvedValue({\n accessToken: \"meli-token\",\n });\n\n vi.mocked(createClientMock).mockReturnValue({\n get: getPaymentMock,\n } as never);\n });\n\n it(\"encodes the payment id in the request path\", async () => {\n vi.mocked(getPaymentMock).mockResolvedValueOnce({ data: { id: \"ok\" } });\n\n const result = await getMercadoLibrePaymentDetails(\"meli-profile-1\", \"pay/ment id?=1\");\n\n expect(accessProfileMock).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(createClientMock).toHaveBeenCalledWith(\"meli-token\", \"https://api.mercadopago.com\");\n expect(getPaymentMock).toHaveBeenCalledWith(\"/v1/payments/pay%2Fment%20id%3F%3D1\");\n expect(result).toEqual({ id: \"ok\" });\n });\n\n it(\"propagates upstream failures\", async () => {\n const upstreamError = new Error(\"Request failed with status code 401\");\n vi.mocked(getPaymentMock).mockRejectedValueOnce(upstreamError);\n\n await expect(\n getMercadoLibrePaymentDetails(\"meli-profile-1\", \"28382111111\")\n ).rejects.toBe(upstreamError);\n });\n\n it(\"chunks payment batches in groups of 50\", async () => {\n vi.mocked(getPaymentMock).mockImplementation(async (path: string) => ({\n data: { id: path.split(\"/\").pop() },\n }));\n\n const paymentIds = Array.from({ length: 101 }, (_, index) => `pay-${index + 1}`);\n const originalAllSettled = Promise.allSettled.bind(Promise);\n const allSettledSpy = vi\n .spyOn(Promise, \"allSettled\")\n .mockImplementation(((iterable: Iterable<PromiseLike<unknown> | unknown>) =>\n originalAllSettled(iterable)) as typeof Promise.allSettled);\n\n const result = await getMercadoLibrePaymentDetailsBatch(\"meli-profile-1\", paymentIds);\n\n expect(accessProfileMock).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(allSettledSpy).toHaveBeenCalledTimes(3);\n expect(allSettledSpy.mock.calls[0]?.[0]).toHaveLength(50);\n expect(allSettledSpy.mock.calls[1]?.[0]).toHaveLength(50);\n expect(allSettledSpy.mock.calls[2]?.[0]).toHaveLength(1);\n expect(result.successful).toHaveLength(101);\n expect(result.failed).toHaveLength(0);\n expect(result.successful[0]).toEqual({ paymentId: \"pay-1\", payment: { id: \"pay-1\" } });\n expect(result.successful[100]).toEqual({ paymentId: \"pay-101\", payment: { id: \"pay-101\" } });\n\n allSettledSpy.mockRestore();\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,YAAY,UAAU,QAAQ,IAAI,UAAU;AAErD,MAAM,EAAE,mBAAmB,kBAAkB,eAAe,IAAI,GAAG,QAAQ,OAAO;AAAA,EAChF,mBAAmB,GAAG,GAAG;AAAA,EACzB,kBAAkB,GAAG,GAAG;AAAA,EACxB,gBAAgB,GAAG,GAAG;AACxB,EAAE;AAEF,GAAG,KAAK,oCAAoC,OAAO;AAAA,EACjD,iCAAiC;AACnC,EAAE;AAEF,GAAG,KAAK,uDAAuD,OAAO;AAAA,EACpE,0BAA0B;AAC5B,EAAE;AAEF;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iCAAiC,MAAM;AAC9C,aAAW,MAAM;AACf,OAAG,cAAc;AAEjB,OAAG,OAAO,iBAAiB,EAAE,kBAAkB;AAAA,MAC7C,aAAa;AAAA,IACf,CAAC;AAED,OAAG,OAAO,gBAAgB,EAAE,gBAAgB;AAAA,MAC1C,KAAK;AAAA,IACP,CAAU;AAAA,EACZ,CAAC;AAED,KAAG,8CAA8C,YAAY;AAC3D,OAAG,OAAO,cAAc,EAAE,sBAAsB,EAAE,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;AAEtE,UAAM,SAAS,MAAM,8BAA8B,kBAAkB,gBAAgB;AAErF,WAAO,iBAAiB,EAAE,qBAAqB,gBAAgB;AAC/D,WAAO,gBAAgB,EAAE,qBAAqB,cAAc,6BAA6B;AACzF,WAAO,cAAc,EAAE,qBAAqB,qCAAqC;AACjF,WAAO,MAAM,EAAE,QAAQ,EAAE,IAAI,KAAK,CAAC;AAAA,EACrC,CAAC;AAED,KAAG,gCAAgC,YAAY;AAC7C,UAAM,gBAAgB,IAAI,MAAM,qCAAqC;AACrE,OAAG,OAAO,cAAc,EAAE,sBAAsB,aAAa;AAE7D,UAAM;AAAA,MACJ,8BAA8B,kBAAkB,aAAa;AAAA,IAC/D,EAAE,QAAQ,KAAK,aAAa;AAAA,EAC9B,CAAC;AAED,KAAG,0CAA0C,YAAY;AACvD,OAAG,OAAO,cAAc,EAAE,mBAAmB,OAAO,UAAkB;AAAA,MACpE,MAAM,EAAE,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,EAAE;AAAA,IACpC,EAAE;AAEF,UAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,CAAC,GAAG,UAAU,OAAO,QAAQ,CAAC,EAAE;AAC/E,UAAM,qBAAqB,QAAQ,WAAW,KAAK,OAAO;AAC1D,UAAM,gBAAgB,GACnB,MAAM,SAAS,YAAY,EAC3B,oBAAoB,CAAC,aACpB,mBAAmB,QAAQ,EAA+B;AAE9D,UAAM,SAAS,MAAM,mCAAmC,kBAAkB,UAAU;AAEpF,WAAO,iBAAiB,EAAE,qBAAqB,gBAAgB;AAC/D,WAAO,aAAa,EAAE,sBAAsB,CAAC;AAC7C,WAAO,cAAc,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE;AACxD,WAAO,cAAc,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE;AACxD,WAAO,cAAc,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC;AACvD,WAAO,OAAO,UAAU,EAAE,aAAa,GAAG;AAC1C,WAAO,OAAO,MAAM,EAAE,aAAa,CAAC;AACpC,WAAO,OAAO,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,SAAS,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;AACrF,WAAO,OAAO,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAE,WAAW,WAAW,SAAS,EAAE,IAAI,UAAU,EAAE,CAAC;AAE3F,kBAAc,YAAY;AAAA,EAC5B,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,90 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { describe, expect, it } from "vitest";
3
+ describe("MercadoLibre Product Ads ad-groups MCP surface", () => {
4
+ it("registers the public tool and rejects invalid calendar dates through MCP tools/call", async () => {
5
+ const previousNodeEnv = process.env.NODE_ENV;
6
+ const previousTelemetry = process.env.MCP_USE_ANONYMIZED_TELEMETRY;
7
+ process.env.NODE_ENV = "production";
8
+ process.env.MCP_USE_ANONYMIZED_TELEMETRY = "false";
9
+ try {
10
+ const [{ MCPServer }, { MCPClient }, toolModule] = await Promise.all([
11
+ import("mcp-use/server"),
12
+ import("mcp-use"),
13
+ import("../../src/tools/mercadolibre/search-product-ads-ad-groups.js")
14
+ ]);
15
+ const server = new MCPServer({
16
+ name: "test-meli-product-ads-ad-groups-server",
17
+ version: "1.0.0",
18
+ baseUrl: "http://localhost:3000"
19
+ });
20
+ server.tool(
21
+ {
22
+ name: "meli_search_product_ads_ad_groups",
23
+ description: "Search MercadoLibre Product Ads ad groups.",
24
+ schema: toolModule.meliSearchProductAdsAdGroupsSchema,
25
+ annotations: {
26
+ readOnlyHint: true,
27
+ destructiveHint: false,
28
+ openWorldHint: true
29
+ }
30
+ },
31
+ async (params) => toolModule.meliSearchProductAdsAdGroupsHandler(params)
32
+ );
33
+ const handler = await server.getHandler();
34
+ const client = new MCPClient({
35
+ mcpServers: {
36
+ local: {
37
+ url: "http://localhost:3000/mcp",
38
+ transport: "http",
39
+ fetch: (input, init) => handler(input instanceof Request ? init === void 0 ? input : new Request(input, init) : new Request(input, init))
40
+ }
41
+ }
42
+ });
43
+ try {
44
+ const session = await client.createSession("local");
45
+ const tools = await session.listTools();
46
+ const tool = tools.find((candidate) => candidate.name === "meli_search_product_ads_ad_groups");
47
+ expect(tool).toEqual(
48
+ expect.objectContaining({
49
+ name: "meli_search_product_ads_ad_groups",
50
+ inputSchema: expect.objectContaining({
51
+ properties: expect.objectContaining({
52
+ dateFrom: expect.any(Object),
53
+ dateTo: expect.any(Object),
54
+ filters: expect.any(Object)
55
+ })
56
+ })
57
+ })
58
+ );
59
+ expect(JSON.stringify(tool?.inputSchema)).toContain("campaigns");
60
+ expect(JSON.stringify(tool?.inputSchema)).toContain("statuses");
61
+ const result = await session.callTool("meli_search_product_ads_ad_groups", {
62
+ profileId: "triplim",
63
+ siteId: "MLA",
64
+ advertiserId: "89015",
65
+ dateFrom: "2026-02-30",
66
+ dateTo: "2026-03-01"
67
+ });
68
+ expect(result.isError).toBe(true);
69
+ expect(JSON.stringify(result.content)).toContain("valid calendar date");
70
+ } finally {
71
+ await client.closeAllSessions();
72
+ await server.close();
73
+ }
74
+ } finally {
75
+ if (previousNodeEnv === void 0) delete process.env.NODE_ENV;
76
+ else process.env.NODE_ENV = previousNodeEnv;
77
+ if (previousTelemetry === void 0) delete process.env.MCP_USE_ANONYMIZED_TELEMETRY;
78
+ else process.env.MCP_USE_ANONYMIZED_TELEMETRY = previousTelemetry;
79
+ }
80
+ });
81
+ it("keeps the registered public tool wired to the exported schema and handler", async () => {
82
+ const serverSource = await readFile(new URL("../../index.ts", import.meta.url), "utf8");
83
+ const registrationStart = serverSource.indexOf('name: "meli_search_product_ads_ad_groups"');
84
+ expect(registrationStart, "meli_search_product_ads_ad_groups registration exists").toBeGreaterThan(-1);
85
+ const registration = serverSource.slice(registrationStart, registrationStart + 700);
86
+ expect(registration).toContain("schema: meliSearchProductAdsAdGroupsSchema");
87
+ expect(registration).toContain("meliSearchProductAdsAdGroupsHandler");
88
+ });
89
+ });
90
+ //# sourceMappingURL=mercadolibre-product-ads-ad-groups-surface.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../tests/meli/mercadolibre-product-ads-ad-groups-surface.test.ts"],
4
+ "sourcesContent": ["import { readFile } from \"node:fs/promises\";\nimport { describe, expect, it } from \"vitest\";\n\ndescribe(\"MercadoLibre Product Ads ad-groups MCP surface\", () => {\n it(\"registers the public tool and rejects invalid calendar dates through MCP tools/call\", async () => {\n const previousNodeEnv = process.env.NODE_ENV;\n const previousTelemetry = process.env.MCP_USE_ANONYMIZED_TELEMETRY;\n\n process.env.NODE_ENV = \"production\";\n process.env.MCP_USE_ANONYMIZED_TELEMETRY = \"false\";\n\n try {\n const [{ MCPServer }, { MCPClient }, toolModule] = await Promise.all([\n import(\"mcp-use/server\"),\n import(\"mcp-use\"),\n import(\"../../src/tools/mercadolibre/search-product-ads-ad-groups.js\"),\n ]);\n const server = new MCPServer({\n name: \"test-meli-product-ads-ad-groups-server\",\n version: \"1.0.0\",\n baseUrl: \"http://localhost:3000\",\n });\n\n server.tool(\n {\n name: \"meli_search_product_ads_ad_groups\",\n description: \"Search MercadoLibre Product Ads ad groups.\",\n schema: toolModule.meliSearchProductAdsAdGroupsSchema,\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n openWorldHint: true,\n },\n },\n async (params) => toolModule.meliSearchProductAdsAdGroupsHandler(params)\n );\n\n const handler = await server.getHandler();\n const client = new MCPClient({\n mcpServers: {\n local: {\n url: \"http://localhost:3000/mcp\",\n transport: \"http\",\n fetch: (input: Request | URL | string, init?: RequestInit) =>\n handler(input instanceof Request ? (init === undefined ? input : new Request(input, init)) : new Request(input, init)),\n },\n },\n });\n\n try {\n const session = await client.createSession(\"local\");\n const tools = await session.listTools();\n const tool = tools.find((candidate) => candidate.name === \"meli_search_product_ads_ad_groups\");\n\n expect(tool).toEqual(\n expect.objectContaining({\n name: \"meli_search_product_ads_ad_groups\",\n inputSchema: expect.objectContaining({\n properties: expect.objectContaining({\n dateFrom: expect.any(Object),\n dateTo: expect.any(Object),\n filters: expect.any(Object),\n }),\n }),\n })\n );\n expect(JSON.stringify(tool?.inputSchema)).toContain(\"campaigns\");\n expect(JSON.stringify(tool?.inputSchema)).toContain(\"statuses\");\n\n const result = await session.callTool(\"meli_search_product_ads_ad_groups\", {\n profileId: \"triplim\",\n siteId: \"MLA\",\n advertiserId: \"89015\",\n dateFrom: \"2026-02-30\",\n dateTo: \"2026-03-01\",\n });\n\n expect(result.isError).toBe(true);\n expect(JSON.stringify(result.content)).toContain(\"valid calendar date\");\n } finally {\n await client.closeAllSessions();\n await server.close();\n }\n } finally {\n if (previousNodeEnv === undefined) delete process.env.NODE_ENV;\n else process.env.NODE_ENV = previousNodeEnv;\n\n if (previousTelemetry === undefined) delete process.env.MCP_USE_ANONYMIZED_TELEMETRY;\n else process.env.MCP_USE_ANONYMIZED_TELEMETRY = previousTelemetry;\n }\n });\n\n it(\"keeps the registered public tool wired to the exported schema and handler\", async () => {\n const serverSource = await readFile(new URL(\"../../index.ts\", import.meta.url), \"utf8\");\n const registrationStart = serverSource.indexOf('name: \"meli_search_product_ads_ad_groups\"');\n\n expect(registrationStart, \"meli_search_product_ads_ad_groups registration exists\").toBeGreaterThan(-1);\n\n const registration = serverSource.slice(registrationStart, registrationStart + 700);\n expect(registration).toContain(\"schema: meliSearchProductAdsAdGroupsSchema\");\n expect(registration).toContain(\"meliSearchProductAdsAdGroupsHandler\");\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }