wingman-monitor
Version:
Runtime error monitoring package with React provider that automatically reports errors to webhook endpoints
270 lines β’ 11.5 kB
JavaScript
;
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