UNPKG

wingman-monitor

Version:

Runtime error monitoring package with React provider that automatically reports errors to webhook endpoints

270 lines β€’ 11.5 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const config_1 = require("./config"); const chalk_1 = __importDefault(require("chalk")); const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const axios_1 = __importDefault(require("axios")); const program = new commander_1.Command(); // Function to test webhook connection and validate access token async function testWebhookConnection(webhookUrl, accessToken, environment) { let projectId = undefined; try { console.log(chalk_1.default.blue('πŸ”— Testing webhook connection...')); // const testPayload = { // event: 'wingman.init', // data: { // message: 'Wingman initialization test', // timestamp: new Date().toISOString(), // environment: environment, // projectInfo: { // name: 'wingman-test', // version: '1.0.0' // }, // errorType: 'initialization', // severity: 'low' as const, // accessToken: accessToken, // projectPath: process.cwd() // }, // timestamp: Date.now(), // source: 'wingman-monitor-init' // }; const testPayload = { event: 'wingman.init', data: { accessToken: accessToken, environment: environment, }, timestamp: Date.now(), source: 'wingman-monitor-init' }; const response = await axios_1.default.post(webhookUrl, testPayload, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}`, 'User-Agent': 'Wingman-Monitor/1.0.0' }, timeout: 10000 // 10 second timeout for init }); if (response.status >= 200 && response.status < 300) { projectId = response.data?.projectId; // Grab projectId from webhook response return { success: true, message: 'Webhook connection successful', projectId: projectId }; } else { return { success: false, message: `Webhook returned status ${response.status}` }; } } catch (error) { if (axios_1.default.isAxiosError(error)) { if (error.code === 'ECONNREFUSED') { return { success: false, message: 'Unable to connect to webhook URL. Please check the URL and ensure the server is running.' }; } else if (error.response?.status === 401) { return { success: false, message: 'Access token is invalid or unauthorized.' }; } else if (error.response?.status === 404) { return { success: false, message: 'Webhook endpoint not found. Please check the URL.' }; } else if (error.response && error.response.status >= 500) { return { success: false, message: 'Webhook server error. Please try again later.' }; } else { return { success: false, message: `Webhook error: ${error.response?.status || error.message}` }; } } return { success: false, message: `Connection failed: ${error instanceof Error ? error.message : 'Unknown error'}` }; } } program .name('wingman') .description('Runtime error monitoring CLI') .version('1.0.0'); program .command('init') .description('Initialize Wingman monitoring in the current project') .argument('<accessToken>', 'Access token for webhook authentication') .option('-w, --webhook <url>', 'Webhook URL for error reporting') .option('-e, --env <environment>', 'Environment name (development, staging, production)', 'development') .action(async (accessToken, options) => { try { console.log(chalk_1.default.blue('πŸ›‘οΈ Initializing Wingman monitoring...')); const webhookUrl = options.webhook || process.env.WINGMAN_WEBHOOK_URL || 'https://patchworks-seven.vercel.app/webhook'; // Test webhook connection and validate access token FIRST const testResult = await testWebhookConnection(webhookUrl, accessToken, options.env); if (!testResult.success) { console.error(chalk_1.default.red('❌ Webhook test failed:'), testResult.message); console.log(chalk_1.default.yellow('πŸ’‘ Please check:')); console.log(chalk_1.default.gray(' - Your webhook URL is correct')); console.log(chalk_1.default.gray(' - Your access token is valid')); console.log(chalk_1.default.gray(' - Your webhook server is running and accessible')); process.exit(1); } console.log(chalk_1.default.green('βœ… Webhook connection verified')); const config = new config_1.ConfigManager(); // Grab projectId from the webhook response if available if (testResult.success && testResult.message && typeof testResult === 'object') { // If the response contains data with projectId, extract it // You may want to adjust this depending on your actual response structure // For example, if testWebhookConnection returns the full response data: // projectId = testResult.projectId; // But currently, testWebhookConnection only returns { success, message } // So you need to modify testWebhookConnection to return projectId if present // Example if you update testWebhookConnection to return projectId: // projectId = testResult.projectId; } await config.initialize({ accessToken, projectId: testResult.projectId, environment: options.env, projectPath: process.cwd() }); // Create wingman config file const configPath = path.join(process.cwd(), '.wingman.json'); const configData = { accessToken, environment: options.env, enabled: true, createdAt: new Date().toISOString() }; if (testResult.projectId) { configData.projectId = testResult.projectId; } await fs.writeJson(configPath, configData, { spaces: 2 }); console.log(chalk_1.default.green('βœ… Wingman monitoring initialized successfully!')); if (testResult.projectId) { console.log(chalk_1.default.blue(`πŸ†” Project ID: ${testResult.projectId}`)); } console.log(chalk_1.default.yellow('πŸ“ Configuration saved to .wingman.json')); console.log(chalk_1.default.gray('πŸ’‘ Add the following to your main application file:')); console.log(chalk_1.default.cyan(' import { WingmanMonitor } from "wingman-monitor";')); console.log(chalk_1.default.cyan(' const monitor = new WingmanMonitor();')); console.log(chalk_1.default.cyan(' monitor.start();')); } catch (error) { console.error(chalk_1.default.red('❌ Failed to initialize Wingman:'), error); process.exit(1); } }); program .command('status') .description('Check Wingman monitoring status') .action(async () => { try { const configPath = path.join(process.cwd(), '.wingman.json'); if (!await fs.pathExists(configPath)) { console.log(chalk_1.default.yellow('⚠️ Wingman not initialized. Run "wingman init <accessToken>" first.')); return; } const config = await fs.readJson(configPath); console.log(chalk_1.default.blue('πŸ›‘οΈ Wingman Status:')); console.log(chalk_1.default.green(` Environment: ${config.environment}`)); console.log(chalk_1.default.green(` Webhook URL: ${config.webhookUrl}`)); console.log(chalk_1.default.green(` Status: ${config.enabled ? 'Enabled' : 'Disabled'}`)); console.log(chalk_1.default.gray(` Initialized: ${config.createdAt}`)); } catch (error) { console.error(chalk_1.default.red('❌ Failed to check status:'), error); } }); program .command('disable') .description('Disable Wingman monitoring') .action(async () => { try { const configPath = path.join(process.cwd(), '.wingman.json'); if (!await fs.pathExists(configPath)) { console.log(chalk_1.default.yellow('⚠️ Wingman not initialized.')); return; } const config = await fs.readJson(configPath); config.enabled = false; await fs.writeJson(configPath, config, { spaces: 2 }); console.log(chalk_1.default.yellow('⏸️ Wingman monitoring disabled')); } catch (error) { console.error(chalk_1.default.red('❌ Failed to disable Wingman:'), error); } }); program .command('enable') .description('Enable Wingman monitoring') .action(async () => { try { const configPath = path.join(process.cwd(), '.wingman.json'); if (!await fs.pathExists(configPath)) { console.log(chalk_1.default.yellow('⚠️ Wingman not initialized.')); return; } const config = await fs.readJson(configPath); config.enabled = true; await fs.writeJson(configPath, config, { spaces: 2 }); console.log(chalk_1.default.green('▢️ Wingman monitoring enabled')); } catch (error) { console.error(chalk_1.default.red('❌ Failed to enable Wingman:'), error); } }); program.parse(); //# sourceMappingURL=cli.js.map