@ultracart/bq-skill 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/README.md +952 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +42 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/alarm.d.ts +3 -0
- package/dist/commands/alarm.d.ts.map +1 -0
- package/dist/commands/alarm.js +146 -0
- package/dist/commands/alarm.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +749 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/deck.d.ts +3 -0
- package/dist/commands/deck.d.ts.map +1 -0
- package/dist/commands/deck.js +567 -0
- package/dist/commands/deck.js.map +1 -0
- package/dist/commands/dry-run.d.ts +3 -0
- package/dist/commands/dry-run.d.ts.map +1 -0
- package/dist/commands/dry-run.js +105 -0
- package/dist/commands/dry-run.js.map +1 -0
- package/dist/commands/history.d.ts +3 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +127 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +302 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install-skill.d.ts +3 -0
- package/dist/commands/install-skill.d.ts.map +1 -0
- package/dist/commands/install-skill.js +132 -0
- package/dist/commands/install-skill.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +89 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/query.d.ts +3 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +152 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/render.d.ts +3 -0
- package/dist/commands/render.d.ts.map +1 -0
- package/dist/commands/render.js +107 -0
- package/dist/commands/render.js.map +1 -0
- package/dist/commands/run-all.d.ts +3 -0
- package/dist/commands/run-all.d.ts.map +1 -0
- package/dist/commands/run-all.js +285 -0
- package/dist/commands/run-all.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +321 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/schema.d.ts +3 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +271 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +109 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/lib/alarm-notify.d.ts +16 -0
- package/dist/lib/alarm-notify.d.ts.map +1 -0
- package/dist/lib/alarm-notify.js +312 -0
- package/dist/lib/alarm-notify.js.map +1 -0
- package/dist/lib/alarm-state.d.ts +26 -0
- package/dist/lib/alarm-state.d.ts.map +1 -0
- package/dist/lib/alarm-state.js +118 -0
- package/dist/lib/alarm-state.js.map +1 -0
- package/dist/lib/alarm.d.ts +28 -0
- package/dist/lib/alarm.d.ts.map +1 -0
- package/dist/lib/alarm.js +215 -0
- package/dist/lib/alarm.js.map +1 -0
- package/dist/lib/analysis.d.ts +16 -0
- package/dist/lib/analysis.d.ts.map +1 -0
- package/dist/lib/analysis.js +134 -0
- package/dist/lib/analysis.js.map +1 -0
- package/dist/lib/bigquery.d.ts +55 -0
- package/dist/lib/bigquery.d.ts.map +1 -0
- package/dist/lib/bigquery.js +321 -0
- package/dist/lib/bigquery.js.map +1 -0
- package/dist/lib/config-writer.d.ts +3 -0
- package/dist/lib/config-writer.d.ts.map +1 -0
- package/dist/lib/config-writer.js +60 -0
- package/dist/lib/config-writer.js.map +1 -0
- package/dist/lib/config.d.ts +63 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +151 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/dashboard.d.ts +3 -0
- package/dist/lib/dashboard.d.ts.map +1 -0
- package/dist/lib/dashboard.js +468 -0
- package/dist/lib/dashboard.js.map +1 -0
- package/dist/lib/deck.d.ts +58 -0
- package/dist/lib/deck.d.ts.map +1 -0
- package/dist/lib/deck.js +232 -0
- package/dist/lib/deck.js.map +1 -0
- package/dist/lib/deliver-email.d.ts +14 -0
- package/dist/lib/deliver-email.d.ts.map +1 -0
- package/dist/lib/deliver-email.js +360 -0
- package/dist/lib/deliver-email.js.map +1 -0
- package/dist/lib/deliver-slack.d.ts +6 -0
- package/dist/lib/deliver-slack.d.ts.map +1 -0
- package/dist/lib/deliver-slack.js +73 -0
- package/dist/lib/deliver-slack.js.map +1 -0
- package/dist/lib/deliver.d.ts +10 -0
- package/dist/lib/deliver.d.ts.map +1 -0
- package/dist/lib/deliver.js +95 -0
- package/dist/lib/deliver.js.map +1 -0
- package/dist/lib/llm/anthropic.d.ts +7 -0
- package/dist/lib/llm/anthropic.d.ts.map +1 -0
- package/dist/lib/llm/anthropic.js +69 -0
- package/dist/lib/llm/anthropic.js.map +1 -0
- package/dist/lib/llm/bedrock.d.ts +7 -0
- package/dist/lib/llm/bedrock.d.ts.map +1 -0
- package/dist/lib/llm/bedrock.js +67 -0
- package/dist/lib/llm/bedrock.js.map +1 -0
- package/dist/lib/llm/gemini.d.ts +7 -0
- package/dist/lib/llm/gemini.d.ts.map +1 -0
- package/dist/lib/llm/gemini.js +67 -0
- package/dist/lib/llm/gemini.js.map +1 -0
- package/dist/lib/llm/index.d.ts +5 -0
- package/dist/lib/llm/index.d.ts.map +1 -0
- package/dist/lib/llm/index.js +61 -0
- package/dist/lib/llm/index.js.map +1 -0
- package/dist/lib/llm/models.d.ts +5 -0
- package/dist/lib/llm/models.d.ts.map +1 -0
- package/dist/lib/llm/models.js +33 -0
- package/dist/lib/llm/models.js.map +1 -0
- package/dist/lib/llm/openai.d.ts +8 -0
- package/dist/lib/llm/openai.d.ts.map +1 -0
- package/dist/lib/llm/openai.js +48 -0
- package/dist/lib/llm/openai.js.map +1 -0
- package/dist/lib/llm/provider.d.ts +28 -0
- package/dist/lib/llm/provider.d.ts.map +1 -0
- package/dist/lib/llm/provider.js +3 -0
- package/dist/lib/llm/provider.js.map +1 -0
- package/dist/lib/manifest.d.ts +95 -0
- package/dist/lib/manifest.d.ts.map +1 -0
- package/dist/lib/manifest.js +105 -0
- package/dist/lib/manifest.js.map +1 -0
- package/dist/lib/params.d.ts +27 -0
- package/dist/lib/params.d.ts.map +1 -0
- package/dist/lib/params.js +192 -0
- package/dist/lib/params.js.map +1 -0
- package/dist/lib/pdf.d.ts +8 -0
- package/dist/lib/pdf.d.ts.map +1 -0
- package/dist/lib/pdf.js +86 -0
- package/dist/lib/pdf.js.map +1 -0
- package/dist/lib/renderer.d.ts +17 -0
- package/dist/lib/renderer.d.ts.map +1 -0
- package/dist/lib/renderer.js +166 -0
- package/dist/lib/renderer.js.map +1 -0
- package/dist/lib/schema-filter.d.ts +3 -0
- package/dist/lib/schema-filter.d.ts.map +1 -0
- package/dist/lib/schema-filter.js +49 -0
- package/dist/lib/schema-filter.js.map +1 -0
- package/dist/lib/template.d.ts +4 -0
- package/dist/lib/template.d.ts.map +1 -0
- package/dist/lib/template.js +37 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/lib/validator.d.ts +8 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +88 -0
- package/dist/lib/validator.js.map +1 -0
- package/package.json +59 -0
- package/schemas/deck.schema.json +122 -0
- package/schemas/report-manifest.schema.json +309 -0
- package/schemas/tables/README.md +45 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_clicks.json +186 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_commission_groups.json +317 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_ledgers.json +404 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_network_pixel_postback_logs.json +166 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_network_pixels.json +106 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_payments.json +204 -0
- package/schemas/tables/ultracart_dw/uc_affiliate_postback_logs.json +90 -0
- package/schemas/tables/ultracart_dw/uc_affiliates.json +425 -0
- package/schemas/tables/ultracart_dw/uc_auto_orders.json +13848 -0
- package/schemas/tables/ultracart_dw/uc_cart_abandons.json +3971 -0
- package/schemas/tables/ultracart_dw/uc_conversation_pbx_calls.json +374 -0
- package/schemas/tables/ultracart_dw/uc_conversations.json +374 -0
- package/schemas/tables/ultracart_dw/uc_coupons.json +1893 -0
- package/schemas/tables/ultracart_dw/uc_customers.json +11886 -0
- package/schemas/tables/ultracart_dw/uc_fraud_rules.json +239 -0
- package/schemas/tables/ultracart_dw/uc_gift_certificates.json +135 -0
- package/schemas/tables/ultracart_dw/uc_item_inventory_history.json +79 -0
- package/schemas/tables/ultracart_dw/uc_items.json +4437 -0
- package/schemas/tables/ultracart_dw/uc_orders.json +6629 -0
- package/schemas/tables/ultracart_dw/uc_rotating_transaction_gateway_history.json +271 -0
- package/schemas/tables/ultracart_dw/uc_rotating_transaction_gateways.json +416 -0
- package/schemas/tables/ultracart_dw/uc_shipping_methods.json +1372 -0
- package/schemas/tables/ultracart_dw/uc_storefront_customers.json +261 -0
- package/schemas/tables/ultracart_dw/uc_storefront_experiments.json +386 -0
- package/schemas/tables/ultracart_dw/uc_storefront_pages.json +513 -0
- package/schemas/tables/ultracart_dw/uc_storefront_upsell_offer_events.json +338 -0
- package/schemas/tables/ultracart_dw/uc_storefront_upsell_offers.json +431 -0
- package/schemas/tables/ultracart_dw/uc_storefront_upsell_paths.json +163 -0
- package/schemas/tables/ultracart_dw/uc_storefronts.json +62 -0
- package/schemas/tables/ultracart_dw/uc_surveys.json +238 -0
- package/schemas/tables/ultracart_dw/uc_workflow_tasks.json +377 -0
- package/schemas/tables/ultracart_dw/uc_zoho_desk_tickets.json +1184 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_clicks.json +186 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_commission_groups.json +317 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_ledgers.json +404 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_network_pixel_postback_logs.json +166 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_network_pixels.json +106 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_payments.json +204 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliate_postback_logs.json +90 -0
- package/schemas/tables/ultracart_dw_high/uc_affiliates.json +425 -0
- package/schemas/tables/ultracart_dw_high/uc_auto_orders.json +14332 -0
- package/schemas/tables/ultracart_dw_high/uc_cart_abandons.json +4245 -0
- package/schemas/tables/ultracart_dw_high/uc_conversation_pbx_calls.json +415 -0
- package/schemas/tables/ultracart_dw_high/uc_conversations.json +415 -0
- package/schemas/tables/ultracart_dw_high/uc_coupons.json +1893 -0
- package/schemas/tables/ultracart_dw_high/uc_customers.json +12250 -0
- package/schemas/tables/ultracart_dw_high/uc_fraud_rules.json +239 -0
- package/schemas/tables/ultracart_dw_high/uc_gift_certificates.json +135 -0
- package/schemas/tables/ultracart_dw_high/uc_item_inventory_history.json +79 -0
- package/schemas/tables/ultracart_dw_high/uc_items.json +4437 -0
- package/schemas/tables/ultracart_dw_high/uc_orders.json +6871 -0
- package/schemas/tables/ultracart_dw_high/uc_rotating_transaction_gateway_history.json +271 -0
- package/schemas/tables/ultracart_dw_high/uc_rotating_transaction_gateways.json +416 -0
- package/schemas/tables/ultracart_dw_high/uc_shipping_methods.json +1372 -0
- package/schemas/tables/ultracart_dw_high/uc_storefront_customers.json +261 -0
- package/schemas/tables/ultracart_dw_high/uc_storefront_experiments.json +386 -0
- package/schemas/tables/ultracart_dw_high/uc_storefront_pages.json +513 -0
- package/schemas/tables/ultracart_dw_high/uc_storefront_upsell_offer_events.json +338 -0
- package/schemas/tables/ultracart_dw_high/uc_storefront_upsell_offers.json +431 -0
- package/schemas/tables/ultracart_dw_high/uc_storefront_upsell_paths.json +163 -0
- package/schemas/tables/ultracart_dw_high/uc_storefronts.json +62 -0
- package/schemas/tables/ultracart_dw_high/uc_surveys.json +269 -0
- package/schemas/tables/ultracart_dw_high/uc_workflow_tasks.json +377 -0
- package/schemas/tables/ultracart_dw_high/uc_zoho_desk_tickets.json +1330 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_clicks.json +186 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_commission_groups.json +317 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_ledgers.json +404 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_network_pixel_postback_logs.json +166 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_network_pixels.json +106 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_payments.json +204 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliate_postback_logs.json +90 -0
- package/schemas/tables/ultracart_dw_low/uc_affiliates.json +425 -0
- package/schemas/tables/ultracart_dw_low/uc_auto_orders.json +13868 -0
- package/schemas/tables/ultracart_dw_low/uc_cart_abandons.json +3971 -0
- package/schemas/tables/ultracart_dw_low/uc_conversation_pbx_calls.json +374 -0
- package/schemas/tables/ultracart_dw_low/uc_conversations.json +374 -0
- package/schemas/tables/ultracart_dw_low/uc_coupons.json +1893 -0
- package/schemas/tables/ultracart_dw_low/uc_customers.json +11900 -0
- package/schemas/tables/ultracart_dw_low/uc_fraud_rules.json +239 -0
- package/schemas/tables/ultracart_dw_low/uc_gift_certificates.json +135 -0
- package/schemas/tables/ultracart_dw_low/uc_item_inventory_history.json +79 -0
- package/schemas/tables/ultracart_dw_low/uc_items.json +4437 -0
- package/schemas/tables/ultracart_dw_low/uc_orders.json +6639 -0
- package/schemas/tables/ultracart_dw_low/uc_rotating_transaction_gateway_history.json +271 -0
- package/schemas/tables/ultracart_dw_low/uc_rotating_transaction_gateways.json +416 -0
- package/schemas/tables/ultracart_dw_low/uc_shipping_methods.json +1372 -0
- package/schemas/tables/ultracart_dw_low/uc_storefront_customers.json +261 -0
- package/schemas/tables/ultracart_dw_low/uc_storefront_experiments.json +386 -0
- package/schemas/tables/ultracart_dw_low/uc_storefront_pages.json +513 -0
- package/schemas/tables/ultracart_dw_low/uc_storefront_upsell_offer_events.json +338 -0
- package/schemas/tables/ultracart_dw_low/uc_storefront_upsell_offers.json +431 -0
- package/schemas/tables/ultracart_dw_low/uc_storefront_upsell_paths.json +163 -0
- package/schemas/tables/ultracart_dw_low/uc_storefronts.json +62 -0
- package/schemas/tables/ultracart_dw_low/uc_surveys.json +238 -0
- package/schemas/tables/ultracart_dw_low/uc_workflow_tasks.json +377 -0
- package/schemas/tables/ultracart_dw_low/uc_zoho_desk_tickets.json +1184 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_clicks.json +186 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_commission_groups.json +317 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_ledgers.json +404 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_network_pixel_postback_logs.json +166 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_network_pixels.json +106 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_payments.json +204 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliate_postback_logs.json +90 -0
- package/schemas/tables/ultracart_dw_medium/uc_affiliates.json +425 -0
- package/schemas/tables/ultracart_dw_medium/uc_auto_orders.json +14320 -0
- package/schemas/tables/ultracart_dw_medium/uc_cart_abandons.json +4245 -0
- package/schemas/tables/ultracart_dw_medium/uc_conversation_pbx_calls.json +415 -0
- package/schemas/tables/ultracart_dw_medium/uc_conversations.json +415 -0
- package/schemas/tables/ultracart_dw_medium/uc_coupons.json +1893 -0
- package/schemas/tables/ultracart_dw_medium/uc_customers.json +12250 -0
- package/schemas/tables/ultracart_dw_medium/uc_fraud_rules.json +239 -0
- package/schemas/tables/ultracart_dw_medium/uc_gift_certificates.json +135 -0
- package/schemas/tables/ultracart_dw_medium/uc_item_inventory_history.json +79 -0
- package/schemas/tables/ultracart_dw_medium/uc_items.json +4437 -0
- package/schemas/tables/ultracart_dw_medium/uc_orders.json +6865 -0
- package/schemas/tables/ultracart_dw_medium/uc_rotating_transaction_gateway_history.json +271 -0
- package/schemas/tables/ultracart_dw_medium/uc_rotating_transaction_gateways.json +416 -0
- package/schemas/tables/ultracart_dw_medium/uc_shipping_methods.json +1372 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefront_customers.json +261 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefront_experiments.json +386 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefront_pages.json +513 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefront_upsell_offer_events.json +338 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefront_upsell_offers.json +431 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefront_upsell_paths.json +163 -0
- package/schemas/tables/ultracart_dw_medium/uc_storefronts.json +62 -0
- package/schemas/tables/ultracart_dw_medium/uc_surveys.json +269 -0
- package/schemas/tables/ultracart_dw_medium/uc_workflow_tasks.json +377 -0
- package/schemas/tables/ultracart_dw_medium/uc_zoho_desk_tickets.json +1330 -0
- package/schemas/tables/ultracart_dw_streaming/uc_analytics_session_streaming.json +2444 -0
- package/schemas/tables/ultracart_dw_streaming/uc_screen_recording_streaming.json +509 -0
- package/schemas/ultracart-bq-config.schema.json +140 -0
- package/skill/skill.md +1228 -0
- package/templates/render.html +73 -0
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.configCommand = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const commander_1 = require("commander");
|
|
40
|
+
const bigquery_1 = require("@google-cloud/bigquery");
|
|
41
|
+
const config_writer_1 = require("../lib/config-writer");
|
|
42
|
+
const config_1 = require("../lib/config");
|
|
43
|
+
const manifest_1 = require("../lib/manifest");
|
|
44
|
+
const deck_1 = require("../lib/deck");
|
|
45
|
+
function getMerchantId(cmd) {
|
|
46
|
+
const globalOpts = cmd.optsWithGlobals ? cmd.optsWithGlobals() : (cmd.parent?.parent?.opts() || {});
|
|
47
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
48
|
+
return globalOpts.merchant || raw.default_merchant;
|
|
49
|
+
}
|
|
50
|
+
function ensureMerchant(raw, merchantId) {
|
|
51
|
+
if (!raw.merchants?.[merchantId]) {
|
|
52
|
+
throw new Error(`Merchant "${merchantId}" not found in config. Available: ${Object.keys(raw.merchants || {}).join(', ')}`);
|
|
53
|
+
}
|
|
54
|
+
return raw.merchants[merchantId];
|
|
55
|
+
}
|
|
56
|
+
function ensureExternalProject(merchant, alias) {
|
|
57
|
+
if (!merchant.external_projects?.[alias]) {
|
|
58
|
+
throw new Error(`External project "${alias}" not found. Available: ${Object.keys(merchant.external_projects || {}).join(', ') || 'none'}`);
|
|
59
|
+
}
|
|
60
|
+
return merchant.external_projects[alias];
|
|
61
|
+
}
|
|
62
|
+
exports.configCommand = new commander_1.Command('config')
|
|
63
|
+
.description('Manage configuration — add/remove merchants, external projects, datasets, tables');
|
|
64
|
+
// show
|
|
65
|
+
exports.configCommand
|
|
66
|
+
.command('show')
|
|
67
|
+
.description('Display current configuration')
|
|
68
|
+
.action(() => {
|
|
69
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
70
|
+
console.log(JSON.stringify(raw, null, 2));
|
|
71
|
+
});
|
|
72
|
+
// add-merchant
|
|
73
|
+
exports.configCommand
|
|
74
|
+
.command('add-merchant <id>')
|
|
75
|
+
.description('Add a merchant to the config')
|
|
76
|
+
.requiredOption('--taxonomy <level>', 'Taxonomy level: standard, low, medium, high')
|
|
77
|
+
.option('--dataset <dataset>', 'BigQuery dataset name', 'ultracart_dw')
|
|
78
|
+
.action((id, options) => {
|
|
79
|
+
const validLevels = ['standard', 'low', 'medium', 'high'];
|
|
80
|
+
if (!validLevels.includes(options.taxonomy)) {
|
|
81
|
+
console.error(`Error: taxonomy must be one of: ${validLevels.join(', ')}`);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
85
|
+
if (raw.merchants?.[id]) {
|
|
86
|
+
console.error(`Error: Merchant "${id}" already exists.`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
if (!raw.merchants)
|
|
90
|
+
raw.merchants = {};
|
|
91
|
+
raw.merchants[id] = { taxonomy_level: options.taxonomy, dataset: options.dataset };
|
|
92
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
93
|
+
console.log(` Added merchant "${id}" (taxonomy: ${options.taxonomy}, dataset: ${options.dataset})`);
|
|
94
|
+
});
|
|
95
|
+
// remove-merchant
|
|
96
|
+
exports.configCommand
|
|
97
|
+
.command('remove-merchant <id>')
|
|
98
|
+
.description('Remove a merchant from the config')
|
|
99
|
+
.action((id) => {
|
|
100
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
101
|
+
ensureMerchant(raw, id);
|
|
102
|
+
if (raw.default_merchant === id) {
|
|
103
|
+
console.error(`Error: Cannot remove the default merchant "${id}". Change default_merchant first.`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
delete raw.merchants[id];
|
|
107
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
108
|
+
console.log(` Removed merchant "${id}"`);
|
|
109
|
+
});
|
|
110
|
+
// add-project
|
|
111
|
+
exports.configCommand
|
|
112
|
+
.command('add-project <alias>')
|
|
113
|
+
.description('Register an external BigQuery project')
|
|
114
|
+
.requiredOption('--project-id <id>', 'GCP project ID')
|
|
115
|
+
.option('--description <desc>', 'Description of the project')
|
|
116
|
+
.action((alias, options, cmd) => {
|
|
117
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
118
|
+
const merchantId = getMerchantId(cmd);
|
|
119
|
+
const merchant = ensureMerchant(raw, merchantId);
|
|
120
|
+
if (merchant.external_projects?.[alias]) {
|
|
121
|
+
console.error(`Error: External project "${alias}" already exists for merchant "${merchantId}".`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
if (!merchant.external_projects)
|
|
125
|
+
merchant.external_projects = {};
|
|
126
|
+
merchant.external_projects[alias] = {
|
|
127
|
+
project_id: options.projectId,
|
|
128
|
+
...(options.description ? { description: options.description } : {}),
|
|
129
|
+
datasets: {},
|
|
130
|
+
};
|
|
131
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
132
|
+
console.log(` Added external project "${alias}" (${options.projectId}) to merchant "${merchantId}"`);
|
|
133
|
+
});
|
|
134
|
+
// remove-project
|
|
135
|
+
exports.configCommand
|
|
136
|
+
.command('remove-project <alias>')
|
|
137
|
+
.description('Remove an external BigQuery project')
|
|
138
|
+
.action((alias, _options, cmd) => {
|
|
139
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
140
|
+
const merchantId = getMerchantId(cmd);
|
|
141
|
+
const merchant = ensureMerchant(raw, merchantId);
|
|
142
|
+
ensureExternalProject(merchant, alias);
|
|
143
|
+
delete merchant.external_projects[alias];
|
|
144
|
+
if (Object.keys(merchant.external_projects).length === 0) {
|
|
145
|
+
delete merchant.external_projects;
|
|
146
|
+
}
|
|
147
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
148
|
+
console.log(` Removed external project "${alias}" from merchant "${merchantId}"`);
|
|
149
|
+
});
|
|
150
|
+
// add-dataset
|
|
151
|
+
exports.configCommand
|
|
152
|
+
.command('add-dataset <alias> <dataset>')
|
|
153
|
+
.description('Add a dataset to an external project')
|
|
154
|
+
.option('--discover', 'Auto-discover and add all tables from the dataset')
|
|
155
|
+
.action(async (alias, dataset, options, cmd) => {
|
|
156
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
157
|
+
const merchantId = getMerchantId(cmd);
|
|
158
|
+
const merchant = ensureMerchant(raw, merchantId);
|
|
159
|
+
const project = ensureExternalProject(merchant, alias);
|
|
160
|
+
if (project.datasets[dataset]) {
|
|
161
|
+
console.error(`Error: Dataset "${dataset}" already exists in project "${alias}".`);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
let tables = [];
|
|
165
|
+
if (options.discover) {
|
|
166
|
+
console.log(` Discovering tables in ${project.project_id}.${dataset}...`);
|
|
167
|
+
const bq = new bigquery_1.BigQuery({ projectId: project.project_id });
|
|
168
|
+
const [bqTables] = await bq.dataset(dataset).getTables();
|
|
169
|
+
tables = bqTables.map(t => t.id).filter(Boolean);
|
|
170
|
+
console.log(` Found ${tables.length} tables`);
|
|
171
|
+
}
|
|
172
|
+
project.datasets[dataset] = tables;
|
|
173
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
174
|
+
console.log(` Added dataset "${dataset}" to project "${alias}" (${tables.length} tables)`);
|
|
175
|
+
});
|
|
176
|
+
// remove-dataset
|
|
177
|
+
exports.configCommand
|
|
178
|
+
.command('remove-dataset <alias> <dataset>')
|
|
179
|
+
.description('Remove a dataset from an external project')
|
|
180
|
+
.action((alias, dataset, _options, cmd) => {
|
|
181
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
182
|
+
const merchantId = getMerchantId(cmd);
|
|
183
|
+
const merchant = ensureMerchant(raw, merchantId);
|
|
184
|
+
const project = ensureExternalProject(merchant, alias);
|
|
185
|
+
if (!project.datasets[dataset]) {
|
|
186
|
+
console.error(`Error: Dataset "${dataset}" not found in project "${alias}".`);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
delete project.datasets[dataset];
|
|
190
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
191
|
+
console.log(` Removed dataset "${dataset}" from project "${alias}"`);
|
|
192
|
+
});
|
|
193
|
+
// add-tables
|
|
194
|
+
exports.configCommand
|
|
195
|
+
.command('add-tables <alias> <dataset> <tables...>')
|
|
196
|
+
.description('Add tables to a dataset in an external project')
|
|
197
|
+
.action((alias, dataset, tables, cmd) => {
|
|
198
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
199
|
+
const merchantId = getMerchantId(cmd);
|
|
200
|
+
const merchant = ensureMerchant(raw, merchantId);
|
|
201
|
+
const project = ensureExternalProject(merchant, alias);
|
|
202
|
+
if (!project.datasets[dataset]) {
|
|
203
|
+
project.datasets[dataset] = [];
|
|
204
|
+
}
|
|
205
|
+
const existing = new Set(project.datasets[dataset]);
|
|
206
|
+
let added = 0;
|
|
207
|
+
for (const t of tables) {
|
|
208
|
+
if (!existing.has(t)) {
|
|
209
|
+
project.datasets[dataset].push(t);
|
|
210
|
+
existing.add(t);
|
|
211
|
+
added++;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
215
|
+
console.log(` Added ${added} table(s) to ${alias}.${dataset} (${project.datasets[dataset].length} total)`);
|
|
216
|
+
});
|
|
217
|
+
// remove-tables
|
|
218
|
+
exports.configCommand
|
|
219
|
+
.command('remove-tables <alias> <dataset> <tables...>')
|
|
220
|
+
.description('Remove tables from a dataset in an external project')
|
|
221
|
+
.action((alias, dataset, tables, cmd) => {
|
|
222
|
+
const raw = (0, config_writer_1.readRawConfig)();
|
|
223
|
+
const merchantId = getMerchantId(cmd);
|
|
224
|
+
const merchant = ensureMerchant(raw, merchantId);
|
|
225
|
+
const project = ensureExternalProject(merchant, alias);
|
|
226
|
+
if (!project.datasets[dataset]) {
|
|
227
|
+
console.error(`Error: Dataset "${dataset}" not found in project "${alias}".`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
const toRemove = new Set(tables);
|
|
231
|
+
const before = project.datasets[dataset].length;
|
|
232
|
+
project.datasets[dataset] = project.datasets[dataset].filter((t) => !toRemove.has(t));
|
|
233
|
+
(0, config_writer_1.writeConfig)(raw);
|
|
234
|
+
console.log(` Removed ${before - project.datasets[dataset].length} table(s) from ${alias}.${dataset} (${project.datasets[dataset].length} remaining)`);
|
|
235
|
+
});
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// Delivery config helpers & subcommands
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
function loadReportForDelivery(cmd, reportName) {
|
|
240
|
+
const config = (0, config_1.loadConfig)();
|
|
241
|
+
const globalOpts = cmd.optsWithGlobals ? cmd.optsWithGlobals() : (cmd.parent?.parent?.opts() || {});
|
|
242
|
+
const merchant = (0, config_1.resolveMerchant)(config, globalOpts.merchant);
|
|
243
|
+
const reportDir = path.join(path.resolve(merchant.default_output_dir), reportName);
|
|
244
|
+
if (!fs.existsSync(reportDir))
|
|
245
|
+
throw new Error(`Report "${reportName}" not found`);
|
|
246
|
+
const manifest = (0, manifest_1.loadManifest)(reportDir);
|
|
247
|
+
return { manifest, reportDir };
|
|
248
|
+
}
|
|
249
|
+
// add-slack
|
|
250
|
+
exports.configCommand
|
|
251
|
+
.command('add-slack <report> <channels...>')
|
|
252
|
+
.description('Add Slack channel(s) to a report\'s delivery config')
|
|
253
|
+
.action((report, channels, _options, cmd) => {
|
|
254
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
255
|
+
if (!manifest.delivery)
|
|
256
|
+
manifest.delivery = {};
|
|
257
|
+
if (!manifest.delivery.slack)
|
|
258
|
+
manifest.delivery.slack = { channels: [] };
|
|
259
|
+
const existing = new Set(manifest.delivery.slack.channels);
|
|
260
|
+
for (const ch of channels) {
|
|
261
|
+
existing.add(ch);
|
|
262
|
+
}
|
|
263
|
+
manifest.delivery.slack.channels = [...existing];
|
|
264
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
265
|
+
console.log(` Slack channels for "${report}": ${manifest.delivery.slack.channels.join(', ')}`);
|
|
266
|
+
});
|
|
267
|
+
// remove-slack
|
|
268
|
+
exports.configCommand
|
|
269
|
+
.command('remove-slack <report> <channels...>')
|
|
270
|
+
.description('Remove Slack channel(s) from a report\'s delivery config')
|
|
271
|
+
.action((report, channels, _options, cmd) => {
|
|
272
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
273
|
+
if (!manifest.delivery?.slack) {
|
|
274
|
+
console.log(' No Slack delivery configured.');
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const toRemove = new Set(channels);
|
|
278
|
+
manifest.delivery.slack.channels = manifest.delivery.slack.channels.filter(ch => !toRemove.has(ch));
|
|
279
|
+
if (manifest.delivery.slack.channels.length === 0) {
|
|
280
|
+
delete manifest.delivery.slack;
|
|
281
|
+
}
|
|
282
|
+
if (manifest.delivery && !manifest.delivery.slack && !manifest.delivery.email) {
|
|
283
|
+
delete manifest.delivery;
|
|
284
|
+
}
|
|
285
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
286
|
+
if (manifest.delivery?.slack) {
|
|
287
|
+
console.log(` Slack channels for "${report}": ${manifest.delivery.slack.channels.join(', ')}`);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
console.log(` Removed all Slack channels from "${report}".`);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
// set-email
|
|
294
|
+
exports.configCommand
|
|
295
|
+
.command('set-email <report>')
|
|
296
|
+
.description('Set email delivery config for a report')
|
|
297
|
+
.option('--to <emails>', 'Comma-separated recipient email addresses')
|
|
298
|
+
.option('--provider <provider>', 'Email provider: sendgrid, ses, postmark, mailgun, resend')
|
|
299
|
+
.option('--subject <subject>', 'Email subject line')
|
|
300
|
+
.action((report, options, cmd) => {
|
|
301
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
302
|
+
if (!manifest.delivery)
|
|
303
|
+
manifest.delivery = {};
|
|
304
|
+
const validProviders = ['sendgrid', 'ses', 'postmark', 'mailgun', 'resend'];
|
|
305
|
+
if (!manifest.delivery.email) {
|
|
306
|
+
// First use — all three are required
|
|
307
|
+
if (!options.to || !options.provider || !options.subject) {
|
|
308
|
+
console.error('Error: --to, --provider, and --subject are all required when creating email delivery config.');
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
if (!validProviders.includes(options.provider)) {
|
|
312
|
+
console.error(`Error: provider must be one of: ${validProviders.join(', ')}`);
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
manifest.delivery.email = {
|
|
316
|
+
to: options.to.split(',').map(e => e.trim()),
|
|
317
|
+
provider: options.provider,
|
|
318
|
+
subject: options.subject,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Subsequent use — update only what's specified
|
|
323
|
+
if (options.to) {
|
|
324
|
+
manifest.delivery.email.to = options.to.split(',').map(e => e.trim());
|
|
325
|
+
}
|
|
326
|
+
if (options.provider) {
|
|
327
|
+
if (!validProviders.includes(options.provider)) {
|
|
328
|
+
console.error(`Error: provider must be one of: ${validProviders.join(', ')}`);
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
manifest.delivery.email.provider = options.provider;
|
|
332
|
+
}
|
|
333
|
+
if (options.subject) {
|
|
334
|
+
manifest.delivery.email.subject = options.subject;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
338
|
+
console.log(` Email delivery for "${report}":`);
|
|
339
|
+
console.log(` To: ${manifest.delivery.email.to.join(', ')}`);
|
|
340
|
+
console.log(` Provider: ${manifest.delivery.email.provider}`);
|
|
341
|
+
console.log(` Subject: ${manifest.delivery.email.subject}`);
|
|
342
|
+
});
|
|
343
|
+
// add-email
|
|
344
|
+
exports.configCommand
|
|
345
|
+
.command('add-email <report> <emails...>')
|
|
346
|
+
.description('Add email recipient(s) to a report\'s delivery config')
|
|
347
|
+
.action((report, emails, _options, cmd) => {
|
|
348
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
349
|
+
if (!manifest.delivery?.email) {
|
|
350
|
+
console.error('Error: No email delivery configured. Use "set-email" first to set provider and subject.');
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
const existing = new Set(manifest.delivery.email.to);
|
|
354
|
+
for (const e of emails) {
|
|
355
|
+
existing.add(e);
|
|
356
|
+
}
|
|
357
|
+
manifest.delivery.email.to = [...existing];
|
|
358
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
359
|
+
console.log(` Email recipients for "${report}": ${manifest.delivery.email.to.join(', ')}`);
|
|
360
|
+
});
|
|
361
|
+
// remove-email
|
|
362
|
+
exports.configCommand
|
|
363
|
+
.command('remove-email <report> <emails...>')
|
|
364
|
+
.description('Remove email recipient(s) from a report\'s delivery config')
|
|
365
|
+
.action((report, emails, _options, cmd) => {
|
|
366
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
367
|
+
if (!manifest.delivery?.email) {
|
|
368
|
+
console.log(' No email delivery configured.');
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const toRemove = new Set(emails);
|
|
372
|
+
manifest.delivery.email.to = manifest.delivery.email.to.filter(e => !toRemove.has(e));
|
|
373
|
+
if (manifest.delivery.email.to.length === 0) {
|
|
374
|
+
delete manifest.delivery.email;
|
|
375
|
+
}
|
|
376
|
+
if (manifest.delivery && !manifest.delivery.slack && !manifest.delivery.email) {
|
|
377
|
+
delete manifest.delivery;
|
|
378
|
+
}
|
|
379
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
380
|
+
if (manifest.delivery?.email) {
|
|
381
|
+
console.log(` Email recipients for "${report}": ${manifest.delivery.email.to.join(', ')}`);
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
console.log(` Removed all email delivery from "${report}".`);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
// set-email-provider
|
|
388
|
+
exports.configCommand
|
|
389
|
+
.command('set-email-provider <report> <provider>')
|
|
390
|
+
.description('Update the email provider for a report')
|
|
391
|
+
.action((report, provider, _options, cmd) => {
|
|
392
|
+
const validProviders = ['sendgrid', 'ses', 'postmark', 'mailgun', 'resend'];
|
|
393
|
+
if (!validProviders.includes(provider)) {
|
|
394
|
+
console.error(`Error: provider must be one of: ${validProviders.join(', ')}`);
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
398
|
+
if (!manifest.delivery?.email) {
|
|
399
|
+
console.error('Error: No email delivery configured. Use "set-email" first.');
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
manifest.delivery.email.provider = provider;
|
|
403
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
404
|
+
console.log(` Email provider for "${report}" set to: ${provider}`);
|
|
405
|
+
});
|
|
406
|
+
// set-email-subject
|
|
407
|
+
exports.configCommand
|
|
408
|
+
.command('set-email-subject <report> <subject>')
|
|
409
|
+
.description('Update the email subject for a report')
|
|
410
|
+
.action((report, subject, _options, cmd) => {
|
|
411
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
412
|
+
if (!manifest.delivery?.email) {
|
|
413
|
+
console.error('Error: No email delivery configured. Use "set-email" first.');
|
|
414
|
+
process.exit(1);
|
|
415
|
+
}
|
|
416
|
+
manifest.delivery.email.subject = subject;
|
|
417
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
418
|
+
console.log(` Email subject for "${report}" set to: ${subject}`);
|
|
419
|
+
});
|
|
420
|
+
// show-delivery
|
|
421
|
+
exports.configCommand
|
|
422
|
+
.command('show-delivery <report>')
|
|
423
|
+
.description('Display the delivery configuration for a report')
|
|
424
|
+
.action((report, _options, cmd) => {
|
|
425
|
+
const { manifest } = loadReportForDelivery(cmd, report);
|
|
426
|
+
if (!manifest.delivery) {
|
|
427
|
+
console.log(` No delivery configured for "${report}".`);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
console.log(` Delivery config for "${report}":`);
|
|
431
|
+
if (manifest.delivery.slack) {
|
|
432
|
+
console.log(` Slack channels: ${manifest.delivery.slack.channels.join(', ')}`);
|
|
433
|
+
}
|
|
434
|
+
if (manifest.delivery.email) {
|
|
435
|
+
console.log(` Email to: ${manifest.delivery.email.to.join(', ')}`);
|
|
436
|
+
console.log(` Email provider: ${manifest.delivery.email.provider}`);
|
|
437
|
+
console.log(` Email subject: ${manifest.delivery.email.subject}`);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
// ---------------------------------------------------------------------------
|
|
441
|
+
// Alarm config subcommands
|
|
442
|
+
// ---------------------------------------------------------------------------
|
|
443
|
+
const VALID_ALARM_TYPES = ['threshold', 'pct_change', 'missing_data'];
|
|
444
|
+
const VALID_SEVERITIES = ['low', 'high', 'critical'];
|
|
445
|
+
const VALID_OPERATORS = ['<', '>', '<=', '>=', '==', '!='];
|
|
446
|
+
const VALID_AGGREGATES = ['sum', 'avg', 'min', 'max', 'first', 'last'];
|
|
447
|
+
const VALID_DELIVERY_MODES = ['always', 'alarm_only'];
|
|
448
|
+
// add-alarm
|
|
449
|
+
exports.configCommand
|
|
450
|
+
.command('add-alarm <report>')
|
|
451
|
+
.description('Add an alarm to a report')
|
|
452
|
+
.requiredOption('--name <name>', 'Alarm name')
|
|
453
|
+
.requiredOption('--type <type>', 'Alarm type: threshold, pct_change, missing_data')
|
|
454
|
+
.option('--metric <metric>', 'Column name in data.json to evaluate')
|
|
455
|
+
.option('--aggregate <agg>', 'Aggregation: sum, avg, min, max, first, last', 'sum')
|
|
456
|
+
.option('--operator <op>', 'Comparison operator: <, >, <=, >=, ==, !=')
|
|
457
|
+
.option('--value <value>', 'Threshold value or percent')
|
|
458
|
+
.option('--severity <severity>', 'Severity: low, high, critical', 'high')
|
|
459
|
+
.option('--cooldown <cooldown>', 'Cooldown duration (e.g. 24h, 7d, 1h)', '24h')
|
|
460
|
+
.action((report, options, cmd) => {
|
|
461
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
462
|
+
if (!VALID_ALARM_TYPES.includes(options.type)) {
|
|
463
|
+
console.error(`Error: type must be one of: ${VALID_ALARM_TYPES.join(', ')}`);
|
|
464
|
+
process.exit(1);
|
|
465
|
+
}
|
|
466
|
+
if (options.severity && !VALID_SEVERITIES.includes(options.severity)) {
|
|
467
|
+
console.error(`Error: severity must be one of: ${VALID_SEVERITIES.join(', ')}`);
|
|
468
|
+
process.exit(1);
|
|
469
|
+
}
|
|
470
|
+
if (options.operator && !VALID_OPERATORS.includes(options.operator)) {
|
|
471
|
+
console.error(`Error: operator must be one of: ${VALID_OPERATORS.join(', ')}`);
|
|
472
|
+
process.exit(1);
|
|
473
|
+
}
|
|
474
|
+
if (options.aggregate && !VALID_AGGREGATES.includes(options.aggregate)) {
|
|
475
|
+
console.error(`Error: aggregate must be one of: ${VALID_AGGREGATES.join(', ')}`);
|
|
476
|
+
process.exit(1);
|
|
477
|
+
}
|
|
478
|
+
// Validate required fields per type
|
|
479
|
+
if (options.type !== 'missing_data') {
|
|
480
|
+
if (!options.metric) {
|
|
481
|
+
console.error('Error: --metric is required for threshold and pct_change alarms.');
|
|
482
|
+
process.exit(1);
|
|
483
|
+
}
|
|
484
|
+
if (!options.operator) {
|
|
485
|
+
console.error('Error: --operator is required for threshold and pct_change alarms.');
|
|
486
|
+
process.exit(1);
|
|
487
|
+
}
|
|
488
|
+
if (options.value === undefined) {
|
|
489
|
+
console.error('Error: --value is required for threshold and pct_change alarms.');
|
|
490
|
+
process.exit(1);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if (!manifest.alarms)
|
|
494
|
+
manifest.alarms = [];
|
|
495
|
+
// Check for duplicate name
|
|
496
|
+
if (manifest.alarms.some(a => a.name === options.name)) {
|
|
497
|
+
console.error(`Error: Alarm "${options.name}" already exists on report "${report}".`);
|
|
498
|
+
process.exit(1);
|
|
499
|
+
}
|
|
500
|
+
const alarm = {
|
|
501
|
+
name: options.name,
|
|
502
|
+
type: options.type,
|
|
503
|
+
severity: options.severity || 'high',
|
|
504
|
+
cooldown: options.cooldown || '24h',
|
|
505
|
+
};
|
|
506
|
+
if (options.type !== 'missing_data') {
|
|
507
|
+
alarm.metric = options.metric;
|
|
508
|
+
alarm.aggregate = options.aggregate || 'sum';
|
|
509
|
+
alarm.operator = options.operator;
|
|
510
|
+
alarm.value = parseFloat(options.value);
|
|
511
|
+
if (options.type === 'pct_change') {
|
|
512
|
+
alarm.compare_to = 'previous_run';
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
manifest.alarms.push(alarm);
|
|
516
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
517
|
+
console.log(` Added alarm "${options.name}" to report "${report}"`);
|
|
518
|
+
console.log(` Type: ${options.type}`);
|
|
519
|
+
if (alarm.metric)
|
|
520
|
+
console.log(` Metric: ${alarm.metric} (${alarm.aggregate})`);
|
|
521
|
+
if (alarm.operator)
|
|
522
|
+
console.log(` Condition: ${alarm.operator} ${alarm.value}`);
|
|
523
|
+
console.log(` Severity: ${alarm.severity}`);
|
|
524
|
+
console.log(` Cooldown: ${alarm.cooldown}`);
|
|
525
|
+
});
|
|
526
|
+
// show-alarms
|
|
527
|
+
exports.configCommand
|
|
528
|
+
.command('show-alarms <report>')
|
|
529
|
+
.description('Display all alarms configured on a report')
|
|
530
|
+
.action((report, _options, cmd) => {
|
|
531
|
+
const { manifest } = loadReportForDelivery(cmd, report);
|
|
532
|
+
if (!manifest.alarms || manifest.alarms.length === 0) {
|
|
533
|
+
console.log(` No alarms configured for "${report}".`);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
console.log('');
|
|
537
|
+
console.log(` Alarms for "${report}":`);
|
|
538
|
+
console.log(' ' + '─'.repeat(60));
|
|
539
|
+
for (const alarm of manifest.alarms) {
|
|
540
|
+
console.log(` ${alarm.name}`);
|
|
541
|
+
console.log(` Type: ${alarm.type}`);
|
|
542
|
+
if (alarm.metric)
|
|
543
|
+
console.log(` Metric: ${alarm.metric} (${alarm.aggregate || 'sum'})`);
|
|
544
|
+
if (alarm.operator)
|
|
545
|
+
console.log(` Condition: ${alarm.operator} ${alarm.value}`);
|
|
546
|
+
console.log(` Severity: ${alarm.severity}`);
|
|
547
|
+
console.log(` Cooldown: ${alarm.cooldown || '24h'}`);
|
|
548
|
+
console.log('');
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
// remove-alarm
|
|
552
|
+
exports.configCommand
|
|
553
|
+
.command('remove-alarm <report> <alarm-name>')
|
|
554
|
+
.description('Remove an alarm from a report')
|
|
555
|
+
.action((report, alarmName, _options, cmd) => {
|
|
556
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
557
|
+
if (!manifest.alarms || manifest.alarms.length === 0) {
|
|
558
|
+
console.log(` No alarms configured for "${report}".`);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
const before = manifest.alarms.length;
|
|
562
|
+
manifest.alarms = manifest.alarms.filter(a => a.name !== alarmName);
|
|
563
|
+
if (manifest.alarms.length === before) {
|
|
564
|
+
console.error(`Error: Alarm "${alarmName}" not found on report "${report}".`);
|
|
565
|
+
console.error(` Available: ${manifest.alarms.map(a => a.name).join(', ')}`);
|
|
566
|
+
process.exit(1);
|
|
567
|
+
}
|
|
568
|
+
if (manifest.alarms.length === 0) {
|
|
569
|
+
delete manifest.alarms;
|
|
570
|
+
}
|
|
571
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
572
|
+
console.log(` Removed alarm "${alarmName}" from report "${report}".`);
|
|
573
|
+
});
|
|
574
|
+
// set-delivery-mode
|
|
575
|
+
exports.configCommand
|
|
576
|
+
.command('set-delivery-mode <report> <mode>')
|
|
577
|
+
.description('Set delivery mode for a report (always or alarm_only)')
|
|
578
|
+
.action((report, mode, _options, cmd) => {
|
|
579
|
+
if (!VALID_DELIVERY_MODES.includes(mode)) {
|
|
580
|
+
console.error(`Error: mode must be one of: ${VALID_DELIVERY_MODES.join(', ')}`);
|
|
581
|
+
process.exit(1);
|
|
582
|
+
}
|
|
583
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
584
|
+
if (!manifest.delivery)
|
|
585
|
+
manifest.delivery = {};
|
|
586
|
+
manifest.delivery.mode = mode;
|
|
587
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
588
|
+
console.log(` Delivery mode for "${report}" set to: ${mode}`);
|
|
589
|
+
});
|
|
590
|
+
// set-mention-on-alarm
|
|
591
|
+
exports.configCommand
|
|
592
|
+
.command('set-mention-on-alarm <report> <mention>')
|
|
593
|
+
.description('Set the Slack mention for critical alarms (e.g., @channel, @here)')
|
|
594
|
+
.action((report, mention, _options, cmd) => {
|
|
595
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
596
|
+
if (!manifest.delivery)
|
|
597
|
+
manifest.delivery = {};
|
|
598
|
+
if (!manifest.delivery.slack) {
|
|
599
|
+
console.error('Error: No Slack delivery configured. Use "add-slack" first.');
|
|
600
|
+
process.exit(1);
|
|
601
|
+
}
|
|
602
|
+
manifest.delivery.slack.mention_on_alarm = mention;
|
|
603
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
604
|
+
console.log(` Slack mention_on_alarm for "${report}" set to: ${mention}`);
|
|
605
|
+
});
|
|
606
|
+
// ---------------------------------------------------------------------------
|
|
607
|
+
// Deck delivery mode
|
|
608
|
+
// ---------------------------------------------------------------------------
|
|
609
|
+
// set-deck-delivery-mode
|
|
610
|
+
exports.configCommand
|
|
611
|
+
.command('set-deck-delivery-mode <deck> <mode>')
|
|
612
|
+
.description('Set delivery mode for a deck (always or alarm_only)')
|
|
613
|
+
.action((deckArg, mode, _options, cmd) => {
|
|
614
|
+
if (!VALID_DELIVERY_MODES.includes(mode)) {
|
|
615
|
+
console.error(`Error: mode must be one of: ${VALID_DELIVERY_MODES.join(', ')}`);
|
|
616
|
+
process.exit(1);
|
|
617
|
+
}
|
|
618
|
+
const { deck, decksDir, deckName } = loadDeckForConfig(cmd, deckArg);
|
|
619
|
+
if (!deck.delivery)
|
|
620
|
+
deck.delivery = {};
|
|
621
|
+
deck.delivery.mode = mode;
|
|
622
|
+
(0, deck_1.saveDeck)(decksDir, deckName, deck);
|
|
623
|
+
console.log(` Delivery mode for deck "${deckName}" set to: ${mode}`);
|
|
624
|
+
});
|
|
625
|
+
// ---------------------------------------------------------------------------
|
|
626
|
+
// Deck parameter helpers & subcommands
|
|
627
|
+
// ---------------------------------------------------------------------------
|
|
628
|
+
function loadDeckForConfig(cmd, deckName) {
|
|
629
|
+
const config = (0, config_1.loadConfig)();
|
|
630
|
+
const globalOpts = cmd.optsWithGlobals ? cmd.optsWithGlobals() : (cmd.parent?.parent?.opts() || {});
|
|
631
|
+
const merchant = (0, config_1.resolveMerchant)(config, globalOpts.merchant);
|
|
632
|
+
const decksDir = path.join(path.resolve(merchant.default_output_dir), 'decks');
|
|
633
|
+
const deck = (0, deck_1.loadDeck)(decksDir, deckName);
|
|
634
|
+
return { deck, decksDir, deckName };
|
|
635
|
+
}
|
|
636
|
+
// set-deck-param
|
|
637
|
+
exports.configCommand
|
|
638
|
+
.command('set-deck-param <deck> <param> <value>')
|
|
639
|
+
.description('Set a parameter default on a deck')
|
|
640
|
+
.action((deckArg, param, value, _options, cmd) => {
|
|
641
|
+
const { deck, decksDir, deckName } = loadDeckForConfig(cmd, deckArg);
|
|
642
|
+
if (!deck.parameters)
|
|
643
|
+
deck.parameters = {};
|
|
644
|
+
deck.parameters[param] = value;
|
|
645
|
+
(0, deck_1.saveDeck)(decksDir, deckName, deck);
|
|
646
|
+
console.log(` Set deck parameter "${param}" = "${value}" on deck "${deckName}"`);
|
|
647
|
+
});
|
|
648
|
+
// remove-deck-param
|
|
649
|
+
exports.configCommand
|
|
650
|
+
.command('remove-deck-param <deck> <param>')
|
|
651
|
+
.description('Remove a parameter default from a deck')
|
|
652
|
+
.action((deckArg, param, _options, cmd) => {
|
|
653
|
+
const { deck, decksDir, deckName } = loadDeckForConfig(cmd, deckArg);
|
|
654
|
+
if (!deck.parameters || deck.parameters[param] === undefined) {
|
|
655
|
+
console.log(` Parameter "${param}" not found on deck "${deckName}".`);
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
delete deck.parameters[param];
|
|
659
|
+
if (Object.keys(deck.parameters).length === 0) {
|
|
660
|
+
delete deck.parameters;
|
|
661
|
+
}
|
|
662
|
+
(0, deck_1.saveDeck)(decksDir, deckName, deck);
|
|
663
|
+
console.log(` Removed deck parameter "${param}" from deck "${deckName}"`);
|
|
664
|
+
});
|
|
665
|
+
// show-deck-params
|
|
666
|
+
exports.configCommand
|
|
667
|
+
.command('show-deck-params <deck>')
|
|
668
|
+
.description('Display all parameter defaults for a deck')
|
|
669
|
+
.action((deckArg, _options, cmd) => {
|
|
670
|
+
const { deck, deckName } = loadDeckForConfig(cmd, deckArg);
|
|
671
|
+
const params = deck.parameters || {};
|
|
672
|
+
const keys = Object.keys(params);
|
|
673
|
+
if (keys.length === 0) {
|
|
674
|
+
console.log(` No parameters configured for deck "${deckName}".`);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
console.log('');
|
|
678
|
+
console.log(` Deck parameters for "${deckName}":`);
|
|
679
|
+
console.log(' ' + '─'.repeat(50));
|
|
680
|
+
for (const key of keys) {
|
|
681
|
+
console.log(` ${key.padEnd(25)} ${params[key]}`);
|
|
682
|
+
}
|
|
683
|
+
console.log('');
|
|
684
|
+
});
|
|
685
|
+
// ---------------------------------------------------------------------------
|
|
686
|
+
// Report parameter helpers & subcommands
|
|
687
|
+
// ---------------------------------------------------------------------------
|
|
688
|
+
// set-param
|
|
689
|
+
exports.configCommand
|
|
690
|
+
.command('set-param <report> <param> <value>')
|
|
691
|
+
.description('Set the default value for a report parameter')
|
|
692
|
+
.action((report, param, value, _options, cmd) => {
|
|
693
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
694
|
+
const params = manifest.parameters || [];
|
|
695
|
+
const paramDef = params.find((p) => p.name === param);
|
|
696
|
+
if (!paramDef) {
|
|
697
|
+
console.error(`Error: Parameter "${param}" not found in report "${report}". Available: ${params.map((p) => p.name).join(', ') || 'none'}`);
|
|
698
|
+
process.exit(1);
|
|
699
|
+
}
|
|
700
|
+
paramDef.default = value;
|
|
701
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
702
|
+
console.log(` Set parameter "${param}" default = "${value}" on report "${report}"`);
|
|
703
|
+
});
|
|
704
|
+
// remove-param
|
|
705
|
+
exports.configCommand
|
|
706
|
+
.command('remove-param <report> <param>')
|
|
707
|
+
.description('Remove the default value for a report parameter (will prompt on run)')
|
|
708
|
+
.action((report, param, _options, cmd) => {
|
|
709
|
+
const { manifest, reportDir } = loadReportForDelivery(cmd, report);
|
|
710
|
+
const params = manifest.parameters || [];
|
|
711
|
+
const paramDef = params.find((p) => p.name === param);
|
|
712
|
+
if (!paramDef) {
|
|
713
|
+
console.error(`Error: Parameter "${param}" not found in report "${report}". Available: ${params.map((p) => p.name).join(', ') || 'none'}`);
|
|
714
|
+
process.exit(1);
|
|
715
|
+
}
|
|
716
|
+
if (paramDef.default === undefined) {
|
|
717
|
+
console.log(` Parameter "${param}" already has no default on report "${report}".`);
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
delete paramDef.default;
|
|
721
|
+
(0, manifest_1.saveManifest)(reportDir, manifest);
|
|
722
|
+
console.log(` Removed default for parameter "${param}" on report "${report}"`);
|
|
723
|
+
});
|
|
724
|
+
// show-params
|
|
725
|
+
exports.configCommand
|
|
726
|
+
.command('show-params <report>')
|
|
727
|
+
.description('Display all parameters and their defaults for a report')
|
|
728
|
+
.action((report, _options, cmd) => {
|
|
729
|
+
const { manifest } = loadReportForDelivery(cmd, report);
|
|
730
|
+
const params = manifest.parameters || [];
|
|
731
|
+
if (params.length === 0) {
|
|
732
|
+
console.log(` No parameters defined for report "${report}".`);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
console.log('');
|
|
736
|
+
console.log(` Parameters for "${report}":`);
|
|
737
|
+
console.log(' ' + '─'.repeat(60));
|
|
738
|
+
console.log(` ${'Name'.padEnd(20)} ${'Type'.padEnd(10)} ${'Required'.padEnd(10)} Default`);
|
|
739
|
+
console.log(' ' + '─'.repeat(60));
|
|
740
|
+
for (const p of params) {
|
|
741
|
+
const name = p.name || '';
|
|
742
|
+
const type = p.type || '';
|
|
743
|
+
const required = p.required ? 'yes' : 'no';
|
|
744
|
+
const defaultVal = p.default !== undefined ? String(p.default) : '(none)';
|
|
745
|
+
console.log(` ${name.padEnd(20)} ${type.padEnd(10)} ${required.padEnd(10)} ${defaultVal}`);
|
|
746
|
+
}
|
|
747
|
+
console.log('');
|
|
748
|
+
});
|
|
749
|
+
//# sourceMappingURL=config.js.map
|