@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.
- package/README.md +12 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.js +179 -6
- package/dist/index.js.map +2 -2
- package/dist/mcp-use.json +3 -6
- package/dist/src/config/__tests__/google-store.test.js +30 -0
- package/dist/src/config/__tests__/google-store.test.js.map +7 -0
- package/dist/src/config/__tests__/mcp-tool-deadline.test.js +64 -0
- package/dist/src/config/__tests__/mcp-tool-deadline.test.js.map +7 -0
- package/dist/src/config/google-store.js +18 -0
- package/dist/src/config/google-store.js.map +2 -2
- package/dist/src/config/mcp-tool-deadline-context.js +34 -0
- package/dist/src/config/mcp-tool-deadline-context.js.map +7 -0
- package/dist/src/config/mcp-tool-deadline.js +67 -0
- package/dist/src/config/mcp-tool-deadline.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-api.test.js +38 -3
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-api.test.js.map +2 -2
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-buyer-reconciliation.test.js +226 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-buyer-reconciliation.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-claim-reconciliation.test.js +127 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-claim-reconciliation.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-kits.test.js +103 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-kits.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-order-billing-info.test.js +582 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-order-billing-info.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-orders.test.js +10 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-orders.test.js.map +2 -2
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-packs.test.js +36 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-packs.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js +137 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-group-ads.test.js +105 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-group-ads.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-groups.test.js +143 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-ad-groups.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-campaigns.test.js +100 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads-campaigns.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads.test.js +350 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-product-ads.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-return-reconciliation.test.js +228 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-return-reconciliation.test.js.map +7 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-shipping.test.js +58 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-shipping.test.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-api.js +15 -3
- package/dist/src/services/mercadolibre/mercadolibre-api.js.map +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-billing.js +110 -3
- package/dist/src/services/mercadolibre/mercadolibre-billing.js.map +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-buyer-reconciliation.js +368 -0
- package/dist/src/services/mercadolibre/mercadolibre-buyer-reconciliation.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-claim-reconciliation.js +399 -0
- package/dist/src/services/mercadolibre/mercadolibre-claim-reconciliation.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-kits.js +55 -0
- package/dist/src/services/mercadolibre/mercadolibre-kits.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-order-billing-info.js +392 -0
- package/dist/src/services/mercadolibre/mercadolibre-order-billing-info.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-orders.js +8 -8
- package/dist/src/services/mercadolibre/mercadolibre-orders.js.map +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-packs.js +21 -0
- package/dist/src/services/mercadolibre/mercadolibre-packs.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-payments.js +60 -0
- package/dist/src/services/mercadolibre/mercadolibre-payments.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-product-ads.js +429 -0
- package/dist/src/services/mercadolibre/mercadolibre-product-ads.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-return-reconciliation.js +436 -0
- package/dist/src/services/mercadolibre/mercadolibre-return-reconciliation.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-shipping.js +35 -0
- package/dist/src/services/mercadolibre/mercadolibre-shipping.js.map +7 -0
- package/dist/src/services/vtex/__tests__/vtex-api.test.js +67 -0
- package/dist/src/services/vtex/__tests__/vtex-api.test.js.map +7 -0
- package/dist/src/services/vtex/vtex-api.js +6 -0
- package/dist/src/services/vtex/vtex-api.js.map +2 -2
- package/dist/src/tools/config/__tests__/list-profiles.test.js +154 -0
- package/dist/src/tools/config/__tests__/list-profiles.test.js.map +7 -0
- package/dist/src/tools/config/list-profiles.js +39 -3
- package/dist/src/tools/config/list-profiles.js.map +2 -2
- package/dist/src/tools/mercadolibre/__tests__/get-order-billing-info.test.js +339 -0
- package/dist/src/tools/mercadolibre/__tests__/get-order-billing-info.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-group-ads.test.js +225 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-group-ads.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-groups.test.js +148 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-ad-groups.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-campaigns.test.js +60 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-campaigns.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-helpers.test.js +128 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-helpers.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-tools.test.js +435 -0
- package/dist/src/tools/mercadolibre/__tests__/product-ads-tools.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/reconcile-buyer-data.test.js +31 -0
- package/dist/src/tools/mercadolibre/__tests__/reconcile-buyer-data.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/reconcile-claim-data.test.js +36 -0
- package/dist/src/tools/mercadolibre/__tests__/reconcile-claim-data.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/__tests__/validate-connection.test.js +205 -0
- package/dist/src/tools/mercadolibre/__tests__/validate-connection.test.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js +313 -0
- package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-bundle-context-by-item.js +176 -0
- package/dist/src/tools/mercadolibre/get-bundle-context-by-item.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-full-storage-charges.js +183 -0
- package/dist/src/tools/mercadolibre/get-full-storage-charges.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-order-billing-info.js +189 -0
- package/dist/src/tools/mercadolibre/get-order-billing-info.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-pack-context-by-order.js +150 -0
- package/dist/src/tools/mercadolibre/get-pack-context-by-order.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-payment-details.js +322 -0
- package/dist/src/tools/mercadolibre/get-payment-details.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-product-ads-ad-group-ads.js +144 -0
- package/dist/src/tools/mercadolibre/get-product-ads-ad-group-ads.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-product-ads-advertisers.js +59 -0
- package/dist/src/tools/mercadolibre/get-product-ads-advertisers.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-shipping-quote-by-declared-dimensions.js +104 -0
- package/dist/src/tools/mercadolibre/get-shipping-quote-by-declared-dimensions.js.map +7 -0
- package/dist/src/tools/mercadolibre/index.js +32 -0
- package/dist/src/tools/mercadolibre/index.js.map +2 -2
- package/dist/src/tools/mercadolibre/product-ads-helpers.js +130 -0
- package/dist/src/tools/mercadolibre/product-ads-helpers.js.map +7 -0
- package/dist/src/tools/mercadolibre/reconcile-buyer-data.js +27 -0
- package/dist/src/tools/mercadolibre/reconcile-buyer-data.js.map +7 -0
- package/dist/src/tools/mercadolibre/reconcile-claim-data.js +46 -0
- package/dist/src/tools/mercadolibre/reconcile-claim-data.js.map +7 -0
- package/dist/src/tools/mercadolibre/reconcile-return-data.js +25 -0
- package/dist/src/tools/mercadolibre/reconcile-return-data.js.map +7 -0
- package/dist/src/tools/mercadolibre/search-product-ads-ad-groups.js +162 -0
- package/dist/src/tools/mercadolibre/search-product-ads-ad-groups.js.map +7 -0
- package/dist/src/tools/mercadolibre/search-product-ads-ads.js +216 -0
- package/dist/src/tools/mercadolibre/search-product-ads-ads.js.map +7 -0
- package/dist/src/tools/mercadolibre/search-product-ads-campaigns.js +116 -0
- package/dist/src/tools/mercadolibre/search-product-ads-campaigns.js.map +7 -0
- package/dist/src/tools/mercadolibre/validate-connection.js +40 -12
- package/dist/src/tools/mercadolibre/validate-connection.js.map +2 -2
- package/dist/tests/meli/mercadolibre-billing-provisions.test.js +378 -0
- package/dist/tests/meli/mercadolibre-billing-provisions.test.js.map +2 -2
- package/dist/tests/meli/mercadolibre-order-billing-info-surface.test.js +123 -0
- package/dist/tests/meli/mercadolibre-order-billing-info-surface.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-payment-details.test.js +356 -0
- package/dist/tests/meli/mercadolibre-payment-details.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-payments.test.js +62 -0
- package/dist/tests/meli/mercadolibre-payments.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-product-ads-ad-groups-surface.test.js +90 -0
- package/dist/tests/meli/mercadolibre-product-ads-ad-groups-surface.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-product-ads-campaigns-surface.test.js +72 -0
- package/dist/tests/meli/mercadolibre-product-ads-campaigns-surface.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-tool-handlers-pack-kit-shipping.test.js +400 -0
- package/dist/tests/meli/mercadolibre-tool-handlers-pack-kit-shipping.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-tool-handlers-small.test.js +31 -12
- package/dist/tests/meli/mercadolibre-tool-handlers-small.test.js.map +2 -2
- package/dist/tests/vtex/vtex-commercial-conditions-docs.test.js +1 -1
- package/dist/tests/vtex/vtex-commercial-conditions-docs.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/google-ads/report-utils.js +0 -78
- package/dist/src/google-ads/report-utils.js.map +0 -7
- package/dist/src/search-console/search-console-utils.js +0 -275
- package/dist/src/search-console/search-console-utils.js.map +0 -7
- package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +0 -165
- package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +0 -7
- package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +0 -233
- package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +0 -7
- package/dist/src/tools/vtex/catalog-admin-batch.js +0 -298
- package/dist/src/tools/vtex/catalog-admin-batch.js.map +0 -7
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
const requestUse = vi.fn();
|
|
4
|
+
vi.mock("axios", async () => {
|
|
5
|
+
const actual = await vi.importActual("axios");
|
|
6
|
+
return {
|
|
7
|
+
...actual,
|
|
8
|
+
default: {
|
|
9
|
+
...actual.default,
|
|
10
|
+
create: vi.fn((...args) => {
|
|
11
|
+
const client = actual.default.create(...args);
|
|
12
|
+
const use = client.interceptors.request.use.bind(client.interceptors.request);
|
|
13
|
+
client.interceptors.request.use = (handler, ...rest) => {
|
|
14
|
+
requestUse(handler);
|
|
15
|
+
return use(handler, ...rest);
|
|
16
|
+
};
|
|
17
|
+
return client;
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
import axios from "axios";
|
|
23
|
+
import { runWithMcpToolDeadlineContext } from "../../../config/mcp-tool-deadline-context.js";
|
|
24
|
+
import { createVtexClient } from "../vtex-api.js";
|
|
25
|
+
describe("VTEX Axios deadline propagation", () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
vi.clearAllMocks();
|
|
28
|
+
});
|
|
29
|
+
it("composes the global signal and propagates abort to the Axios request signal", async () => {
|
|
30
|
+
createVtexClient({ apiKey: "key", apiToken: "token" }, "https://vtex.test");
|
|
31
|
+
const requestInterceptor = requestUse.mock.calls[0]?.[0];
|
|
32
|
+
const globalController = new AbortController();
|
|
33
|
+
const requestController = new AbortController();
|
|
34
|
+
const request = await runWithMcpToolDeadlineContext(globalController.signal, async () => requestInterceptor({ signal: requestController.signal }));
|
|
35
|
+
expect(request.signal).toBeDefined();
|
|
36
|
+
expect(request.signal).not.toBe(globalController.signal);
|
|
37
|
+
expect(request.signal).not.toBe(requestController.signal);
|
|
38
|
+
expect(request.signal?.aborted).toBe(false);
|
|
39
|
+
globalController.abort();
|
|
40
|
+
expect(request.signal?.aborted).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
it("keeps the composed signal aborted when the request signal was already aborted", async () => {
|
|
43
|
+
createVtexClient({ apiKey: "key", apiToken: "token" }, "https://vtex.test");
|
|
44
|
+
const requestInterceptor = requestUse.mock.calls[0]?.[0];
|
|
45
|
+
const globalController = new AbortController();
|
|
46
|
+
const requestController = new AbortController();
|
|
47
|
+
requestController.abort();
|
|
48
|
+
const request = await runWithMcpToolDeadlineContext(globalController.signal, async () => requestInterceptor({ signal: requestController.signal }));
|
|
49
|
+
expect(request.signal?.aborted).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
it("keeps the provider request timeout at 30 seconds", () => {
|
|
52
|
+
createVtexClient({ apiKey: "key", apiToken: "token" }, "https://vtex.test");
|
|
53
|
+
expect(vi.mocked(axios.create)).toHaveBeenCalledWith(expect.objectContaining({ timeout: 3e4 }));
|
|
54
|
+
});
|
|
55
|
+
it("aborts an in-flight mutating POST through the instrumented client", async () => {
|
|
56
|
+
const server = createServer((_request, response) => setTimeout(() => response.end('{"Id":801}'), 100));
|
|
57
|
+
await new Promise((resolve) => server.listen(0, resolve));
|
|
58
|
+
const address = server.address();
|
|
59
|
+
const client = createVtexClient({ apiKey: "key", apiToken: "token" }, `http://127.0.0.1:${address.port}`);
|
|
60
|
+
const controller = new AbortController();
|
|
61
|
+
const post = runWithMcpToolDeadlineContext(controller.signal, () => client.post("/api/catalog/pvt/stockkeepingunit", { Name: "SKU" }));
|
|
62
|
+
setTimeout(() => controller.abort(), 10);
|
|
63
|
+
await expect(post).rejects.toMatchObject({ code: "ERR_CANCELED" });
|
|
64
|
+
server.close();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=vtex-api.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/services/vtex/__tests__/vtex-api.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { createServer } from \"node:http\";\n\nconst requestUse = vi.fn();\nvi.mock(\"axios\", async () => {\n const actual = await vi.importActual<typeof import(\"axios\")>(\"axios\");\n return {\n ...actual,\n default: {\n ...actual.default,\n create: vi.fn((...args: Parameters<typeof actual.default.create>) => {\n const client = actual.default.create(...args);\n const use = client.interceptors.request.use.bind(client.interceptors.request);\n client.interceptors.request.use = (handler, ...rest) => {\n requestUse(handler);\n return use(handler, ...rest);\n };\n return client;\n }),\n },\n };\n});\n\nimport axios from \"axios\";\nimport { runWithMcpToolDeadlineContext } from \"../../../config/mcp-tool-deadline-context.js\";\nimport { createVtexClient } from \"../vtex-api.js\";\n\ndescribe(\"VTEX Axios deadline propagation\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it(\"composes the global signal and propagates abort to the Axios request signal\", async () => {\n createVtexClient({ apiKey: \"key\", apiToken: \"token\" } as never, \"https://vtex.test\");\n const requestInterceptor = requestUse.mock.calls[0]?.[0] as (config: { signal?: AbortSignal }) => { signal?: AbortSignal };\n const globalController = new AbortController();\n const requestController = new AbortController();\n const request = await runWithMcpToolDeadlineContext(globalController.signal, async () => requestInterceptor({ signal: requestController.signal }));\n expect(request.signal).toBeDefined();\n expect(request.signal).not.toBe(globalController.signal);\n expect(request.signal).not.toBe(requestController.signal);\n expect(request.signal?.aborted).toBe(false);\n\n globalController.abort();\n expect(request.signal?.aborted).toBe(true);\n });\n\n it(\"keeps the composed signal aborted when the request signal was already aborted\", async () => {\n createVtexClient({ apiKey: \"key\", apiToken: \"token\" } as never, \"https://vtex.test\");\n const requestInterceptor = requestUse.mock.calls[0]?.[0] as (config: { signal?: AbortSignal }) => { signal?: AbortSignal };\n const globalController = new AbortController();\n const requestController = new AbortController();\n requestController.abort();\n const request = await runWithMcpToolDeadlineContext(globalController.signal, async () => requestInterceptor({ signal: requestController.signal }));\n expect(request.signal?.aborted).toBe(true);\n });\n\n it(\"keeps the provider request timeout at 30 seconds\", () => {\n createVtexClient({ apiKey: \"key\", apiToken: \"token\" } as never, \"https://vtex.test\");\n expect(vi.mocked(axios.create)).toHaveBeenCalledWith(expect.objectContaining({ timeout: 30000 }));\n });\n\n it(\"aborts an in-flight mutating POST through the instrumented client\", async () => {\n const server = createServer((_request, response) => setTimeout(() => response.end('{\"Id\":801}'), 100));\n await new Promise<void>((resolve) => server.listen(0, resolve));\n const address = server.address();\n const client = createVtexClient({ apiKey: \"key\", apiToken: \"token\" } as never, `http://127.0.0.1:${(address as { port: number }).port}`);\n const controller = new AbortController();\n const post = runWithMcpToolDeadlineContext(controller.signal, () => client.post(\"/api/catalog/pvt/stockkeepingunit\", { Name: \"SKU\" }));\n setTimeout(() => controller.abort(), 10);\n await expect(post).rejects.toMatchObject({ code: \"ERR_CANCELED\" });\n server.close();\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import { getVtexConfigForProfile } from "../../config/vtex.js";
|
|
3
|
+
import { composeMcpToolDeadlineSignal } from "../../config/mcp-tool-deadline-context.js";
|
|
3
4
|
function createVtexClient(config, baseURL) {
|
|
4
5
|
const client = axios.create({
|
|
5
6
|
baseURL,
|
|
@@ -11,6 +12,11 @@ function createVtexClient(config, baseURL) {
|
|
|
11
12
|
},
|
|
12
13
|
timeout: 3e4
|
|
13
14
|
});
|
|
15
|
+
client.interceptors.request.use((request) => {
|
|
16
|
+
const signal = composeMcpToolDeadlineSignal(request.signal);
|
|
17
|
+
if (signal) request.signal = signal;
|
|
18
|
+
return request;
|
|
19
|
+
});
|
|
14
20
|
client.interceptors.response.use(
|
|
15
21
|
(response) => response,
|
|
16
22
|
(error) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/services/vtex/vtex-api.ts"],
|
|
4
|
-
"sourcesContent": ["import axios from \"axios\";\nimport type { AxiosError, AxiosInstance } from \"axios\";\n\nimport { getVtexConfigForProfile, type VtexConfig } from \"../../config/vtex.js\";\n\nexport function createVtexClient(config: VtexConfig, baseURL: string): AxiosInstance {\n const client = axios.create({\n baseURL,\n headers: {\n \"X-VTEX-API-AppKey\": config.apiKey,\n \"X-VTEX-API-AppToken\": config.apiToken,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n timeout: 30000,\n });\n\n client.interceptors.response.use(\n (response) => response,\n (error: AxiosError) => {\n const method = error.config?.method?.toUpperCase() ?? \"UNKNOWN\";\n const url = error.config?.url ?? \"UNKNOWN_URL\";\n const status = error.response?.status ?? \"NO_STATUS\";\n\n console.error(`[VTEX API ERROR] ${method} ${url} -> ${status}`);\n\n if (error.response?.data) {\n console.error(\"[VTEX API ERROR BODY]\", error.response.data);\n }\n\n return Promise.reject(error);\n }\n );\n\n return client;\n}\n\nexport async function getVtexApiClients(profileId: string) {\n const config = await getVtexConfigForProfile(profileId);\n\n return {\n config,\n vtexApi: createVtexClient(config, config.baseUrl),\n vtexPricingApi: createVtexClient(config, config.pricingBaseUrl),\n };\n}\n\nexport async function validateVtexConfig(config: VtexConfig): Promise<void> {\n const client = createVtexClient(config, config.baseUrl);\n await client.get(\"/api/oms/pvt/orders\", {\n params: {\n page: 1,\n per_page: 1,\n },\n });\n}\n\nexport function formatVtexError(error: unknown, fallback = \"Unexpected VTEX API error\"): string {\n if (axios.isAxiosError(error)) {\n const status = error.response?.status;\n const responseData = error.response?.data;\n const responseMessage =\n typeof responseData === \"object\" && responseData !== null && \"message\" in responseData\n ? String((responseData as { message?: unknown }).message)\n : typeof responseData === \"string\"\n ? responseData\n : undefined;\n\n if (status) {\n return `VTEX API request failed (${status}): ${responseMessage ?? error.message}`;\n }\n\n return `VTEX API request failed: ${responseMessage ?? error.message}`;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return fallback;\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,WAAW;AAGlB,SAAS,+BAAgD;
|
|
4
|
+
"sourcesContent": ["import axios from \"axios\";\nimport type { AxiosError, AxiosInstance } from \"axios\";\n\nimport { getVtexConfigForProfile, type VtexConfig } from \"../../config/vtex.js\";\nimport { composeMcpToolDeadlineSignal } from \"../../config/mcp-tool-deadline-context.js\";\n\nexport function createVtexClient(config: VtexConfig, baseURL: string): AxiosInstance {\n const client = axios.create({\n baseURL,\n headers: {\n \"X-VTEX-API-AppKey\": config.apiKey,\n \"X-VTEX-API-AppToken\": config.apiToken,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n timeout: 30000,\n });\n\n client.interceptors.request.use((request) => {\n const signal = composeMcpToolDeadlineSignal(request.signal);\n if (signal) request.signal = signal;\n return request;\n });\n\n client.interceptors.response.use(\n (response) => response,\n (error: AxiosError) => {\n const method = error.config?.method?.toUpperCase() ?? \"UNKNOWN\";\n const url = error.config?.url ?? \"UNKNOWN_URL\";\n const status = error.response?.status ?? \"NO_STATUS\";\n\n console.error(`[VTEX API ERROR] ${method} ${url} -> ${status}`);\n\n if (error.response?.data) {\n console.error(\"[VTEX API ERROR BODY]\", error.response.data);\n }\n\n return Promise.reject(error);\n }\n );\n\n return client;\n}\n\nexport async function getVtexApiClients(profileId: string) {\n const config = await getVtexConfigForProfile(profileId);\n\n return {\n config,\n vtexApi: createVtexClient(config, config.baseUrl),\n vtexPricingApi: createVtexClient(config, config.pricingBaseUrl),\n };\n}\n\nexport async function validateVtexConfig(config: VtexConfig): Promise<void> {\n const client = createVtexClient(config, config.baseUrl);\n await client.get(\"/api/oms/pvt/orders\", {\n params: {\n page: 1,\n per_page: 1,\n },\n });\n}\n\nexport function formatVtexError(error: unknown, fallback = \"Unexpected VTEX API error\"): string {\n if (axios.isAxiosError(error)) {\n const status = error.response?.status;\n const responseData = error.response?.data;\n const responseMessage =\n typeof responseData === \"object\" && responseData !== null && \"message\" in responseData\n ? String((responseData as { message?: unknown }).message)\n : typeof responseData === \"string\"\n ? responseData\n : undefined;\n\n if (status) {\n return `VTEX API request failed (${status}): ${responseMessage ?? error.message}`;\n }\n\n return `VTEX API request failed: ${responseMessage ?? error.message}`;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return fallback;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,WAAW;AAGlB,SAAS,+BAAgD;AACzD,SAAS,oCAAoC;AAEtC,SAAS,iBAAiB,QAAoB,SAAgC;AACnF,QAAM,SAAS,MAAM,OAAO;AAAA,IAC1B;AAAA,IACA,SAAS;AAAA,MACP,qBAAqB,OAAO;AAAA,MAC5B,uBAAuB,OAAO;AAAA,MAC9B,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,SAAO,aAAa,QAAQ,IAAI,CAAC,YAAY;AAC3C,UAAM,SAAS,6BAA6B,QAAQ,MAAM;AAC1D,QAAI,OAAQ,SAAQ,SAAS;AAC7B,WAAO;AAAA,EACT,CAAC;AAED,SAAO,aAAa,SAAS;AAAA,IAC3B,CAAC,aAAa;AAAA,IACd,CAAC,UAAsB;AACrB,YAAM,SAAS,MAAM,QAAQ,QAAQ,YAAY,KAAK;AACtD,YAAM,MAAM,MAAM,QAAQ,OAAO;AACjC,YAAM,SAAS,MAAM,UAAU,UAAU;AAEzC,cAAQ,MAAM,oBAAoB,MAAM,IAAI,GAAG,OAAO,MAAM,EAAE;AAE9D,UAAI,MAAM,UAAU,MAAM;AACxB,gBAAQ,MAAM,yBAAyB,MAAM,SAAS,IAAI;AAAA,MAC5D;AAEA,aAAO,QAAQ,OAAO,KAAK;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,kBAAkB,WAAmB;AACzD,QAAM,SAAS,MAAM,wBAAwB,SAAS;AAEtD,SAAO;AAAA,IACL;AAAA,IACA,SAAS,iBAAiB,QAAQ,OAAO,OAAO;AAAA,IAChD,gBAAgB,iBAAiB,QAAQ,OAAO,cAAc;AAAA,EAChE;AACF;AAEA,eAAsB,mBAAmB,QAAmC;AAC1E,QAAM,SAAS,iBAAiB,QAAQ,OAAO,OAAO;AACtD,QAAM,OAAO,IAAI,uBAAuB;AAAA,IACtC,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACH;AAEO,SAAS,gBAAgB,OAAgB,WAAW,6BAAqC;AAC9F,MAAI,MAAM,aAAa,KAAK,GAAG;AAC7B,UAAM,SAAS,MAAM,UAAU;AAC/B,UAAM,eAAe,MAAM,UAAU;AACrC,UAAM,kBACJ,OAAO,iBAAiB,YAAY,iBAAiB,QAAQ,aAAa,eACtE,OAAQ,aAAuC,OAAO,IACtD,OAAO,iBAAiB,WACtB,eACA;AAER,QAAI,QAAQ;AACV,aAAO,4BAA4B,MAAM,MAAM,mBAAmB,MAAM,OAAO;AAAA,IACjF;AAEA,WAAO,4BAA4B,mBAAmB,MAAM,OAAO;AAAA,EACrE;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const objectMock = vi.fn((value) => ({ kind: "object", value }));
|
|
3
|
+
const errorMock = vi.fn((message) => ({ kind: "error", message }));
|
|
4
|
+
const listProfilesMock = vi.fn();
|
|
5
|
+
const listGoogleMappingsMock = vi.fn();
|
|
6
|
+
const listGtmSummariesMock = vi.fn();
|
|
7
|
+
const getGoogleOAuthConnectionMock = vi.fn();
|
|
8
|
+
const listVtexConnectionsMock = vi.fn();
|
|
9
|
+
const listMercadolibreConnectionsMock = vi.fn();
|
|
10
|
+
const listMetaMappingsMock = vi.fn();
|
|
11
|
+
vi.mock("mcp-use/server", () => ({ object: objectMock, error: errorMock }));
|
|
12
|
+
vi.mock("../../../config/profile-store.js", () => ({
|
|
13
|
+
listProfiles: listProfilesMock
|
|
14
|
+
}));
|
|
15
|
+
vi.mock("../../../config/google-store.js", () => ({
|
|
16
|
+
listProfileGoogleServiceMappings: listGoogleMappingsMock,
|
|
17
|
+
listActiveProfileGtmMappingSummaries: listGtmSummariesMock,
|
|
18
|
+
getGoogleOAuthConnection: getGoogleOAuthConnectionMock
|
|
19
|
+
}));
|
|
20
|
+
vi.mock("../../../config/vtex-profile-store.js", () => ({
|
|
21
|
+
listVtexConnections: listVtexConnectionsMock
|
|
22
|
+
}));
|
|
23
|
+
vi.mock("../../../config/mercadolibre-profile-store.js", () => ({
|
|
24
|
+
listMercadoLibreConnections: listMercadolibreConnectionsMock
|
|
25
|
+
}));
|
|
26
|
+
vi.mock("../../../config/meta-store.js", () => ({
|
|
27
|
+
listProfileMetaMappings: listMetaMappingsMock
|
|
28
|
+
}));
|
|
29
|
+
const { listProfilesHandler } = await import("../list-profiles.js");
|
|
30
|
+
const requiredScopes = [
|
|
31
|
+
"tagmanager.manage.accounts",
|
|
32
|
+
"tagmanager.edit.containers",
|
|
33
|
+
"tagmanager.delete.containers",
|
|
34
|
+
"tagmanager.edit.containerversions",
|
|
35
|
+
"tagmanager.manage.users",
|
|
36
|
+
"tagmanager.publish",
|
|
37
|
+
"tagmanager.readonly"
|
|
38
|
+
].map((scope) => `https://www.googleapis.com/auth/${scope}`);
|
|
39
|
+
function connection(overrides = {}) {
|
|
40
|
+
return {
|
|
41
|
+
id: "global",
|
|
42
|
+
encryptedRefreshToken: "encrypted-token",
|
|
43
|
+
scopes: requiredScopes,
|
|
44
|
+
status: "active",
|
|
45
|
+
googleAccountEmail: null,
|
|
46
|
+
lastValidatedAt: null,
|
|
47
|
+
lastError: null,
|
|
48
|
+
...overrides
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function getGtmService() {
|
|
52
|
+
const response = await listProfilesHandler();
|
|
53
|
+
return response.value.profiles[0].services.google.gtm;
|
|
54
|
+
}
|
|
55
|
+
describe("config_list_profiles GTM readiness", () => {
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
vi.clearAllMocks();
|
|
58
|
+
listProfilesMock.mockResolvedValue([
|
|
59
|
+
{
|
|
60
|
+
id: "profile-1",
|
|
61
|
+
name: "Alpha",
|
|
62
|
+
isActive: true,
|
|
63
|
+
createdAt: /* @__PURE__ */ new Date("2026-01-01T00:00:00.000Z"),
|
|
64
|
+
updatedAt: /* @__PURE__ */ new Date("2026-01-02T00:00:00.000Z")
|
|
65
|
+
}
|
|
66
|
+
]);
|
|
67
|
+
listGoogleMappingsMock.mockResolvedValue([]);
|
|
68
|
+
listGtmSummariesMock.mockResolvedValue([
|
|
69
|
+
{ profileId: "profile-1", activeMappingCount: 2 }
|
|
70
|
+
]);
|
|
71
|
+
getGoogleOAuthConnectionMock.mockResolvedValue(connection());
|
|
72
|
+
listVtexConnectionsMock.mockResolvedValue([]);
|
|
73
|
+
listMercadolibreConnectionsMock.mockResolvedValue([]);
|
|
74
|
+
listMetaMappingsMock.mockResolvedValue([]);
|
|
75
|
+
});
|
|
76
|
+
it("adds active GTM readiness without leaking mapped resource identifiers", async () => {
|
|
77
|
+
const response = await listProfilesHandler();
|
|
78
|
+
const profile = response.value.profiles[0];
|
|
79
|
+
expect(profile).toMatchObject({
|
|
80
|
+
profile_id: "profile-1",
|
|
81
|
+
name: "Alpha",
|
|
82
|
+
is_active: true,
|
|
83
|
+
created_at: "2026-01-01T00:00:00.000Z",
|
|
84
|
+
updated_at: "2026-01-02T00:00:00.000Z",
|
|
85
|
+
services: {
|
|
86
|
+
google: {
|
|
87
|
+
google_ads: {
|
|
88
|
+
configured: false,
|
|
89
|
+
status: "not_configured",
|
|
90
|
+
raw_status: null
|
|
91
|
+
},
|
|
92
|
+
ga4: {
|
|
93
|
+
configured: false,
|
|
94
|
+
status: "not_configured",
|
|
95
|
+
raw_status: null
|
|
96
|
+
},
|
|
97
|
+
search_console: {
|
|
98
|
+
configured: false,
|
|
99
|
+
status: "not_configured",
|
|
100
|
+
raw_status: null
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
vtex: { configured: false, status: "not_configured", raw_status: null },
|
|
104
|
+
mercadolibre: {
|
|
105
|
+
configured: false,
|
|
106
|
+
status: "not_configured",
|
|
107
|
+
raw_status: null
|
|
108
|
+
},
|
|
109
|
+
meta: { configured: false, status: "not_configured", raw_status: null }
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
expect(
|
|
113
|
+
profile.services.google.gtm
|
|
114
|
+
).toEqual({
|
|
115
|
+
configured: true,
|
|
116
|
+
status: "active",
|
|
117
|
+
raw_status: "active"
|
|
118
|
+
});
|
|
119
|
+
expect(JSON.stringify(profile)).not.toContain("account");
|
|
120
|
+
expect(JSON.stringify(profile)).not.toContain("container");
|
|
121
|
+
});
|
|
122
|
+
it("reports not_configured and hides OAuth raw status without active mappings", async () => {
|
|
123
|
+
listGtmSummariesMock.mockResolvedValue([]);
|
|
124
|
+
await expect(getGtmService()).resolves.toEqual({
|
|
125
|
+
configured: false,
|
|
126
|
+
status: "not_configured",
|
|
127
|
+
raw_status: null
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
it.each(["disabled", "expired", "pending", "error"])(
|
|
131
|
+
"normalizes an eligible mapping with OAuth status %s",
|
|
132
|
+
async (status) => {
|
|
133
|
+
getGoogleOAuthConnectionMock.mockResolvedValue(connection({ status }));
|
|
134
|
+
await expect(getGtmService()).resolves.toEqual({
|
|
135
|
+
configured: true,
|
|
136
|
+
status,
|
|
137
|
+
raw_status: status
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
it.each([
|
|
142
|
+
["missing connection", null],
|
|
143
|
+
["missing token", connection({ encryptedRefreshToken: null })],
|
|
144
|
+
["incomplete scopes", connection({ scopes: requiredScopes.slice(0, -1) })]
|
|
145
|
+
])("reports error for %s", async (_case, oauthConnection) => {
|
|
146
|
+
getGoogleOAuthConnectionMock.mockResolvedValue(oauthConnection);
|
|
147
|
+
await expect(getGtmService()).resolves.toEqual({
|
|
148
|
+
configured: true,
|
|
149
|
+
status: "error",
|
|
150
|
+
raw_status: oauthConnection ? "active" : null
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=list-profiles.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/tools/config/__tests__/list-profiles.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst objectMock = vi.fn((value) => ({ kind: \"object\", value }));\nconst errorMock = vi.fn((message) => ({ kind: \"error\", message }));\nconst listProfilesMock = vi.fn();\nconst listGoogleMappingsMock = vi.fn();\nconst listGtmSummariesMock = vi.fn();\nconst getGoogleOAuthConnectionMock = vi.fn();\nconst listVtexConnectionsMock = vi.fn();\nconst listMercadolibreConnectionsMock = vi.fn();\nconst listMetaMappingsMock = vi.fn();\n\nvi.mock(\"mcp-use/server\", () => ({ object: objectMock, error: errorMock }));\nvi.mock(\"../../../config/profile-store.js\", () => ({\n listProfiles: listProfilesMock,\n}));\nvi.mock(\"../../../config/google-store.js\", () => ({\n listProfileGoogleServiceMappings: listGoogleMappingsMock,\n listActiveProfileGtmMappingSummaries: listGtmSummariesMock,\n getGoogleOAuthConnection: getGoogleOAuthConnectionMock,\n}));\nvi.mock(\"../../../config/vtex-profile-store.js\", () => ({\n listVtexConnections: listVtexConnectionsMock,\n}));\nvi.mock(\"../../../config/mercadolibre-profile-store.js\", () => ({\n listMercadoLibreConnections: listMercadolibreConnectionsMock,\n}));\nvi.mock(\"../../../config/meta-store.js\", () => ({\n listProfileMetaMappings: listMetaMappingsMock,\n}));\n\nconst { listProfilesHandler } = await import(\"../list-profiles.js\");\nconst requiredScopes = [\n \"tagmanager.manage.accounts\",\n \"tagmanager.edit.containers\",\n \"tagmanager.delete.containers\",\n \"tagmanager.edit.containerversions\",\n \"tagmanager.manage.users\",\n \"tagmanager.publish\",\n \"tagmanager.readonly\",\n].map((scope) => `https://www.googleapis.com/auth/${scope}`);\n\nfunction connection(overrides: Record<string, unknown> = {}) {\n return {\n id: \"global\",\n encryptedRefreshToken: \"encrypted-token\",\n scopes: requiredScopes,\n status: \"active\",\n googleAccountEmail: null,\n lastValidatedAt: null,\n lastError: null,\n ...overrides,\n };\n}\n\nasync function getGtmService() {\n const response = await listProfilesHandler();\n return (\n response as unknown as {\n value: { profiles: Array<{ services: { google: { gtm: unknown } } }> };\n }\n ).value.profiles[0].services.google.gtm;\n}\n\ndescribe(\"config_list_profiles GTM readiness\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n listProfilesMock.mockResolvedValue([\n {\n id: \"profile-1\",\n name: \"Alpha\",\n isActive: true,\n createdAt: new Date(\"2026-01-01T00:00:00.000Z\"),\n updatedAt: new Date(\"2026-01-02T00:00:00.000Z\"),\n },\n ]);\n listGoogleMappingsMock.mockResolvedValue([]);\n listGtmSummariesMock.mockResolvedValue([\n { profileId: \"profile-1\", activeMappingCount: 2 },\n ]);\n getGoogleOAuthConnectionMock.mockResolvedValue(connection());\n listVtexConnectionsMock.mockResolvedValue([]);\n listMercadolibreConnectionsMock.mockResolvedValue([]);\n listMetaMappingsMock.mockResolvedValue([]);\n });\n\n it(\"adds active GTM readiness without leaking mapped resource identifiers\", async () => {\n const response = await listProfilesHandler();\n const profile = (\n response as unknown as {\n value: { profiles: Array<Record<string, unknown>> };\n }\n ).value.profiles[0];\n\n expect(profile).toMatchObject({\n profile_id: \"profile-1\",\n name: \"Alpha\",\n is_active: true,\n created_at: \"2026-01-01T00:00:00.000Z\",\n updated_at: \"2026-01-02T00:00:00.000Z\",\n services: {\n google: {\n google_ads: {\n configured: false,\n status: \"not_configured\",\n raw_status: null,\n },\n ga4: {\n configured: false,\n status: \"not_configured\",\n raw_status: null,\n },\n search_console: {\n configured: false,\n status: \"not_configured\",\n raw_status: null,\n },\n },\n vtex: { configured: false, status: \"not_configured\", raw_status: null },\n mercadolibre: {\n configured: false,\n status: \"not_configured\",\n raw_status: null,\n },\n meta: { configured: false, status: \"not_configured\", raw_status: null },\n },\n });\n expect(\n (profile.services as { google: { gtm: unknown } }).google.gtm,\n ).toEqual({\n configured: true,\n status: \"active\",\n raw_status: \"active\",\n });\n expect(JSON.stringify(profile)).not.toContain(\"account\");\n expect(JSON.stringify(profile)).not.toContain(\"container\");\n });\n\n it(\"reports not_configured and hides OAuth raw status without active mappings\", async () => {\n listGtmSummariesMock.mockResolvedValue([]);\n\n await expect(getGtmService()).resolves.toEqual({\n configured: false,\n status: \"not_configured\",\n raw_status: null,\n });\n });\n\n it.each([\"disabled\", \"expired\", \"pending\", \"error\"])(\n \"normalizes an eligible mapping with OAuth status %s\",\n async (status) => {\n getGoogleOAuthConnectionMock.mockResolvedValue(connection({ status }));\n\n await expect(getGtmService()).resolves.toEqual({\n configured: true,\n status,\n raw_status: status,\n });\n },\n );\n\n it.each([\n [\"missing connection\", null],\n [\"missing token\", connection({ encryptedRefreshToken: null })],\n [\"incomplete scopes\", connection({ scopes: requiredScopes.slice(0, -1) })],\n ])(\"reports error for %s\", async (_case, oauthConnection) => {\n getGoogleOAuthConnectionMock.mockResolvedValue(oauthConnection);\n\n await expect(getGtmService()).resolves.toEqual({\n configured: true,\n status: \"error\",\n raw_status: oauthConnection ? \"active\" : null,\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { error, object } from "mcp-use/server";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getGoogleOAuthConnection,
|
|
5
|
+
listActiveProfileGtmMappingSummaries,
|
|
6
|
+
listProfileGoogleServiceMappings
|
|
7
|
+
} from "../../config/google-store.js";
|
|
4
8
|
import { listMercadoLibreConnections } from "../../config/mercadolibre-profile-store.js";
|
|
5
9
|
import { listProfileMetaMappings } from "../../config/meta-store.js";
|
|
6
10
|
import { listProfiles } from "../../config/profile-store.js";
|
|
7
11
|
import { listVtexConnections } from "../../config/vtex-profile-store.js";
|
|
8
12
|
const listProfilesSchema = z.object({});
|
|
13
|
+
const REQUIRED_GTM_SCOPES = [
|
|
14
|
+
"https://www.googleapis.com/auth/tagmanager.manage.accounts",
|
|
15
|
+
"https://www.googleapis.com/auth/tagmanager.edit.containers",
|
|
16
|
+
"https://www.googleapis.com/auth/tagmanager.delete.containers",
|
|
17
|
+
"https://www.googleapis.com/auth/tagmanager.edit.containerversions",
|
|
18
|
+
"https://www.googleapis.com/auth/tagmanager.manage.users",
|
|
19
|
+
"https://www.googleapis.com/auth/tagmanager.publish",
|
|
20
|
+
"https://www.googleapis.com/auth/tagmanager.readonly"
|
|
21
|
+
];
|
|
22
|
+
function getGtmStatus(configured, connection) {
|
|
23
|
+
if (!configured) return "not_configured";
|
|
24
|
+
if (!connection) return "error";
|
|
25
|
+
if (connection.status !== "active") return connection.status;
|
|
26
|
+
if (!connection.encryptedRefreshToken) return "error";
|
|
27
|
+
return REQUIRED_GTM_SCOPES.every((scope) => connection.scopes.includes(scope)) ? "active" : "error";
|
|
28
|
+
}
|
|
9
29
|
function normalizeVtexStatus(status) {
|
|
10
30
|
switch (status) {
|
|
11
31
|
case "valid":
|
|
@@ -26,13 +46,17 @@ async function listProfilesHandler() {
|
|
|
26
46
|
mappings,
|
|
27
47
|
vtexConnections,
|
|
28
48
|
mercadolibreConnections,
|
|
29
|
-
metaMappings
|
|
49
|
+
metaMappings,
|
|
50
|
+
gtmMappingSummaries,
|
|
51
|
+
googleOAuthConnection
|
|
30
52
|
] = await Promise.all([
|
|
31
53
|
listProfiles({ activeOnly: true }),
|
|
32
54
|
listProfileGoogleServiceMappings(),
|
|
33
55
|
listVtexConnections(),
|
|
34
56
|
listMercadoLibreConnections(),
|
|
35
|
-
listProfileMetaMappings()
|
|
57
|
+
listProfileMetaMappings(),
|
|
58
|
+
listActiveProfileGtmMappingSummaries(),
|
|
59
|
+
getGoogleOAuthConnection()
|
|
36
60
|
]);
|
|
37
61
|
const mappingsByProfileId = new Map(
|
|
38
62
|
mappings.map((mapping) => [mapping.profileId, mapping])
|
|
@@ -49,6 +73,12 @@ async function listProfilesHandler() {
|
|
|
49
73
|
const metaByProfileId = new Map(
|
|
50
74
|
metaMappings.map((mapping) => [mapping.profileId, mapping])
|
|
51
75
|
);
|
|
76
|
+
const gtmMappingCountByProfileId = new Map(
|
|
77
|
+
gtmMappingSummaries.map((summary) => [
|
|
78
|
+
summary.profileId,
|
|
79
|
+
summary.activeMappingCount
|
|
80
|
+
])
|
|
81
|
+
);
|
|
52
82
|
return object({
|
|
53
83
|
total_profiles: profiles.length,
|
|
54
84
|
profiles: profiles.map((profile) => {
|
|
@@ -59,6 +89,7 @@ async function listProfilesHandler() {
|
|
|
59
89
|
const metaConfigured = Boolean(
|
|
60
90
|
metaMapping?.metaBusinessId && metaMapping.status === "active"
|
|
61
91
|
);
|
|
92
|
+
const gtmConfigured = (gtmMappingCountByProfileId.get(profile.id) ?? 0) > 0;
|
|
62
93
|
return {
|
|
63
94
|
profile_id: profile.id,
|
|
64
95
|
name: profile.name,
|
|
@@ -81,6 +112,11 @@ async function listProfilesHandler() {
|
|
|
81
112
|
configured: Boolean(mapping?.searchConsoleSiteUrl),
|
|
82
113
|
status: mapping?.searchConsoleSiteUrl ? mapping.searchConsoleStatus : "not_configured",
|
|
83
114
|
raw_status: mapping?.searchConsoleSiteUrl ? mapping.searchConsoleStatus : null
|
|
115
|
+
},
|
|
116
|
+
gtm: {
|
|
117
|
+
configured: gtmConfigured,
|
|
118
|
+
status: getGtmStatus(gtmConfigured, googleOAuthConnection),
|
|
119
|
+
raw_status: gtmConfigured ? googleOAuthConnection?.status ?? null : null
|
|
84
120
|
}
|
|
85
121
|
},
|
|
86
122
|
vtex: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/tools/config/list-profiles.ts"],
|
|
4
|
-
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAClB,
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\nimport {\n\tgetGoogleOAuthConnection,\n\tlistActiveProfileGtmMappingSummaries,\n\tlistProfileGoogleServiceMappings,\n\ttype GoogleOAuthConnectionRecord,\n} from \"../../config/google-store.js\";\nimport { listMercadoLibreConnections } from \"../../config/mercadolibre-profile-store.js\";\nimport { listProfileMetaMappings } from \"../../config/meta-store.js\";\nimport { listProfiles } from \"../../config/profile-store.js\";\nimport { listVtexConnections } from \"../../config/vtex-profile-store.js\";\n\nexport const listProfilesSchema = z.object({});\n\ntype NormalizedServiceStatus =\n\t| \"active\"\n\t| \"disabled\"\n\t| \"expired\"\n\t| \"error\"\n\t| \"pending\"\n\t| \"not_configured\";\n\nconst REQUIRED_GTM_SCOPES = [\n\t\"https://www.googleapis.com/auth/tagmanager.manage.accounts\",\n\t\"https://www.googleapis.com/auth/tagmanager.edit.containers\",\n\t\"https://www.googleapis.com/auth/tagmanager.delete.containers\",\n\t\"https://www.googleapis.com/auth/tagmanager.edit.containerversions\",\n\t\"https://www.googleapis.com/auth/tagmanager.manage.users\",\n\t\"https://www.googleapis.com/auth/tagmanager.publish\",\n\t\"https://www.googleapis.com/auth/tagmanager.readonly\",\n] as const;\n\nfunction getGtmStatus(\n\tconfigured: boolean,\n\tconnection: GoogleOAuthConnectionRecord | null,\n): NormalizedServiceStatus {\n\tif (!configured) return \"not_configured\";\n\tif (!connection) return \"error\";\n\tif (connection.status !== \"active\") return connection.status;\n\tif (!connection.encryptedRefreshToken) return \"error\";\n\treturn REQUIRED_GTM_SCOPES.every((scope) => connection.scopes.includes(scope))\n\t\t? \"active\"\n\t\t: \"error\";\n}\n\nfunction normalizeVtexStatus(\n\tstatus: \"pending\" | \"valid\" | \"invalid\" | \"disabled\",\n): Exclude<NormalizedServiceStatus, \"expired\" | \"not_configured\"> {\n\tswitch (status) {\n\t\tcase \"valid\":\n\t\t\treturn \"active\";\n\t\tcase \"invalid\":\n\t\t\treturn \"error\";\n\t\tcase \"disabled\":\n\t\t\treturn \"disabled\";\n\t\tcase \"pending\":\n\t\tdefault:\n\t\t\treturn \"pending\";\n\t}\n}\n\nexport async function listProfilesHandler() {\n\ttry {\n\t\tconst [\n\t\t\tprofiles,\n\t\t\tmappings,\n\t\t\tvtexConnections,\n\t\t\tmercadolibreConnections,\n\t\t\tmetaMappings,\n\t\t\tgtmMappingSummaries,\n\t\t\tgoogleOAuthConnection,\n\t\t] = await Promise.all([\n\t\t\tlistProfiles({ activeOnly: true }),\n\t\t\tlistProfileGoogleServiceMappings(),\n\t\t\tlistVtexConnections(),\n\t\t\tlistMercadoLibreConnections(),\n\t\t\tlistProfileMetaMappings(),\n\t\t\tlistActiveProfileGtmMappingSummaries(),\n\t\t\tgetGoogleOAuthConnection(),\n\t\t]);\n\t\tconst mappingsByProfileId = new Map(\n\t\t\tmappings.map((mapping) => [mapping.profileId, mapping]),\n\t\t);\n\t\tconst vtexByProfileId = new Map(\n\t\t\tvtexConnections.map((connection) => [connection.profileId, connection]),\n\t\t);\n\t\tconst mercadolibreByProfileId = new Map(\n\t\t\tmercadolibreConnections.map((connection) => [\n\t\t\t\tconnection.profileId,\n\t\t\t\tconnection,\n\t\t\t]),\n\t\t);\n\t\tconst metaByProfileId = new Map(\n\t\t\tmetaMappings.map((mapping) => [mapping.profileId, mapping]),\n\t\t);\n\t\tconst gtmMappingCountByProfileId = new Map(\n\t\t\tgtmMappingSummaries.map((summary) => [\n\t\t\t\tsummary.profileId,\n\t\t\t\tsummary.activeMappingCount,\n\t\t\t]),\n\t\t);\n\t\treturn object({\n\t\t\ttotal_profiles: profiles.length,\n\t\t\tprofiles: profiles.map((profile) => {\n\t\t\t\tconst mapping = mappingsByProfileId.get(profile.id);\n\t\t\t\tconst vtexConnection = vtexByProfileId.get(profile.id);\n\t\t\t\tconst mercadolibreConnection = mercadolibreByProfileId.get(profile.id);\n\t\t\t\tconst metaMapping = metaByProfileId.get(profile.id);\n\t\t\t\tconst metaConfigured = Boolean(\n\t\t\t\t\tmetaMapping?.metaBusinessId && metaMapping.status === \"active\",\n\t\t\t\t);\n\t\t\t\tconst gtmConfigured =\n\t\t\t\t\t(gtmMappingCountByProfileId.get(profile.id) ?? 0) > 0;\n\t\t\t\treturn {\n\t\t\t\t\tprofile_id: profile.id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\tis_active: profile.isActive,\n\t\t\t\t\tcreated_at: profile.createdAt.toISOString(),\n\t\t\t\t\tupdated_at: profile.updatedAt.toISOString(),\n\t\t\t\t\tservices: {\n\t\t\t\t\t\tgoogle: {\n\t\t\t\t\t\t\tgoogle_ads: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.googleAdsCustomerId),\n\t\t\t\t\t\t\t\tstatus: mapping?.googleAdsCustomerId\n\t\t\t\t\t\t\t\t\t? mapping.googleAdsStatus\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.googleAdsCustomerId\n\t\t\t\t\t\t\t\t\t? mapping.googleAdsStatus\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tga4: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.ga4PropertyId),\n\t\t\t\t\t\t\t\tstatus: mapping?.ga4PropertyId\n\t\t\t\t\t\t\t\t\t? mapping.ga4Status\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.ga4PropertyId ? mapping.ga4Status : null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsearch_console: {\n\t\t\t\t\t\t\t\tconfigured: Boolean(mapping?.searchConsoleSiteUrl),\n\t\t\t\t\t\t\t\tstatus: mapping?.searchConsoleSiteUrl\n\t\t\t\t\t\t\t\t\t? mapping.searchConsoleStatus\n\t\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\t\traw_status: mapping?.searchConsoleSiteUrl\n\t\t\t\t\t\t\t\t\t? mapping.searchConsoleStatus\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tgtm: {\n\t\t\t\t\t\t\t\tconfigured: gtmConfigured,\n\t\t\t\t\t\t\t\tstatus: getGtmStatus(gtmConfigured, googleOAuthConnection),\n\t\t\t\t\t\t\t\traw_status: gtmConfigured\n\t\t\t\t\t\t\t\t\t? (googleOAuthConnection?.status ?? null)\n\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvtex: {\n\t\t\t\t\t\t\tconfigured: Boolean(vtexConnection),\n\t\t\t\t\t\t\tstatus: vtexConnection\n\t\t\t\t\t\t\t\t? normalizeVtexStatus(vtexConnection.status)\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: vtexConnection ? vtexConnection.status : null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmercadolibre: {\n\t\t\t\t\t\t\tconfigured: Boolean(mercadolibreConnection),\n\t\t\t\t\t\t\tstatus: mercadolibreConnection\n\t\t\t\t\t\t\t\t? mercadolibreConnection.status\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: mercadolibreConnection\n\t\t\t\t\t\t\t\t? mercadolibreConnection.status\n\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\tconfigured: metaConfigured,\n\t\t\t\t\t\t\tstatus: metaConfigured\n\t\t\t\t\t\t\t\t? (metaMapping?.status ?? \"not_configured\")\n\t\t\t\t\t\t\t\t: \"not_configured\",\n\t\t\t\t\t\t\traw_status: metaMapping?.status ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t\t});\n\t} catch (err) {\n\t\treturn error(\n\t\t\terr instanceof Error ? err.message : \"Failed to list profiles\",\n\t\t);\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|