@yoryoboy/bi-mcp 1.0.5 → 1.2.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 +140 -9
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.js +151 -1
- package/dist/index.js.map +2 -2
- package/dist/mcp-use.json +2 -2
- package/dist/scripts/_helpers.js +44 -0
- package/dist/scripts/_helpers.js.map +7 -0
- package/dist/scripts/admin-profile-delete.js +72 -0
- package/dist/scripts/admin-profile-delete.js.map +7 -0
- package/dist/scripts/admin-profile-list.js +24 -0
- package/dist/scripts/admin-profile-list.js.map +7 -0
- package/dist/scripts/admin-profile-upsert.js +25 -0
- package/dist/scripts/admin-profile-upsert.js.map +7 -0
- package/dist/scripts/admin-vtex-list.js +28 -0
- package/dist/scripts/admin-vtex-list.js.map +7 -0
- package/dist/scripts/admin-vtex-upsert.js +73 -0
- package/dist/scripts/admin-vtex-upsert.js.map +7 -0
- package/dist/scripts/admin-vtex-validate.js +55 -0
- package/dist/scripts/admin-vtex-validate.js.map +7 -0
- package/dist/scripts/run-migrations.js +50 -0
- package/dist/scripts/run-migrations.js.map +7 -0
- package/dist/scripts/test-db-connection.js +19 -0
- package/dist/scripts/test-db-connection.js.map +7 -0
- package/dist/src/config/meta.js +29 -0
- package/dist/src/config/meta.js.map +7 -0
- package/dist/src/config/profile-store.js +86 -0
- package/dist/src/config/profile-store.js.map +7 -0
- package/dist/src/config/vtex-crypto.js +43 -0
- package/dist/src/config/vtex-crypto.js.map +7 -0
- package/dist/src/config/vtex-profile-store.js +132 -0
- package/dist/src/config/vtex-profile-store.js.map +7 -0
- package/dist/src/config/vtex.js +27 -21
- package/dist/src/config/vtex.js.map +2 -2
- package/dist/src/db/client.js +58 -0
- package/dist/src/db/client.js.map +7 -0
- package/dist/src/meta/meta-utils.js +148 -0
- package/dist/src/meta/meta-utils.js.map +7 -0
- package/dist/src/services/meta/meta-ads.js +89 -0
- package/dist/src/services/meta/meta-ads.js.map +7 -0
- package/dist/src/services/meta/meta-api.js +35 -0
- package/dist/src/services/meta/meta-api.js.map +7 -0
- package/dist/src/services/vtex/vtex-api.js +24 -8
- package/dist/src/services/vtex/vtex-api.js.map +2 -2
- package/dist/src/services/vtex/vtex-catalog.js +5 -3
- package/dist/src/services/vtex/vtex-catalog.js.map +2 -2
- package/dist/src/services/vtex/vtex-logistics.js +18 -9
- package/dist/src/services/vtex/vtex-logistics.js.map +2 -2
- package/dist/src/services/vtex/vtex-orders.js +13 -7
- package/dist/src/services/vtex/vtex-orders.js.map +2 -2
- package/dist/src/services/vtex/vtex-pricing.js +5 -3
- package/dist/src/services/vtex/vtex-pricing.js.map +2 -2
- package/dist/src/tools/config/check-database-connection.js +59 -0
- package/dist/src/tools/config/check-database-connection.js.map +7 -0
- package/dist/src/tools/config/index.js +3 -0
- package/dist/src/tools/config/index.js.map +7 -0
- package/dist/src/tools/config/list-profiles.js +26 -0
- package/dist/src/tools/config/list-profiles.js.map +7 -0
- package/dist/src/tools/index.js +2 -0
- package/dist/src/tools/index.js.map +2 -2
- package/dist/src/tools/meta/account-overview.js +92 -0
- package/dist/src/tools/meta/account-overview.js.map +7 -0
- package/dist/src/tools/meta/ad-account-info.js +37 -0
- package/dist/src/tools/meta/ad-account-info.js.map +7 -0
- package/dist/src/tools/meta/ads-performance.js +79 -0
- package/dist/src/tools/meta/ads-performance.js.map +7 -0
- package/dist/src/tools/meta/campaign-performance.js +81 -0
- package/dist/src/tools/meta/campaign-performance.js.map +7 -0
- package/dist/src/tools/meta/index.js +9 -0
- package/dist/src/tools/meta/index.js.map +7 -0
- package/dist/src/tools/meta/list-accessible-ad-accounts.js +44 -0
- package/dist/src/tools/meta/list-accessible-ad-accounts.js.map +7 -0
- package/dist/src/tools/meta/list-accessible-businesses.js +36 -0
- package/dist/src/tools/meta/list-accessible-businesses.js.map +7 -0
- package/dist/src/tools/meta/placement-mix.js +67 -0
- package/dist/src/tools/meta/placement-mix.js.map +7 -0
- package/dist/src/tools/meta/time-series.js +69 -0
- package/dist/src/tools/meta/time-series.js.map +7 -0
- package/dist/src/tools/vtex/computed-price.js +12 -1
- package/dist/src/tools/vtex/computed-price.js.map +2 -2
- package/dist/src/tools/vtex/index.js +1 -0
- package/dist/src/tools/vtex/index.js.map +2 -2
- package/dist/src/tools/vtex/inventory-check.js +15 -2
- package/dist/src/tools/vtex/inventory-check.js.map +2 -2
- package/dist/src/tools/vtex/order-details.js +16 -2
- package/dist/src/tools/vtex/order-details.js.map +2 -2
- package/dist/src/tools/vtex/orders-summary.js +11 -1
- package/dist/src/tools/vtex/orders-summary.js.map +2 -2
- package/dist/src/tools/vtex/product-offers.js +15 -2
- package/dist/src/tools/vtex/product-offers.js.map +2 -2
- package/dist/src/tools/vtex/profile-resolution.js +57 -0
- package/dist/src/tools/vtex/profile-resolution.js.map +7 -0
- package/dist/src/tools/vtex/sku-offers.js +16 -2
- package/dist/src/tools/vtex/sku-offers.js.map +2 -2
- package/dist/src/tools/vtex/sku-price.js +12 -2
- package/dist/src/tools/vtex/sku-price.js.map +2 -2
- package/dist/src/tools/vtex/update-inventory.js +12 -1
- package/dist/src/tools/vtex/update-inventory.js.map +2 -2
- package/dist/src/tools/vtex/update-lead-time.js +12 -1
- package/dist/src/tools/vtex/update-lead-time.js.map +2 -2
- package/dist/src/tools/vtex/warehouse-inventory.js +12 -1
- package/dist/src/tools/vtex/warehouse-inventory.js.map +2 -2
- package/package.json +12 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/services/vtex/vtex-logistics.ts"],
|
|
4
|
-
"sourcesContent": ["import axios from \"axios\";\nimport {
|
|
5
|
-
"mappings": "AAAA,OAAO,WAAW;
|
|
4
|
+
"sourcesContent": ["import axios from \"axios\";\nimport type { AxiosInstance } from \"axios\";\n\nimport { getVtexApiClients } from \"./vtex-api.js\";\n\nexport interface WarehouseBalance {\n warehouseId?: string;\n warehouseName?: string;\n totalQuantity?: number;\n reservedQuantity?: number;\n availableQuantity?: number;\n isUnlimited?: boolean;\n hasUnlimitedQuantity?: boolean;\n timeToRefill?: string;\n dateOfSupplyUtc?: string;\n leadTime?: string;\n}\n\nexport interface InventoryBySkuResponse {\n skuId?: string;\n balance?: WarehouseBalance[];\n}\n\nexport interface InventoryByWarehouseItem {\n skuId?: string;\n warehouseId?: string;\n totalQuantity?: number;\n reservedQuantity?: number;\n availableQuantity?: number;\n isUnlimited?: boolean;\n keepSellingAfterExpiration?: boolean;\n}\n\nexport interface UpdateInventoryQuantityPayload {\n quantity: number;\n unlimitedQuantity: boolean;\n dateUtcOnBalanceSystem?: string;\n}\n\nexport interface UpdateLeadTimePayload {\n leadTime: string;\n}\n\nexport interface GetInventoryBatchOptions {\n maxConcurrency?: number;\n maxRetries?: number;\n baseRetryDelayMs?: number;\n}\n\nexport interface InventoryBatchSuccess {\n skuId: string;\n document: InventoryBySkuResponse;\n}\n\nexport interface InventoryBatchFailure {\n skuId: string;\n message: string;\n statusCode?: number;\n attempts: number;\n retryable: boolean;\n}\n\nexport interface InventoryBatchResult {\n successful: InventoryBatchSuccess[];\n failed: InventoryBatchFailure[];\n}\n\ninterface InventoryFetchError extends Error {\n skuId: string;\n statusCode?: number;\n attempts: number;\n retryable: boolean;\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504]);\nconst DEFAULT_BATCH_CONCURRENCY = 10;\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_BASE_RETRY_DELAY_MS = 250;\n\nexport async function getInventoryBySku(\n profileId: string,\n skuId: string\n): Promise<InventoryBySkuResponse> {\n const { vtexApi } = await getVtexApiClients(profileId);\n const response = await vtexApi.get<InventoryBySkuResponse>(`/api/logistics/pvt/inventory/skus/${skuId}`);\n return response.data;\n}\n\nasync function getInventoryBySkuWithClient(\n vtexApi: AxiosInstance,\n skuId: string\n): Promise<InventoryBySkuResponse> {\n const response = await vtexApi.get<InventoryBySkuResponse>(`/api/logistics/pvt/inventory/skus/${skuId}`);\n return response.data;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction parseRetryAfterMs(headerValue: unknown): number | undefined {\n if (Array.isArray(headerValue)) {\n return parseRetryAfterMs(headerValue[0]);\n }\n\n if (typeof headerValue === \"number\" && Number.isFinite(headerValue)) {\n return Math.max(0, Math.floor(headerValue * 1000));\n }\n\n if (typeof headerValue !== \"string\") {\n return undefined;\n }\n\n const trimmedValue = headerValue.trim();\n if (!trimmedValue) {\n return undefined;\n }\n\n const seconds = Number(trimmedValue);\n if (Number.isFinite(seconds)) {\n return Math.max(0, Math.floor(seconds * 1000));\n }\n\n const absoluteDateMs = Date.parse(trimmedValue);\n if (Number.isNaN(absoluteDateMs)) {\n return undefined;\n }\n\n return Math.max(0, absoluteDateMs - Date.now());\n}\n\nfunction computeBackoffDelayMs(attempt: number, baseDelayMs: number): number {\n const exponential = baseDelayMs * 2 ** Math.max(0, attempt - 1);\n const jitter = Math.floor(Math.random() * 150);\n return exponential + jitter;\n}\n\nfunction isRetryableRequestError(error: unknown): boolean {\n if (!axios.isAxiosError(error)) {\n return false;\n }\n\n if (!error.response?.status) {\n return true;\n }\n\n return RETRYABLE_STATUS_CODES.has(error.response.status);\n}\n\nfunction toInventoryFetchError(\n skuId: string,\n source: unknown,\n attempts: number,\n retryable: boolean\n): InventoryFetchError {\n const statusCode = axios.isAxiosError(source) ? source.response?.status : undefined;\n const message =\n source instanceof Error\n ? source.message\n : typeof source === \"string\"\n ? source\n : \"Unexpected error while fetching inventory details\";\n\n const error = new Error(message) as InventoryFetchError;\n error.skuId = skuId;\n error.statusCode = statusCode;\n error.attempts = attempts;\n error.retryable = retryable;\n return error;\n}\n\nfunction isInventoryFetchError(error: unknown): error is InventoryFetchError {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return (\n \"skuId\" in error &&\n \"attempts\" in error &&\n \"retryable\" in error &&\n typeof (error as Partial<InventoryFetchError>).skuId === \"string\"\n );\n}\n\nasync function getInventoryBySkuWithRetry(\n vtexApi: AxiosInstance,\n skuId: string,\n options: GetInventoryBatchOptions\n): Promise<InventoryBatchSuccess> {\n const maxRetries = Math.max(0, Math.floor(options.maxRetries ?? DEFAULT_MAX_RETRIES));\n const baseRetryDelayMs = Math.max(\n 50,\n Math.floor(options.baseRetryDelayMs ?? DEFAULT_BASE_RETRY_DELAY_MS)\n );\n let attempts = 0;\n\n while (true) {\n attempts += 1;\n\n try {\n const document = await getInventoryBySkuWithClient(vtexApi, skuId);\n return { skuId, document };\n } catch (error) {\n const retryable = isRetryableRequestError(error);\n\n if (!retryable || attempts > maxRetries) {\n throw toInventoryFetchError(skuId, error, attempts, retryable);\n }\n\n const retryAfterHeader = axios.isAxiosError(error)\n ? error.response?.headers?.[\"retry-after\"]\n : undefined;\n const retryAfterMs = parseRetryAfterMs(retryAfterHeader);\n const delayMs = retryAfterMs ?? computeBackoffDelayMs(attempts, baseRetryDelayMs);\n await sleep(delayMs);\n }\n }\n}\n\nexport async function getInventoryBySkuBatch(\n profileId: string,\n skuIds: string[],\n options: GetInventoryBatchOptions = {}\n): Promise<InventoryBatchResult> {\n const { vtexApi } = await getVtexApiClients(profileId);\n const maxConcurrency = Math.max(\n 1,\n Math.floor(options.maxConcurrency ?? DEFAULT_BATCH_CONCURRENCY)\n );\n const successful: InventoryBatchSuccess[] = [];\n const failed: InventoryBatchFailure[] = [];\n\n for (let start = 0; start < skuIds.length; start += maxConcurrency) {\n const chunk = skuIds.slice(start, start + maxConcurrency);\n const settledChunk = await Promise.allSettled(\n chunk.map((skuId) => getInventoryBySkuWithRetry(vtexApi, skuId, options))\n );\n\n settledChunk.forEach((result, index) => {\n const skuId = chunk[index];\n\n if (result.status === \"fulfilled\") {\n successful.push(result.value);\n return;\n }\n\n if (isInventoryFetchError(result.reason)) {\n failed.push({\n skuId: result.reason.skuId,\n message: result.reason.message,\n statusCode: result.reason.statusCode,\n attempts: result.reason.attempts,\n retryable: result.reason.retryable,\n });\n return;\n }\n\n failed.push({\n skuId,\n message:\n result.reason instanceof Error\n ? result.reason.message\n : \"Unexpected error while fetching inventory details\",\n attempts: 1,\n retryable: false,\n });\n });\n }\n\n return { successful, failed };\n}\n\nexport async function getInventoryByWarehouse(\n profileId: string,\n skuId: string,\n warehouseId: string\n): Promise<InventoryByWarehouseItem[]> {\n const { vtexApi } = await getVtexApiClients(profileId);\n const response = await vtexApi.get<InventoryByWarehouseItem[]>(\n `/api/logistics/pvt/inventory/items/${skuId}/warehouses/${warehouseId}`\n );\n return response.data;\n}\n\nexport async function updateInventoryQuantity(\n profileId: string,\n skuId: string,\n warehouseId: string,\n payload: UpdateInventoryQuantityPayload\n): Promise<void> {\n const { vtexApi } = await getVtexApiClients(profileId);\n await vtexApi.patch(`/api/logistics/pvt/inventory/skus/${skuId}/warehouses/${warehouseId}/quantity`, payload);\n}\n\nexport async function updateInventoryLeadTime(\n profileId: string,\n skuId: string,\n warehouseId: string,\n payload: UpdateLeadTimePayload\n): Promise<void> {\n const { vtexApi } = await getVtexApiClients(profileId);\n await vtexApi.patch(`/api/logistics/pvt/inventory/skus/${skuId}/warehouses/${warehouseId}/lead-time`, payload);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
|
-
import {
|
|
2
|
+
import { getVtexApiClients } from "./vtex-api.js";
|
|
3
3
|
const RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
|
|
4
4
|
const DEFAULT_BATCH_CONCURRENCY = 10;
|
|
5
5
|
const DEFAULT_MAX_RETRIES = 2;
|
|
6
6
|
const DEFAULT_BASE_RETRY_DELAY_MS = 250;
|
|
7
|
-
async function listOrders(params) {
|
|
7
|
+
async function listOrders(profileId, params) {
|
|
8
|
+
const { vtexApi } = await getVtexApiClients(profileId);
|
|
8
9
|
const response = await vtexApi.get("/api/oms/pvt/orders", { params });
|
|
9
10
|
return response.data;
|
|
10
11
|
}
|
|
11
|
-
async function getOrderDocument(orderId, reason) {
|
|
12
|
+
async function getOrderDocument(profileId, orderId, reason) {
|
|
13
|
+
const { vtexApi } = await getVtexApiClients(profileId);
|
|
12
14
|
const response = await vtexApi.get(`/api/orders/pvt/document/${orderId}`, {
|
|
13
15
|
params: reason ? { reason } : void 0
|
|
14
16
|
});
|
|
@@ -73,7 +75,7 @@ function isOrderDocumentFetchError(error) {
|
|
|
73
75
|
}
|
|
74
76
|
return "orderId" in error && "attempts" in error && "retryable" in error && typeof error.orderId === "string";
|
|
75
77
|
}
|
|
76
|
-
async function getOrderDocumentWithRetry(orderId, options) {
|
|
78
|
+
async function getOrderDocumentWithRetry(vtexApi, orderId, options) {
|
|
77
79
|
const maxRetries = Math.max(0, Math.floor(options.maxRetries ?? DEFAULT_MAX_RETRIES));
|
|
78
80
|
const baseRetryDelayMs = Math.max(
|
|
79
81
|
50,
|
|
@@ -83,7 +85,10 @@ async function getOrderDocumentWithRetry(orderId, options) {
|
|
|
83
85
|
while (true) {
|
|
84
86
|
attempts += 1;
|
|
85
87
|
try {
|
|
86
|
-
const
|
|
88
|
+
const response = await vtexApi.get(`/api/orders/pvt/document/${orderId}`, {
|
|
89
|
+
params: options.reason ? { reason: options.reason } : void 0
|
|
90
|
+
});
|
|
91
|
+
const document = response.data;
|
|
87
92
|
return { orderId, document };
|
|
88
93
|
} catch (error) {
|
|
89
94
|
const retryable = isRetryableRequestError(error);
|
|
@@ -97,7 +102,8 @@ async function getOrderDocumentWithRetry(orderId, options) {
|
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
|
-
async function getOrderDocumentsBatch(orderIds, options = {}) {
|
|
105
|
+
async function getOrderDocumentsBatch(profileId, orderIds, options = {}) {
|
|
106
|
+
const { vtexApi } = await getVtexApiClients(profileId);
|
|
101
107
|
const maxConcurrency = Math.max(
|
|
102
108
|
1,
|
|
103
109
|
Math.floor(options.maxConcurrency ?? DEFAULT_BATCH_CONCURRENCY)
|
|
@@ -107,7 +113,7 @@ async function getOrderDocumentsBatch(orderIds, options = {}) {
|
|
|
107
113
|
for (let start = 0; start < orderIds.length; start += maxConcurrency) {
|
|
108
114
|
const chunk = orderIds.slice(start, start + maxConcurrency);
|
|
109
115
|
const settledChunk = await Promise.allSettled(
|
|
110
|
-
chunk.map((orderId) => getOrderDocumentWithRetry(orderId, options))
|
|
116
|
+
chunk.map((orderId) => getOrderDocumentWithRetry(vtexApi, orderId, options))
|
|
111
117
|
);
|
|
112
118
|
settledChunk.forEach((result, index) => {
|
|
113
119
|
const orderId = chunk[index];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/services/vtex/vtex-orders.ts"],
|
|
4
|
-
"sourcesContent": ["import axios from \"axios\";\nimport {
|
|
5
|
-
"mappings": "AAAA,OAAO,WAAW;
|
|
4
|
+
"sourcesContent": ["import axios from \"axios\";\nimport type { AxiosInstance } from \"axios\";\n\nimport { getVtexApiClients } from \"./vtex-api.js\";\n\nexport interface VtexOrderListItem {\n orderId: string;\n creationDate?: string;\n status?: string;\n totalValue?: number;\n currencyCode?: string;\n paymentNames?: string;\n salesChannel?: string;\n origin?: string;\n totalItems?: number;\n lastChange?: string;\n orderIsComplete?: boolean;\n authorizedDate?: string;\n paymentApprovedDate?: string;\n readyForHandlingDate?: string;\n}\n\nexport interface VtexOrdersPaging {\n total?: number;\n pages?: number;\n currentPage?: number;\n perPage?: number;\n}\n\nexport interface VtexOrdersListResponse {\n list: VtexOrderListItem[];\n paging: VtexOrdersPaging;\n stats?: unknown;\n}\n\nexport interface ListOrdersParams {\n page?: number;\n per_page?: number;\n orderBy?: string;\n f_creationDate?: string;\n f_invoicedDate?: string;\n f_status?: string;\n f_salesChannel?: string;\n f_paymentNames?: string;\n f_UtmSource?: string;\n q?: string;\n}\n\nexport interface GetOrderDocumentsBatchOptions {\n reason?: string;\n maxConcurrency?: number;\n maxRetries?: number;\n baseRetryDelayMs?: number;\n}\n\nexport interface OrderDocumentSuccess {\n orderId: string;\n document: Record<string, unknown>;\n}\n\nexport interface OrderDocumentFailure {\n orderId: string;\n message: string;\n statusCode?: number;\n attempts: number;\n retryable: boolean;\n}\n\nexport interface OrderDocumentsBatchResult {\n successful: OrderDocumentSuccess[];\n failed: OrderDocumentFailure[];\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504]);\nconst DEFAULT_BATCH_CONCURRENCY = 10;\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_BASE_RETRY_DELAY_MS = 250;\n\nexport async function listOrders(\n profileId: string,\n params: ListOrdersParams\n): Promise<VtexOrdersListResponse> {\n const { vtexApi } = await getVtexApiClients(profileId);\n const response = await vtexApi.get<VtexOrdersListResponse>(\"/api/oms/pvt/orders\", { params });\n return response.data;\n}\n\nexport async function getOrderDocument(\n profileId: string,\n orderId: string,\n reason?: string\n): Promise<Record<string, unknown>> {\n const { vtexApi } = await getVtexApiClients(profileId);\n const response = await vtexApi.get<Record<string, unknown>>(`/api/orders/pvt/document/${orderId}`, {\n params: reason ? { reason } : undefined,\n });\n\n return response.data;\n}\n\ninterface OrderDocumentFetchError extends Error {\n orderId: string;\n statusCode?: number;\n attempts: number;\n retryable: boolean;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction parseRetryAfterMs(headerValue: unknown): number | undefined {\n if (Array.isArray(headerValue)) {\n return parseRetryAfterMs(headerValue[0]);\n }\n\n if (typeof headerValue === \"number\" && Number.isFinite(headerValue)) {\n return Math.max(0, Math.floor(headerValue * 1000));\n }\n\n if (typeof headerValue !== \"string\") {\n return undefined;\n }\n\n const trimmedValue = headerValue.trim();\n if (!trimmedValue) {\n return undefined;\n }\n\n const seconds = Number(trimmedValue);\n if (Number.isFinite(seconds)) {\n return Math.max(0, Math.floor(seconds * 1000));\n }\n\n const absoluteDateMs = Date.parse(trimmedValue);\n if (Number.isNaN(absoluteDateMs)) {\n return undefined;\n }\n\n return Math.max(0, absoluteDateMs - Date.now());\n}\n\nfunction computeBackoffDelayMs(attempt: number, baseDelayMs: number): number {\n const exponential = baseDelayMs * 2 ** Math.max(0, attempt - 1);\n const jitter = Math.floor(Math.random() * 150);\n return exponential + jitter;\n}\n\nfunction isRetryableRequestError(error: unknown): boolean {\n if (!axios.isAxiosError(error)) {\n return false;\n }\n\n if (!error.response?.status) {\n return true;\n }\n\n return RETRYABLE_STATUS_CODES.has(error.response.status);\n}\n\nfunction toOrderDocumentFetchError(\n orderId: string,\n source: unknown,\n attempts: number,\n retryable: boolean\n): OrderDocumentFetchError {\n const statusCode = axios.isAxiosError(source) ? source.response?.status : undefined;\n const message =\n source instanceof Error\n ? source.message\n : typeof source === \"string\"\n ? source\n : \"Unexpected error while fetching order details\";\n\n const error = new Error(message) as OrderDocumentFetchError;\n error.orderId = orderId;\n error.statusCode = statusCode;\n error.attempts = attempts;\n error.retryable = retryable;\n return error;\n}\n\nfunction isOrderDocumentFetchError(error: unknown): error is OrderDocumentFetchError {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return (\n \"orderId\" in error &&\n \"attempts\" in error &&\n \"retryable\" in error &&\n typeof (error as Partial<OrderDocumentFetchError>).orderId === \"string\"\n );\n}\n\nasync function getOrderDocumentWithRetry(\n vtexApi: AxiosInstance,\n orderId: string,\n options: GetOrderDocumentsBatchOptions\n): Promise<OrderDocumentSuccess> {\n const maxRetries = Math.max(0, Math.floor(options.maxRetries ?? DEFAULT_MAX_RETRIES));\n const baseRetryDelayMs = Math.max(\n 50,\n Math.floor(options.baseRetryDelayMs ?? DEFAULT_BASE_RETRY_DELAY_MS)\n );\n let attempts = 0;\n\n while (true) {\n attempts += 1;\n\n try {\n const response = await vtexApi.get<Record<string, unknown>>(`/api/orders/pvt/document/${orderId}`, {\n params: options.reason ? { reason: options.reason } : undefined,\n });\n const document = response.data;\n return { orderId, document };\n } catch (error) {\n const retryable = isRetryableRequestError(error);\n\n if (!retryable || attempts > maxRetries) {\n throw toOrderDocumentFetchError(orderId, error, attempts, retryable);\n }\n\n const retryAfterHeader = axios.isAxiosError(error)\n ? error.response?.headers?.[\"retry-after\"]\n : undefined;\n const retryAfterMs = parseRetryAfterMs(retryAfterHeader);\n const delayMs = retryAfterMs ?? computeBackoffDelayMs(attempts, baseRetryDelayMs);\n await sleep(delayMs);\n }\n }\n}\n\nexport async function getOrderDocumentsBatch(\n profileId: string,\n orderIds: string[],\n options: GetOrderDocumentsBatchOptions = {}\n): Promise<OrderDocumentsBatchResult> {\n const { vtexApi } = await getVtexApiClients(profileId);\n const maxConcurrency = Math.max(\n 1,\n Math.floor(options.maxConcurrency ?? DEFAULT_BATCH_CONCURRENCY)\n );\n const successful: OrderDocumentSuccess[] = [];\n const failed: OrderDocumentFailure[] = [];\n\n for (let start = 0; start < orderIds.length; start += maxConcurrency) {\n const chunk = orderIds.slice(start, start + maxConcurrency);\n const settledChunk = await Promise.allSettled(\n chunk.map((orderId) => getOrderDocumentWithRetry(vtexApi, orderId, options))\n );\n\n settledChunk.forEach((result, index) => {\n const orderId = chunk[index];\n\n if (result.status === \"fulfilled\") {\n successful.push(result.value);\n return;\n }\n\n if (isOrderDocumentFetchError(result.reason)) {\n failed.push({\n orderId: result.reason.orderId,\n message: result.reason.message,\n statusCode: result.reason.statusCode,\n attempts: result.reason.attempts,\n retryable: result.reason.retryable,\n });\n return;\n }\n\n failed.push({\n orderId,\n message:\n result.reason instanceof Error\n ? result.reason.message\n : \"Unexpected error while fetching order details\",\n attempts: 1,\n retryable: false,\n });\n });\n }\n\n return { successful, failed };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
async function getSkuPrice(itemId) {
|
|
1
|
+
import { getVtexApiClients } from "./vtex-api.js";
|
|
2
|
+
async function getSkuPrice(profileId, itemId) {
|
|
3
|
+
const { vtexPricingApi } = await getVtexApiClients(profileId);
|
|
3
4
|
const response = await vtexPricingApi.get(`/pricing/prices/${itemId}`);
|
|
4
5
|
return response.data;
|
|
5
6
|
}
|
|
6
|
-
async function getComputedPrice(itemId, priceTableId, params) {
|
|
7
|
+
async function getComputedPrice(profileId, itemId, priceTableId, params) {
|
|
8
|
+
const { vtexPricingApi } = await getVtexApiClients(profileId);
|
|
7
9
|
const response = await vtexPricingApi.get(
|
|
8
10
|
`/pricing/prices/${itemId}/computed/${priceTableId}`,
|
|
9
11
|
{ params }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/services/vtex/vtex-pricing.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { getVtexApiClients } from \"./vtex-api.js\";\n\nexport interface SkuFixedPrice {\n value?: number;\n listPrice?: number;\n minQuantity?: number;\n dateRange?: {\n from?: string;\n to?: string;\n };\n tradePolicyId?: string;\n}\n\nexport interface SkuPriceResponse {\n itemId: string;\n listPrice: number;\n costPrice: number;\n markup: number;\n basePrice: number;\n fixedPrices: SkuFixedPrice[];\n}\n\nexport interface ComputedPriceParams {\n categoryId: number;\n brandId: number;\n quantity: number;\n}\n\nexport interface ComputedPriceResponse {\n tradePolicyId: string;\n listPrice: number;\n costPrice?: number;\n sellingPrice: number;\n priceValidUntil: string;\n}\n\nexport async function getSkuPrice(\n profileId: string,\n itemId: string\n): Promise<SkuPriceResponse> {\n const { vtexPricingApi } = await getVtexApiClients(profileId);\n const response = await vtexPricingApi.get<SkuPriceResponse>(`/pricing/prices/${itemId}`);\n return response.data;\n}\n\nexport async function getComputedPrice(\n profileId: string,\n itemId: string,\n priceTableId: string,\n params: ComputedPriceParams\n): Promise<ComputedPriceResponse> {\n const { vtexPricingApi } = await getVtexApiClients(profileId);\n const response = await vtexPricingApi.get<ComputedPriceResponse>(\n `/pricing/prices/${itemId}/computed/${priceTableId}`,\n { params }\n );\n\n return response.data;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,yBAAyB;AAoClC,eAAsB,YACpB,WACA,QAC2B;AAC3B,QAAM,EAAE,eAAe,IAAI,MAAM,kBAAkB,SAAS;AAC5D,QAAM,WAAW,MAAM,eAAe,IAAsB,mBAAmB,MAAM,EAAE;AACvF,SAAO,SAAS;AAClB;AAEA,eAAsB,iBACpB,WACA,QACA,cACA,QACgC;AAChC,QAAM,EAAE,eAAe,IAAI,MAAM,kBAAkB,SAAS;AAC5D,QAAM,WAAW,MAAM,eAAe;AAAA,IACpC,mBAAmB,MAAM,aAAa,YAAY;AAAA,IAClD,EAAE,OAAO;AAAA,EACX;AAEA,SAAO,SAAS;AAClB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { checkTableExists, getDatabaseUrl, testDatabaseConnection } from "../../db/client.js";
|
|
4
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
5
|
+
const checkDatabaseConnectionSchema = z.object({});
|
|
6
|
+
function getConnectionHints() {
|
|
7
|
+
const databaseUrl = getDatabaseUrl();
|
|
8
|
+
if (!databaseUrl) {
|
|
9
|
+
return {
|
|
10
|
+
database_url_present: false,
|
|
11
|
+
host_hint: void 0,
|
|
12
|
+
port_hint: void 0
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const parsedUrl = new URL(databaseUrl);
|
|
17
|
+
return {
|
|
18
|
+
database_url_present: true,
|
|
19
|
+
host_hint: parsedUrl.hostname || void 0,
|
|
20
|
+
port_hint: parsedUrl.port || void 0
|
|
21
|
+
};
|
|
22
|
+
} catch {
|
|
23
|
+
return {
|
|
24
|
+
database_url_present: true,
|
|
25
|
+
host_hint: void 0,
|
|
26
|
+
port_hint: void 0
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function checkDatabaseConnectionHandler() {
|
|
31
|
+
try {
|
|
32
|
+
const result = await testDatabaseConnection();
|
|
33
|
+
const schemaMigrationsTablePresent = await checkTableExists("schema_migrations");
|
|
34
|
+
const profilesTablePresent = await checkTableExists("profiles");
|
|
35
|
+
const profileVtexConnectionsTablePresent = await checkTableExists("profile_vtex_connections");
|
|
36
|
+
const hints = getConnectionHints();
|
|
37
|
+
return object(
|
|
38
|
+
stripNulls({
|
|
39
|
+
status: "ok",
|
|
40
|
+
database: result.current_database,
|
|
41
|
+
user: result.current_user,
|
|
42
|
+
server_time: result.now.toISOString(),
|
|
43
|
+
database_url_present: hints.database_url_present,
|
|
44
|
+
host_hint: hints.host_hint,
|
|
45
|
+
port_hint: hints.port_hint,
|
|
46
|
+
schema_migrations_table_present: schemaMigrationsTablePresent,
|
|
47
|
+
profiles_table_present: profilesTablePresent,
|
|
48
|
+
profile_vtex_connections_table_present: profileVtexConnectionsTablePresent
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
return error(err instanceof Error ? err.message : "Database connection check failed");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
checkDatabaseConnectionHandler,
|
|
57
|
+
checkDatabaseConnectionSchema
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=check-database-connection.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/config/check-database-connection.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { checkTableExists, getDatabaseUrl, testDatabaseConnection } from \"../../db/client.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const checkDatabaseConnectionSchema = z.object({});\n\nfunction getConnectionHints() {\n const databaseUrl = getDatabaseUrl();\n if (!databaseUrl) {\n return {\n database_url_present: false,\n host_hint: undefined,\n port_hint: undefined,\n };\n }\n\n try {\n const parsedUrl = new URL(databaseUrl);\n\n return {\n database_url_present: true,\n host_hint: parsedUrl.hostname || undefined,\n port_hint: parsedUrl.port || undefined,\n };\n } catch {\n return {\n database_url_present: true,\n host_hint: undefined,\n port_hint: undefined,\n };\n }\n}\n\nexport async function checkDatabaseConnectionHandler() {\n try {\n const result = await testDatabaseConnection();\n const schemaMigrationsTablePresent = await checkTableExists(\"schema_migrations\");\n const profilesTablePresent = await checkTableExists(\"profiles\");\n const profileVtexConnectionsTablePresent = await checkTableExists(\"profile_vtex_connections\");\n const hints = getConnectionHints();\n\n return object(\n stripNulls({\n status: \"ok\",\n database: result.current_database,\n user: result.current_user,\n server_time: result.now.toISOString(),\n database_url_present: hints.database_url_present,\n host_hint: hints.host_hint,\n port_hint: hints.port_hint,\n schema_migrations_table_present: schemaMigrationsTablePresent,\n profiles_table_present: profilesTablePresent,\n profile_vtex_connections_table_present: profileVtexConnectionsTablePresent,\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Database connection check failed\");\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,kBAAkB,gBAAgB,8BAA8B;AACzE,SAAS,kBAAkB;AAEpB,MAAM,gCAAgC,EAAE,OAAO,CAAC,CAAC;AAExD,SAAS,qBAAqB;AAC5B,QAAM,cAAc,eAAe;AACnC,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,MACL,sBAAsB;AAAA,MACtB,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,EACF;AAEA,MAAI;AACF,UAAM,YAAY,IAAI,IAAI,WAAW;AAErC,WAAO;AAAA,MACL,sBAAsB;AAAA,MACtB,WAAW,UAAU,YAAY;AAAA,MACjC,WAAW,UAAU,QAAQ;AAAA,IAC/B;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,sBAAsB;AAAA,MACtB,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAEA,eAAsB,iCAAiC;AACrD,MAAI;AACF,UAAM,SAAS,MAAM,uBAAuB;AAC5C,UAAM,+BAA+B,MAAM,iBAAiB,mBAAmB;AAC/E,UAAM,uBAAuB,MAAM,iBAAiB,UAAU;AAC9D,UAAM,qCAAqC,MAAM,iBAAiB,0BAA0B;AAC5F,UAAM,QAAQ,mBAAmB;AAEjC,WAAO;AAAA,MACL,WAAW;AAAA,QACT,QAAQ;AAAA,QACR,UAAU,OAAO;AAAA,QACjB,MAAM,OAAO;AAAA,QACb,aAAa,OAAO,IAAI,YAAY;AAAA,QACpC,sBAAsB,MAAM;AAAA,QAC5B,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM;AAAA,QACjB,iCAAiC;AAAA,QACjC,wBAAwB;AAAA,QACxB,wCAAwC;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,kCAAkC;AAAA,EACtF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { listProfiles } from "../../config/profile-store.js";
|
|
4
|
+
const listProfilesSchema = z.object({});
|
|
5
|
+
async function listProfilesHandler() {
|
|
6
|
+
try {
|
|
7
|
+
const profiles = await listProfiles();
|
|
8
|
+
return object({
|
|
9
|
+
total_profiles: profiles.length,
|
|
10
|
+
profiles: profiles.map((profile) => ({
|
|
11
|
+
profile_id: profile.id,
|
|
12
|
+
name: profile.name,
|
|
13
|
+
is_active: profile.isActive,
|
|
14
|
+
created_at: profile.createdAt.toISOString(),
|
|
15
|
+
updated_at: profile.updatedAt.toISOString()
|
|
16
|
+
}))
|
|
17
|
+
});
|
|
18
|
+
} catch (err) {
|
|
19
|
+
return error(err instanceof Error ? err.message : "Failed to list profiles");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
listProfilesHandler,
|
|
24
|
+
listProfilesSchema
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=list-profiles.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/config/list-profiles.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { listProfiles } from \"../../config/profile-store.js\";\n\nexport const listProfilesSchema = z.object({});\n\nexport async function listProfilesHandler() {\n try {\n const profiles = await listProfiles();\n\n return object({\n total_profiles: profiles.length,\n profiles: profiles.map((profile) => ({\n profile_id: profile.id,\n name: profile.name,\n is_active: profile.isActive,\n created_at: profile.createdAt.toISOString(),\n updated_at: profile.updatedAt.toISOString(),\n })),\n });\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to list profiles\");\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,oBAAoB;AAEtB,MAAM,qBAAqB,EAAE,OAAO,CAAC,CAAC;AAE7C,eAAsB,sBAAsB;AAC1C,MAAI;AACF,UAAM,WAAW,MAAM,aAAa;AAEpC,WAAO,OAAO;AAAA,MACZ,gBAAgB,SAAS;AAAA,MACzB,UAAU,SAAS,IAAI,CAAC,aAAa;AAAA,QACnC,YAAY,QAAQ;AAAA,QACpB,MAAM,QAAQ;AAAA,QACd,WAAW,QAAQ;AAAA,QACnB,YAAY,QAAQ,UAAU,YAAY;AAAA,QAC1C,YAAY,QAAQ,UAAU,YAAY;AAAA,MAC5C,EAAE;AAAA,IACJ,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,yBAAyB;AAAA,EAC7E;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/src/tools/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from \"./vtex/index.js\";\nexport * from \"./analytics/index.js\";\nexport * from \"./google-ads/index.js\";\nexport * from \"./search-console/index.js\";\n"],
|
|
5
|
-
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
4
|
+
"sourcesContent": ["export * from \"./config/index.js\";\nexport * from \"./vtex/index.js\";\nexport * from \"./analytics/index.js\";\nexport * from \"./google-ads/index.js\";\nexport * from \"./meta/index.js\";\nexport * from \"./search-console/index.js\";\n"],
|
|
5
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import {
|
|
4
|
+
getMetaInsights,
|
|
5
|
+
listAccessibleMetaAdAccounts
|
|
6
|
+
} from "../../services/meta/meta-ads.js";
|
|
7
|
+
import {
|
|
8
|
+
aggregateInsightsByCurrency,
|
|
9
|
+
dateRegex,
|
|
10
|
+
getMetricBundle,
|
|
11
|
+
normalizeRequestedAccountIds,
|
|
12
|
+
resolveRequestedAccounts
|
|
13
|
+
} from "../../meta/meta-utils.js";
|
|
14
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
15
|
+
const metaAccountOverviewSchema = z.object({
|
|
16
|
+
startDate: z.string().regex(dateRegex).describe("Start date in YYYY-MM-DD format."),
|
|
17
|
+
endDate: z.string().regex(dateRegex).describe("End date in YYYY-MM-DD format."),
|
|
18
|
+
adAccountIds: z.array(z.string()).optional().describe(
|
|
19
|
+
"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts."
|
|
20
|
+
)
|
|
21
|
+
});
|
|
22
|
+
async function metaAccountOverviewHandler(params) {
|
|
23
|
+
try {
|
|
24
|
+
const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;
|
|
25
|
+
const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);
|
|
26
|
+
const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);
|
|
27
|
+
const accountResults = await Promise.all(
|
|
28
|
+
accounts.map(async (account) => {
|
|
29
|
+
const insights = await getMetaInsights(`act_${account.account_id}`, {
|
|
30
|
+
time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),
|
|
31
|
+
level: "account"
|
|
32
|
+
});
|
|
33
|
+
const insight = insights[0];
|
|
34
|
+
return {
|
|
35
|
+
ad_account_id: account.account_id,
|
|
36
|
+
act_id: `act_${account.account_id}`,
|
|
37
|
+
account_name: account.name,
|
|
38
|
+
currency_code: account.currency,
|
|
39
|
+
business: account.business,
|
|
40
|
+
overview: getMetricBundle(insight)
|
|
41
|
+
};
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
return object(
|
|
45
|
+
stripNulls({
|
|
46
|
+
date_range: {
|
|
47
|
+
start_date: params.startDate,
|
|
48
|
+
end_date: params.endDate
|
|
49
|
+
},
|
|
50
|
+
accounts: accountResults,
|
|
51
|
+
summary_by_currency: aggregateInsightsByCurrency(
|
|
52
|
+
accountResults.map((account, index) => ({
|
|
53
|
+
currencyCode: account.currency_code,
|
|
54
|
+
insight: {
|
|
55
|
+
spend: String(accountResults[index].overview.spend),
|
|
56
|
+
impressions: String(accountResults[index].overview.impressions),
|
|
57
|
+
clicks: String(accountResults[index].overview.clicks),
|
|
58
|
+
reach: String(accountResults[index].overview.reach),
|
|
59
|
+
ctr: String(accountResults[index].overview.ctr_percent),
|
|
60
|
+
cpc: String(accountResults[index].overview.cpc),
|
|
61
|
+
cpm: String(accountResults[index].overview.cpm),
|
|
62
|
+
actions: [
|
|
63
|
+
{
|
|
64
|
+
action_type: "purchase",
|
|
65
|
+
value: String(accountResults[index].overview.purchases)
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
action_values: [
|
|
69
|
+
{
|
|
70
|
+
action_type: "purchase",
|
|
71
|
+
value: String(accountResults[index].overview.purchase_value)
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}))
|
|
76
|
+
),
|
|
77
|
+
metadata: {
|
|
78
|
+
requested_accounts: requestedIds?.length || 0,
|
|
79
|
+
analyzed_accounts: accountResults.length,
|
|
80
|
+
note: "Results are returned per ad account. Summary aggregates are split by currency to avoid unsafe cross-currency totals."
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
return error(err instanceof Error ? err.message : "Failed to fetch Meta account overview");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
metaAccountOverviewHandler,
|
|
90
|
+
metaAccountOverviewSchema
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=account-overview.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/meta/account-overview.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n aggregateInsightsByCurrency,\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaAccountOverviewSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\n adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n});\n\nexport async function metaAccountOverviewHandler(\n params: z.infer<typeof metaAccountOverviewSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n\n const accountResults = await Promise.all(\n accounts.map(async (account) => {\n const insights = await getMetaInsights(`act_${account.account_id}`, {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n level: \"account\",\n });\n const insight = insights[0];\n return {\n ad_account_id: account.account_id,\n act_id: `act_${account.account_id}`,\n account_name: account.name,\n currency_code: account.currency,\n business: account.business,\n overview: getMetricBundle(insight),\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n accounts: accountResults,\n summary_by_currency: aggregateInsightsByCurrency(\n accountResults.map((account, index) => ({\n currencyCode: account.currency_code,\n insight: {\n spend: String(accountResults[index].overview.spend),\n impressions: String(accountResults[index].overview.impressions),\n clicks: String(accountResults[index].overview.clicks),\n reach: String(accountResults[index].overview.reach),\n ctr: String(accountResults[index].overview.ctr_percent),\n cpc: String(accountResults[index].overview.cpc),\n cpm: String(accountResults[index].overview.cpm),\n actions: [\n {\n action_type: \"purchase\",\n value: String(accountResults[index].overview.purchases),\n },\n ],\n action_values: [\n {\n action_type: \"purchase\",\n value: String(accountResults[index].overview.purchase_value),\n },\n ],\n },\n }))\n ),\n metadata: {\n requested_accounts: requestedIds?.length || 0,\n analyzed_accounts: accountResults.length,\n note:\n \"Results are returned per ad account. Summary aggregates are split by currency to avoid unsafe cross-currency totals.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta account overview\");\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAED,eAAsB,2BACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAE1E,UAAM,iBAAiB,MAAM,QAAQ;AAAA,MACnC,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,WAAW,MAAM,gBAAgB,OAAO,QAAQ,UAAU,IAAI;AAAA,UAClE,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,UAC7E,OAAO;AAAA,QACT,CAAC;AACD,cAAM,UAAU,SAAS,CAAC;AAC1B,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,QAAQ,OAAO,QAAQ,UAAU;AAAA,UACjC,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,UAAU,QAAQ;AAAA,UAClB,UAAU,gBAAgB,OAAO;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,qBAAqB;AAAA,UACnB,eAAe,IAAI,CAAC,SAAS,WAAW;AAAA,YACtC,cAAc,QAAQ;AAAA,YACtB,SAAS;AAAA,cACP,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,KAAK;AAAA,cAClD,aAAa,OAAO,eAAe,KAAK,EAAE,SAAS,WAAW;AAAA,cAC9D,QAAQ,OAAO,eAAe,KAAK,EAAE,SAAS,MAAM;AAAA,cACpD,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,KAAK;AAAA,cAClD,KAAK,OAAO,eAAe,KAAK,EAAE,SAAS,WAAW;AAAA,cACtD,KAAK,OAAO,eAAe,KAAK,EAAE,SAAS,GAAG;AAAA,cAC9C,KAAK,OAAO,eAAe,KAAK,EAAE,SAAS,GAAG;AAAA,cAC9C,SAAS;AAAA,gBACP;AAAA,kBACE,aAAa;AAAA,kBACb,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,SAAS;AAAA,gBACxD;AAAA,cACF;AAAA,cACA,eAAe;AAAA,gBACb;AAAA,kBACE,aAAa;AAAA,kBACb,OAAO,OAAO,eAAe,KAAK,EAAE,SAAS,cAAc;AAAA,gBAC7D;AAAA,cACF;AAAA,YACF;AAAA,UACF,EAAE;AAAA,QACJ;AAAA,QACA,UAAU;AAAA,UACR,oBAAoB,cAAc,UAAU;AAAA,UAC5C,mBAAmB,eAAe;AAAA,UAClC,MACE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,uCAAuC;AAAA,EAC3F;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getMetaAdAccountInfo } from "../../services/meta/meta-ads.js";
|
|
4
|
+
import { getMetaAdAccountStatusLabel, normalizeMetaAdAccountId } from "../../meta/meta-utils.js";
|
|
5
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
6
|
+
const metaAdAccountInfoSchema = z.object({
|
|
7
|
+
adAccountId: z.string().describe("Meta ad account ID to inspect. Accepts digits with or without the act_ prefix.")
|
|
8
|
+
});
|
|
9
|
+
async function metaAdAccountInfoHandler(params) {
|
|
10
|
+
try {
|
|
11
|
+
const adAccountId = normalizeMetaAdAccountId(params.adAccountId);
|
|
12
|
+
const account = await getMetaAdAccountInfo(adAccountId);
|
|
13
|
+
return object(
|
|
14
|
+
stripNulls({
|
|
15
|
+
ad_account: {
|
|
16
|
+
id: account.id,
|
|
17
|
+
account_id: account.account_id,
|
|
18
|
+
act_id: `act_${adAccountId}`,
|
|
19
|
+
name: account.name,
|
|
20
|
+
currency: account.currency,
|
|
21
|
+
account_status: account.account_status,
|
|
22
|
+
account_status_label: getMetaAdAccountStatusLabel(account.account_status),
|
|
23
|
+
timezone_name: account.timezone_name,
|
|
24
|
+
timezone_offset_hours_utc: account.timezone_offset_hours_utc,
|
|
25
|
+
business: account.business
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
return error(err instanceof Error ? err.message : "Failed to fetch Meta ad account info");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
metaAdAccountInfoHandler,
|
|
35
|
+
metaAdAccountInfoSchema
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=ad-account-info.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/meta/ad-account-info.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { getMetaAdAccountInfo } from \"../../services/meta/meta-ads.js\";\nimport { getMetaAdAccountStatusLabel, normalizeMetaAdAccountId } from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaAdAccountInfoSchema = z.object({\n adAccountId: z\n .string()\n .describe(\"Meta ad account ID to inspect. Accepts digits with or without the act_ prefix.\"),\n});\n\nexport async function metaAdAccountInfoHandler(\n params: z.infer<typeof metaAdAccountInfoSchema>\n) {\n try {\n const adAccountId = normalizeMetaAdAccountId(params.adAccountId);\n const account = await getMetaAdAccountInfo(adAccountId);\n\n return object(\n stripNulls({\n ad_account: {\n id: account.id,\n account_id: account.account_id,\n act_id: `act_${adAccountId}`,\n name: account.name,\n currency: account.currency,\n account_status: account.account_status,\n account_status_label: getMetaAdAccountStatusLabel(account.account_status),\n timezone_name: account.timezone_name,\n timezone_offset_hours_utc: account.timezone_offset_hours_utc,\n business: account.business,\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta ad account info\");\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,4BAA4B;AACrC,SAAS,6BAA6B,gCAAgC;AACtE,SAAS,kBAAkB;AAEpB,MAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,aAAa,EACV,OAAO,EACP,SAAS,gFAAgF;AAC9F,CAAC;AAED,eAAsB,yBACpB,QACA;AACA,MAAI;AACF,UAAM,cAAc,yBAAyB,OAAO,WAAW;AAC/D,UAAM,UAAU,MAAM,qBAAqB,WAAW;AAEtD,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,IAAI,QAAQ;AAAA,UACZ,YAAY,QAAQ;AAAA,UACpB,QAAQ,OAAO,WAAW;AAAA,UAC1B,MAAM,QAAQ;AAAA,UACd,UAAU,QAAQ;AAAA,UAClB,gBAAgB,QAAQ;AAAA,UACxB,sBAAsB,4BAA4B,QAAQ,cAAc;AAAA,UACxE,eAAe,QAAQ;AAAA,UACvB,2BAA2B,QAAQ;AAAA,UACnC,UAAU,QAAQ;AAAA,QACpB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,sCAAsC;AAAA,EAC1F;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { error, object } from "mcp-use/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import {
|
|
4
|
+
getMetaAds,
|
|
5
|
+
getMetaInsights,
|
|
6
|
+
listAccessibleMetaAdAccounts
|
|
7
|
+
} from "../../services/meta/meta-ads.js";
|
|
8
|
+
import {
|
|
9
|
+
dateRegex,
|
|
10
|
+
getMetricBundle,
|
|
11
|
+
normalizeRequestedAccountIds,
|
|
12
|
+
resolveRequestedAccounts
|
|
13
|
+
} from "../../meta/meta-utils.js";
|
|
14
|
+
import { stripNulls } from "../../utils/strip-payload.js";
|
|
15
|
+
const metaAdsPerformanceSchema = z.object({
|
|
16
|
+
startDate: z.string().regex(dateRegex).describe("Start date in YYYY-MM-DD format."),
|
|
17
|
+
endDate: z.string().regex(dateRegex).describe("End date in YYYY-MM-DD format."),
|
|
18
|
+
adAccountIds: z.array(z.string()).optional().describe(
|
|
19
|
+
"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts."
|
|
20
|
+
),
|
|
21
|
+
limit: z.number().int().min(1).max(100).optional().describe("Maximum number of ads to return per ad account. Default: 25.")
|
|
22
|
+
});
|
|
23
|
+
async function metaAdsPerformanceHandler(params) {
|
|
24
|
+
try {
|
|
25
|
+
const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;
|
|
26
|
+
const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);
|
|
27
|
+
const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);
|
|
28
|
+
const limit = params.limit ?? 25;
|
|
29
|
+
const results = await Promise.all(
|
|
30
|
+
accounts.map(async (account) => {
|
|
31
|
+
const ads = await getMetaAds(account.account_id || "", limit);
|
|
32
|
+
const rows = await Promise.all(
|
|
33
|
+
ads.map(async (ad) => {
|
|
34
|
+
const insight = (await getMetaInsights(ad.id || "", {
|
|
35
|
+
time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),
|
|
36
|
+
level: "ad"
|
|
37
|
+
}))[0];
|
|
38
|
+
return {
|
|
39
|
+
ad_id: ad.id,
|
|
40
|
+
ad_name: ad.name,
|
|
41
|
+
status: ad.status,
|
|
42
|
+
effective_status: ad.effective_status,
|
|
43
|
+
creative_id: ad.creative?.id,
|
|
44
|
+
...getMetricBundle(insight)
|
|
45
|
+
};
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
rows.sort((left, right) => right.spend - left.spend);
|
|
49
|
+
return {
|
|
50
|
+
ad_account_id: account.account_id,
|
|
51
|
+
account_name: account.name,
|
|
52
|
+
currency_code: account.currency,
|
|
53
|
+
ads: rows
|
|
54
|
+
};
|
|
55
|
+
})
|
|
56
|
+
);
|
|
57
|
+
return object(
|
|
58
|
+
stripNulls({
|
|
59
|
+
date_range: {
|
|
60
|
+
start_date: params.startDate,
|
|
61
|
+
end_date: params.endDate
|
|
62
|
+
},
|
|
63
|
+
accounts: results,
|
|
64
|
+
metadata: {
|
|
65
|
+
analyzed_accounts: results.length,
|
|
66
|
+
ads_per_account_limit: limit,
|
|
67
|
+
note: "Ads are ranked inside each ad account. This output is intended for creative review and performance diagnosis, not for full asset exports."
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return error(err instanceof Error ? err.message : "Failed to fetch Meta ads performance");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
metaAdsPerformanceHandler,
|
|
77
|
+
metaAdsPerformanceSchema
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=ads-performance.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/tools/meta/ads-performance.ts"],
|
|
4
|
+
"sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport {\n getMetaAds,\n getMetaInsights,\n listAccessibleMetaAdAccounts,\n} from \"../../services/meta/meta-ads.js\";\nimport {\n dateRegex,\n getMetricBundle,\n normalizeRequestedAccountIds,\n resolveRequestedAccounts,\n} from \"../../meta/meta-utils.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\n\nexport const metaAdsPerformanceSchema = z.object({\n startDate: z.string().regex(dateRegex).describe(\"Start date in YYYY-MM-DD format.\"),\n endDate: z.string().regex(dateRegex).describe(\"End date in YYYY-MM-DD format.\"),\n adAccountIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of Meta ad account IDs. Accepts digits with or without the act_ prefix. If omitted, uses all accessible ad accounts.\"\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\"Maximum number of ads to return per ad account. Default: 25.\"),\n});\n\nexport async function metaAdsPerformanceHandler(\n params: z.infer<typeof metaAdsPerformanceSchema>\n) {\n try {\n const accessibleAccounts = (await listAccessibleMetaAdAccounts()).adAccounts;\n const requestedIds = normalizeRequestedAccountIds(params.adAccountIds);\n const accounts = resolveRequestedAccounts(requestedIds, accessibleAccounts);\n const limit = params.limit ?? 25;\n\n const results = await Promise.all(\n accounts.map(async (account) => {\n const ads = await getMetaAds(account.account_id || \"\", limit);\n const rows = await Promise.all(\n ads.map(async (ad) => {\n const insight = (\n await getMetaInsights(ad.id || \"\", {\n time_range: JSON.stringify({ since: params.startDate, until: params.endDate }),\n level: \"ad\",\n })\n )[0];\n\n return {\n ad_id: ad.id,\n ad_name: ad.name,\n status: ad.status,\n effective_status: ad.effective_status,\n creative_id: ad.creative?.id,\n ...getMetricBundle(insight),\n };\n })\n );\n\n rows.sort((left, right) => right.spend - left.spend);\n\n return {\n ad_account_id: account.account_id,\n account_name: account.name,\n currency_code: account.currency,\n ads: rows,\n };\n })\n );\n\n return object(\n stripNulls({\n date_range: {\n start_date: params.startDate,\n end_date: params.endDate,\n },\n accounts: results,\n metadata: {\n analyzed_accounts: results.length,\n ads_per_account_limit: limit,\n note:\n \"Ads are ranked inside each ad account. This output is intended for creative review and performance diagnosis, not for full asset exports.\",\n },\n })\n );\n } catch (err) {\n return error(err instanceof Error ? err.message : \"Failed to fetch Meta ads performance\");\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAEpB,MAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAClF,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC9E,cAAc,EACX,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAO,EACJ,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,SAAS,EACT,SAAS,8DAA8D;AAC5E,CAAC;AAED,eAAsB,0BACpB,QACA;AACA,MAAI;AACF,UAAM,sBAAsB,MAAM,6BAA6B,GAAG;AAClE,UAAM,eAAe,6BAA6B,OAAO,YAAY;AACrE,UAAM,WAAW,yBAAyB,cAAc,kBAAkB;AAC1E,UAAM,QAAQ,OAAO,SAAS;AAE9B,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,IAAI,OAAO,YAAY;AAC9B,cAAM,MAAM,MAAM,WAAW,QAAQ,cAAc,IAAI,KAAK;AAC5D,cAAM,OAAO,MAAM,QAAQ;AAAA,UACzB,IAAI,IAAI,OAAO,OAAO;AACpB,kBAAM,WACJ,MAAM,gBAAgB,GAAG,MAAM,IAAI;AAAA,cACjC,YAAY,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAAA,cAC7E,OAAO;AAAA,YACT,CAAC,GACD,CAAC;AAEH,mBAAO;AAAA,cACL,OAAO,GAAG;AAAA,cACV,SAAS,GAAG;AAAA,cACZ,QAAQ,GAAG;AAAA,cACX,kBAAkB,GAAG;AAAA,cACrB,aAAa,GAAG,UAAU;AAAA,cAC1B,GAAG,gBAAgB,OAAO;AAAA,YAC5B;AAAA,UACF,CAAC;AAAA,QACH;AAEA,aAAK,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK;AAEnD,eAAO;AAAA,UACL,eAAe,QAAQ;AAAA,UACvB,cAAc,QAAQ;AAAA,UACtB,eAAe,QAAQ;AAAA,UACvB,KAAK;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,QACT,YAAY;AAAA,UACV,YAAY,OAAO;AAAA,UACnB,UAAU,OAAO;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,UACR,mBAAmB,QAAQ;AAAA,UAC3B,uBAAuB;AAAA,UACvB,MACE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,sCAAsC;AAAA,EAC1F;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|