@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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../tests/meli/mercadolibre-tool-handlers-small.test.ts"],
4
- "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { meliGetAccountContextHandler } from \"../../src/tools/mercadolibre/get-account-context.js\";\nimport { meliValidateConnectionHandler } from \"../../src/tools/mercadolibre/validate-connection.js\";\nimport { meliPredictCategoryHandler } from \"../../src/tools/mercadolibre/predict-category.js\";\nimport { meliGetCategoryRequirementsHandler } from \"../../src/tools/mercadolibre/get-category-requirements.js\";\nimport { meliEstimateListingFeeHandler } from \"../../src/tools/mercadolibre/estimate-listing-fee.js\";\nimport { meliGetSiteCategoriesAndListingTypesHandler } from \"../../src/tools/mercadolibre/get-site-categories-and-listing-types.js\";\nimport { meliGetItemDetailsHandler } from \"../../src/tools/mercadolibre/get-item-details.js\";\nimport { meliSearchQuestionsHandler } from \"../../src/tools/mercadolibre/search-questions.js\";\nimport { meliAnswerQuestionHandler } from \"../../src/tools/mercadolibre/answer-question.js\";\nimport { meliGetListingQualityHandler } from \"../../src/tools/mercadolibre/get-listing-quality.js\";\nimport { meliGetItemVisitsHandler } from \"../../src/tools/mercadolibre/get-item-visits.js\";\nimport { resolveMercadoLibreProfileOrSelection } from \"../../src/tools/mercadolibre/profile-resolution.js\";\nimport {\n buildMercadoLibreWriteSuccessResponse,\n handleMercadoLibreWriteError,\n resolveMercadoLibreWriteProfile,\n} from \"../../src/tools/mercadolibre/write-helpers.js\";\nimport { getMercadoLibreAccessForProfile } from \"../../src/config/mercadolibre.js\";\nimport { getMercadoLibreConnectionRow } from \"../../src/config/mercadolibre-profile-store.js\";\nimport {\n buildMercadoLibrePaginationMetadata,\n formatMercadoLibreError,\n getMercadoLibreUsersMe,\n normalizeMercadoLibrePaging,\n} from \"../../src/services/mercadolibre/mercadolibre-api.js\";\nimport {\n getMercadoLibreCategoryAttributes,\n getMercadoLibreCategoryShippingPreferences,\n getMercadoLibreItemDetailsBatch,\n getMercadoLibreItemDetailsWithFallbackBatch,\n getMercadoLibreItemPerformance,\n getMercadoLibreItemVisitsWindow,\n getMercadoLibreSiteCategoriesAndListingTypes,\n getMercadoLibreUserItemsVisits,\n searchMercadoLibreDomainDiscovery,\n} from \"../../src/services/mercadolibre/mercadolibre-items.js\";\nimport {\n answerMercadoLibreQuestion,\n searchMercadoLibreQuestions,\n} from \"../../src/services/mercadolibre/mercadolibre-questions.js\";\nimport { buildMercadoLibreListingFeeEstimate } from \"../../src/tools/mercadolibre/listing-fee-helpers.js\";\n\nvi.mock(\"mcp-use/server\", () => ({\n object: vi.fn((payload: unknown) => ({ kind: \"object\", payload })),\n error: vi.fn((message: string) => ({ kind: \"error\", message })),\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/profile-resolution.js\", () => ({\n resolveMercadoLibreProfileOrSelection: vi.fn(),\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/write-helpers.js\", async () => {\n const { z } = await import(\"zod\");\n\n return {\n mercadolibreProfileIdSchemaField: z.string().optional(),\n resolveMercadoLibreWriteProfile: vi.fn(),\n buildMercadoLibreWriteSuccessResponse: vi.fn((payload: unknown) => ({ kind: \"success\", payload })),\n handleMercadoLibreWriteError: vi.fn(\n (err: unknown, fallback: string) => ({\n kind: \"error\",\n message: `write:${fallback}:${err instanceof Error ? err.message : String(err)}`,\n })\n ),\n };\n});\n\nvi.mock(\"../../src/config/mercadolibre.js\", () => ({\n getMercadoLibreAccessForProfile: vi.fn(),\n}));\n\nvi.mock(\"../../src/config/mercadolibre-profile-store.js\", () => ({\n getMercadoLibreConnectionRow: vi.fn(),\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-api.js\", () => ({\n getMercadoLibreUsersMe: vi.fn(),\n formatMercadoLibreError: vi.fn(\n (err: unknown, fallback: string) =>\n `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`\n ),\n normalizeMercadoLibrePaging: vi.fn((paging: unknown) => paging),\n buildMercadoLibrePaginationMetadata: vi.fn((metadata: unknown) => metadata),\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-items.js\", () => ({\n searchMercadoLibreDomainDiscovery: vi.fn(),\n getMercadoLibreCategoryAttributes: vi.fn(),\n getMercadoLibreCategoryShippingPreferences: vi.fn(),\n getMercadoLibreSiteCategoriesAndListingTypes: vi.fn(),\n getMercadoLibreItemDetailsBatch: vi.fn(),\n getMercadoLibreItemDetailsWithFallbackBatch: vi.fn(),\n getMercadoLibreItemPerformance: vi.fn(),\n getMercadoLibreItemVisitsWindow: vi.fn(),\n getMercadoLibreUserItemsVisits: vi.fn(),\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-questions.js\", () => ({\n searchMercadoLibreQuestions: vi.fn(),\n answerMercadoLibreQuestion: vi.fn(),\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/listing-fee-helpers.js\", () => ({\n buildMercadoLibreListingFeeEstimate: vi.fn(),\n}));\n\ndescribe(\"MercadoLibre small and medium tool handlers\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(resolveMercadoLibreProfileOrSelection).mockResolvedValue({\n ok: true,\n value: { profileId: \"meli-profile-1\" },\n });\n\n vi.mocked(resolveMercadoLibreWriteProfile).mockResolvedValue({\n ok: true,\n value: { profileId: \"meli-profile-1\" },\n });\n\n vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({\n sellerId: \"seller-99\",\n scopes: [\"read\", \"write\"],\n expiresAt: \"2026-07-01T00:00:00.000Z\",\n } as never);\n\n vi.mocked(getMercadoLibreUsersMe).mockResolvedValue({\n id: 12345,\n nickname: \"meli-store\",\n } as never);\n\n vi.mocked(buildMercadoLibrePaginationMetadata).mockImplementation((metadata) => metadata as never);\n vi.mocked(normalizeMercadoLibrePaging).mockImplementation((paging) => paging as never);\n });\n\n it(\"returns MercadoLibre account context with resolved profile access\", async () => {\n const result = await meliGetAccountContextHandler({ profileId: \"custom-profile\" });\n\n expect(resolveMercadoLibreProfileOrSelection).toHaveBeenCalledWith(\"custom-profile\");\n expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(getMercadoLibreUsersMe).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n seller_id: \"seller-99\",\n nickname: \"meli-store\",\n account_id: 12345,\n scopes: [\"read\", \"write\"],\n expires_at: \"2026-07-01T00:00:00.000Z\",\n },\n });\n });\n\n it(\"returns profile selection payload unchanged for read handlers\", async () => {\n vi.mocked(resolveMercadoLibreProfileOrSelection).mockResolvedValue({\n ok: false,\n response: { selection_required: true },\n } as never);\n\n const result = await meliGetAccountContextHandler({ profileId: undefined });\n\n expect(result).toEqual({ selection_required: true });\n expect(getMercadoLibreAccessForProfile).not.toHaveBeenCalled();\n });\n\n it(\"validates connection and reports refresh detection\", async () => {\n vi.mocked(getMercadoLibreConnectionRow)\n .mockResolvedValueOnce({\n expiresAt: new Date(\"2026-06-01T00:00:00.000Z\"),\n encryptedAccessToken: \"old-token\",\n } as never)\n .mockResolvedValueOnce({\n status: \"active\",\n expiresAt: new Date(\"2026-07-01T00:00:00.000Z\"),\n encryptedAccessToken: \"new-token\",\n } as never);\n\n const result = await meliValidateConnectionHandler({ profileId: \"meli-profile-1\" });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n validation_status: \"active\",\n refreshed: true,\n seller_id: \"seller-99\",\n account_id: 12345,\n nickname: \"meli-store\",\n expires_at: \"2026-07-01T00:00:00.000Z\",\n scopes: [\"read\", \"write\"],\n },\n });\n });\n\n it(\"predicts categories with normalized candidate payloads and defaults\", async () => {\n vi.mocked(searchMercadoLibreDomainDiscovery).mockResolvedValue([\n {\n category_id: \"MLA123\",\n category_name: \"Sneakers\",\n domain_id: \"MLA-SNEAKERS\",\n domain_name: \"Sneakers\",\n attributes_matched: \"4\",\n },\n ] as never);\n\n const result = await meliPredictCategoryHandler({\n profileId: \"meli-profile-1\",\n query: \"running shoes\",\n });\n\n expect(searchMercadoLibreDomainDiscovery).toHaveBeenCalledWith(\n \"meli-profile-1\",\n \"running shoes\",\n 5,\n \"MLA\"\n );\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n query: \"running shoes\",\n site_id: \"MLA\",\n candidates: [\n {\n category_id: \"MLA123\",\n category_name: \"Sneakers\",\n domain_id: \"MLA-SNEAKERS\",\n domain_name: \"Sneakers\",\n attributes_matched: 4,\n },\n ],\n },\n });\n });\n\n it(\"splits required and recommended category requirements\", async () => {\n vi.mocked(getMercadoLibreCategoryAttributes).mockResolvedValue([\n {\n id: \"BRAND\",\n name: \"Brand\",\n value_type: \"string\",\n value_max_length: 255,\n tags: { required: true },\n },\n {\n id: \"MODEL\",\n name: \"Model\",\n value_type: \"string\",\n tags: {},\n },\n ] as never);\n vi.mocked(getMercadoLibreCategoryShippingPreferences).mockResolvedValue({\n mode: \"me2\",\n logistic_types: [\"drop_off\"],\n } as never);\n\n const result = await meliGetCategoryRequirementsHandler({\n profileId: \"meli-profile-1\",\n categoryId: \"MLA999\",\n });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n category_id: \"MLA999\",\n required_attributes: [\n {\n id: \"BRAND\",\n name: \"Brand\",\n value_type: \"string\",\n value_max_length: 255,\n },\n ],\n recommended_attributes: [\n {\n id: \"MODEL\",\n name: \"Model\",\n value_type: \"string\",\n },\n ],\n shipping_preferences: {\n mode: \"me2\",\n logistics: [\"drop_off\"],\n },\n },\n });\n });\n\n it(\"delegates listing fee estimation with the resolved profile\", async () => {\n vi.mocked(buildMercadoLibreListingFeeEstimate).mockResolvedValue({\n profile_id: \"meli-profile-1\",\n fee_amount: 1234,\n site_id: null,\n } as never);\n\n const result = await meliEstimateListingFeeHandler({\n profileId: \"meli-profile-1\",\n itemId: \"MLA1\",\n query: \"running shoes\",\n price: 10000,\n categoryId: \"MLA123\",\n listingTypeId: \"gold_special\",\n shippingMode: \"me2\",\n logisticType: \"drop_off\",\n billableWeight: 1200,\n currencyId: \"ARS\",\n tags: [\"test-tag\"],\n });\n\n expect(buildMercadoLibreListingFeeEstimate).toHaveBeenCalledWith({\n profileId: \"meli-profile-1\",\n itemId: \"MLA1\",\n query: \"running shoes\",\n price: 10000,\n categoryId: \"MLA123\",\n listingTypeId: \"gold_special\",\n shippingMode: \"me2\",\n logisticType: \"drop_off\",\n billableWeight: 1200,\n currencyId: \"ARS\",\n tags: [\"test-tag\"],\n });\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n fee_amount: 1234,\n },\n });\n });\n\n it(\"combines site categories and listing types metadata\", async () => {\n vi.mocked(getMercadoLibreSiteCategoriesAndListingTypes).mockResolvedValue({\n siteId: \"MLA\",\n categories: [{ id: \"MLA1\", name: \"Shoes\" }],\n listingTypes: [{ id: \"gold_special\", name: \"Cl\u00E1sica\" }],\n } as never);\n\n const result = await meliGetSiteCategoriesAndListingTypesHandler({ profileId: \"meli-profile-1\" });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n site_id: \"MLA\",\n categories: [{ id: \"MLA1\", name: \"Shoes\" }],\n listing_types: [{ id: \"gold_special\", name: \"Cl\u00E1sica\" }],\n metadata: {\n site_id: \"MLA\",\n categories_count: 1,\n listing_types_count: 1,\n pagination: \"No aplica. La tool consolida dos endpoints de cat\u00E1logo del sitio MLA en una sola respuesta.\",\n },\n },\n });\n });\n\n it(\"returns item details directly from multiget when all requested ids are found\", async () => {\n vi.mocked(getMercadoLibreItemDetailsBatch).mockResolvedValue([\n { id: \"MLA1\", title: \"Boots\", pictures: [{ id: \"1\" }], status: \"active\" },\n { id: \"MLA2\", title: \"Sneakers\", pictures: [{ id: \"2\" }], status: \"paused\" },\n ] as never);\n\n const result = await meliGetItemDetailsHandler({\n profileId: \"meli-profile-1\",\n itemIds: [\"MLA1\", \"MLA1\", \"MLA2\"],\n });\n\n expect(getMercadoLibreItemDetailsBatch).toHaveBeenCalledWith(\"meli-profile-1\", [\"MLA1\", \"MLA2\"]);\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n metadata: {\n profile_id: \"meli-profile-1\",\n requested: 2,\n successful: 2,\n failed: 0,\n source: \"items_multiget\",\n },\n items: [\n { id: \"MLA1\", title: \"Boots\", status: \"active\" },\n { id: \"MLA2\", title: \"Sneakers\", status: \"paused\" },\n ],\n },\n });\n });\n\n it(\"falls back to item-by-item details when multiget coverage is partial\", async () => {\n vi.mocked(getMercadoLibreItemDetailsBatch).mockResolvedValue([{ id: \"MLA1\", title: \"Boots\" }] as never);\n vi.mocked(getMercadoLibreItemDetailsWithFallbackBatch).mockResolvedValue({\n successful: [\n {\n id: \"MLA1\",\n document: { id: \"MLA1\", title: \"Boots\" },\n },\n ],\n failed: [\n {\n id: \"MLA2\",\n message: \"not found\",\n statusCode: 404,\n attempts: 2,\n retryable: false,\n },\n ],\n } as never);\n\n const result = await meliGetItemDetailsHandler({\n profileId: \"meli-profile-1\",\n itemIds: [\"MLA1\", \"MLA2\"],\n });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n metadata: {\n profile_id: \"meli-profile-1\",\n requested: 2,\n successful: 1,\n failed: 1,\n has_failures: true,\n source: \"item_by_item_fallback\",\n },\n items: [{ id: \"MLA1\", title: \"Boots\" }],\n failures: [\n {\n item_id: \"MLA2\",\n message: \"not found\",\n status_code: 404,\n attempts: 2,\n retryable: false,\n },\n ],\n },\n });\n });\n\n it(\"searches questions with seller context and normalized pagination\", async () => {\n vi.mocked(searchMercadoLibreQuestions).mockResolvedValue({\n questions: [\n {\n id: 777,\n item_id: \"MLA1\",\n item: { title: \"Boots\" },\n status: \"unanswered\",\n text: \"Do you ship today?\",\n date_created: \"2026-03-10T14:45:55.000Z\",\n from: { id: 555, nickname: \"buyer\" },\n answer: { status: \"not_answered\" },\n },\n ],\n paging: { total: 1, limit: 20, offset: 0 },\n } as never);\n\n const result = await meliSearchQuestionsHandler({ profileId: \"meli-profile-1\" });\n\n expect(searchMercadoLibreQuestions).toHaveBeenCalledWith(\"meli-profile-1\", {\n sellerId: \"seller-99\",\n itemId: undefined,\n status: undefined,\n limit: 20,\n offset: 0,\n });\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n metadata: {\n total: 1,\n limit: 20,\n offset: 0,\n returned: 1,\n nextField: \"offset\",\n },\n questions: [\n {\n question_id: 777,\n item_id: \"MLA1\",\n item_title: \"Boots\",\n status: \"unanswered\",\n text: \"Do you ship today?\",\n date_created: \"2026-03-10 14:45\",\n from: { id: \"\", nickname: \"buyer\" },\n answer_status: \"not_answered\",\n },\n ],\n },\n });\n });\n\n it(\"routes question answers through write helpers\", async () => {\n vi.mocked(answerMercadoLibreQuestion).mockResolvedValue({ id: 777, status: \"answered\" } as never);\n\n const result = await meliAnswerQuestionHandler({\n profileId: \"meli-profile-1\",\n questionId: 777,\n text: \"Yes, we can ship today.\",\n });\n\n expect(resolveMercadoLibreWriteProfile).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(answerMercadoLibreQuestion).toHaveBeenCalledWith(\n \"meli-profile-1\",\n 777,\n \"Yes, we can ship today.\"\n );\n expect(buildMercadoLibreWriteSuccessResponse).toHaveBeenCalledWith({\n profileId: \"meli-profile-1\",\n operation: \"answer_question\",\n resourceId: \"777\",\n message: \"MercadoLibre question answered successfully.\",\n after: { id: 777, status: \"answered\" },\n });\n expect(result).toEqual({\n kind: \"success\",\n payload: {\n profileId: \"meli-profile-1\",\n operation: \"answer_question\",\n resourceId: \"777\",\n message: \"MercadoLibre question answered successfully.\",\n after: { id: 777, status: \"answered\" },\n },\n });\n });\n\n it(\"formats listing quality summaries with warning normalization\", async () => {\n vi.mocked(getMercadoLibreItemPerformance).mockResolvedValue({\n score: \"85\",\n status: \"healthy\",\n health: \"good\",\n sales: 20,\n visits: 300,\n warnings: [{ id: \"photo\", text: \"Add more photos\", severity: \"medium\" }],\n item: { title: \"Boots\", status: \"active\" },\n } as never);\n\n const result = await meliGetListingQualityHandler({\n profileId: \"meli-profile-1\",\n itemId: \"MLA1\",\n });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n item_id: \"MLA1\",\n quality_score: 85,\n level: \"healthy\",\n health: \"good\",\n sales: 20,\n visits: 300,\n warnings: [\n {\n type: \"photo\",\n message: \"Add more photos\",\n severity: \"medium\",\n },\n ],\n raw_summary: {\n title: \"Boots\",\n status: \"active\",\n },\n },\n });\n });\n\n it(\"returns item-level visits windows when item ids are provided\", async () => {\n vi.mocked(getMercadoLibreItemVisitsWindow).mockResolvedValue({\n total_visits: 14,\n results: [{ date: \"2026-03-10\", visits: 14 }],\n } as never);\n\n const result = await meliGetItemVisitsHandler({\n profileId: \"meli-profile-1\",\n itemIds: [\"MLA1\", \"MLA1\"],\n last: 7,\n ending: \"2026-03-10\",\n });\n\n expect(getMercadoLibreItemVisitsWindow).toHaveBeenCalledTimes(1);\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n seller_id: \"seller-99\",\n total_visits: 14,\n items: [\n {\n item_id: \"MLA1\",\n total_visits: 14,\n last: 7,\n unit: \"day\",\n ending: \"2026-03-10\",\n time_window: [{ date: \"2026-03-10\", visits: 14 }],\n },\n ],\n },\n });\n });\n\n it(\"returns a validation error when visits are requested without item ids or date range\", async () => {\n const result = await meliGetItemVisitsHandler({ profileId: \"meli-profile-1\" });\n\n expect(result).toEqual({\n kind: \"error\",\n message: \"Provide itemIds, or provide both startDate and endDate for seller-level visits.\",\n });\n expect(getMercadoLibreUserItemsVisits).not.toHaveBeenCalled();\n });\n\n it(\"returns seller-level visits when a date range is provided\", async () => {\n vi.mocked(getMercadoLibreUserItemsVisits).mockResolvedValue({\n results: [\n { item_id: \"MLA1\", total_visits: 10 },\n { id: \"MLA2\", visits: 4 },\n ],\n } as never);\n\n const result = await meliGetItemVisitsHandler({\n profileId: \"meli-profile-1\",\n startDate: \"2026-03-01\",\n endDate: \"2026-03-10\",\n });\n\n expect(getMercadoLibreUserItemsVisits).toHaveBeenCalledWith(\n \"meli-profile-1\",\n \"seller-99\",\n \"2026-03-01\",\n \"2026-03-10\"\n );\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n seller_id: \"seller-99\",\n total_visits: 14,\n item_visit_rows: [\n { item_id: \"MLA1\", total_visits: 10 },\n { item_id: \"MLA2\", total_visits: 4 },\n ],\n },\n });\n });\n\n it(\"formats service failures through MercadoLibre error helpers\", async () => {\n vi.mocked(getMercadoLibreUsersMe).mockRejectedValue(new Error(\"boom\"));\n\n const result = await meliValidateConnectionHandler({ profileId: \"meli-profile-1\" });\n\n expect(formatMercadoLibreError).toHaveBeenCalledWith(\n expect.any(Error),\n \"Failed to validate MercadoLibre connection\"\n );\n expect(result).toEqual({\n kind: \"error\",\n message: \"formatted:Failed to validate MercadoLibre connection:boom\",\n });\n });\n\n it(\"returns write-helper selection payloads unchanged and skips answer calls\", async () => {\n vi.mocked(resolveMercadoLibreWriteProfile).mockResolvedValue({\n ok: false,\n response: { selection_required: true, provider: \"mercadolibre\" },\n } as never);\n\n const result = await meliAnswerQuestionHandler({\n profileId: undefined,\n questionId: 777,\n text: \"Answer\",\n });\n\n expect(result).toEqual({ selection_required: true, provider: \"mercadolibre\" });\n expect(answerMercadoLibreQuestion).not.toHaveBeenCalled();\n });\n\n it(\"routes write failures through the MercadoLibre write error helper\", async () => {\n vi.mocked(answerMercadoLibreQuestion).mockRejectedValue(new Error(\"cannot-answer\"));\n\n const result = await meliAnswerQuestionHandler({\n profileId: \"meli-profile-1\",\n questionId: 888,\n text: \"Answer\",\n });\n\n expect(handleMercadoLibreWriteError).toHaveBeenCalledWith(\n expect.any(Error),\n \"Failed to answer MercadoLibre question 888\"\n );\n expect(result).toEqual({\n kind: \"error\",\n message: \"write:Failed to answer MercadoLibre question 888:cannot-answer\",\n });\n });\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nimport { meliGetAccountContextHandler } from \"../../src/tools/mercadolibre/get-account-context.js\";\nimport { meliValidateConnectionHandler } from \"../../src/tools/mercadolibre/validate-connection.js\";\nimport { meliPredictCategoryHandler } from \"../../src/tools/mercadolibre/predict-category.js\";\nimport { meliGetCategoryRequirementsHandler } from \"../../src/tools/mercadolibre/get-category-requirements.js\";\nimport { meliEstimateListingFeeHandler } from \"../../src/tools/mercadolibre/estimate-listing-fee.js\";\nimport { meliGetSiteCategoriesAndListingTypesHandler } from \"../../src/tools/mercadolibre/get-site-categories-and-listing-types.js\";\nimport { meliGetItemDetailsHandler } from \"../../src/tools/mercadolibre/get-item-details.js\";\nimport { meliSearchQuestionsHandler } from \"../../src/tools/mercadolibre/search-questions.js\";\nimport { meliAnswerQuestionHandler } from \"../../src/tools/mercadolibre/answer-question.js\";\nimport { meliGetListingQualityHandler } from \"../../src/tools/mercadolibre/get-listing-quality.js\";\nimport { meliGetItemVisitsHandler } from \"../../src/tools/mercadolibre/get-item-visits.js\";\nimport { resolveMercadoLibreProfileOrSelection } from \"../../src/tools/mercadolibre/profile-resolution.js\";\nimport {\n buildMercadoLibreWriteSuccessResponse,\n handleMercadoLibreWriteError,\n resolveMercadoLibreWriteProfile,\n} from \"../../src/tools/mercadolibre/write-helpers.js\";\nimport { getMercadoLibreAccessForProfile } from \"../../src/config/mercadolibre.js\";\nimport { getMercadoLibreConnectionRow } from \"../../src/config/mercadolibre-profile-store.js\";\nimport { decryptSecret } from \"../../src/config/vtex-crypto.js\";\nimport {\n buildMercadoLibrePaginationMetadata,\n formatMercadoLibreError,\n getMercadoLibreUsersMe,\n getMercadoLibreUsersMeWithAccessToken,\n normalizeMercadoLibrePaging,\n} from \"../../src/services/mercadolibre/mercadolibre-api.js\";\nimport {\n getMercadoLibreCategoryAttributes,\n getMercadoLibreCategoryShippingPreferences,\n getMercadoLibreItemDetailsBatch,\n getMercadoLibreItemDetailsWithFallbackBatch,\n getMercadoLibreItemPerformance,\n getMercadoLibreItemVisitsWindow,\n getMercadoLibreSiteCategoriesAndListingTypes,\n getMercadoLibreUserItemsVisits,\n searchMercadoLibreDomainDiscovery,\n} from \"../../src/services/mercadolibre/mercadolibre-items.js\";\nimport {\n answerMercadoLibreQuestion,\n searchMercadoLibreQuestions,\n} from \"../../src/services/mercadolibre/mercadolibre-questions.js\";\nimport { buildMercadoLibreListingFeeEstimate } from \"../../src/tools/mercadolibre/listing-fee-helpers.js\";\n\nvi.mock(\"mcp-use/server\", () => ({\n object: vi.fn((payload: unknown) => ({ kind: \"object\", payload })),\n error: vi.fn((message: string) => ({ kind: \"error\", message })),\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/profile-resolution.js\", () => ({\n resolveMercadoLibreProfileOrSelection: vi.fn(),\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/write-helpers.js\", async () => {\n const { z } = await import(\"zod\");\n\n return {\n mercadolibreProfileIdSchemaField: z.string().optional(),\n resolveMercadoLibreWriteProfile: vi.fn(),\n buildMercadoLibreWriteSuccessResponse: vi.fn((payload: unknown) => ({ kind: \"success\", payload })),\n handleMercadoLibreWriteError: vi.fn(\n (err: unknown, fallback: string) => ({\n kind: \"error\",\n message: `write:${fallback}:${err instanceof Error ? err.message : String(err)}`,\n })\n ),\n };\n});\n\nvi.mock(\"../../src/config/mercadolibre.js\", () => ({\n getMercadoLibreAccessForProfile: vi.fn(),\n}));\n\nvi.mock(\"../../src/config/mercadolibre-profile-store.js\", () => ({\n getMercadoLibreConnectionRow: vi.fn(),\n}));\n\nvi.mock(\"../../src/config/vtex-crypto.js\", () => ({\n decryptSecret: vi.fn(),\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-api.js\", () => ({\n getMercadoLibreUsersMe: vi.fn(),\n getMercadoLibreUsersMeWithAccessToken: vi.fn(),\n formatMercadoLibreError: vi.fn(\n (err: unknown, fallback: string) =>\n `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`\n ),\n normalizeMercadoLibrePaging: vi.fn((paging: unknown) => paging),\n buildMercadoLibrePaginationMetadata: vi.fn((metadata: unknown) => metadata),\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-items.js\", () => ({\n searchMercadoLibreDomainDiscovery: vi.fn(),\n getMercadoLibreCategoryAttributes: vi.fn(),\n getMercadoLibreCategoryShippingPreferences: vi.fn(),\n getMercadoLibreSiteCategoriesAndListingTypes: vi.fn(),\n getMercadoLibreItemDetailsBatch: vi.fn(),\n getMercadoLibreItemDetailsWithFallbackBatch: vi.fn(),\n getMercadoLibreItemPerformance: vi.fn(),\n getMercadoLibreItemVisitsWindow: vi.fn(),\n getMercadoLibreUserItemsVisits: vi.fn(),\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-questions.js\", () => ({\n searchMercadoLibreQuestions: vi.fn(),\n answerMercadoLibreQuestion: vi.fn(),\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/listing-fee-helpers.js\", () => ({\n buildMercadoLibreListingFeeEstimate: vi.fn(),\n}));\n\ndescribe(\"MercadoLibre small and medium tool handlers\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(resolveMercadoLibreProfileOrSelection).mockResolvedValue({\n ok: true,\n value: { profileId: \"meli-profile-1\" },\n });\n\n vi.mocked(resolveMercadoLibreWriteProfile).mockResolvedValue({\n ok: true,\n value: { profileId: \"meli-profile-1\" },\n });\n\n vi.mocked(getMercadoLibreAccessForProfile).mockResolvedValue({\n sellerId: \"seller-99\",\n scopes: [\"read\", \"write\"],\n expiresAt: \"2026-07-01T00:00:00.000Z\",\n } as never);\n\n vi.mocked(getMercadoLibreUsersMe).mockResolvedValue({\n id: 12345,\n nickname: \"meli-store\",\n } as never);\n\n vi.mocked(buildMercadoLibrePaginationMetadata).mockImplementation((metadata) => metadata as never);\n vi.mocked(normalizeMercadoLibrePaging).mockImplementation((paging) => paging as never);\n });\n\n it(\"returns MercadoLibre account context with resolved profile access\", async () => {\n const result = await meliGetAccountContextHandler({ profileId: \"custom-profile\" });\n\n expect(resolveMercadoLibreProfileOrSelection).toHaveBeenCalledWith(\"custom-profile\");\n expect(getMercadoLibreAccessForProfile).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(getMercadoLibreUsersMe).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n seller_id: \"seller-99\",\n nickname: \"meli-store\",\n account_id: 12345,\n scopes: [\"read\", \"write\"],\n expires_at: \"2026-07-01T00:00:00.000Z\",\n },\n });\n });\n\n it(\"returns profile selection payload unchanged for read handlers\", async () => {\n vi.mocked(resolveMercadoLibreProfileOrSelection).mockResolvedValue({\n ok: false,\n response: { selection_required: true },\n } as never);\n\n const result = await meliGetAccountContextHandler({ profileId: undefined });\n\n expect(result).toEqual({ selection_required: true });\n expect(getMercadoLibreAccessForProfile).not.toHaveBeenCalled();\n });\n\n it(\"validates connection with its persisted unexpired token without refresh\", async () => {\n vi.mocked(getMercadoLibreConnectionRow).mockResolvedValue({\n sellerId: \"seller-99\",\n scopes: [\"read\", \"write\"],\n expiresAt: new Date(\"2099-07-01T00:00:00.000Z\"),\n encryptedAccessToken: \"stored-token\",\n status: \"error\",\n } as never);\n vi.mocked(decryptSecret).mockReturnValue(\"stored-access-token\");\n vi.mocked(getMercadoLibreUsersMeWithAccessToken).mockResolvedValue({\n id: 12345,\n nickname: \"meli-store\",\n } as never);\n\n const result = await meliValidateConnectionHandler({ profileId: \"meli-profile-1\" });\n\n expect(getMercadoLibreUsersMeWithAccessToken).toHaveBeenCalledWith(\"stored-access-token\");\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n observation_only: true,\n validation_status: \"valid\",\n seller_id: \"seller-99\",\n account_id: 12345,\n nickname: \"meli-store\",\n expires_at: \"2099-07-01T00:00:00.000Z\",\n scopes: [\"read\", \"write\"],\n },\n });\n });\n\n it(\"predicts categories with normalized candidate payloads and defaults\", async () => {\n vi.mocked(searchMercadoLibreDomainDiscovery).mockResolvedValue([\n {\n category_id: \"MLA123\",\n category_name: \"Sneakers\",\n domain_id: \"MLA-SNEAKERS\",\n domain_name: \"Sneakers\",\n attributes_matched: \"4\",\n },\n ] as never);\n\n const result = await meliPredictCategoryHandler({\n profileId: \"meli-profile-1\",\n query: \"running shoes\",\n });\n\n expect(searchMercadoLibreDomainDiscovery).toHaveBeenCalledWith(\n \"meli-profile-1\",\n \"running shoes\",\n 5,\n \"MLA\"\n );\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n query: \"running shoes\",\n site_id: \"MLA\",\n candidates: [\n {\n category_id: \"MLA123\",\n category_name: \"Sneakers\",\n domain_id: \"MLA-SNEAKERS\",\n domain_name: \"Sneakers\",\n attributes_matched: 4,\n },\n ],\n },\n });\n });\n\n it(\"splits required and recommended category requirements\", async () => {\n vi.mocked(getMercadoLibreCategoryAttributes).mockResolvedValue([\n {\n id: \"BRAND\",\n name: \"Brand\",\n value_type: \"string\",\n value_max_length: 255,\n tags: { required: true },\n },\n {\n id: \"MODEL\",\n name: \"Model\",\n value_type: \"string\",\n tags: {},\n },\n ] as never);\n vi.mocked(getMercadoLibreCategoryShippingPreferences).mockResolvedValue({\n mode: \"me2\",\n logistic_types: [\"drop_off\"],\n } as never);\n\n const result = await meliGetCategoryRequirementsHandler({\n profileId: \"meli-profile-1\",\n categoryId: \"MLA999\",\n });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n category_id: \"MLA999\",\n required_attributes: [\n {\n id: \"BRAND\",\n name: \"Brand\",\n value_type: \"string\",\n value_max_length: 255,\n },\n ],\n recommended_attributes: [\n {\n id: \"MODEL\",\n name: \"Model\",\n value_type: \"string\",\n },\n ],\n shipping_preferences: {\n mode: \"me2\",\n logistics: [\"drop_off\"],\n },\n },\n });\n });\n\n it(\"delegates listing fee estimation with the resolved profile\", async () => {\n vi.mocked(buildMercadoLibreListingFeeEstimate).mockResolvedValue({\n profile_id: \"meli-profile-1\",\n fee_amount: 1234,\n site_id: null,\n } as never);\n\n const result = await meliEstimateListingFeeHandler({\n profileId: \"meli-profile-1\",\n itemId: \"MLA1\",\n query: \"running shoes\",\n price: 10000,\n categoryId: \"MLA123\",\n listingTypeId: \"gold_special\",\n shippingMode: \"me2\",\n logisticType: \"drop_off\",\n billableWeight: 1200,\n currencyId: \"ARS\",\n tags: [\"test-tag\"],\n });\n\n expect(buildMercadoLibreListingFeeEstimate).toHaveBeenCalledWith({\n profileId: \"meli-profile-1\",\n itemId: \"MLA1\",\n query: \"running shoes\",\n price: 10000,\n categoryId: \"MLA123\",\n listingTypeId: \"gold_special\",\n shippingMode: \"me2\",\n logisticType: \"drop_off\",\n billableWeight: 1200,\n currencyId: \"ARS\",\n tags: [\"test-tag\"],\n });\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n fee_amount: 1234,\n },\n });\n });\n\n it(\"combines site categories and listing types metadata\", async () => {\n vi.mocked(getMercadoLibreSiteCategoriesAndListingTypes).mockResolvedValue({\n siteId: \"MLA\",\n categories: [{ id: \"MLA1\", name: \"Shoes\" }],\n listingTypes: [{ id: \"gold_special\", name: \"Cl\u00E1sica\" }],\n } as never);\n\n const result = await meliGetSiteCategoriesAndListingTypesHandler({ profileId: \"meli-profile-1\" });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n site_id: \"MLA\",\n categories: [{ id: \"MLA1\", name: \"Shoes\" }],\n listing_types: [{ id: \"gold_special\", name: \"Cl\u00E1sica\" }],\n metadata: {\n site_id: \"MLA\",\n categories_count: 1,\n listing_types_count: 1,\n pagination: \"No aplica. La tool consolida dos endpoints de cat\u00E1logo del sitio MLA en una sola respuesta.\",\n },\n },\n });\n });\n\n it(\"returns item details directly from multiget when all requested ids are found\", async () => {\n vi.mocked(getMercadoLibreItemDetailsBatch).mockResolvedValue([\n { id: \"MLA1\", title: \"Boots\", pictures: [{ id: \"1\" }], status: \"active\" },\n { id: \"MLA2\", title: \"Sneakers\", pictures: [{ id: \"2\" }], status: \"paused\" },\n ] as never);\n\n const result = await meliGetItemDetailsHandler({\n profileId: \"meli-profile-1\",\n itemIds: [\"MLA1\", \"MLA1\", \"MLA2\"],\n });\n\n expect(getMercadoLibreItemDetailsBatch).toHaveBeenCalledWith(\"meli-profile-1\", [\"MLA1\", \"MLA2\"]);\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n metadata: {\n profile_id: \"meli-profile-1\",\n requested: 2,\n successful: 2,\n failed: 0,\n source: \"items_multiget\",\n },\n items: [\n { id: \"MLA1\", title: \"Boots\", status: \"active\" },\n { id: \"MLA2\", title: \"Sneakers\", status: \"paused\" },\n ],\n },\n });\n });\n\n it(\"falls back to item-by-item details when multiget coverage is partial\", async () => {\n vi.mocked(getMercadoLibreItemDetailsBatch).mockResolvedValue([{ id: \"MLA1\", title: \"Boots\" }] as never);\n vi.mocked(getMercadoLibreItemDetailsWithFallbackBatch).mockResolvedValue({\n successful: [\n {\n id: \"MLA1\",\n document: { id: \"MLA1\", title: \"Boots\" },\n },\n ],\n failed: [\n {\n id: \"MLA2\",\n message: \"not found\",\n statusCode: 404,\n attempts: 2,\n retryable: false,\n },\n ],\n } as never);\n\n const result = await meliGetItemDetailsHandler({\n profileId: \"meli-profile-1\",\n itemIds: [\"MLA1\", \"MLA2\"],\n });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n metadata: {\n profile_id: \"meli-profile-1\",\n requested: 2,\n successful: 1,\n failed: 1,\n has_failures: true,\n source: \"item_by_item_fallback\",\n },\n items: [{ id: \"MLA1\", title: \"Boots\" }],\n failures: [\n {\n item_id: \"MLA2\",\n message: \"not found\",\n status_code: 404,\n attempts: 2,\n retryable: false,\n },\n ],\n },\n });\n });\n\n it(\"searches questions with seller context and normalized pagination\", async () => {\n vi.mocked(searchMercadoLibreQuestions).mockResolvedValue({\n questions: [\n {\n id: 777,\n item_id: \"MLA1\",\n item: { title: \"Boots\" },\n status: \"unanswered\",\n text: \"Do you ship today?\",\n date_created: \"2026-03-10T14:45:55.000Z\",\n from: { id: 555, nickname: \"buyer\" },\n answer: { status: \"not_answered\" },\n },\n ],\n paging: { total: 1, limit: 20, offset: 0 },\n } as never);\n\n const result = await meliSearchQuestionsHandler({ profileId: \"meli-profile-1\" });\n\n expect(searchMercadoLibreQuestions).toHaveBeenCalledWith(\"meli-profile-1\", {\n sellerId: \"seller-99\",\n itemId: undefined,\n status: undefined,\n limit: 20,\n offset: 0,\n });\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n metadata: {\n total: 1,\n limit: 20,\n offset: 0,\n returned: 1,\n nextField: \"offset\",\n },\n questions: [\n {\n question_id: 777,\n item_id: \"MLA1\",\n item_title: \"Boots\",\n status: \"unanswered\",\n text: \"Do you ship today?\",\n date_created: \"2026-03-10 14:45\",\n from: { id: \"\", nickname: \"buyer\" },\n answer_status: \"not_answered\",\n },\n ],\n },\n });\n });\n\n it(\"routes question answers through write helpers\", async () => {\n vi.mocked(answerMercadoLibreQuestion).mockResolvedValue({ id: 777, status: \"answered\" } as never);\n\n const result = await meliAnswerQuestionHandler({\n profileId: \"meli-profile-1\",\n questionId: 777,\n text: \"Yes, we can ship today.\",\n });\n\n expect(resolveMercadoLibreWriteProfile).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(answerMercadoLibreQuestion).toHaveBeenCalledWith(\n \"meli-profile-1\",\n 777,\n \"Yes, we can ship today.\"\n );\n expect(buildMercadoLibreWriteSuccessResponse).toHaveBeenCalledWith({\n profileId: \"meli-profile-1\",\n operation: \"answer_question\",\n resourceId: \"777\",\n message: \"MercadoLibre question answered successfully.\",\n after: { id: 777, status: \"answered\" },\n });\n expect(result).toEqual({\n kind: \"success\",\n payload: {\n profileId: \"meli-profile-1\",\n operation: \"answer_question\",\n resourceId: \"777\",\n message: \"MercadoLibre question answered successfully.\",\n after: { id: 777, status: \"answered\" },\n },\n });\n });\n\n it(\"formats listing quality summaries with warning normalization\", async () => {\n vi.mocked(getMercadoLibreItemPerformance).mockResolvedValue({\n score: \"85\",\n status: \"healthy\",\n health: \"good\",\n sales: 20,\n visits: 300,\n warnings: [{ id: \"photo\", text: \"Add more photos\", severity: \"medium\" }],\n item: { title: \"Boots\", status: \"active\" },\n } as never);\n\n const result = await meliGetListingQualityHandler({\n profileId: \"meli-profile-1\",\n itemId: \"MLA1\",\n });\n\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n item_id: \"MLA1\",\n quality_score: 85,\n level: \"healthy\",\n health: \"good\",\n sales: 20,\n visits: 300,\n warnings: [\n {\n type: \"photo\",\n message: \"Add more photos\",\n severity: \"medium\",\n },\n ],\n raw_summary: {\n title: \"Boots\",\n status: \"active\",\n },\n },\n });\n });\n\n it(\"returns item-level visits windows when item ids are provided\", async () => {\n vi.mocked(getMercadoLibreItemVisitsWindow).mockResolvedValue({\n total_visits: 14,\n results: [{ date: \"2026-03-10\", visits: 14 }],\n } as never);\n\n const result = await meliGetItemVisitsHandler({\n profileId: \"meli-profile-1\",\n itemIds: [\"MLA1\", \"MLA1\"],\n last: 7,\n ending: \"2026-03-10\",\n });\n\n expect(getMercadoLibreItemVisitsWindow).toHaveBeenCalledTimes(1);\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n seller_id: \"seller-99\",\n total_visits: 14,\n items: [\n {\n item_id: \"MLA1\",\n total_visits: 14,\n last: 7,\n unit: \"day\",\n ending: \"2026-03-10\",\n time_window: [{ date: \"2026-03-10\", visits: 14 }],\n },\n ],\n },\n });\n });\n\n it(\"returns a validation error when visits are requested without item ids or date range\", async () => {\n const result = await meliGetItemVisitsHandler({ profileId: \"meli-profile-1\" });\n\n expect(result).toEqual({\n kind: \"error\",\n message: \"Provide itemIds, or provide both startDate and endDate for seller-level visits.\",\n });\n expect(getMercadoLibreUserItemsVisits).not.toHaveBeenCalled();\n });\n\n it(\"returns seller-level visits when a date range is provided\", async () => {\n vi.mocked(getMercadoLibreUserItemsVisits).mockResolvedValue({\n results: [\n { item_id: \"MLA1\", total_visits: 10 },\n { id: \"MLA2\", visits: 4 },\n ],\n } as never);\n\n const result = await meliGetItemVisitsHandler({\n profileId: \"meli-profile-1\",\n startDate: \"2026-03-01\",\n endDate: \"2026-03-10\",\n });\n\n expect(getMercadoLibreUserItemsVisits).toHaveBeenCalledWith(\n \"meli-profile-1\",\n \"seller-99\",\n \"2026-03-01\",\n \"2026-03-10\"\n );\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n profile_id: \"meli-profile-1\",\n seller_id: \"seller-99\",\n total_visits: 14,\n item_visit_rows: [\n { item_id: \"MLA1\", total_visits: 10 },\n { item_id: \"MLA2\", total_visits: 4 },\n ],\n },\n });\n });\n\n it(\"formats service failures through MercadoLibre error helpers\", async () => {\n vi.mocked(getMercadoLibreConnectionRow).mockResolvedValue({\n sellerId: \"seller-99\",\n scopes: [\"read\"],\n expiresAt: new Date(\"2099-07-01T00:00:00.000Z\"),\n encryptedAccessToken: \"stored-token\",\n status: \"active\",\n } as never);\n vi.mocked(decryptSecret).mockReturnValue(\"stored-access-token\");\n vi.mocked(getMercadoLibreUsersMeWithAccessToken).mockRejectedValue(new Error(\"boom\"));\n\n const result = await meliValidateConnectionHandler({ profileId: \"meli-profile-1\" });\n\n expect(formatMercadoLibreError).toHaveBeenCalledWith(\n expect.any(Error),\n \"Failed to validate MercadoLibre connection\"\n );\n expect(result).toEqual({\n kind: \"error\",\n message: \"formatted:Failed to validate MercadoLibre connection:boom\",\n });\n });\n\n it(\"returns write-helper selection payloads unchanged and skips answer calls\", async () => {\n vi.mocked(resolveMercadoLibreWriteProfile).mockResolvedValue({\n ok: false,\n response: { selection_required: true, provider: \"mercadolibre\" },\n } as never);\n\n const result = await meliAnswerQuestionHandler({\n profileId: undefined,\n questionId: 777,\n text: \"Answer\",\n });\n\n expect(result).toEqual({ selection_required: true, provider: \"mercadolibre\" });\n expect(answerMercadoLibreQuestion).not.toHaveBeenCalled();\n });\n\n it(\"routes write failures through the MercadoLibre write error helper\", async () => {\n vi.mocked(answerMercadoLibreQuestion).mockRejectedValue(new Error(\"cannot-answer\"));\n\n const result = await meliAnswerQuestionHandler({\n profileId: \"meli-profile-1\",\n questionId: 888,\n text: \"Answer\",\n });\n\n expect(handleMercadoLibreWriteError).toHaveBeenCalledWith(\n expect.any(Error),\n \"Failed to answer MercadoLibre question 888\"\n );\n expect(result).toEqual({\n kind: \"error\",\n message: \"write:Failed to answer MercadoLibre question 888:cannot-answer\",\n });\n });\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,7 +11,7 @@ describe("VTEX commercial conditions documentation", () => {
11
11
  new URL("../../../bi-mcp-dashboard/docs/content/CAPACIDADES_MCP.md", import.meta.url),
12
12
  "utf8"
13
13
  );
14
- expect(projectStatus).toContain("`35` tools VTEX.");
14
+ expect(projectStatus).toContain("`58` tools VTEX.");
15
15
  expect(projectStatus).toContain("condiciones comerciales solo lectura oficial");
16
16
  expect(keyEndpoints).toContain("Commercial conditions Catalog reads and legacy payment rules writes");
17
17
  expect(keyEndpoints).toContain("/api/catalog_system/pvt/commercialcondition/list");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../tests/vtex/vtex-commercial-conditions-docs.test.ts"],
4
- "sourcesContent": ["import { readFile } from \"node:fs/promises\";\nimport { describe, expect, it } from \"vitest\";\n\ndescribe(\"VTEX commercial conditions documentation\", () => {\n it(\"documents the corrected VTEX commercial conditions capability across project docs\", async () => {\n const projectStatus = await readFile(new URL(\"../../docs/PROJECT_STATUS.md\", import.meta.url), \"utf8\");\n const keyEndpoints = await readFile(\n new URL(\"../../src/services/vtex/docs/vtex-key-endpoints.md\", import.meta.url),\n \"utf8\"\n );\n const dashboardCapabilities = await readFile(\n new URL(\"../../../bi-mcp-dashboard/docs/content/CAPACIDADES_MCP.md\", import.meta.url),\n \"utf8\"\n );\n\n expect(projectStatus).toContain(\"`35` tools VTEX.\");\n expect(projectStatus).toContain(\"condiciones comerciales solo lectura oficial\");\n\n expect(keyEndpoints).toContain(\"Commercial conditions Catalog reads and legacy payment rules writes\");\n expect(keyEndpoints).toContain(\"/api/catalog_system/pvt/commercialcondition/list\");\n expect(keyEndpoints).toContain(\"manually in VTEX Admin\");\n expect(keyEndpoints).toContain(\"`vtex_payment_rules`\");\n\n expect(dashboardCapabilities).toContain(\n \"Gesti\u00F3n de Condiciones Comerciales y Reglas de Pago\"\n );\n expect(dashboardCapabilities).toContain(\"`vtex_commercial_conditions`\");\n expect(dashboardCapabilities).toContain(\"`vtex_payment_rules`\");\n expect(dashboardCapabilities).toContain(\"solo permite listar y consultar condiciones comerciales\");\n expect(dashboardCapabilities).toContain(\n \"crear manualmente la condici\u00F3n faltante en VTEX Admin\"\n );\n expect(dashboardCapabilities).not.toContain(\n \"primero conviene administrar esa condici\u00F3n y sus reglas desde `vtex_commercial_conditions`\"\n );\n });\n});\n"],
4
+ "sourcesContent": ["import { readFile } from \"node:fs/promises\";\nimport { describe, expect, it } from \"vitest\";\n\ndescribe(\"VTEX commercial conditions documentation\", () => {\n it(\"documents the corrected VTEX commercial conditions capability across project docs\", async () => {\n const projectStatus = await readFile(new URL(\"../../docs/PROJECT_STATUS.md\", import.meta.url), \"utf8\");\n const keyEndpoints = await readFile(\n new URL(\"../../src/services/vtex/docs/vtex-key-endpoints.md\", import.meta.url),\n \"utf8\"\n );\n const dashboardCapabilities = await readFile(\n new URL(\"../../../bi-mcp-dashboard/docs/content/CAPACIDADES_MCP.md\", import.meta.url),\n \"utf8\"\n );\n\n expect(projectStatus).toContain(\"`58` tools VTEX.\");\n expect(projectStatus).toContain(\"condiciones comerciales solo lectura oficial\");\n\n expect(keyEndpoints).toContain(\"Commercial conditions Catalog reads and legacy payment rules writes\");\n expect(keyEndpoints).toContain(\"/api/catalog_system/pvt/commercialcondition/list\");\n expect(keyEndpoints).toContain(\"manually in VTEX Admin\");\n expect(keyEndpoints).toContain(\"`vtex_payment_rules`\");\n\n expect(dashboardCapabilities).toContain(\n \"Gesti\u00F3n de Condiciones Comerciales y Reglas de Pago\"\n );\n expect(dashboardCapabilities).toContain(\"`vtex_commercial_conditions`\");\n expect(dashboardCapabilities).toContain(\"`vtex_payment_rules`\");\n expect(dashboardCapabilities).toContain(\"solo permite listar y consultar condiciones comerciales\");\n expect(dashboardCapabilities).toContain(\n \"crear manualmente la condici\u00F3n faltante en VTEX Admin\"\n );\n expect(dashboardCapabilities).not.toContain(\n \"primero conviene administrar esa condici\u00F3n y sus reglas desde `vtex_commercial_conditions`\"\n );\n });\n});\n"],
5
5
  "mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,4CAA4C,MAAM;AACzD,KAAG,qFAAqF,YAAY;AAClG,UAAM,gBAAgB,MAAM,SAAS,IAAI,IAAI,gCAAgC,YAAY,GAAG,GAAG,MAAM;AACrG,UAAM,eAAe,MAAM;AAAA,MACzB,IAAI,IAAI,sDAAsD,YAAY,GAAG;AAAA,MAC7E;AAAA,IACF;AACA,UAAM,wBAAwB,MAAM;AAAA,MAClC,IAAI,IAAI,6DAA6D,YAAY,GAAG;AAAA,MACpF;AAAA,IACF;AAEA,WAAO,aAAa,EAAE,UAAU,kBAAkB;AAClD,WAAO,aAAa,EAAE,UAAU,8CAA8C;AAE9E,WAAO,YAAY,EAAE,UAAU,qEAAqE;AACpG,WAAO,YAAY,EAAE,UAAU,kDAAkD;AACjF,WAAO,YAAY,EAAE,UAAU,wBAAwB;AACvD,WAAO,YAAY,EAAE,UAAU,sBAAsB;AAErD,WAAO,qBAAqB,EAAE;AAAA,MAC5B;AAAA,IACF;AACA,WAAO,qBAAqB,EAAE,UAAU,8BAA8B;AACtE,WAAO,qBAAqB,EAAE,UAAU,sBAAsB;AAC9D,WAAO,qBAAqB,EAAE,UAAU,yDAAyD;AACjG,WAAO,qBAAqB,EAAE;AAAA,MAC5B;AAAA,IACF;AACA,WAAO,qBAAqB,EAAE,IAAI;AAAA,MAChC;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yoryoboy/bi-mcp",
3
3
  "type": "module",
4
- "version": "1.16.0",
4
+ "version": "1.19.0",
5
5
  "description": "MCP server: bi-mcp",
6
6
  "author": "",
7
7
  "license": "MIT",
@@ -1,78 +0,0 @@
1
- import {
2
- getDefaultGoogleAdsLoginCustomerId,
3
- getGoogleAdsDeveloperToken
4
- } from "../config/google.js";
5
- const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
6
- function normalizeCustomerId(customerId) {
7
- const normalized = customerId.trim().replace(/-/g, "");
8
- if (!/^\d+$/.test(normalized)) {
9
- throw new Error("Invalid Google Ads customer ID. Use digits only, with or without hyphens.");
10
- }
11
- return normalized;
12
- }
13
- function resolveGoogleAdsCustomerId(customerId) {
14
- if (!customerId?.trim()) {
15
- throw new Error("Missing Google Ads customer ID. Provide customerId.");
16
- }
17
- return normalizeCustomerId(customerId);
18
- }
19
- function resolveGoogleAdsLoginCustomerId(loginCustomerId) {
20
- const explicitCustomerId = loginCustomerId?.trim();
21
- if (explicitCustomerId) {
22
- return normalizeCustomerId(explicitCustomerId);
23
- }
24
- return getDefaultGoogleAdsLoginCustomerId();
25
- }
26
- function resolveGoogleAdsDeveloperToken() {
27
- return getGoogleAdsDeveloperToken();
28
- }
29
- function parseGoogleAdsMetricValue(value) {
30
- if (typeof value === "number" && Number.isFinite(value)) {
31
- return value;
32
- }
33
- if (typeof value === "string") {
34
- const parsedValue = Number(value);
35
- return Number.isFinite(parsedValue) ? parsedValue : 0;
36
- }
37
- return 0;
38
- }
39
- function microsToCurrency(value, decimals = 2) {
40
- return round(parseGoogleAdsMetricValue(value) / 1e6, decimals);
41
- }
42
- function round(value, decimals = 2) {
43
- if (!Number.isFinite(value)) {
44
- return 0;
45
- }
46
- const factor = 10 ** decimals;
47
- return Math.round(value * factor) / factor;
48
- }
49
- function toPercent(numerator, denominator) {
50
- if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0) {
51
- return 0;
52
- }
53
- return numerator / denominator * 100;
54
- }
55
- function getFieldValue(row, path, fallback) {
56
- const segments = path.split(".");
57
- let current = row;
58
- for (const segment of segments) {
59
- if (!current || typeof current !== "object") {
60
- return fallback;
61
- }
62
- current = current[segment];
63
- }
64
- return current ?? fallback;
65
- }
66
- export {
67
- dateRegex,
68
- getFieldValue,
69
- microsToCurrency,
70
- normalizeCustomerId,
71
- parseGoogleAdsMetricValue,
72
- resolveGoogleAdsCustomerId,
73
- resolveGoogleAdsDeveloperToken,
74
- resolveGoogleAdsLoginCustomerId,
75
- round,
76
- toPercent
77
- };
78
- //# sourceMappingURL=report-utils.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/google-ads/report-utils.ts"],
4
- "sourcesContent": ["import {\n getDefaultGoogleAdsLoginCustomerId,\n getGoogleAdsDeveloperToken,\n} from \"../config/google.js\";\nimport type { GoogleAdsMetricValue, GoogleAdsSearchRow } from \"../services/google-ads/google-ads-client.js\";\n\nexport const dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport function normalizeCustomerId(customerId: string): string {\n const normalized = customerId.trim().replace(/-/g, \"\");\n if (!/^\\d+$/.test(normalized)) {\n throw new Error(\"Invalid Google Ads customer ID. Use digits only, with or without hyphens.\");\n }\n\n return normalized;\n}\n\nexport function resolveGoogleAdsCustomerId(customerId?: string): string {\n if (!customerId?.trim()) {\n throw new Error(\"Missing Google Ads customer ID. Provide customerId.\");\n }\n\n return normalizeCustomerId(customerId);\n}\n\nexport function resolveGoogleAdsLoginCustomerId(loginCustomerId?: string): string | undefined {\n const explicitCustomerId = loginCustomerId?.trim();\n if (explicitCustomerId) {\n return normalizeCustomerId(explicitCustomerId);\n }\n\n return getDefaultGoogleAdsLoginCustomerId();\n}\n\nexport function resolveGoogleAdsDeveloperToken(): string {\n return getGoogleAdsDeveloperToken();\n}\n\nexport function parseGoogleAdsMetricValue(value: GoogleAdsMetricValue | undefined): number {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value === \"string\") {\n const parsedValue = Number(value);\n return Number.isFinite(parsedValue) ? parsedValue : 0;\n }\n\n return 0;\n}\n\nexport function microsToCurrency(value: GoogleAdsMetricValue | undefined, decimals = 2): number {\n return round(parseGoogleAdsMetricValue(value) / 1_000_000, decimals);\n}\n\nexport function round(value: number, decimals = 2): number {\n if (!Number.isFinite(value)) {\n return 0;\n }\n\n const factor = 10 ** decimals;\n return Math.round(value * factor) / factor;\n}\n\nexport function toPercent(numerator: number, denominator: number): number {\n if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0) {\n return 0;\n }\n\n return (numerator / denominator) * 100;\n}\n\nexport function getFieldValue<T>(row: GoogleAdsSearchRow, path: string, fallback?: T): T | undefined {\n const segments = path.split(\".\");\n let current: unknown = row;\n\n for (const segment of segments) {\n if (!current || typeof current !== \"object\") {\n return fallback;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return (current as T | undefined) ?? fallback;\n}\n"],
5
- "mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAGA,MAAM,YAAY;AAElB,SAAS,oBAAoB,YAA4B;AAC9D,QAAM,aAAa,WAAW,KAAK,EAAE,QAAQ,MAAM,EAAE;AACrD,MAAI,CAAC,QAAQ,KAAK,UAAU,GAAG;AAC7B,UAAM,IAAI,MAAM,2EAA2E;AAAA,EAC7F;AAEA,SAAO;AACT;AAEO,SAAS,2BAA2B,YAA6B;AACtE,MAAI,CAAC,YAAY,KAAK,GAAG;AACvB,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,SAAO,oBAAoB,UAAU;AACvC;AAEO,SAAS,gCAAgC,iBAA8C;AAC5F,QAAM,qBAAqB,iBAAiB,KAAK;AACjD,MAAI,oBAAoB;AACtB,WAAO,oBAAoB,kBAAkB;AAAA,EAC/C;AAEA,SAAO,mCAAmC;AAC5C;AAEO,SAAS,iCAAyC;AACvD,SAAO,2BAA2B;AACpC;AAEO,SAAS,0BAA0B,OAAiD;AACzF,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,cAAc,OAAO,KAAK;AAChC,WAAO,OAAO,SAAS,WAAW,IAAI,cAAc;AAAA,EACtD;AAEA,SAAO;AACT;AAEO,SAAS,iBAAiB,OAAyC,WAAW,GAAW;AAC9F,SAAO,MAAM,0BAA0B,KAAK,IAAI,KAAW,QAAQ;AACrE;AAEO,SAAS,MAAM,OAAe,WAAW,GAAW;AACzD,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM;AACrB,SAAO,KAAK,MAAM,QAAQ,MAAM,IAAI;AACtC;AAEO,SAAS,UAAU,WAAmB,aAA6B;AACxE,MAAI,CAAC,OAAO,SAAS,SAAS,KAAK,CAAC,OAAO,SAAS,WAAW,KAAK,eAAe,GAAG;AACpF,WAAO;AAAA,EACT;AAEA,SAAQ,YAAY,cAAe;AACrC;AAEO,SAAS,cAAiB,KAAyB,MAAc,UAA6B;AACnG,QAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,MAAI,UAAmB;AAEvB,aAAW,WAAW,UAAU;AAC9B,QAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,aAAO;AAAA,IACT;AAEA,cAAW,QAAoC,OAAO;AAAA,EACxD;AAEA,SAAQ,WAA6B;AACvC;",
6
- "names": []
7
- }
@@ -1,275 +0,0 @@
1
- import { z } from "zod";
2
- const searchConsoleDateRegex = /^\d{4}-\d{2}-\d{2}$/;
3
- const searchConsoleSearchTypes = ["web", "image", "video", "news", "discover"];
4
- const searchConsoleDimensions = [
5
- "query",
6
- "page",
7
- "country",
8
- "device",
9
- "date",
10
- "searchAppearance"
11
- ];
12
- const searchConsoleFilterOperators = [
13
- "contains",
14
- "equals",
15
- "notContains",
16
- "notEquals",
17
- "includingRegex",
18
- "excludingRegex"
19
- ];
20
- const searchConsoleAggregationTypes = ["auto", "byPage", "byProperty"];
21
- const searchConsoleDimensionFilterSchema = z.object({
22
- dimension: z.enum(searchConsoleDimensions).describe("Dimension to filter on in Search Console (query, page, country, device, date, or searchAppearance)"),
23
- operator: z.enum(searchConsoleFilterOperators).describe("Filter operator supported by Search Console."),
24
- expression: z.string().min(1).describe("Filter value or regex expression.")
25
- });
26
- const siteUrlSchemaField = z.string().optional().describe(
27
- "Search Console site URL or domain property identifier (for example https://www.example.com/ or sc-domain:example.com). If omitted, the tool expects the site to be configured elsewhere."
28
- );
29
- const profileIdSchemaField = z.string().optional().describe("Optional business profile identifier for future multi-profile resolution. Defaults to the active profile when supported.");
30
- const startDateSchemaField = z.string().regex(searchConsoleDateRegex).describe("Start date in YYYY-MM-DD format.");
31
- const endDateSchemaField = z.string().regex(searchConsoleDateRegex).describe("End date in YYYY-MM-DD format.");
32
- const currentStartDateSchemaField = z.string().regex(searchConsoleDateRegex).describe("Current comparison period start date in YYYY-MM-DD format.");
33
- const currentEndDateSchemaField = z.string().regex(searchConsoleDateRegex).describe("Current comparison period end date in YYYY-MM-DD format.");
34
- const previousStartDateSchemaField = z.string().regex(searchConsoleDateRegex).describe("Previous comparison period start date in YYYY-MM-DD format.");
35
- const previousEndDateSchemaField = z.string().regex(searchConsoleDateRegex).describe("Previous comparison period end date in YYYY-MM-DD format.");
36
- const rowLimitSchemaField = z.number().int().min(1).max(25e3).optional().describe("Maximum number of rows to return. Search Console supports up to 25,000 rows per request.");
37
- const startRowSchemaField = z.number().int().min(0).optional().describe("Zero-based row offset for paginated Search Console requests.");
38
- const searchTypeSchemaField = z.enum(searchConsoleSearchTypes).optional().describe("Search type to query. Defaults to web.");
39
- const brandTermsSchemaField = z.array(z.string().min(1)).max(50).optional().describe("Brand tokens used to separate branded from non-branded queries.");
40
- function resolveSearchConsoleSiteUrl(siteUrl, profileId) {
41
- const explicitSiteUrl = siteUrl?.trim();
42
- if (explicitSiteUrl) {
43
- return explicitSiteUrl;
44
- }
45
- if (profileId?.trim()) {
46
- throw new Error(
47
- `Missing Search Console site URL. profileId "${profileId}" was provided, but business-data based site resolution is not implemented yet. Pass siteUrl explicitly or configure Search Console site resolution first.`
48
- );
49
- }
50
- throw new Error(
51
- "Missing Search Console site URL. Pass siteUrl explicitly or first call gsc_list_accessible_sites to discover available properties."
52
- );
53
- }
54
- function inferSearchConsolePropertyType(siteUrl) {
55
- if (siteUrl.startsWith("sc-domain:")) {
56
- return "domain";
57
- }
58
- if (/^https?:\/\//.test(siteUrl)) {
59
- return "url_prefix";
60
- }
61
- return "unknown";
62
- }
63
- function normalizePermissionLevel(permissionLevel) {
64
- return permissionLevel?.trim().toLowerCase() || void 0;
65
- }
66
- function normalizeSearchConsoleSiteEntry(siteEntry) {
67
- return {
68
- site_url: siteEntry.siteUrl,
69
- property_type: inferSearchConsolePropertyType(siteEntry.siteUrl),
70
- permission_level: normalizePermissionLevel(siteEntry.permissionLevel)
71
- };
72
- }
73
- function toPercent(numerator, denominator) {
74
- if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0) {
75
- return 0;
76
- }
77
- return numerator / denominator * 100;
78
- }
79
- function round(value, decimals = 2) {
80
- if (!Number.isFinite(value)) {
81
- return 0;
82
- }
83
- const factor = 10 ** decimals;
84
- return Math.round(value * factor) / factor;
85
- }
86
- function normalizeSearchConsoleRow(row, dimensions = []) {
87
- const clicks = row.clicks ?? 0;
88
- const impressions = row.impressions ?? 0;
89
- const ctr = typeof row.ctr === "number" ? row.ctr * 100 : toPercent(clicks, impressions);
90
- const keys = row.keys ?? [];
91
- return {
92
- keys,
93
- dimensions: dimensions.reduce((accumulator, dimension, index) => {
94
- accumulator[dimension] = keys[index] ?? "";
95
- return accumulator;
96
- }, {}),
97
- clicks: round(clicks, 2),
98
- impressions: round(impressions, 2),
99
- ctr_percent: round(ctr, 2),
100
- position: round(row.position ?? 0, 2)
101
- };
102
- }
103
- function buildSearchConsoleQueryBody(input) {
104
- const dimensionFilterGroups = input.dimensionFilters && input.dimensionFilters.length > 0 ? [
105
- {
106
- groupType: "and",
107
- filters: input.dimensionFilters
108
- }
109
- ] : void 0;
110
- return {
111
- startDate: input.startDate,
112
- endDate: input.endDate,
113
- dimensions: input.dimensions,
114
- type: input.searchType ?? "web",
115
- dimensionFilterGroups,
116
- aggregationType: input.aggregationType,
117
- rowLimit: input.rowLimit,
118
- startRow: input.startRow
119
- };
120
- }
121
- function buildPaginationMetadata(input) {
122
- const startRow = input.startRow ?? 0;
123
- const rowLimit = input.rowLimit;
124
- const isPartial = Boolean(rowLimit) && input.returnedRows === rowLimit;
125
- const nextStartRow = isPartial ? startRow + input.returnedRows : void 0;
126
- return {
127
- is_partial: isPartial,
128
- start_row: startRow,
129
- row_limit: rowLimit,
130
- returned_rows: input.returnedRows,
131
- next_start_row: nextStartRow,
132
- continuation_instructions: nextStartRow ? "This Search Console response may be truncated at row_limit. If you need additional rows, call the same tool again with startRow set to next_start_row." : void 0
133
- };
134
- }
135
- function parseBrandTerms(brandTerms) {
136
- return (brandTerms ?? []).map((term) => term.trim().toLowerCase()).filter(Boolean);
137
- }
138
- function isBrandedQuery(query, brandTerms) {
139
- const normalizedQuery = query.trim().toLowerCase();
140
- const normalizedBrandTerms = parseBrandTerms(brandTerms);
141
- if (!normalizedQuery || normalizedBrandTerms.length === 0) {
142
- return false;
143
- }
144
- return normalizedBrandTerms.some((brandTerm) => normalizedQuery.includes(brandTerm));
145
- }
146
- function classifyBrandLabel(query, brandTerms) {
147
- return isBrandedQuery(query, brandTerms) ? "brand" : "non_brand";
148
- }
149
- function computeChangePercent(currentValue, previousValue) {
150
- if (!Number.isFinite(currentValue) || !Number.isFinite(previousValue)) {
151
- return null;
152
- }
153
- if (previousValue === 0) {
154
- if (currentValue === 0) {
155
- return 0;
156
- }
157
- return null;
158
- }
159
- return round((currentValue - previousValue) / previousValue * 100, 2);
160
- }
161
- function sumSearchConsoleRows(rows) {
162
- const totals = rows.reduce(
163
- (accumulator, row) => {
164
- accumulator.clicks += row.clicks;
165
- accumulator.impressions += row.impressions;
166
- accumulator.weightedPosition += row.position * row.impressions;
167
- return accumulator;
168
- },
169
- {
170
- clicks: 0,
171
- impressions: 0,
172
- weightedPosition: 0
173
- }
174
- );
175
- return {
176
- clicks: round(totals.clicks, 2),
177
- impressions: round(totals.impressions, 2),
178
- ctrPercent: round(toPercent(totals.clicks, totals.impressions), 2),
179
- averagePosition: totals.impressions > 0 ? round(totals.weightedPosition / totals.impressions, 2) : 0
180
- };
181
- }
182
- function buildComparisonMap(rows, keyBuilder) {
183
- return new Map(rows.map((row) => [keyBuilder(row), row]));
184
- }
185
- function tokenizeQuery(query) {
186
- return query.toLowerCase().split(/[^a-z0-9áéíóúüñ]+/i).map((token) => token.trim()).filter(Boolean);
187
- }
188
- function looksLikeCommercialQuery(query) {
189
- const tokens = tokenizeQuery(query);
190
- const commercialTerms = /* @__PURE__ */ new Set([
191
- "comprar",
192
- "precio",
193
- "precios",
194
- "cuanto",
195
- "oferta",
196
- "ofertas",
197
- "envio",
198
- "shop",
199
- "tienda",
200
- "modelo",
201
- "medida",
202
- "ml",
203
- "cm",
204
- "kg"
205
- ]);
206
- return tokens.some((token) => commercialTerms.has(token));
207
- }
208
- function looksLikeProductQuery(query, productTerms) {
209
- const normalizedProductTerms = parseBrandTerms(productTerms);
210
- const normalizedQuery = query.toLowerCase();
211
- if (normalizedProductTerms.some((term) => normalizedQuery.includes(term))) {
212
- return true;
213
- }
214
- return looksLikeCommercialQuery(query) || tokenizeQuery(query).length >= 3;
215
- }
216
- function classifyQuickWinType(position, ctrPercent) {
217
- if (position <= 8 && ctrPercent <= 3) {
218
- return "ctr";
219
- }
220
- return "position";
221
- }
222
- function scoreHighImpressionLowClickOpportunity(input) {
223
- const impressionScore = Math.min(input.impressions / 100, 60);
224
- const ctrPenalty = Math.max(0, 15 - input.ctrPercent) * 2;
225
- const positionBonus = input.position > 0 && input.position <= 20 ? Math.max(0, 20 - input.position) : 0;
226
- return round(impressionScore + ctrPenalty + positionBonus, 2);
227
- }
228
- function scoreQuickWinOpportunity(input) {
229
- const impressionWeight = Math.min(input.impressions / 150, 50);
230
- const ctrWeight = Math.max(0, 10 - input.ctrPercent) * 3;
231
- const positionWeight = input.position > 0 && input.position <= 20 ? Math.max(0, 18 - input.position) * 1.8 : 0;
232
- return round(impressionWeight + ctrWeight + positionWeight, 2);
233
- }
234
- export {
235
- brandTermsSchemaField,
236
- buildComparisonMap,
237
- buildPaginationMetadata,
238
- buildSearchConsoleQueryBody,
239
- classifyBrandLabel,
240
- classifyQuickWinType,
241
- computeChangePercent,
242
- currentEndDateSchemaField,
243
- currentStartDateSchemaField,
244
- endDateSchemaField,
245
- inferSearchConsolePropertyType,
246
- isBrandedQuery,
247
- looksLikeCommercialQuery,
248
- looksLikeProductQuery,
249
- normalizePermissionLevel,
250
- normalizeSearchConsoleRow,
251
- normalizeSearchConsoleSiteEntry,
252
- parseBrandTerms,
253
- previousEndDateSchemaField,
254
- previousStartDateSchemaField,
255
- profileIdSchemaField,
256
- resolveSearchConsoleSiteUrl,
257
- round,
258
- rowLimitSchemaField,
259
- scoreHighImpressionLowClickOpportunity,
260
- scoreQuickWinOpportunity,
261
- searchConsoleAggregationTypes,
262
- searchConsoleDateRegex,
263
- searchConsoleDimensionFilterSchema,
264
- searchConsoleDimensions,
265
- searchConsoleFilterOperators,
266
- searchConsoleSearchTypes,
267
- searchTypeSchemaField,
268
- siteUrlSchemaField,
269
- startDateSchemaField,
270
- startRowSchemaField,
271
- sumSearchConsoleRows,
272
- toPercent,
273
- tokenizeQuery
274
- };
275
- //# sourceMappingURL=search-console-utils.js.map