@yoryoboy/bi-mcp 1.13.0 → 1.14.2
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/dist/.tsbuildinfo +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +2 -2
- package/dist/mcp-use.json +2 -2
- package/dist/src/services/vtex/__tests__/vtex-payments.test.js +98 -0
- package/dist/src/services/vtex/__tests__/vtex-payments.test.js.map +7 -0
- package/dist/src/services/vtex/vtex-payments-write.js +64 -0
- package/dist/src/services/vtex/vtex-payments-write.js.map +7 -0
- package/dist/src/services/vtex/vtex-payments.js +49 -0
- package/dist/src/services/vtex/vtex-payments.js.map +7 -0
- package/dist/src/tools/vtex/__tests__/commercial-condition-references.test.js +14 -0
- package/dist/src/tools/vtex/__tests__/commercial-condition-references.test.js.map +7 -0
- package/dist/src/tools/vtex/__tests__/commercial-conditions.test.js +107 -0
- package/dist/src/tools/vtex/__tests__/commercial-conditions.test.js.map +7 -0
- package/dist/src/tools/vtex/__tests__/payment-rules.test.js +254 -0
- package/dist/src/tools/vtex/__tests__/payment-rules.test.js.map +7 -0
- package/dist/src/tools/vtex/catalog-admin-products-skus.js +3 -1
- package/dist/src/tools/vtex/catalog-admin-products-skus.js.map +2 -2
- package/dist/src/tools/vtex/commercial-conditions.js +105 -0
- package/dist/src/tools/vtex/commercial-conditions.js.map +7 -0
- package/dist/src/tools/vtex/create-sku.js +3 -1
- package/dist/src/tools/vtex/create-sku.js.map +2 -2
- package/dist/src/tools/vtex/index.js +2 -0
- package/dist/src/tools/vtex/index.js.map +2 -2
- package/dist/src/tools/vtex/payment-rules.js +272 -0
- package/dist/src/tools/vtex/payment-rules.js.map +7 -0
- package/dist/tests/vtex/vtex-commercial-conditions-docs.test.js +34 -0
- package/dist/tests/vtex/vtex-commercial-conditions-docs.test.js.map +7 -0
- package/dist/tests/vtex/vtex-commercial-conditions-surface.test.js +151 -0
- package/dist/tests/vtex/vtex-commercial-conditions-surface.test.js.map +7 -0
- package/dist/tests/vtex/vtex-commercial-conditions-workflow.test.js +182 -0
- package/dist/tests/vtex/vtex-commercial-conditions-workflow.test.js.map +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatVtexError } from "../../services/vtex/vtex-api.js";
|
|
4
|
+
import { getPaymentRule, listPaymentRules } from "../../services/vtex/vtex-payments.js";
|
|
5
|
+
import {
|
|
6
|
+
createPaymentRule,
|
|
7
|
+
deletePaymentRule,
|
|
8
|
+
updatePaymentRule
|
|
9
|
+
} from "../../services/vtex/vtex-payments-write.js";
|
|
10
|
+
import { toSnakeCaseKeys } from "../../utils/case-conversion.js";
|
|
11
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
12
|
+
import {
|
|
13
|
+
buildWriteSuccessResponse,
|
|
14
|
+
confirmationSchemaField,
|
|
15
|
+
handleVtexWriteError,
|
|
16
|
+
requireExplicitConfirmation,
|
|
17
|
+
resolveVtexWriteProfile,
|
|
18
|
+
vtexProfileIdSchemaField
|
|
19
|
+
} from "./write-helpers.js";
|
|
20
|
+
const requiredProfileIdSchemaField = vtexProfileIdSchemaField.unwrap().describe("Explicit VTEX profile id to use for this operation.");
|
|
21
|
+
const paymentRuleActionSchema = z.enum(["list", "get", "create", "update", "delete"]).describe("Action to perform for VTEX payment rules.");
|
|
22
|
+
const positiveIntegerSchemaField = (description) => z.number().int().positive().describe(description);
|
|
23
|
+
const installmentsSchemaField = z.array(
|
|
24
|
+
z.object({
|
|
25
|
+
count: positiveIntegerSchemaField("Installment count."),
|
|
26
|
+
interest: z.boolean().describe("Whether this installment carries interest.")
|
|
27
|
+
})
|
|
28
|
+
).min(1).describe("Installment configuration rows for the payment rule.");
|
|
29
|
+
const paymentRuleWarnings = {
|
|
30
|
+
delete: "Deleting a payment rule can immediately remove installment options from checkout for affected shoppers."
|
|
31
|
+
};
|
|
32
|
+
const paymentRuleRowsSchema = [
|
|
33
|
+
"id",
|
|
34
|
+
"commercial_condition_id",
|
|
35
|
+
"payment_system",
|
|
36
|
+
"sales_channel",
|
|
37
|
+
"restricted_by_condition"
|
|
38
|
+
];
|
|
39
|
+
function readValue(record, ...keys) {
|
|
40
|
+
for (const key of keys) {
|
|
41
|
+
if (key in record) {
|
|
42
|
+
return record[key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
const listActionSchema = z.object({
|
|
48
|
+
action: z.literal("list"),
|
|
49
|
+
profileId: requiredProfileIdSchemaField,
|
|
50
|
+
commercialConditionId: positiveIntegerSchemaField(
|
|
51
|
+
"Optional commercial condition filter for payment rules."
|
|
52
|
+
).optional()
|
|
53
|
+
});
|
|
54
|
+
const getActionSchema = z.object({
|
|
55
|
+
action: z.literal("get"),
|
|
56
|
+
profileId: requiredProfileIdSchemaField,
|
|
57
|
+
ruleId: positiveIntegerSchemaField("Positive VTEX payment rule identifier.")
|
|
58
|
+
});
|
|
59
|
+
const createActionSchema = z.object({
|
|
60
|
+
action: z.literal("create"),
|
|
61
|
+
profileId: requiredProfileIdSchemaField,
|
|
62
|
+
commercialConditionId: positiveIntegerSchemaField(
|
|
63
|
+
"Commercial condition identifier linked to this payment rule."
|
|
64
|
+
),
|
|
65
|
+
paymentSystem: z.string().trim().min(1).describe("VTEX payment system identifier."),
|
|
66
|
+
salesChannel: z.string().trim().min(1).optional().describe("Optional VTEX sales channel identifier."),
|
|
67
|
+
restrictedByCondition: z.boolean().optional().describe("Whether checkout should restrict this rule to the linked commercial condition."),
|
|
68
|
+
installments: installmentsSchemaField
|
|
69
|
+
});
|
|
70
|
+
const updateActionSchema = z.object({
|
|
71
|
+
action: z.literal("update"),
|
|
72
|
+
profileId: requiredProfileIdSchemaField,
|
|
73
|
+
ruleId: positiveIntegerSchemaField("Positive VTEX payment rule identifier."),
|
|
74
|
+
commercialConditionId: positiveIntegerSchemaField(
|
|
75
|
+
"Commercial condition identifier linked to this payment rule."
|
|
76
|
+
).optional(),
|
|
77
|
+
paymentSystem: z.string().trim().min(1).optional().describe("Updated VTEX payment system identifier."),
|
|
78
|
+
salesChannel: z.string().trim().min(1).optional().describe("Updated VTEX sales channel identifier."),
|
|
79
|
+
restrictedByCondition: z.boolean().optional().describe("Updated restricted-by-condition flag."),
|
|
80
|
+
installments: installmentsSchemaField.optional()
|
|
81
|
+
}).refine(
|
|
82
|
+
(value) => value.commercialConditionId !== void 0 || value.paymentSystem !== void 0 || value.salesChannel !== void 0 || value.restrictedByCondition !== void 0 || value.installments !== void 0,
|
|
83
|
+
{
|
|
84
|
+
message: "At least one payment rule field must be provided.",
|
|
85
|
+
path: ["paymentSystem"]
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
const deleteActionSchema = z.object({
|
|
89
|
+
action: z.literal("delete"),
|
|
90
|
+
profileId: requiredProfileIdSchemaField,
|
|
91
|
+
ruleId: positiveIntegerSchemaField("Positive VTEX payment rule identifier."),
|
|
92
|
+
confirmed: confirmationSchemaField
|
|
93
|
+
});
|
|
94
|
+
function getPaymentRulesActionSchema(action) {
|
|
95
|
+
switch (action) {
|
|
96
|
+
case "list":
|
|
97
|
+
return listActionSchema;
|
|
98
|
+
case "get":
|
|
99
|
+
return getActionSchema;
|
|
100
|
+
case "create":
|
|
101
|
+
return createActionSchema;
|
|
102
|
+
case "update":
|
|
103
|
+
return updateActionSchema;
|
|
104
|
+
case "delete":
|
|
105
|
+
return deleteActionSchema;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const paymentRulesSchema = z.object({
|
|
109
|
+
action: paymentRuleActionSchema,
|
|
110
|
+
profileId: requiredProfileIdSchemaField,
|
|
111
|
+
commercialConditionId: positiveIntegerSchemaField(
|
|
112
|
+
"Commercial condition identifier linked to this payment rule."
|
|
113
|
+
).optional(),
|
|
114
|
+
ruleId: positiveIntegerSchemaField("Positive VTEX payment rule identifier.").optional(),
|
|
115
|
+
paymentSystem: z.string().trim().min(1).optional().describe("VTEX payment system identifier."),
|
|
116
|
+
salesChannel: z.string().trim().min(1).optional().describe("Optional VTEX sales channel identifier."),
|
|
117
|
+
restrictedByCondition: z.boolean().optional().describe("Whether checkout should restrict this rule to the linked commercial condition."),
|
|
118
|
+
installments: installmentsSchemaField.optional(),
|
|
119
|
+
confirmed: confirmationSchemaField
|
|
120
|
+
}).superRefine((value, ctx) => {
|
|
121
|
+
const validation = getPaymentRulesActionSchema(value.action).safeParse(value);
|
|
122
|
+
if (validation.success) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
for (const issue of validation.error.issues) {
|
|
126
|
+
ctx.addIssue(issue);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
async function paymentRulesHandler(params) {
|
|
130
|
+
switch (params.action) {
|
|
131
|
+
case "list": {
|
|
132
|
+
const validatedParams = listActionSchema.parse(params);
|
|
133
|
+
try {
|
|
134
|
+
const rules = await listPaymentRules(validatedParams.profileId, {
|
|
135
|
+
commercialConditionId: validatedParams.commercialConditionId
|
|
136
|
+
});
|
|
137
|
+
return object({
|
|
138
|
+
metadata: stripNulls({
|
|
139
|
+
total: rules.length,
|
|
140
|
+
profile_id: validatedParams.profileId,
|
|
141
|
+
filters: validatedParams.commercialConditionId === void 0 ? void 0 : { commercial_condition_id: validatedParams.commercialConditionId }
|
|
142
|
+
}),
|
|
143
|
+
payment_rules_schema: paymentRuleRowsSchema,
|
|
144
|
+
payment_rules: rules.map((rule) => [
|
|
145
|
+
readValue(rule, "id", "Id"),
|
|
146
|
+
readValue(rule, "commercialConditionId", "CommercialConditionId", "commercial_condition_id"),
|
|
147
|
+
readValue(rule, "paymentSystem", "PaymentSystem", "payment_system"),
|
|
148
|
+
readValue(rule, "salesChannel", "SalesChannel", "sales_channel"),
|
|
149
|
+
readValue(
|
|
150
|
+
rule,
|
|
151
|
+
"restrictedByCondition",
|
|
152
|
+
"RestrictedByCondition",
|
|
153
|
+
"restricted_by_condition"
|
|
154
|
+
)
|
|
155
|
+
])
|
|
156
|
+
});
|
|
157
|
+
} catch (err) {
|
|
158
|
+
return error(formatVtexError(err, "Failed to list VTEX payment rules"));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
case "get": {
|
|
162
|
+
const validatedParams = getActionSchema.parse(params);
|
|
163
|
+
try {
|
|
164
|
+
const rule = await getPaymentRule(validatedParams.profileId, validatedParams.ruleId);
|
|
165
|
+
return object({
|
|
166
|
+
profile_id: validatedParams.profileId,
|
|
167
|
+
rule_id: validatedParams.ruleId,
|
|
168
|
+
payment_rule: toSnakeCaseKeys(rule)
|
|
169
|
+
});
|
|
170
|
+
} catch (err) {
|
|
171
|
+
return error(
|
|
172
|
+
formatVtexError(err, `Failed to fetch VTEX payment rule ${validatedParams.ruleId}`)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
case "create": {
|
|
177
|
+
const validatedParams = createActionSchema.parse(params);
|
|
178
|
+
try {
|
|
179
|
+
const profileResolution = await resolveVtexWriteProfile(validatedParams.profileId);
|
|
180
|
+
if (!profileResolution.ok) {
|
|
181
|
+
return profileResolution.response;
|
|
182
|
+
}
|
|
183
|
+
const created = await createPaymentRule(profileResolution.value.profileId, {
|
|
184
|
+
commercialConditionId: validatedParams.commercialConditionId,
|
|
185
|
+
paymentSystem: validatedParams.paymentSystem,
|
|
186
|
+
...validatedParams.salesChannel !== void 0 ? { salesChannel: validatedParams.salesChannel } : {},
|
|
187
|
+
...validatedParams.restrictedByCondition !== void 0 ? { restrictedByCondition: validatedParams.restrictedByCondition } : {},
|
|
188
|
+
installments: validatedParams.installments
|
|
189
|
+
});
|
|
190
|
+
return buildWriteSuccessResponse({
|
|
191
|
+
profileId: profileResolution.value.profileId,
|
|
192
|
+
operation: "payment_rules_create",
|
|
193
|
+
resourceId: created.id == null ? void 0 : String(created.id),
|
|
194
|
+
riskLevel: "medium",
|
|
195
|
+
message: "Payment rule created. Review checkout installments and condition targeting to confirm the expected shopper experience.",
|
|
196
|
+
before: null,
|
|
197
|
+
after: created
|
|
198
|
+
});
|
|
199
|
+
} catch (err) {
|
|
200
|
+
return handleVtexWriteError(err, "Failed to create VTEX payment rule");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
case "update": {
|
|
204
|
+
const validatedParams = updateActionSchema.parse(params);
|
|
205
|
+
try {
|
|
206
|
+
const profileResolution = await resolveVtexWriteProfile(validatedParams.profileId);
|
|
207
|
+
if (!profileResolution.ok) {
|
|
208
|
+
return profileResolution.response;
|
|
209
|
+
}
|
|
210
|
+
const updated = await updatePaymentRule(profileResolution.value.profileId, validatedParams.ruleId, {
|
|
211
|
+
...validatedParams.commercialConditionId !== void 0 ? { commercialConditionId: validatedParams.commercialConditionId } : {},
|
|
212
|
+
...validatedParams.paymentSystem !== void 0 ? { paymentSystem: validatedParams.paymentSystem } : {},
|
|
213
|
+
...validatedParams.salesChannel !== void 0 ? { salesChannel: validatedParams.salesChannel } : {},
|
|
214
|
+
...validatedParams.restrictedByCondition !== void 0 ? { restrictedByCondition: validatedParams.restrictedByCondition } : {},
|
|
215
|
+
...validatedParams.installments !== void 0 ? { installments: validatedParams.installments } : {}
|
|
216
|
+
});
|
|
217
|
+
return buildWriteSuccessResponse({
|
|
218
|
+
profileId: profileResolution.value.profileId,
|
|
219
|
+
operation: "payment_rules_update",
|
|
220
|
+
resourceId: String(validatedParams.ruleId),
|
|
221
|
+
riskLevel: "medium",
|
|
222
|
+
message: "Payment rule updated. Review checkout installments to confirm the expected payment options.",
|
|
223
|
+
before: null,
|
|
224
|
+
after: updated
|
|
225
|
+
});
|
|
226
|
+
} catch (err) {
|
|
227
|
+
return handleVtexWriteError(
|
|
228
|
+
err,
|
|
229
|
+
`Failed to update VTEX payment rule ${validatedParams.ruleId}`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
case "delete": {
|
|
234
|
+
const validatedParams = deleteActionSchema.parse(params);
|
|
235
|
+
const confirmationResponse = requireExplicitConfirmation(validatedParams.confirmed, "payment_rules_delete", {
|
|
236
|
+
rule_id: validatedParams.ruleId,
|
|
237
|
+
warnings: [paymentRuleWarnings.delete]
|
|
238
|
+
});
|
|
239
|
+
if (confirmationResponse) {
|
|
240
|
+
return confirmationResponse;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const profileResolution = await resolveVtexWriteProfile(validatedParams.profileId);
|
|
244
|
+
if (!profileResolution.ok) {
|
|
245
|
+
return profileResolution.response;
|
|
246
|
+
}
|
|
247
|
+
await deletePaymentRule(profileResolution.value.profileId, validatedParams.ruleId);
|
|
248
|
+
return buildWriteSuccessResponse({
|
|
249
|
+
profileId: profileResolution.value.profileId,
|
|
250
|
+
operation: "payment_rules_delete",
|
|
251
|
+
resourceId: String(validatedParams.ruleId),
|
|
252
|
+
riskLevel: "high",
|
|
253
|
+
confirmed: true,
|
|
254
|
+
message: "Payment rule deleted. Verify checkout no longer exposes the removed installment option to affected shoppers.",
|
|
255
|
+
warnings: [paymentRuleWarnings.delete],
|
|
256
|
+
before: null,
|
|
257
|
+
after: null
|
|
258
|
+
});
|
|
259
|
+
} catch (err) {
|
|
260
|
+
return handleVtexWriteError(
|
|
261
|
+
err,
|
|
262
|
+
`Failed to delete VTEX payment rule ${validatedParams.ruleId}`
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export {
|
|
269
|
+
paymentRulesHandler,
|
|
270
|
+
paymentRulesSchema
|
|
271
|
+
};
|
|
272
|
+
//# sourceMappingURL=payment-rules.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/vtex/payment-rules.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatVtexError } from \"../../services/vtex/vtex-api.js\";\nimport { getPaymentRule, listPaymentRules } from \"../../services/vtex/vtex-payments.js\";\nimport {\n createPaymentRule,\n deletePaymentRule,\n updatePaymentRule,\n} from \"../../services/vtex/vtex-payments-write.js\";\nimport { toSnakeCaseKeys } from \"../../utils/case-conversion.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\nimport {\n buildWriteSuccessResponse,\n confirmationSchemaField,\n handleVtexWriteError,\n requireExplicitConfirmation,\n resolveVtexWriteProfile,\n vtexProfileIdSchemaField,\n} from \"./write-helpers.js\";\n\nconst requiredProfileIdSchemaField = vtexProfileIdSchemaField\n .unwrap()\n .describe(\"Explicit VTEX profile id to use for this operation.\");\n\nconst paymentRuleActionSchema = z\n .enum([\"list\", \"get\", \"create\", \"update\", \"delete\"])\n .describe(\"Action to perform for VTEX payment rules.\");\n\nconst positiveIntegerSchemaField = (description: string) =>\n z.number().int().positive().describe(description);\n\nconst installmentsSchemaField = z\n .array(\n z.object({\n count: positiveIntegerSchemaField(\"Installment count.\"),\n interest: z.boolean().describe(\"Whether this installment carries interest.\"),\n })\n )\n .min(1)\n .describe(\"Installment configuration rows for the payment rule.\");\n\nconst paymentRuleWarnings = {\n delete:\n \"Deleting a payment rule can immediately remove installment options from checkout for affected shoppers.\",\n} as const;\n\nconst paymentRuleRowsSchema = [\n \"id\",\n \"commercial_condition_id\",\n \"payment_system\",\n \"sales_channel\",\n \"restricted_by_condition\",\n] as const;\n\nfunction readValue(record: Record<string, unknown>, ...keys: string[]): unknown {\n for (const key of keys) {\n if (key in record) {\n return record[key];\n }\n }\n\n return undefined;\n}\n\nconst listActionSchema = z.object({\n action: z.literal(\"list\"),\n profileId: requiredProfileIdSchemaField,\n commercialConditionId: positiveIntegerSchemaField(\n \"Optional commercial condition filter for payment rules.\"\n ).optional(),\n});\n\nconst getActionSchema = z.object({\n action: z.literal(\"get\"),\n profileId: requiredProfileIdSchemaField,\n ruleId: positiveIntegerSchemaField(\"Positive VTEX payment rule identifier.\"),\n});\n\nconst createActionSchema = z.object({\n action: z.literal(\"create\"),\n profileId: requiredProfileIdSchemaField,\n commercialConditionId: positiveIntegerSchemaField(\n \"Commercial condition identifier linked to this payment rule.\"\n ),\n paymentSystem: z.string().trim().min(1).describe(\"VTEX payment system identifier.\"),\n salesChannel: z.string().trim().min(1).optional().describe(\"Optional VTEX sales channel identifier.\"),\n restrictedByCondition: z\n .boolean()\n .optional()\n .describe(\"Whether checkout should restrict this rule to the linked commercial condition.\"),\n installments: installmentsSchemaField,\n});\n\nconst updateActionSchema = z\n .object({\n action: z.literal(\"update\"),\n profileId: requiredProfileIdSchemaField,\n ruleId: positiveIntegerSchemaField(\"Positive VTEX payment rule identifier.\"),\n commercialConditionId: positiveIntegerSchemaField(\n \"Commercial condition identifier linked to this payment rule.\"\n ).optional(),\n paymentSystem: z.string().trim().min(1).optional().describe(\"Updated VTEX payment system identifier.\"),\n salesChannel: z.string().trim().min(1).optional().describe(\"Updated VTEX sales channel identifier.\"),\n restrictedByCondition: z\n .boolean()\n .optional()\n .describe(\"Updated restricted-by-condition flag.\"),\n installments: installmentsSchemaField.optional(),\n })\n .refine(\n (value) =>\n value.commercialConditionId !== undefined ||\n value.paymentSystem !== undefined ||\n value.salesChannel !== undefined ||\n value.restrictedByCondition !== undefined ||\n value.installments !== undefined,\n {\n message: \"At least one payment rule field must be provided.\",\n path: [\"paymentSystem\"],\n }\n );\n\nconst deleteActionSchema = z.object({\n action: z.literal(\"delete\"),\n profileId: requiredProfileIdSchemaField,\n ruleId: positiveIntegerSchemaField(\"Positive VTEX payment rule identifier.\"),\n confirmed: confirmationSchemaField,\n});\n\nfunction getPaymentRulesActionSchema(action: z.infer<typeof paymentRuleActionSchema>) {\n switch (action) {\n case \"list\":\n return listActionSchema;\n case \"get\":\n return getActionSchema;\n case \"create\":\n return createActionSchema;\n case \"update\":\n return updateActionSchema;\n case \"delete\":\n return deleteActionSchema;\n }\n}\n\nexport const paymentRulesSchema = z\n .object({\n action: paymentRuleActionSchema,\n profileId: requiredProfileIdSchemaField,\n commercialConditionId: positiveIntegerSchemaField(\n \"Commercial condition identifier linked to this payment rule.\"\n ).optional(),\n ruleId: positiveIntegerSchemaField(\"Positive VTEX payment rule identifier.\").optional(),\n paymentSystem: z.string().trim().min(1).optional().describe(\"VTEX payment system identifier.\"),\n salesChannel: z.string().trim().min(1).optional().describe(\"Optional VTEX sales channel identifier.\"),\n restrictedByCondition: z\n .boolean()\n .optional()\n .describe(\"Whether checkout should restrict this rule to the linked commercial condition.\"),\n installments: installmentsSchemaField.optional(),\n confirmed: confirmationSchemaField,\n })\n .superRefine((value, ctx) => {\n const validation = getPaymentRulesActionSchema(value.action).safeParse(value);\n if (validation.success) {\n return;\n }\n\n for (const issue of validation.error.issues) {\n ctx.addIssue(issue as Parameters<typeof ctx.addIssue>[0]);\n }\n });\n\nexport async function paymentRulesHandler(params: z.infer<typeof paymentRulesSchema>) {\n switch (params.action) {\n case \"list\": {\n const validatedParams = listActionSchema.parse(params);\n\n try {\n const rules = await listPaymentRules(validatedParams.profileId, {\n commercialConditionId: validatedParams.commercialConditionId,\n });\n\n return object({\n metadata: stripNulls({\n total: rules.length,\n profile_id: validatedParams.profileId,\n filters:\n validatedParams.commercialConditionId === undefined\n ? undefined\n : { commercial_condition_id: validatedParams.commercialConditionId },\n }),\n payment_rules_schema: paymentRuleRowsSchema,\n payment_rules: rules.map((rule) => [\n readValue(rule, \"id\", \"Id\"),\n readValue(rule, \"commercialConditionId\", \"CommercialConditionId\", \"commercial_condition_id\"),\n readValue(rule, \"paymentSystem\", \"PaymentSystem\", \"payment_system\"),\n readValue(rule, \"salesChannel\", \"SalesChannel\", \"sales_channel\"),\n readValue(\n rule,\n \"restrictedByCondition\",\n \"RestrictedByCondition\",\n \"restricted_by_condition\"\n ),\n ]),\n });\n } catch (err) {\n return error(formatVtexError(err, \"Failed to list VTEX payment rules\"));\n }\n }\n\n case \"get\": {\n const validatedParams = getActionSchema.parse(params);\n\n try {\n const rule = await getPaymentRule(validatedParams.profileId, validatedParams.ruleId);\n\n return object({\n profile_id: validatedParams.profileId,\n rule_id: validatedParams.ruleId,\n payment_rule: toSnakeCaseKeys(rule),\n });\n } catch (err) {\n return error(\n formatVtexError(err, `Failed to fetch VTEX payment rule ${validatedParams.ruleId}`)\n );\n }\n }\n\n case \"create\": {\n const validatedParams = createActionSchema.parse(params);\n\n try {\n const profileResolution = await resolveVtexWriteProfile(validatedParams.profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const created = await createPaymentRule(profileResolution.value.profileId, {\n commercialConditionId: validatedParams.commercialConditionId,\n paymentSystem: validatedParams.paymentSystem,\n ...(validatedParams.salesChannel !== undefined\n ? { salesChannel: validatedParams.salesChannel }\n : {}),\n ...(validatedParams.restrictedByCondition !== undefined\n ? { restrictedByCondition: validatedParams.restrictedByCondition }\n : {}),\n installments: validatedParams.installments,\n });\n\n return buildWriteSuccessResponse({\n profileId: profileResolution.value.profileId,\n operation: \"payment_rules_create\",\n resourceId: created.id == null ? undefined : String(created.id),\n riskLevel: \"medium\",\n message:\n \"Payment rule created. Review checkout installments and condition targeting to confirm the expected shopper experience.\",\n before: null,\n after: created,\n });\n } catch (err) {\n return handleVtexWriteError(err, \"Failed to create VTEX payment rule\");\n }\n }\n\n case \"update\": {\n const validatedParams = updateActionSchema.parse(params);\n\n try {\n const profileResolution = await resolveVtexWriteProfile(validatedParams.profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const updated = await updatePaymentRule(profileResolution.value.profileId, validatedParams.ruleId, {\n ...(validatedParams.commercialConditionId !== undefined\n ? { commercialConditionId: validatedParams.commercialConditionId }\n : {}),\n ...(validatedParams.paymentSystem !== undefined\n ? { paymentSystem: validatedParams.paymentSystem }\n : {}),\n ...(validatedParams.salesChannel !== undefined\n ? { salesChannel: validatedParams.salesChannel }\n : {}),\n ...(validatedParams.restrictedByCondition !== undefined\n ? { restrictedByCondition: validatedParams.restrictedByCondition }\n : {}),\n ...(validatedParams.installments !== undefined\n ? { installments: validatedParams.installments }\n : {}),\n });\n\n return buildWriteSuccessResponse({\n profileId: profileResolution.value.profileId,\n operation: \"payment_rules_update\",\n resourceId: String(validatedParams.ruleId),\n riskLevel: \"medium\",\n message:\n \"Payment rule updated. Review checkout installments to confirm the expected payment options.\",\n before: null,\n after: updated,\n });\n } catch (err) {\n return handleVtexWriteError(\n err,\n `Failed to update VTEX payment rule ${validatedParams.ruleId}`\n );\n }\n }\n\n case \"delete\": {\n const validatedParams = deleteActionSchema.parse(params);\n\n const confirmationResponse = requireExplicitConfirmation(validatedParams.confirmed, \"payment_rules_delete\", {\n rule_id: validatedParams.ruleId,\n warnings: [paymentRuleWarnings.delete],\n });\n if (confirmationResponse) {\n return confirmationResponse;\n }\n\n try {\n const profileResolution = await resolveVtexWriteProfile(validatedParams.profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n await deletePaymentRule(profileResolution.value.profileId, validatedParams.ruleId);\n\n return buildWriteSuccessResponse({\n profileId: profileResolution.value.profileId,\n operation: \"payment_rules_delete\",\n resourceId: String(validatedParams.ruleId),\n riskLevel: \"high\",\n confirmed: true,\n message:\n \"Payment rule deleted. Verify checkout no longer exposes the removed installment option to affected shoppers.\",\n warnings: [paymentRuleWarnings.delete],\n before: null,\n after: null,\n });\n } catch (err) {\n return handleVtexWriteError(\n err,\n `Failed to delete VTEX payment rule ${validatedParams.ruleId}`\n );\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
describe("VTEX commercial conditions documentation", () => {
|
|
4
|
+
it("documents the corrected VTEX commercial conditions capability across project docs", async () => {
|
|
5
|
+
const projectStatus = await readFile(new URL("../../docs/PROJECT_STATUS.md", import.meta.url), "utf8");
|
|
6
|
+
const keyEndpoints = await readFile(
|
|
7
|
+
new URL("../../src/services/vtex/docs/vtex-key-endpoints.md", import.meta.url),
|
|
8
|
+
"utf8"
|
|
9
|
+
);
|
|
10
|
+
const dashboardCapabilities = await readFile(
|
|
11
|
+
new URL("../../../bi-mcp-dashboard/docs/content/CAPACIDADES_MCP.md", import.meta.url),
|
|
12
|
+
"utf8"
|
|
13
|
+
);
|
|
14
|
+
expect(projectStatus).toContain("`35` tools VTEX.");
|
|
15
|
+
expect(projectStatus).toContain("condiciones comerciales solo lectura oficial");
|
|
16
|
+
expect(keyEndpoints).toContain("Commercial conditions Catalog reads and legacy payment rules writes");
|
|
17
|
+
expect(keyEndpoints).toContain("/api/catalog_system/pvt/commercialcondition/list");
|
|
18
|
+
expect(keyEndpoints).toContain("manually in VTEX Admin");
|
|
19
|
+
expect(keyEndpoints).toContain("`vtex_payment_rules`");
|
|
20
|
+
expect(dashboardCapabilities).toContain(
|
|
21
|
+
"Gesti\xF3n de Condiciones Comerciales y Reglas de Pago"
|
|
22
|
+
);
|
|
23
|
+
expect(dashboardCapabilities).toContain("`vtex_commercial_conditions`");
|
|
24
|
+
expect(dashboardCapabilities).toContain("`vtex_payment_rules`");
|
|
25
|
+
expect(dashboardCapabilities).toContain("solo permite listar y consultar condiciones comerciales");
|
|
26
|
+
expect(dashboardCapabilities).toContain(
|
|
27
|
+
"crear manualmente la condici\xF3n faltante en VTEX Admin"
|
|
28
|
+
);
|
|
29
|
+
expect(dashboardCapabilities).not.toContain(
|
|
30
|
+
"primero conviene administrar esa condici\xF3n y sus reglas desde `vtex_commercial_conditions`"
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=vtex-commercial-conditions-docs.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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"],
|
|
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
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
describe("VTEX commercial conditions server surface", () => {
|
|
4
|
+
it("registers and lists both tools through the MCP layer without schema compatibility failures", async () => {
|
|
5
|
+
const previousNodeEnv = process.env.NODE_ENV;
|
|
6
|
+
const previousTelemetry = process.env.MCP_USE_ANONYMIZED_TELEMETRY;
|
|
7
|
+
process.env.NODE_ENV = "production";
|
|
8
|
+
process.env.MCP_USE_ANONYMIZED_TELEMETRY = "false";
|
|
9
|
+
try {
|
|
10
|
+
const [
|
|
11
|
+
{ MCPServer, object },
|
|
12
|
+
{ MCPClient },
|
|
13
|
+
commercialConditionsModule,
|
|
14
|
+
paymentRulesModule
|
|
15
|
+
] = await Promise.all([
|
|
16
|
+
import("mcp-use/server"),
|
|
17
|
+
import("mcp-use"),
|
|
18
|
+
import("../../src/tools/vtex/commercial-conditions.js"),
|
|
19
|
+
import("../../src/tools/vtex/payment-rules.js")
|
|
20
|
+
]);
|
|
21
|
+
const server = new MCPServer({
|
|
22
|
+
name: "test-vtex-payments-server",
|
|
23
|
+
version: "1.0.0",
|
|
24
|
+
baseUrl: "http://localhost:3000"
|
|
25
|
+
});
|
|
26
|
+
server.tool(
|
|
27
|
+
{
|
|
28
|
+
name: "vtex_commercial_conditions",
|
|
29
|
+
description: "Read VTEX commercial conditions.",
|
|
30
|
+
schema: commercialConditionsModule.commercialConditionsSchema,
|
|
31
|
+
annotations: {
|
|
32
|
+
readOnlyHint: true,
|
|
33
|
+
destructiveHint: false,
|
|
34
|
+
openWorldHint: true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
async (params) => commercialConditionsModule.commercialConditionsHandler(params)
|
|
38
|
+
);
|
|
39
|
+
server.tool(
|
|
40
|
+
{
|
|
41
|
+
name: "vtex_payment_rules",
|
|
42
|
+
description: "Manage VTEX payment rules.",
|
|
43
|
+
schema: paymentRulesModule.paymentRulesSchema,
|
|
44
|
+
annotations: {
|
|
45
|
+
readOnlyHint: false,
|
|
46
|
+
destructiveHint: true,
|
|
47
|
+
openWorldHint: true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
async (params) => paymentRulesModule.paymentRulesHandler(params)
|
|
51
|
+
);
|
|
52
|
+
const handler = await server.getHandler();
|
|
53
|
+
const client = new MCPClient({
|
|
54
|
+
mcpServers: {
|
|
55
|
+
local: {
|
|
56
|
+
url: "http://localhost:3000/mcp",
|
|
57
|
+
transport: "http",
|
|
58
|
+
fetch: (input, init) => {
|
|
59
|
+
if (input instanceof Request) {
|
|
60
|
+
return handler(init === void 0 ? input : new Request(input, init));
|
|
61
|
+
}
|
|
62
|
+
return handler(new Request(input, init));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
try {
|
|
68
|
+
const session = await client.createSession("local");
|
|
69
|
+
const tools = await session.listTools();
|
|
70
|
+
expect(tools).toEqual(
|
|
71
|
+
expect.arrayContaining([
|
|
72
|
+
expect.objectContaining({
|
|
73
|
+
name: "vtex_commercial_conditions",
|
|
74
|
+
inputSchema: expect.objectContaining({
|
|
75
|
+
properties: expect.objectContaining({
|
|
76
|
+
action: expect.any(Object),
|
|
77
|
+
profileId: expect.any(Object)
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
}),
|
|
81
|
+
expect.objectContaining({
|
|
82
|
+
name: "vtex_payment_rules",
|
|
83
|
+
inputSchema: expect.objectContaining({
|
|
84
|
+
properties: expect.objectContaining({
|
|
85
|
+
action: expect.any(Object),
|
|
86
|
+
profileId: expect.any(Object)
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
])
|
|
91
|
+
);
|
|
92
|
+
} finally {
|
|
93
|
+
await client.closeAllSessions();
|
|
94
|
+
await server.close();
|
|
95
|
+
}
|
|
96
|
+
} finally {
|
|
97
|
+
if (previousNodeEnv === void 0) {
|
|
98
|
+
delete process.env.NODE_ENV;
|
|
99
|
+
} else {
|
|
100
|
+
process.env.NODE_ENV = previousNodeEnv;
|
|
101
|
+
}
|
|
102
|
+
if (previousTelemetry === void 0) {
|
|
103
|
+
delete process.env.MCP_USE_ANONYMIZED_TELEMETRY;
|
|
104
|
+
} else {
|
|
105
|
+
process.env.MCP_USE_ANONYMIZED_TELEMETRY = previousTelemetry;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
it("exports and registers both action-based payments tools", async () => {
|
|
110
|
+
const serverSource = await readFile(new URL("../../index.ts", import.meta.url), "utf8");
|
|
111
|
+
const exportsSource = await readFile(new URL("../../src/tools/vtex/index.ts", import.meta.url), "utf8");
|
|
112
|
+
expect(exportsSource).toContain('export * from "./commercial-conditions.js"');
|
|
113
|
+
expect(exportsSource).toContain('export * from "./payment-rules.js"');
|
|
114
|
+
const commercialConditionsStart = serverSource.indexOf('name: "vtex_commercial_conditions"');
|
|
115
|
+
const paymentRulesStart = serverSource.indexOf('name: "vtex_payment_rules"');
|
|
116
|
+
expect(commercialConditionsStart, "vtex_commercial_conditions registration exists").toBeGreaterThan(-1);
|
|
117
|
+
expect(paymentRulesStart, "vtex_payment_rules registration exists").toBeGreaterThan(-1);
|
|
118
|
+
const commercialConditionsBlock = serverSource.slice(commercialConditionsStart, commercialConditionsStart + 900);
|
|
119
|
+
const paymentRulesBlock = serverSource.slice(paymentRulesStart, paymentRulesStart + 900);
|
|
120
|
+
expect(commercialConditionsBlock).toContain("readOnlyHint: true");
|
|
121
|
+
expect(commercialConditionsBlock).toContain("destructiveHint: false");
|
|
122
|
+
expect(commercialConditionsBlock).toContain("openWorldHint: true");
|
|
123
|
+
expect(paymentRulesBlock).toContain("readOnlyHint: false");
|
|
124
|
+
expect(paymentRulesBlock).toContain("destructiveHint: true");
|
|
125
|
+
expect(paymentRulesBlock).toContain("openWorldHint: true");
|
|
126
|
+
});
|
|
127
|
+
it("keeps both tool descriptions business-safe and action-focused", async () => {
|
|
128
|
+
const serverSource = await readFile(new URL("../../index.ts", import.meta.url), "utf8");
|
|
129
|
+
const commercialConditionsStart = serverSource.indexOf('name: "vtex_commercial_conditions"');
|
|
130
|
+
const paymentRulesStart = serverSource.indexOf('name: "vtex_payment_rules"');
|
|
131
|
+
expect(commercialConditionsStart).toBeGreaterThan(-1);
|
|
132
|
+
expect(paymentRulesStart).toBeGreaterThan(-1);
|
|
133
|
+
const commercialConditionsBlock = serverSource.slice(commercialConditionsStart, commercialConditionsStart + 900);
|
|
134
|
+
const paymentRulesBlock = serverSource.slice(paymentRulesStart, paymentRulesStart + 900);
|
|
135
|
+
expect(commercialConditionsBlock).toContain(
|
|
136
|
+
"list available condition records or get a specific condition"
|
|
137
|
+
);
|
|
138
|
+
expect(commercialConditionsBlock).toContain("cannot be created or modified through this API");
|
|
139
|
+
expect(commercialConditionsBlock).toContain("created manually in the VTEX admin panel");
|
|
140
|
+
expect(commercialConditionsBlock).not.toContain("sandbox");
|
|
141
|
+
expect(commercialConditionsBlock).not.toContain("Delete operations require confirmed=true");
|
|
142
|
+
expect(paymentRulesBlock).toContain(
|
|
143
|
+
"rules that map installments, payment systems, and optional commercial-condition restrictions"
|
|
144
|
+
);
|
|
145
|
+
expect(paymentRulesBlock).toContain("Delete operations require confirmed=true");
|
|
146
|
+
expect(paymentRulesBlock).not.toContain("sandbox");
|
|
147
|
+
expect(paymentRulesBlock).not.toContain("production writes");
|
|
148
|
+
expect(paymentRulesBlock).not.toContain("legacy VTEX Payments endpoint");
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=vtex-commercial-conditions-surface.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../tests/vtex/vtex-commercial-conditions-surface.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { readFile } from \"node:fs/promises\";\nimport { describe, expect, it } from \"vitest\";\n\ndescribe(\"VTEX commercial conditions server surface\", () => {\n it(\"registers and lists both tools through the MCP layer without schema compatibility failures\", async () => {\n const previousNodeEnv = process.env.NODE_ENV;\n const previousTelemetry = process.env.MCP_USE_ANONYMIZED_TELEMETRY;\n\n process.env.NODE_ENV = \"production\";\n process.env.MCP_USE_ANONYMIZED_TELEMETRY = \"false\";\n\n try {\n const [\n { MCPServer, object },\n { MCPClient },\n commercialConditionsModule,\n paymentRulesModule,\n ] = await Promise.all([\n import(\"mcp-use/server\"),\n import(\"mcp-use\"),\n import(\"../../src/tools/vtex/commercial-conditions.js\"),\n import(\"../../src/tools/vtex/payment-rules.js\"),\n ]);\n\n const server = new MCPServer({\n name: \"test-vtex-payments-server\",\n version: \"1.0.0\",\n baseUrl: \"http://localhost:3000\",\n });\n\n server.tool(\n {\n name: \"vtex_commercial_conditions\",\n description: \"Read VTEX commercial conditions.\",\n schema: commercialConditionsModule.commercialConditionsSchema,\n annotations: {\n readOnlyHint: true,\n destructiveHint: false,\n openWorldHint: true,\n },\n },\n async (params) => commercialConditionsModule.commercialConditionsHandler(params)\n );\n\n server.tool(\n {\n name: \"vtex_payment_rules\",\n description: \"Manage VTEX payment rules.\",\n schema: paymentRulesModule.paymentRulesSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n openWorldHint: true,\n },\n },\n async (params) => paymentRulesModule.paymentRulesHandler(params)\n );\n\n const handler = await server.getHandler();\n const client = new MCPClient({\n mcpServers: {\n local: {\n url: \"http://localhost:3000/mcp\",\n transport: \"http\",\n fetch: (input: Request | URL | string, init?: RequestInit) => {\n if (input instanceof Request) {\n return handler(init === undefined ? input : new Request(input, init));\n }\n\n return handler(new Request(input, init));\n },\n },\n },\n });\n\n try {\n const session = await client.createSession(\"local\");\n const tools = await session.listTools();\n\n expect(tools).toEqual(\n expect.arrayContaining([\n expect.objectContaining({\n name: \"vtex_commercial_conditions\",\n inputSchema: expect.objectContaining({\n properties: expect.objectContaining({\n action: expect.any(Object),\n profileId: expect.any(Object),\n }),\n }),\n }),\n expect.objectContaining({\n name: \"vtex_payment_rules\",\n inputSchema: expect.objectContaining({\n properties: expect.objectContaining({\n action: expect.any(Object),\n profileId: expect.any(Object),\n }),\n }),\n }),\n ])\n );\n } finally {\n await client.closeAllSessions();\n await server.close();\n }\n } finally {\n if (previousNodeEnv === undefined) {\n delete process.env.NODE_ENV;\n } else {\n process.env.NODE_ENV = previousNodeEnv;\n }\n\n if (previousTelemetry === undefined) {\n delete process.env.MCP_USE_ANONYMIZED_TELEMETRY;\n } else {\n process.env.MCP_USE_ANONYMIZED_TELEMETRY = previousTelemetry;\n }\n }\n });\n\n it(\"exports and registers both action-based payments tools\", async () => {\n const serverSource = await readFile(new URL(\"../../index.ts\", import.meta.url), \"utf8\");\n const exportsSource = await readFile(new URL(\"../../src/tools/vtex/index.ts\", import.meta.url), \"utf8\");\n\n expect(exportsSource).toContain('export * from \"./commercial-conditions.js\"');\n expect(exportsSource).toContain('export * from \"./payment-rules.js\"');\n\n const commercialConditionsStart = serverSource.indexOf('name: \"vtex_commercial_conditions\"');\n const paymentRulesStart = serverSource.indexOf('name: \"vtex_payment_rules\"');\n\n expect(commercialConditionsStart, \"vtex_commercial_conditions registration exists\").toBeGreaterThan(-1);\n expect(paymentRulesStart, \"vtex_payment_rules registration exists\").toBeGreaterThan(-1);\n\n const commercialConditionsBlock = serverSource.slice(commercialConditionsStart, commercialConditionsStart + 900);\n const paymentRulesBlock = serverSource.slice(paymentRulesStart, paymentRulesStart + 900);\n\n expect(commercialConditionsBlock).toContain(\"readOnlyHint: true\");\n expect(commercialConditionsBlock).toContain(\"destructiveHint: false\");\n expect(commercialConditionsBlock).toContain(\"openWorldHint: true\");\n\n expect(paymentRulesBlock).toContain(\"readOnlyHint: false\");\n expect(paymentRulesBlock).toContain(\"destructiveHint: true\");\n expect(paymentRulesBlock).toContain(\"openWorldHint: true\");\n });\n\n it(\"keeps both tool descriptions business-safe and action-focused\", async () => {\n const serverSource = await readFile(new URL(\"../../index.ts\", import.meta.url), \"utf8\");\n\n const commercialConditionsStart = serverSource.indexOf('name: \"vtex_commercial_conditions\"');\n const paymentRulesStart = serverSource.indexOf('name: \"vtex_payment_rules\"');\n\n expect(commercialConditionsStart).toBeGreaterThan(-1);\n expect(paymentRulesStart).toBeGreaterThan(-1);\n\n const commercialConditionsBlock = serverSource.slice(commercialConditionsStart, commercialConditionsStart + 900);\n const paymentRulesBlock = serverSource.slice(paymentRulesStart, paymentRulesStart + 900);\n\n expect(commercialConditionsBlock).toContain(\n \"list available condition records or get a specific condition\"\n );\n expect(commercialConditionsBlock).toContain(\"cannot be created or modified through this API\");\n expect(commercialConditionsBlock).toContain(\"created manually in the VTEX admin panel\");\n expect(commercialConditionsBlock).not.toContain(\"sandbox\");\n expect(commercialConditionsBlock).not.toContain(\"Delete operations require confirmed=true\");\n\n expect(paymentRulesBlock).toContain(\n \"rules that map installments, payment systems, and optional commercial-condition restrictions\"\n );\n expect(paymentRulesBlock).toContain(\"Delete operations require confirmed=true\");\n expect(paymentRulesBlock).not.toContain(\"sandbox\");\n expect(paymentRulesBlock).not.toContain(\"production writes\");\n expect(paymentRulesBlock).not.toContain(\"legacy VTEX Payments endpoint\");\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|