@yoryoboy/bi-mcp 1.19.0 → 1.20.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 (53) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/mcp-use.json +6 -3
  3. package/dist/scripts/profile-mercadolibre-billing.js +634 -0
  4. package/dist/scripts/profile-mercadolibre-billing.js.map +7 -0
  5. package/dist/src/config/__tests__/tiendanube-profile-store.test.js +50 -0
  6. package/dist/src/config/__tests__/tiendanube-profile-store.test.js.map +7 -0
  7. package/dist/src/config/tiendanube-profile-store.js +31 -0
  8. package/dist/src/config/tiendanube-profile-store.js.map +7 -0
  9. package/dist/src/google-ads/report-utils.js +78 -0
  10. package/dist/src/google-ads/report-utils.js.map +7 -0
  11. package/dist/src/search-console/search-console-utils.js +275 -0
  12. package/dist/src/search-console/search-console-utils.js.map +7 -0
  13. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js +358 -0
  14. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report-ventas.test.js.map +7 -0
  15. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js +96 -0
  16. package/dist/src/services/mercadolibre/__tests__/mercadolibre-sales-report.test.js.map +7 -0
  17. package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js +15 -0
  18. package/dist/src/services/mercadolibre/mercadolibre-claim-return-lookup.js.map +7 -0
  19. package/dist/src/services/mercadolibre/mercadolibre-observability.js +12 -0
  20. package/dist/src/services/mercadolibre/mercadolibre-observability.js.map +7 -0
  21. package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js +7 -0
  22. package/dist/src/services/mercadolibre/mercadolibre-sale-reference.js.map +7 -0
  23. package/dist/src/services/mercadolibre/mercadolibre-sales-report.js +553 -0
  24. package/dist/src/services/mercadolibre/mercadolibre-sales-report.js.map +7 -0
  25. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js +165 -0
  26. package/dist/src/services/vtex/__tests__/vtex-catalog-write-batch.test.js.map +7 -0
  27. package/dist/src/tools/config/__tests__/list-profiles.test.js +144 -1
  28. package/dist/src/tools/config/__tests__/list-profiles.test.js.map +2 -2
  29. package/dist/src/tools/config/list-profiles.js +50 -6
  30. package/dist/src/tools/config/list-profiles.js.map +2 -2
  31. package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js +417 -0
  32. package/dist/src/tools/mercadolibre/__tests__/get-sales-report-foundation.test.js.map +7 -0
  33. package/dist/src/tools/mercadolibre/get-sales-report.js +474 -0
  34. package/dist/src/tools/mercadolibre/get-sales-report.js.map +7 -0
  35. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js +233 -0
  36. package/dist/src/tools/vtex/__tests__/catalog-admin-batch.test.js.map +7 -0
  37. package/dist/src/tools/vtex/catalog-admin-batch.js +298 -0
  38. package/dist/src/tools/vtex/catalog-admin-batch.js.map +7 -0
  39. package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js +137 -0
  40. package/dist/tests/meli/meli-sales-report-buyers-mcp-e2e.test.js.map +7 -0
  41. package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js +24 -0
  42. package/dist/tests/meli/meli-sales-report-mcp-e2e-server.js.map +7 -0
  43. package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js +207 -0
  44. package/dist/tests/meli/meli-sales-report-mcp-e2e.test.js.map +7 -0
  45. package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js +10 -0
  46. package/dist/tests/meli/meli-sales-report-public-mcp-e2e-server.js.map +7 -0
  47. package/dist/tests/meli/meli-sales-report-public-registration.test.js +98 -0
  48. package/dist/tests/meli/meli-sales-report-public-registration.test.js.map +7 -0
  49. package/dist/tests/smoke/process-harness.js +89 -0
  50. package/dist/tests/smoke/process-harness.js.map +7 -0
  51. package/dist/tests/smoke/process-harness.test.js +39 -0
  52. package/dist/tests/smoke/process-harness.test.js.map +7 -0
  53. package/package.json +1 -1
@@ -0,0 +1,233 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ const resolveVtexProfileOrSelectionMock = vi.fn();
3
+ const planCatalogBatchMock = vi.fn();
4
+ const executeCatalogBatchMock = vi.fn();
5
+ vi.mock("../profile-resolution.js", () => ({
6
+ resolveVtexProfileOrSelection: resolveVtexProfileOrSelectionMock
7
+ }));
8
+ vi.mock("../../../services/vtex/vtex-catalog-write.js", () => ({
9
+ planCatalogBatch: planCatalogBatchMock,
10
+ executeCatalogBatch: executeCatalogBatchMock
11
+ }));
12
+ const moduleUnderTest = await import("../catalog-admin-batch.js");
13
+ function getStructured(result) {
14
+ if (result && typeof result === "object" && "structuredContent" in result) {
15
+ return result.structuredContent;
16
+ }
17
+ return result;
18
+ }
19
+ describe("catalog-admin-batch", () => {
20
+ beforeEach(() => {
21
+ vi.clearAllMocks();
22
+ resolveVtexProfileOrSelectionMock.mockResolvedValue({
23
+ ok: true,
24
+ value: { profileId: "profile-1" }
25
+ });
26
+ });
27
+ it("auto-applies medium-risk batch after safe preflight", async () => {
28
+ planCatalogBatchMock.mockResolvedValue({
29
+ preflight: {
30
+ entities: 2,
31
+ entityTypes: ["product", "sku"],
32
+ destructive: false,
33
+ hasDeleteOrReplaceAll: false,
34
+ dependencyFailureCount: 0,
35
+ multiEntityCriticalReassignment: false
36
+ },
37
+ warnings: [],
38
+ impactedEntityTypes: ["product", "sku"],
39
+ before: [{ operation_index: 0, snapshot: { id: "10" } }],
40
+ after: [{ operation_index: 0, snapshot: { id: "10", updated: true } }]
41
+ });
42
+ executeCatalogBatchMock.mockResolvedValue({
43
+ successful: [
44
+ {
45
+ operation_index: 0,
46
+ operation_type: "update_product_basic_fields",
47
+ resource_id: "10",
48
+ result: { ok: true }
49
+ }
50
+ ],
51
+ failed: []
52
+ });
53
+ const result = await moduleUnderTest.catalogAdminBatchHandler({
54
+ profileId: "profile-1",
55
+ mode: "apply",
56
+ requestedRiskLevel: "medium",
57
+ operations: [
58
+ {
59
+ type: "update_product_basic_fields",
60
+ productId: "10",
61
+ updates: { name: "Updated" }
62
+ }
63
+ ]
64
+ });
65
+ expect(planCatalogBatchMock).toHaveBeenCalledWith("profile-1", [
66
+ {
67
+ type: "update_product_basic_fields",
68
+ productId: "10",
69
+ updates: { name: "Updated" }
70
+ }
71
+ ]);
72
+ expect(executeCatalogBatchMock).toHaveBeenCalledTimes(1);
73
+ const structured = getStructured(result);
74
+ expect(structured).toMatchObject({
75
+ success: true,
76
+ operation: "catalog_admin_batch",
77
+ requested_risk_level: "medium",
78
+ risk_level: "medium",
79
+ details: {
80
+ mode: "apply",
81
+ execution: {
82
+ successful_count: 1,
83
+ failed_count: 0
84
+ }
85
+ }
86
+ });
87
+ });
88
+ it("escalates medium-risk requests to high and returns preview token", async () => {
89
+ planCatalogBatchMock.mockResolvedValue({
90
+ preflight: {
91
+ entities: 12,
92
+ entityTypes: ["product"],
93
+ destructive: false,
94
+ hasDeleteOrReplaceAll: false,
95
+ dependencyFailureCount: 0,
96
+ multiEntityCriticalReassignment: false
97
+ },
98
+ warnings: [],
99
+ impactedEntityTypes: ["product"],
100
+ before: [],
101
+ after: []
102
+ });
103
+ const result = await moduleUnderTest.catalogAdminBatchHandler({
104
+ profileId: "profile-1",
105
+ mode: "preview",
106
+ requestedRiskLevel: "medium",
107
+ operations: [
108
+ {
109
+ type: "update_product_basic_fields",
110
+ productId: "10",
111
+ updates: { name: "Updated" }
112
+ }
113
+ ]
114
+ });
115
+ expect(executeCatalogBatchMock).not.toHaveBeenCalled();
116
+ const structured = getStructured(result);
117
+ expect(structured).toMatchObject({
118
+ success: true,
119
+ operation: "catalog_admin_batch",
120
+ requested_risk_level: "medium",
121
+ risk_level: "high",
122
+ escalated: true
123
+ });
124
+ expect(structured.confirmation_requirements).toMatchObject({ required: true });
125
+ expect(structured.details?.preview_id).toEqual(
126
+ expect.any(String)
127
+ );
128
+ });
129
+ it("blocks high-risk apply without preview id and explicit confirmation", async () => {
130
+ planCatalogBatchMock.mockResolvedValue({
131
+ preflight: {
132
+ entities: 1,
133
+ entityTypes: ["sku"],
134
+ destructive: true,
135
+ hasDeleteOrReplaceAll: true,
136
+ dependencyFailureCount: 0,
137
+ multiEntityCriticalReassignment: false
138
+ },
139
+ warnings: ["destructive_operation_detected"],
140
+ impactedEntityTypes: ["sku"],
141
+ before: [],
142
+ after: []
143
+ });
144
+ const missingPreviewIdResult = await moduleUnderTest.catalogAdminBatchHandler({
145
+ profileId: "profile-1",
146
+ mode: "apply",
147
+ requestedRiskLevel: "high",
148
+ operations: [
149
+ {
150
+ type: "replace_sku_eans",
151
+ skuId: "22",
152
+ eans: ["7790011223344"]
153
+ }
154
+ ],
155
+ confirmed: true
156
+ });
157
+ expect(getStructured(missingPreviewIdResult)).toMatchObject({
158
+ success: false,
159
+ error_code: "INVALID_OPERATION"
160
+ });
161
+ const expectedPreviewId = getStructured(missingPreviewIdResult).details?.expected_preview_id;
162
+ const missingConfirmationResult = await moduleUnderTest.catalogAdminBatchHandler({
163
+ profileId: "profile-1",
164
+ mode: "apply",
165
+ requestedRiskLevel: "high",
166
+ previewId: expectedPreviewId,
167
+ operations: [
168
+ {
169
+ type: "replace_sku_eans",
170
+ skuId: "22",
171
+ eans: ["7790011223344"]
172
+ }
173
+ ]
174
+ });
175
+ expect(getStructured(missingConfirmationResult)).toMatchObject({
176
+ success: false,
177
+ error_code: "EXPLICIT_CONFIRMATION_REQUIRED"
178
+ });
179
+ expect(executeCatalogBatchMock).not.toHaveBeenCalled();
180
+ });
181
+ it("adds partial-failure warnings when apply has failed operations", async () => {
182
+ planCatalogBatchMock.mockResolvedValue({
183
+ preflight: {
184
+ entities: 1,
185
+ entityTypes: ["sku"],
186
+ destructive: false,
187
+ hasDeleteOrReplaceAll: false,
188
+ dependencyFailureCount: 0,
189
+ multiEntityCriticalReassignment: false
190
+ },
191
+ warnings: [],
192
+ impactedEntityTypes: ["sku"],
193
+ before: [],
194
+ after: []
195
+ });
196
+ executeCatalogBatchMock.mockResolvedValue({
197
+ successful: [],
198
+ failed: [
199
+ {
200
+ operation_index: 0,
201
+ operation_type: "update_sku_basic_fields",
202
+ resource_id: "22",
203
+ message: "VTEX timeout"
204
+ }
205
+ ]
206
+ });
207
+ const result = await moduleUnderTest.catalogAdminBatchHandler({
208
+ profileId: "profile-1",
209
+ mode: "apply",
210
+ requestedRiskLevel: "medium",
211
+ operations: [
212
+ {
213
+ type: "update_sku_basic_fields",
214
+ skuId: "22",
215
+ updates: { name: "SKU v2" }
216
+ }
217
+ ]
218
+ });
219
+ const structured = getStructured(result);
220
+ expect(structured).toMatchObject({
221
+ success: true,
222
+ warnings: expect.arrayContaining(["partial_failures_detected"]),
223
+ details: {
224
+ mode: "apply",
225
+ execution: {
226
+ successful_count: 0,
227
+ failed_count: 1
228
+ }
229
+ }
230
+ });
231
+ });
232
+ });
233
+ //# sourceMappingURL=catalog-admin-batch.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/vtex/__tests__/catalog-admin-batch.test.ts"],
4
+ "sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst resolveVtexProfileOrSelectionMock = vi.fn();\n\nconst planCatalogBatchMock = vi.fn();\nconst executeCatalogBatchMock = vi.fn();\n\nvi.mock(\"../profile-resolution.js\", () => ({\n resolveVtexProfileOrSelection: resolveVtexProfileOrSelectionMock,\n}));\n\nvi.mock(\"../../../services/vtex/vtex-catalog-write.js\", () => ({\n planCatalogBatch: planCatalogBatchMock,\n executeCatalogBatch: executeCatalogBatchMock,\n}));\n\nconst moduleUnderTest = await import(\"../catalog-admin-batch.js\");\n\nfunction getStructured(result: unknown): Record<string, unknown> {\n if (result && typeof result === \"object\" && \"structuredContent\" in result) {\n return (result as { structuredContent: Record<string, unknown> }).structuredContent;\n }\n\n return result as Record<string, unknown>;\n}\n\ndescribe(\"catalog-admin-batch\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n resolveVtexProfileOrSelectionMock.mockResolvedValue({\n ok: true,\n value: { profileId: \"profile-1\" },\n });\n });\n\n it(\"auto-applies medium-risk batch after safe preflight\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 2,\n entityTypes: [\"product\", \"sku\"],\n destructive: false,\n hasDeleteOrReplaceAll: false,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [],\n impactedEntityTypes: [\"product\", \"sku\"],\n before: [{ operation_index: 0, snapshot: { id: \"10\" } }],\n after: [{ operation_index: 0, snapshot: { id: \"10\", updated: true } }],\n });\n\n executeCatalogBatchMock.mockResolvedValue({\n successful: [\n {\n operation_index: 0,\n operation_type: \"update_product_basic_fields\",\n resource_id: \"10\",\n result: { ok: true },\n },\n ],\n failed: [],\n });\n\n const result = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"medium\",\n operations: [\n {\n type: \"update_product_basic_fields\",\n productId: \"10\",\n updates: { name: \"Updated\" },\n },\n ],\n });\n\n expect(planCatalogBatchMock).toHaveBeenCalledWith(\"profile-1\", [\n {\n type: \"update_product_basic_fields\",\n productId: \"10\",\n updates: { name: \"Updated\" },\n },\n ]);\n expect(executeCatalogBatchMock).toHaveBeenCalledTimes(1);\n const structured = getStructured(result);\n\n expect(structured).toMatchObject({\n success: true,\n operation: \"catalog_admin_batch\",\n requested_risk_level: \"medium\",\n risk_level: \"medium\",\n details: {\n mode: \"apply\",\n execution: {\n successful_count: 1,\n failed_count: 0,\n },\n },\n });\n });\n\n it(\"escalates medium-risk requests to high and returns preview token\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 12,\n entityTypes: [\"product\"],\n destructive: false,\n hasDeleteOrReplaceAll: false,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [],\n impactedEntityTypes: [\"product\"],\n before: [],\n after: [],\n });\n\n const result = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"preview\",\n requestedRiskLevel: \"medium\",\n operations: [\n {\n type: \"update_product_basic_fields\",\n productId: \"10\",\n updates: { name: \"Updated\" },\n },\n ],\n });\n\n expect(executeCatalogBatchMock).not.toHaveBeenCalled();\n const structured = getStructured(result);\n\n expect(structured).toMatchObject({\n success: true,\n operation: \"catalog_admin_batch\",\n requested_risk_level: \"medium\",\n risk_level: \"high\",\n escalated: true,\n });\n expect(structured.confirmation_requirements).toMatchObject({ required: true });\n expect((structured.details as { preview_id?: string } | undefined)?.preview_id).toEqual(\n expect.any(String)\n );\n });\n\n it(\"blocks high-risk apply without preview id and explicit confirmation\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 1,\n entityTypes: [\"sku\"],\n destructive: true,\n hasDeleteOrReplaceAll: true,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [\"destructive_operation_detected\"],\n impactedEntityTypes: [\"sku\"],\n before: [],\n after: [],\n });\n\n const missingPreviewIdResult = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"high\",\n operations: [\n {\n type: \"replace_sku_eans\",\n skuId: \"22\",\n eans: [\"7790011223344\"],\n },\n ],\n confirmed: true,\n });\n\n expect(getStructured(missingPreviewIdResult)).toMatchObject({\n success: false,\n error_code: \"INVALID_OPERATION\",\n });\n\n const expectedPreviewId = (\n getStructured(missingPreviewIdResult).details as { expected_preview_id?: string } | undefined\n )?.expected_preview_id;\n\n const missingConfirmationResult = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"high\",\n previewId: expectedPreviewId,\n operations: [\n {\n type: \"replace_sku_eans\",\n skuId: \"22\",\n eans: [\"7790011223344\"],\n },\n ],\n });\n\n expect(getStructured(missingConfirmationResult)).toMatchObject({\n success: false,\n error_code: \"EXPLICIT_CONFIRMATION_REQUIRED\",\n });\n expect(executeCatalogBatchMock).not.toHaveBeenCalled();\n });\n\n it(\"adds partial-failure warnings when apply has failed operations\", async () => {\n planCatalogBatchMock.mockResolvedValue({\n preflight: {\n entities: 1,\n entityTypes: [\"sku\"],\n destructive: false,\n hasDeleteOrReplaceAll: false,\n dependencyFailureCount: 0,\n multiEntityCriticalReassignment: false,\n },\n warnings: [],\n impactedEntityTypes: [\"sku\"],\n before: [],\n after: [],\n });\n\n executeCatalogBatchMock.mockResolvedValue({\n successful: [],\n failed: [\n {\n operation_index: 0,\n operation_type: \"update_sku_basic_fields\",\n resource_id: \"22\",\n message: \"VTEX timeout\",\n },\n ],\n });\n\n const result = await moduleUnderTest.catalogAdminBatchHandler({\n profileId: \"profile-1\",\n mode: \"apply\",\n requestedRiskLevel: \"medium\",\n operations: [\n {\n type: \"update_sku_basic_fields\",\n skuId: \"22\",\n updates: { name: \"SKU v2\" },\n },\n ],\n });\n\n const structured = getStructured(result);\n\n expect(structured).toMatchObject({\n success: true,\n warnings: expect.arrayContaining([\"partial_failures_detected\"]),\n details: {\n mode: \"apply\",\n execution: {\n successful_count: 0,\n failed_count: 1,\n },\n },\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,298 @@
1
+ import { object } from "mcp-use/server";
2
+ import { z } from "zod";
3
+ import {
4
+ executeCatalogBatch,
5
+ planCatalogBatch
6
+ } from "../../services/vtex/vtex-catalog-write.js";
7
+ import {
8
+ classifyVtexWriteRisk,
9
+ getPreviewRequirements
10
+ } from "../../services/vtex/vtex-write.js";
11
+ import {
12
+ buildBatchExecutionWarnings,
13
+ buildPreflightSummary,
14
+ buildPreviewResponse,
15
+ buildWriteSuccessResponse,
16
+ confirmationNoteSchemaField,
17
+ confirmationSchemaField,
18
+ createBatchPreviewId,
19
+ createBatchPreviewToken,
20
+ decodeBatchPreviewToken,
21
+ handleVtexWriteError,
22
+ requireExplicitConfirmation,
23
+ resolveVtexWriteProfile,
24
+ vtexProfileIdSchemaField
25
+ } from "./write-helpers.js";
26
+ const updateProductOperationSchema = z.object({
27
+ type: z.literal("update_product_basic_fields"),
28
+ productId: z.string().trim().min(1).describe("VTEX product identifier."),
29
+ updates: z.object({
30
+ name: z.string().optional(),
31
+ categoryId: z.number().int().positive().optional(),
32
+ brandId: z.number().int().positive().optional(),
33
+ description: z.string().optional(),
34
+ descriptionShort: z.string().optional(),
35
+ title: z.string().optional(),
36
+ linkId: z.string().optional(),
37
+ refId: z.string().optional(),
38
+ isVisible: z.boolean().optional(),
39
+ isActive: z.boolean().optional(),
40
+ keyWords: z.string().optional(),
41
+ releaseDate: z.string().optional(),
42
+ metaTagDescription: z.string().optional(),
43
+ showWithoutStock: z.boolean().optional()
44
+ }).refine((value) => Object.values(value).some((entry) => entry !== void 0), {
45
+ message: "At least one product field must be provided."
46
+ })
47
+ });
48
+ const updateSkuOperationSchema = z.object({
49
+ type: z.literal("update_sku_basic_fields"),
50
+ skuId: z.string().trim().min(1).describe("VTEX SKU identifier."),
51
+ updates: z.object({
52
+ name: z.string().optional(),
53
+ refId: z.string().optional(),
54
+ ean: z.string().optional(),
55
+ packagedHeight: z.number().nonnegative().optional(),
56
+ packagedLength: z.number().nonnegative().optional(),
57
+ packagedWidth: z.number().nonnegative().optional(),
58
+ packagedWeightKg: z.number().nonnegative().optional(),
59
+ height: z.number().nonnegative().optional(),
60
+ length: z.number().nonnegative().optional(),
61
+ width: z.number().nonnegative().optional(),
62
+ weightKg: z.number().nonnegative().optional(),
63
+ measurementUnit: z.string().optional(),
64
+ unitMultiplier: z.number().positive().optional(),
65
+ manufacturerCode: z.string().optional(),
66
+ commercialConditionId: z.number().int().positive().optional(),
67
+ isActive: z.boolean().optional(),
68
+ activateIfPossible: z.boolean().optional()
69
+ }).refine((value) => Object.values(value).some((entry) => entry !== void 0), {
70
+ message: "At least one SKU field must be provided."
71
+ })
72
+ });
73
+ const replaceSkuEansOperationSchema = z.object({
74
+ type: z.literal("replace_sku_eans"),
75
+ skuId: z.string().trim().min(1).describe("VTEX SKU identifier."),
76
+ eans: z.array(z.string().trim()).describe("Final list of EAN values to keep on the SKU.")
77
+ });
78
+ const catalogAdminBatchSchema = z.object({
79
+ profileId: vtexProfileIdSchemaField,
80
+ mode: z.enum(["preview", "apply"]).default("preview"),
81
+ requestedRiskLevel: z.enum(["medium", "high"]).default("medium").describe("Requested risk level. Medium may escalate to high after preflight."),
82
+ confirmed: confirmationSchemaField,
83
+ confirmationNote: confirmationNoteSchemaField,
84
+ previewId: z.string().trim().min(1).optional().describe("Preview identifier returned by preview mode for high-risk apply."),
85
+ previewToken: z.string().trim().min(1).optional().describe("Opaque preview token returned by preview mode. If provided, apply validates it."),
86
+ operations: z.array(
87
+ z.discriminatedUnion("type", [
88
+ updateProductOperationSchema,
89
+ updateSkuOperationSchema,
90
+ replaceSkuEansOperationSchema
91
+ ])
92
+ ).min(1).max(50).describe("Catalog write operations to execute in order.")
93
+ });
94
+ function buildInvalidApplyPayload(params) {
95
+ return object({
96
+ success: false,
97
+ error_code: "INVALID_OPERATION",
98
+ message: params.message,
99
+ operation: "catalog_admin_batch",
100
+ risk_level: params.effectiveRiskLevel,
101
+ confirmation_requirements: {
102
+ required: true,
103
+ reason: "explicit_confirmation_required",
104
+ preview_id: params.previewId
105
+ },
106
+ preview_requirements: getPreviewRequirements("high"),
107
+ details: params.details
108
+ });
109
+ }
110
+ function toBatchOperations(operations) {
111
+ return operations.map((operation) => {
112
+ if (operation.type === "update_product_basic_fields") {
113
+ return {
114
+ type: operation.type,
115
+ productId: operation.productId,
116
+ updates: operation.updates
117
+ };
118
+ }
119
+ if (operation.type === "update_sku_basic_fields") {
120
+ return {
121
+ type: operation.type,
122
+ skuId: operation.skuId,
123
+ updates: operation.updates
124
+ };
125
+ }
126
+ return {
127
+ type: operation.type,
128
+ skuId: operation.skuId,
129
+ eans: operation.eans
130
+ };
131
+ });
132
+ }
133
+ async function catalogAdminBatchHandler({
134
+ profileId,
135
+ mode,
136
+ requestedRiskLevel,
137
+ confirmed,
138
+ confirmationNote,
139
+ previewId,
140
+ previewToken,
141
+ operations
142
+ }) {
143
+ try {
144
+ const profileResolution = await resolveVtexWriteProfile(profileId);
145
+ if (!profileResolution.ok) {
146
+ return profileResolution.response;
147
+ }
148
+ const resolvedProfileId = profileResolution.value.profileId;
149
+ const normalizedOperations = toBatchOperations(operations);
150
+ const plan = await planCatalogBatch(resolvedProfileId, normalizedOperations);
151
+ const preflightSummary = buildPreflightSummary({
152
+ entities: plan.preflight.entities,
153
+ entityTypes: plan.preflight.entityTypes,
154
+ destructive: plan.preflight.destructive,
155
+ warnings: plan.warnings
156
+ });
157
+ const riskEvaluation = classifyVtexWriteRisk({
158
+ requestedRiskLevel,
159
+ preflight: plan.preflight
160
+ });
161
+ const effectiveRiskLevel = riskEvaluation.effective_risk_level;
162
+ const generatedPreviewId = createBatchPreviewId({
163
+ profileId: resolvedProfileId,
164
+ operation: "catalog_admin_batch",
165
+ requestedRiskLevel,
166
+ effectiveRiskLevel,
167
+ operations: normalizedOperations,
168
+ preflight: plan.preflight
169
+ });
170
+ const generatedPreviewToken = createBatchPreviewToken({
171
+ preview_id: generatedPreviewId,
172
+ profile_id: resolvedProfileId,
173
+ operation: "catalog_admin_batch",
174
+ requested_risk_level: requestedRiskLevel,
175
+ effective_risk_level: effectiveRiskLevel,
176
+ escalation_reasons: riskEvaluation.escalation_reasons,
177
+ operation_count: normalizedOperations.length
178
+ });
179
+ if (mode === "preview") {
180
+ return object(
181
+ buildPreviewResponse({
182
+ profileId: resolvedProfileId,
183
+ operation: "catalog_admin_batch",
184
+ requestedRiskLevel,
185
+ riskLevel: effectiveRiskLevel,
186
+ escalated: riskEvaluation.escalated,
187
+ escalationReasons: riskEvaluation.escalation_reasons,
188
+ previewId: generatedPreviewId,
189
+ message: effectiveRiskLevel === "high" ? "High-risk batch preview generated. Confirm explicitly before apply." : "Batch preflight preview generated.",
190
+ before: {
191
+ operations: plan.before
192
+ },
193
+ after: {
194
+ operations: plan.after
195
+ },
196
+ warnings: preflightSummary.warnings,
197
+ details: {
198
+ mode: "preview",
199
+ preview_id: generatedPreviewId,
200
+ preview_token: generatedPreviewToken,
201
+ operation_count: normalizedOperations.length,
202
+ preflight: preflightSummary
203
+ },
204
+ impactSummary: {
205
+ entities: preflightSummary.entities,
206
+ entity_types: plan.impactedEntityTypes,
207
+ destructive: preflightSummary.destructive
208
+ }
209
+ })
210
+ );
211
+ }
212
+ if (effectiveRiskLevel === "high") {
213
+ if (!previewId) {
214
+ return buildInvalidApplyPayload({
215
+ message: "High-risk batch apply requires previewId from preview mode.",
216
+ effectiveRiskLevel,
217
+ details: {
218
+ expected_preview_id: generatedPreviewId
219
+ }
220
+ });
221
+ }
222
+ if (previewId !== generatedPreviewId) {
223
+ return buildInvalidApplyPayload({
224
+ message: "previewId does not match current batch plan. Regenerate preview before apply.",
225
+ effectiveRiskLevel,
226
+ previewId,
227
+ details: {
228
+ expected_preview_id: generatedPreviewId,
229
+ received_preview_id: previewId
230
+ }
231
+ });
232
+ }
233
+ if (previewToken) {
234
+ const parsedToken = decodeBatchPreviewToken(previewToken);
235
+ if (!parsedToken || parsedToken.preview_id !== previewId || parsedToken.profile_id !== resolvedProfileId || parsedToken.operation !== "catalog_admin_batch" || parsedToken.operation_count !== normalizedOperations.length) {
236
+ return buildInvalidApplyPayload({
237
+ message: "Invalid previewToken for this batch apply request.",
238
+ effectiveRiskLevel,
239
+ previewId
240
+ });
241
+ }
242
+ }
243
+ const confirmationResponse = requireExplicitConfirmation(confirmed, "catalog_admin_batch", {
244
+ preview_id: previewId
245
+ });
246
+ if (confirmationResponse) {
247
+ return confirmationResponse;
248
+ }
249
+ }
250
+ const execution = await executeCatalogBatch(resolvedProfileId, normalizedOperations);
251
+ const warnings = buildBatchExecutionWarnings({
252
+ existingWarnings: preflightSummary.warnings,
253
+ successfulCount: execution.successful.length,
254
+ failedCount: execution.failed.length
255
+ });
256
+ return buildWriteSuccessResponse({
257
+ profileId: resolvedProfileId,
258
+ operation: "catalog_admin_batch",
259
+ requestedRiskLevel,
260
+ riskLevel: effectiveRiskLevel,
261
+ escalated: riskEvaluation.escalated,
262
+ escalationReasons: riskEvaluation.escalation_reasons,
263
+ confirmed: effectiveRiskLevel === "high" ? true : void 0,
264
+ confirmationNote,
265
+ message: execution.failed.length > 0 ? "Batch applied with partial failures. Review failed operations before retry." : "Batch applied successfully.",
266
+ before: {
267
+ operations: plan.before
268
+ },
269
+ after: {
270
+ operations: execution.successful
271
+ },
272
+ warnings,
273
+ details: {
274
+ mode: "apply",
275
+ preview_id: generatedPreviewId,
276
+ preview_token: generatedPreviewToken,
277
+ preflight: preflightSummary,
278
+ execution: {
279
+ successful_count: execution.successful.length,
280
+ failed_count: execution.failed.length,
281
+ failures: execution.failed
282
+ }
283
+ },
284
+ impactSummary: {
285
+ entities: preflightSummary.entities,
286
+ entity_types: plan.impactedEntityTypes,
287
+ destructive: preflightSummary.destructive
288
+ }
289
+ });
290
+ } catch (err) {
291
+ return handleVtexWriteError(err, "Failed to execute VTEX catalog admin batch");
292
+ }
293
+ }
294
+ export {
295
+ catalogAdminBatchHandler,
296
+ catalogAdminBatchSchema
297
+ };
298
+ //# sourceMappingURL=catalog-admin-batch.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/vtex/catalog-admin-batch.ts"],
4
+ "sourcesContent": ["import { object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n executeCatalogBatch,\n planCatalogBatch,\n type VtexCatalogBatchOperation,\n} from \"../../services/vtex/vtex-catalog-write.js\";\nimport {\n classifyVtexWriteRisk,\n getPreviewRequirements,\n type VtexWriteRiskLevel,\n} from \"../../services/vtex/vtex-write.js\";\nimport {\n buildBatchExecutionWarnings,\n buildPreflightSummary,\n buildPreviewResponse,\n buildWriteSuccessResponse,\n confirmationNoteSchemaField,\n confirmationSchemaField,\n createBatchPreviewId,\n createBatchPreviewToken,\n decodeBatchPreviewToken,\n handleVtexWriteError,\n requireExplicitConfirmation,\n resolveVtexWriteProfile,\n vtexProfileIdSchemaField,\n} from \"./write-helpers.js\";\n\nconst updateProductOperationSchema = z.object({\n type: z.literal(\"update_product_basic_fields\"),\n productId: z.string().trim().min(1).describe(\"VTEX product identifier.\"),\n updates: z\n .object({\n name: z.string().optional(),\n categoryId: z.number().int().positive().optional(),\n brandId: z.number().int().positive().optional(),\n description: z.string().optional(),\n descriptionShort: z.string().optional(),\n title: z.string().optional(),\n linkId: z.string().optional(),\n refId: z.string().optional(),\n isVisible: z.boolean().optional(),\n isActive: z.boolean().optional(),\n keyWords: z.string().optional(),\n releaseDate: z.string().optional(),\n metaTagDescription: z.string().optional(),\n showWithoutStock: z.boolean().optional(),\n })\n .refine((value) => Object.values(value).some((entry) => entry !== undefined), {\n message: \"At least one product field must be provided.\",\n }),\n});\n\nconst updateSkuOperationSchema = z.object({\n type: z.literal(\"update_sku_basic_fields\"),\n skuId: z.string().trim().min(1).describe(\"VTEX SKU identifier.\"),\n updates: z\n .object({\n name: z.string().optional(),\n refId: z.string().optional(),\n ean: z.string().optional(),\n packagedHeight: z.number().nonnegative().optional(),\n packagedLength: z.number().nonnegative().optional(),\n packagedWidth: z.number().nonnegative().optional(),\n packagedWeightKg: z.number().nonnegative().optional(),\n height: z.number().nonnegative().optional(),\n length: z.number().nonnegative().optional(),\n width: z.number().nonnegative().optional(),\n weightKg: z.number().nonnegative().optional(),\n measurementUnit: z.string().optional(),\n unitMultiplier: z.number().positive().optional(),\n manufacturerCode: z.string().optional(),\n commercialConditionId: z.number().int().positive().optional(),\n isActive: z.boolean().optional(),\n activateIfPossible: z.boolean().optional(),\n })\n .refine((value) => Object.values(value).some((entry) => entry !== undefined), {\n message: \"At least one SKU field must be provided.\",\n }),\n});\n\nconst replaceSkuEansOperationSchema = z.object({\n type: z.literal(\"replace_sku_eans\"),\n skuId: z.string().trim().min(1).describe(\"VTEX SKU identifier.\"),\n eans: z.array(z.string().trim()).describe(\"Final list of EAN values to keep on the SKU.\"),\n});\n\nexport const catalogAdminBatchSchema = z.object({\n profileId: vtexProfileIdSchemaField,\n mode: z.enum([\"preview\", \"apply\"]).default(\"preview\"),\n requestedRiskLevel: z\n .enum([\"medium\", \"high\"])\n .default(\"medium\")\n .describe(\"Requested risk level. Medium may escalate to high after preflight.\"),\n confirmed: confirmationSchemaField,\n confirmationNote: confirmationNoteSchemaField,\n previewId: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Preview identifier returned by preview mode for high-risk apply.\"),\n previewToken: z\n .string()\n .trim()\n .min(1)\n .optional()\n .describe(\"Opaque preview token returned by preview mode. If provided, apply validates it.\"),\n operations: z\n .array(\n z.discriminatedUnion(\"type\", [\n updateProductOperationSchema,\n updateSkuOperationSchema,\n replaceSkuEansOperationSchema,\n ])\n )\n .min(1)\n .max(50)\n .describe(\"Catalog write operations to execute in order.\"),\n});\n\nfunction buildInvalidApplyPayload(params: {\n message: string;\n effectiveRiskLevel: VtexWriteRiskLevel;\n previewId?: string;\n details?: Record<string, unknown>;\n}) {\n return object({\n success: false,\n error_code: \"INVALID_OPERATION\",\n message: params.message,\n operation: \"catalog_admin_batch\",\n risk_level: params.effectiveRiskLevel,\n confirmation_requirements: {\n required: true,\n reason: \"explicit_confirmation_required\",\n preview_id: params.previewId,\n },\n preview_requirements: getPreviewRequirements(\"high\"),\n details: params.details,\n });\n}\n\nfunction toBatchOperations(operations: z.infer<typeof catalogAdminBatchSchema>[\"operations\"]): VtexCatalogBatchOperation[] {\n return operations.map((operation) => {\n if (operation.type === \"update_product_basic_fields\") {\n return {\n type: operation.type,\n productId: operation.productId,\n updates: operation.updates,\n } as const;\n }\n\n if (operation.type === \"update_sku_basic_fields\") {\n return {\n type: operation.type,\n skuId: operation.skuId,\n updates: operation.updates,\n } as const;\n }\n\n return {\n type: operation.type,\n skuId: operation.skuId,\n eans: operation.eans,\n } as const;\n });\n}\n\nexport async function catalogAdminBatchHandler({\n profileId,\n mode,\n requestedRiskLevel,\n confirmed,\n confirmationNote,\n previewId,\n previewToken,\n operations,\n}: z.infer<typeof catalogAdminBatchSchema>) {\n try {\n const profileResolution = await resolveVtexWriteProfile(profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const resolvedProfileId = profileResolution.value.profileId;\n const normalizedOperations = toBatchOperations(operations);\n const plan = await planCatalogBatch(resolvedProfileId, normalizedOperations);\n\n const preflightSummary = buildPreflightSummary({\n entities: plan.preflight.entities,\n entityTypes: plan.preflight.entityTypes,\n destructive: plan.preflight.destructive,\n warnings: plan.warnings,\n });\n\n const riskEvaluation = classifyVtexWriteRisk({\n requestedRiskLevel,\n preflight: plan.preflight,\n });\n\n const effectiveRiskLevel = riskEvaluation.effective_risk_level;\n const generatedPreviewId = createBatchPreviewId({\n profileId: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requestedRiskLevel,\n effectiveRiskLevel,\n operations: normalizedOperations,\n preflight: plan.preflight,\n });\n\n const generatedPreviewToken = createBatchPreviewToken({\n preview_id: generatedPreviewId,\n profile_id: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requested_risk_level: requestedRiskLevel,\n effective_risk_level: effectiveRiskLevel,\n escalation_reasons: riskEvaluation.escalation_reasons,\n operation_count: normalizedOperations.length,\n });\n\n if (mode === \"preview\") {\n return object(\n buildPreviewResponse({\n profileId: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requestedRiskLevel,\n riskLevel: effectiveRiskLevel,\n escalated: riskEvaluation.escalated,\n escalationReasons: riskEvaluation.escalation_reasons,\n previewId: generatedPreviewId,\n message:\n effectiveRiskLevel === \"high\"\n ? \"High-risk batch preview generated. Confirm explicitly before apply.\"\n : \"Batch preflight preview generated.\",\n before: {\n operations: plan.before,\n },\n after: {\n operations: plan.after,\n },\n warnings: preflightSummary.warnings,\n details: {\n mode: \"preview\",\n preview_id: generatedPreviewId,\n preview_token: generatedPreviewToken,\n operation_count: normalizedOperations.length,\n preflight: preflightSummary,\n },\n impactSummary: {\n entities: preflightSummary.entities,\n entity_types: plan.impactedEntityTypes,\n destructive: preflightSummary.destructive,\n },\n })\n );\n }\n\n if (effectiveRiskLevel === \"high\") {\n if (!previewId) {\n return buildInvalidApplyPayload({\n message: \"High-risk batch apply requires previewId from preview mode.\",\n effectiveRiskLevel,\n details: {\n expected_preview_id: generatedPreviewId,\n },\n });\n }\n\n if (previewId !== generatedPreviewId) {\n return buildInvalidApplyPayload({\n message: \"previewId does not match current batch plan. Regenerate preview before apply.\",\n effectiveRiskLevel,\n previewId,\n details: {\n expected_preview_id: generatedPreviewId,\n received_preview_id: previewId,\n },\n });\n }\n\n if (previewToken) {\n const parsedToken = decodeBatchPreviewToken(previewToken);\n if (\n !parsedToken ||\n parsedToken.preview_id !== previewId ||\n parsedToken.profile_id !== resolvedProfileId ||\n parsedToken.operation !== \"catalog_admin_batch\" ||\n parsedToken.operation_count !== normalizedOperations.length\n ) {\n return buildInvalidApplyPayload({\n message: \"Invalid previewToken for this batch apply request.\",\n effectiveRiskLevel,\n previewId,\n });\n }\n }\n\n const confirmationResponse = requireExplicitConfirmation(confirmed, \"catalog_admin_batch\", {\n preview_id: previewId,\n });\n\n if (confirmationResponse) {\n return confirmationResponse;\n }\n }\n\n const execution = await executeCatalogBatch(resolvedProfileId, normalizedOperations);\n const warnings = buildBatchExecutionWarnings({\n existingWarnings: preflightSummary.warnings,\n successfulCount: execution.successful.length,\n failedCount: execution.failed.length,\n });\n\n return buildWriteSuccessResponse({\n profileId: resolvedProfileId,\n operation: \"catalog_admin_batch\",\n requestedRiskLevel,\n riskLevel: effectiveRiskLevel,\n escalated: riskEvaluation.escalated,\n escalationReasons: riskEvaluation.escalation_reasons,\n confirmed: effectiveRiskLevel === \"high\" ? true : undefined,\n confirmationNote,\n message:\n execution.failed.length > 0\n ? \"Batch applied with partial failures. Review failed operations before retry.\"\n : \"Batch applied successfully.\",\n before: {\n operations: plan.before,\n },\n after: {\n operations: execution.successful,\n },\n warnings,\n details: {\n mode: \"apply\",\n preview_id: generatedPreviewId,\n preview_token: generatedPreviewToken,\n preflight: preflightSummary,\n execution: {\n successful_count: execution.successful.length,\n failed_count: execution.failed.length,\n failures: execution.failed,\n },\n },\n impactSummary: {\n entities: preflightSummary.entities,\n entity_types: plan.impactedEntityTypes,\n destructive: preflightSummary.destructive,\n },\n });\n } catch (err) {\n return handleVtexWriteError(err, \"Failed to execute VTEX catalog admin batch\");\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }