UNPKG

intertools

Version:

🚀 Professional console log analysis & IDE integration with AI-powered insights. Completely FREE with all features: terminal monitoring, AI chat orchestrator, production analytics, localhost analysis, and Google Analytics integration. No limits, no subscr

535 lines 18.9 kB
"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; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.LocalhostMonitor = void 0; const http = __importStar(require("http")); const https = __importStar(require("https")); const url_1 = require("url"); class LocalhostMonitor { isMonitoring = false; monitoredUrls = new Set(); capturedData = new Map(); constructor() { } /** * Start monitoring a localhost URL */ async startMonitoring(url) { if (this.monitoredUrls.has(url)) { return; } this.monitoredUrls.add(url); this.isMonitoring = true; console.log(`🌐 Starting localhost monitoring: ${url}`); // Initial capture await this.captureLocalhostData(url); // Set up periodic monitoring setInterval(async () => { if (this.isMonitoring && this.monitoredUrls.has(url)) { await this.captureLocalhostData(url); } }, 10000); // Every 10 seconds } /** * Stop monitoring a URL */ stopMonitoring(url) { this.monitoredUrls.delete(url); if (this.monitoredUrls.size === 0) { this.isMonitoring = false; } console.log(`🌐 Stopped monitoring: ${url}`); } /** * Stop all monitoring */ stopAllMonitoring() { this.monitoredUrls.clear(); this.isMonitoring = false; console.log('🌐 Stopped all localhost monitoring'); } /** * Get captured data for a URL */ getLocalhostData(url) { return this.capturedData.get(url) || null; } /** * Get all captured data */ getAllData() { return new Map(this.capturedData); } /** * Monitor localhost development server */ async monitorLocalhost(url) { try { const html = await this.fetchHTML(url); const consoleLogs = await this.captureConsoleLogs(url); const networkRequests = await this.captureNetworkRequests(url); const performance = await this.measurePerformance(url); const domAnalysis = this.analyzeDOMStructure(html); const errors = await this.captureErrors(url); const data = { url, html, consoleLogs, networkRequests, performance, domAnalysis, errors }; this.capturedData.set(url, data); return data; } catch (error) { console.warn(`Failed to monitor ${url}:`, error); // Return simulated data for demo purposes return this.getSimulatedLocalhostData(url); } } /** * Capture localhost data */ async captureLocalhostData(url) { try { await this.monitorLocalhost(url); } catch (error) { console.warn(`Error capturing data for ${url}:`, error); } } /** * Fetch HTML content from localhost */ async fetchHTML(url) { return new Promise((resolve, reject) => { const parsedUrl = new url_1.URL(url); const client = parsedUrl.protocol === 'https:' ? https : http; const req = client.get(url, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { resolve(data); }); }); req.on('error', (error) => { reject(error); }); req.setTimeout(5000, () => { req.destroy(); reject(new Error('Request timeout')); }); }); } /** * Capture console logs (simulated) */ async captureConsoleLogs(url) { // In a real implementation, this would use browser automation // For now, return simulated console logs return [ { type: 'log', message: 'Application initialized successfully', timestamp: new Date(Date.now() - 60000), source: url }, { type: 'warn', message: 'Deprecated API usage detected in component', timestamp: new Date(Date.now() - 45000), source: url }, { type: 'error', message: 'Failed to fetch data from /api/users', timestamp: new Date(Date.now() - 30000), source: url, stack: 'Error: Failed to fetch\n at fetchUsers (app.js:123:5)\n at App.componentDidMount (app.js:89:12)' }, { type: 'info', message: 'User interaction tracked', timestamp: new Date(Date.now() - 15000), source: url } ]; } /** * Capture network requests (simulated) */ async captureNetworkRequests(url) { // In a real implementation, this would intercept network requests return [ { url: `${url}/api/users`, method: 'GET', status: 200, statusText: 'OK', responseTime: 150, timestamp: new Date(Date.now() - 120000), size: 2048, type: 'xhr' }, { url: `${url}/api/posts`, method: 'GET', status: 404, statusText: 'Not Found', responseTime: 300, timestamp: new Date(Date.now() - 90000), size: 512, type: 'fetch' }, { url: `${url}/static/js/main.js`, method: 'GET', status: 200, statusText: 'OK', responseTime: 50, timestamp: new Date(Date.now() - 180000), size: 245760, type: 'resource' }, { url: `${url}/static/css/main.css`, method: 'GET', status: 200, statusText: 'OK', responseTime: 25, timestamp: new Date(Date.now() - 170000), size: 51200, type: 'resource' } ]; } /** * Measure performance metrics (simulated) */ async measurePerformance(url) { // In a real implementation, this would use browser performance APIs return { loadTime: 1200 + Math.random() * 800, // 1.2-2.0 seconds domContentLoaded: 800 + Math.random() * 400, firstContentfulPaint: 600 + Math.random() * 300, largestContentfulPaint: 1000 + Math.random() * 500, cumulativeLayoutShift: Math.random() * 0.1, firstInputDelay: Math.random() * 100, memoryUsage: 45.6 + Math.random() * 20, domNodes: 234 + Math.floor(Math.random() * 100), resourceCount: 12 + Math.floor(Math.random() * 8), totalSize: 512000 + Math.floor(Math.random() * 256000) }; } /** * Analyze DOM structure */ analyzeDOMStructure(html) { // Basic HTML parsing and analysis const elementMatches = html.match(/<(\w+)[\s>]/g) || []; const elements = elementMatches.map(match => match.replace(/<(\w+)[\s>]/, '$1')); const elementsByTag = {}; elements.forEach(tag => { elementsByTag[tag] = (elementsByTag[tag] || 0) + 1; }); const classMatches = html.match(/class=["']([^"']+)["']/g) || []; const classNames = [...new Set(classMatches .map(match => match.replace(/class=["']([^"']+)["']/, '$1')) .flatMap(classes => classes.split(/\s+/)))]; const idMatches = html.match(/id=["']([^"']+)["']/g) || []; const ids = idMatches.map(match => match.replace(/id=["']([^"']+)["']/, '$1')); // Analyze forms const formMatches = html.match(/<form[^>]*>/g) || []; const forms = formMatches.map(form => { const actionMatch = form.match(/action=["']([^"']+)["']/); const methodMatch = form.match(/method=["']([^"']+)["']/); const inputCount = (html.match(/<input[^>]*>/g) || []).length; return { action: actionMatch ? actionMatch[1] : '', method: methodMatch ? methodMatch[1] : 'GET', inputs: inputCount }; }); // Analyze images const imageMatches = html.match(/<img[^>]*>/g) || []; const images = imageMatches.map(img => { const srcMatch = img.match(/src=["']([^"']+)["']/); const altMatch = img.match(/alt=["']([^"']+)["']/); return { src: srcMatch ? srcMatch[1] : '', alt: altMatch ? altMatch[1] : undefined }; }); // Analyze links const linkMatches = html.match(/<a[^>]*>([^<]*)<\/a>/g) || []; const links = linkMatches.map(link => { const hrefMatch = link.match(/href=["']([^"']+)["']/); const textMatch = link.match(/>([^<]*)<\/a>/); return { href: hrefMatch ? hrefMatch[1] : '', text: textMatch ? textMatch[1].trim() : '' }; }); // Analyze scripts const scriptMatches = html.match(/<script[^>]*>[\s\S]*?<\/script>|<script[^>]*\/>/g) || []; const scripts = scriptMatches.map(script => { const srcMatch = script.match(/src=["']([^"']+)["']/); const inline = !srcMatch; return { src: srcMatch ? srcMatch[1] : undefined, inline, size: script.length, async: script.includes('async'), defer: script.includes('defer') }; }); // Analyze stylesheets const stylesheetMatches = html.match(/<link[^>]*rel=["']stylesheet["'][^>]*>|<style[^>]*>[\s\S]*?<\/style>/g) || []; const stylesheets = stylesheetMatches.map(stylesheet => { const hrefMatch = stylesheet.match(/href=["']([^"']+)["']/); const inline = stylesheet.startsWith('<style'); return { href: hrefMatch ? hrefMatch[1] : undefined, inline, size: stylesheet.length }; }); return { totalElements: elements.length, elementsByTag, classNames, ids, forms, images, links, scripts, stylesheets }; } /** * Capture errors (simulated) */ async captureErrors(url) { return [ { type: 'javascript', message: 'Uncaught TypeError: Cannot read property \'map\' of undefined', source: `${url}/static/js/main.js`, line: 123, column: 45, timestamp: new Date(Date.now() - 300000), stack: 'TypeError: Cannot read property \'map\' of undefined\n at Component.render (main.js:123:45)' }, { type: 'network', message: 'Failed to load resource: the server responded with a status of 404 (Not Found)', source: `${url}/api/missing-endpoint`, timestamp: new Date(Date.now() - 180000) }, { type: 'console', message: 'Warning: Deprecated API usage detected', source: `${url}/static/js/main.js`, line: 89, timestamp: new Date(Date.now() - 120000) } ]; } /** * Get simulated localhost data for demo */ getSimulatedLocalhostData(url) { return { url, html: `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Development Server</title> <link rel="stylesheet" href="/static/css/main.css"> </head> <body> <div id="root"> <header class="app-header"> <h1>Development Application</h1> </header> <main class="app-main"> <p>This is your development server content.</p> <form action="/api/submit" method="POST"> <input type="text" name="name" placeholder="Name"> <input type="email" name="email" placeholder="Email"> <button type="submit">Submit</button> </form> </main> </div> <script src="/static/js/main.js"></script> </body> </html>`, consoleLogs: [ { type: 'log', message: 'Development server initialized', timestamp: new Date(Date.now() - 60000), source: url }, { type: 'error', message: 'API endpoint not found: /api/users', timestamp: new Date(Date.now() - 30000), source: url, stack: 'Error: 404 Not Found\n at fetch (/api/users)' } ], networkRequests: [ { url: `${url}/static/js/main.js`, method: 'GET', status: 200, statusText: 'OK', responseTime: 45, timestamp: new Date(Date.now() - 120000), size: 156780, type: 'resource' }, { url: `${url}/api/users`, method: 'GET', status: 404, statusText: 'Not Found', responseTime: 250, timestamp: new Date(Date.now() - 30000), size: 256, type: 'xhr' } ], performance: { loadTime: 1200, domContentLoaded: 800, firstContentfulPaint: 600, largestContentfulPaint: 1000, cumulativeLayoutShift: 0.05, firstInputDelay: 50, memoryUsage: 45.6, domNodes: 234, resourceCount: 12, totalSize: 512000 }, domAnalysis: { totalElements: 15, elementsByTag: { 'div': 3, 'html': 1, 'head': 1, 'body': 1, 'header': 1, 'h1': 1, 'main': 1, 'p': 1, 'form': 1, 'input': 2, 'button': 1, 'script': 1 }, classNames: ['app-header', 'app-main'], ids: ['root'], forms: [ { action: '/api/submit', method: 'POST', inputs: 2 } ], images: [], links: [], scripts: [ { src: '/static/js/main.js', inline: false, size: 45 } ], stylesheets: [ { href: '/static/css/main.css', inline: false, size: 42 } ] }, errors: [ { type: 'network', message: 'Failed to load resource: 404 (Not Found)', source: `${url}/api/users`, timestamp: new Date(Date.now() - 30000) } ] }; } /** * Get monitoring statistics */ getStats() { const allData = Array.from(this.capturedData.values()); const totalRequests = allData.reduce((sum, data) => sum + data.networkRequests.length, 0); const totalErrors = allData.reduce((sum, data) => sum + data.errors.length, 0); const loadTimes = allData.map(data => data.performance.loadTime); const averageLoadTime = loadTimes.length > 0 ? loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length : 0; // Count error frequency const errorCounts = new Map(); allData.forEach(data => { data.errors.forEach(error => { errorCounts.set(error.message, (errorCounts.get(error.message) || 0) + 1); }); }); const mostCommonErrors = Array.from(errorCounts.entries()) .map(([message, count]) => ({ message, count })) .sort((a, b) => b.count - a.count) .slice(0, 5); return { monitoredUrls: this.monitoredUrls.size, totalRequests, totalErrors, averageLoadTime, mostCommonErrors }; } } exports.LocalhostMonitor = LocalhostMonitor; //# sourceMappingURL=localhost-monitor.js.map