@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.
Files changed (102) hide show
  1. package/README.md +140 -9
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/index.js +151 -1
  4. package/dist/index.js.map +2 -2
  5. package/dist/mcp-use.json +2 -2
  6. package/dist/scripts/_helpers.js +44 -0
  7. package/dist/scripts/_helpers.js.map +7 -0
  8. package/dist/scripts/admin-profile-delete.js +72 -0
  9. package/dist/scripts/admin-profile-delete.js.map +7 -0
  10. package/dist/scripts/admin-profile-list.js +24 -0
  11. package/dist/scripts/admin-profile-list.js.map +7 -0
  12. package/dist/scripts/admin-profile-upsert.js +25 -0
  13. package/dist/scripts/admin-profile-upsert.js.map +7 -0
  14. package/dist/scripts/admin-vtex-list.js +28 -0
  15. package/dist/scripts/admin-vtex-list.js.map +7 -0
  16. package/dist/scripts/admin-vtex-upsert.js +73 -0
  17. package/dist/scripts/admin-vtex-upsert.js.map +7 -0
  18. package/dist/scripts/admin-vtex-validate.js +55 -0
  19. package/dist/scripts/admin-vtex-validate.js.map +7 -0
  20. package/dist/scripts/run-migrations.js +50 -0
  21. package/dist/scripts/run-migrations.js.map +7 -0
  22. package/dist/scripts/test-db-connection.js +19 -0
  23. package/dist/scripts/test-db-connection.js.map +7 -0
  24. package/dist/src/config/meta.js +29 -0
  25. package/dist/src/config/meta.js.map +7 -0
  26. package/dist/src/config/profile-store.js +86 -0
  27. package/dist/src/config/profile-store.js.map +7 -0
  28. package/dist/src/config/vtex-crypto.js +43 -0
  29. package/dist/src/config/vtex-crypto.js.map +7 -0
  30. package/dist/src/config/vtex-profile-store.js +132 -0
  31. package/dist/src/config/vtex-profile-store.js.map +7 -0
  32. package/dist/src/config/vtex.js +27 -21
  33. package/dist/src/config/vtex.js.map +2 -2
  34. package/dist/src/db/client.js +58 -0
  35. package/dist/src/db/client.js.map +7 -0
  36. package/dist/src/meta/meta-utils.js +148 -0
  37. package/dist/src/meta/meta-utils.js.map +7 -0
  38. package/dist/src/services/meta/meta-ads.js +89 -0
  39. package/dist/src/services/meta/meta-ads.js.map +7 -0
  40. package/dist/src/services/meta/meta-api.js +35 -0
  41. package/dist/src/services/meta/meta-api.js.map +7 -0
  42. package/dist/src/services/vtex/vtex-api.js +24 -8
  43. package/dist/src/services/vtex/vtex-api.js.map +2 -2
  44. package/dist/src/services/vtex/vtex-catalog.js +5 -3
  45. package/dist/src/services/vtex/vtex-catalog.js.map +2 -2
  46. package/dist/src/services/vtex/vtex-logistics.js +18 -9
  47. package/dist/src/services/vtex/vtex-logistics.js.map +2 -2
  48. package/dist/src/services/vtex/vtex-orders.js +13 -7
  49. package/dist/src/services/vtex/vtex-orders.js.map +2 -2
  50. package/dist/src/services/vtex/vtex-pricing.js +5 -3
  51. package/dist/src/services/vtex/vtex-pricing.js.map +2 -2
  52. package/dist/src/tools/config/check-database-connection.js +59 -0
  53. package/dist/src/tools/config/check-database-connection.js.map +7 -0
  54. package/dist/src/tools/config/index.js +3 -0
  55. package/dist/src/tools/config/index.js.map +7 -0
  56. package/dist/src/tools/config/list-profiles.js +26 -0
  57. package/dist/src/tools/config/list-profiles.js.map +7 -0
  58. package/dist/src/tools/index.js +2 -0
  59. package/dist/src/tools/index.js.map +2 -2
  60. package/dist/src/tools/meta/account-overview.js +92 -0
  61. package/dist/src/tools/meta/account-overview.js.map +7 -0
  62. package/dist/src/tools/meta/ad-account-info.js +37 -0
  63. package/dist/src/tools/meta/ad-account-info.js.map +7 -0
  64. package/dist/src/tools/meta/ads-performance.js +79 -0
  65. package/dist/src/tools/meta/ads-performance.js.map +7 -0
  66. package/dist/src/tools/meta/campaign-performance.js +81 -0
  67. package/dist/src/tools/meta/campaign-performance.js.map +7 -0
  68. package/dist/src/tools/meta/index.js +9 -0
  69. package/dist/src/tools/meta/index.js.map +7 -0
  70. package/dist/src/tools/meta/list-accessible-ad-accounts.js +44 -0
  71. package/dist/src/tools/meta/list-accessible-ad-accounts.js.map +7 -0
  72. package/dist/src/tools/meta/list-accessible-businesses.js +36 -0
  73. package/dist/src/tools/meta/list-accessible-businesses.js.map +7 -0
  74. package/dist/src/tools/meta/placement-mix.js +67 -0
  75. package/dist/src/tools/meta/placement-mix.js.map +7 -0
  76. package/dist/src/tools/meta/time-series.js +69 -0
  77. package/dist/src/tools/meta/time-series.js.map +7 -0
  78. package/dist/src/tools/vtex/computed-price.js +12 -1
  79. package/dist/src/tools/vtex/computed-price.js.map +2 -2
  80. package/dist/src/tools/vtex/index.js +1 -0
  81. package/dist/src/tools/vtex/index.js.map +2 -2
  82. package/dist/src/tools/vtex/inventory-check.js +15 -2
  83. package/dist/src/tools/vtex/inventory-check.js.map +2 -2
  84. package/dist/src/tools/vtex/order-details.js +16 -2
  85. package/dist/src/tools/vtex/order-details.js.map +2 -2
  86. package/dist/src/tools/vtex/orders-summary.js +11 -1
  87. package/dist/src/tools/vtex/orders-summary.js.map +2 -2
  88. package/dist/src/tools/vtex/product-offers.js +15 -2
  89. package/dist/src/tools/vtex/product-offers.js.map +2 -2
  90. package/dist/src/tools/vtex/profile-resolution.js +57 -0
  91. package/dist/src/tools/vtex/profile-resolution.js.map +7 -0
  92. package/dist/src/tools/vtex/sku-offers.js +16 -2
  93. package/dist/src/tools/vtex/sku-offers.js.map +2 -2
  94. package/dist/src/tools/vtex/sku-price.js +12 -2
  95. package/dist/src/tools/vtex/sku-price.js.map +2 -2
  96. package/dist/src/tools/vtex/update-inventory.js +12 -1
  97. package/dist/src/tools/vtex/update-inventory.js.map +2 -2
  98. package/dist/src/tools/vtex/update-lead-time.js +12 -1
  99. package/dist/src/tools/vtex/update-lead-time.js.map +2 -2
  100. package/dist/src/tools/vtex/warehouse-inventory.js +12 -1
  101. package/dist/src/tools/vtex/warehouse-inventory.js.map +2 -2
  102. 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 { vtexApi } 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(skuId: string): 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 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 getInventoryBySku(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 skuIds: string[],\n options: GetInventoryBatchOptions = {}\n): Promise<InventoryBatchResult> {\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(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 skuId: string,\n warehouseId: string\n): Promise<InventoryByWarehouseItem[]> {\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 skuId: string,\n warehouseId: string,\n payload: UpdateInventoryQuantityPayload\n): Promise<void> {\n await vtexApi.patch(`/api/logistics/pvt/inventory/skus/${skuId}/warehouses/${warehouseId}/quantity`, payload);\n}\n\nexport async function updateInventoryLeadTime(\n skuId: string,\n warehouseId: string,\n payload: UpdateLeadTimePayload\n): Promise<void> {\n await vtexApi.patch(`/api/logistics/pvt/inventory/skus/${skuId}/warehouses/${warehouseId}/lead-time`, payload);\n}\n"],
5
- "mappings": "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",
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 { vtexApi } from "./vtex-api.js";
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 document = await getOrderDocument(orderId, options.reason);
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 { vtexApi } 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(params: ListOrdersParams): Promise<VtexOrdersListResponse> {\n const response = await vtexApi.get<VtexOrdersListResponse>(\"/api/oms/pvt/orders\", { params });\n return response.data;\n}\n\nexport async function getOrderDocument(\n orderId: string,\n reason?: string\n): Promise<Record<string, unknown>> {\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 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 document = await getOrderDocument(orderId, options.reason);\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 orderIds: string[],\n options: GetOrderDocumentsBatchOptions = {}\n): Promise<OrderDocumentsBatchResult> {\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(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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",
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 { vtexPricingApi } from "./vtex-api.js";
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 { vtexPricingApi } 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(itemId: string): Promise<SkuPriceResponse> {\n const response = await vtexPricingApi.get<SkuPriceResponse>(`/pricing/prices/${itemId}`);\n return response.data;\n}\n\nexport async function getComputedPrice(\n itemId: string,\n priceTableId: string,\n params: ComputedPriceParams\n): Promise<ComputedPriceResponse> {\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,sBAAsB;AAoC/B,eAAsB,YAAY,QAA2C;AAC3E,QAAM,WAAW,MAAM,eAAe,IAAsB,mBAAmB,MAAM,EAAE;AACvF,SAAO,SAAS;AAClB;AAEA,eAAsB,iBACpB,QACA,cACA,QACgC;AAChC,QAAM,WAAW,MAAM,eAAe;AAAA,IACpC,mBAAmB,MAAM,aAAa,YAAY;AAAA,IAClD,EAAE,OAAO;AAAA,EACX;AAEA,SAAO,SAAS;AAClB;",
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,3 @@
1
+ export * from "./check-database-connection.js";
2
+ export * from "./list-profiles.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/config/index.ts"],
4
+ "sourcesContent": ["export * from \"./check-database-connection.js\";\nexport * from \"./list-profiles.js\";\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;",
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
+ }
@@ -1,5 +1,7 @@
1
+ export * from "./config/index.js";
1
2
  export * from "./vtex/index.js";
2
3
  export * from "./analytics/index.js";
3
4
  export * from "./google-ads/index.js";
5
+ export * from "./meta/index.js";
4
6
  export * from "./search-console/index.js";
5
7
  //# sourceMappingURL=index.js.map
@@ -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
+ }