UNPKG

advanced-live-server-installer

Version:

Auto-installer for Advanced Live Server VS Code Extension

518 lines 24.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HyperServerAIModelManager = void 0; class HyperServerAIModelManager { constructor(context, outputChannel) { this.tools = new Map(); this.extensionPath = context.extensionPath; this.outputChannel = outputChannel; this.initializeTools(); } initializeTools() { // Lightweight, practical development tools this.tools.set('eslint', { name: 'ESLint', type: 'code-analysis', size: 50, description: 'JavaScript/TypeScript linting and code quality analysis', bundled: true, npmPackage: 'eslint', }); this.tools.set('prettier', { name: 'Prettier', type: 'linting', size: 30, description: 'Code formatting and style consistency', bundled: true, npmPackage: 'prettier', }); this.tools.set('axe-core', { name: 'Axe Core', type: 'accessibility', size: 200, description: 'Accessibility testing and analysis', bundled: true, npmPackage: 'axe-core', }); this.tools.set('lighthouse', { name: 'Lighthouse', type: 'performance', size: 500, description: 'Performance, accessibility, and SEO auditing', bundled: true, npmPackage: 'lighthouse', }); this.tools.set('html-validator', { name: 'HTML Validator', type: 'code-analysis', size: 20, description: 'HTML validation and best practices', bundled: true, npmPackage: 'w3c-html-validator', }); this.tools.set('css-validator', { name: 'CSS Validator', type: 'code-analysis', size: 15, description: 'CSS validation and optimization', bundled: true, npmPackage: 'w3c-css-validator', }); this.tools.set('security-scanner', { name: 'Security Scanner', type: 'security', size: 100, description: 'Security vulnerability detection', bundled: true, npmPackage: 'eslint-plugin-security', }); this.tools.set('seo-checker', { name: 'SEO Checker', type: 'seo', size: 80, description: 'SEO analysis and optimization suggestions', bundled: true, npmPackage: 'seo-checker', }); } async ensureToolAvailable(toolId) { const tool = this.tools.get(toolId); if (!tool) { this.outputChannel.appendLine(`❌ Tool ${toolId} not found`); return false; } if (tool.bundled) { // For bundled tools, we'll use npm packages instead of downloading files this.outputChannel.appendLine(`✅ Tool ${tool.name} is available via npm`); return true; } return false; } async analyzeCodeWithTool(toolId, code, task) { const tool = this.tools.get(toolId); if (!tool) { throw new Error(`Tool ${toolId} not found`); } // Ensure tool is available const isAvailable = await this.ensureToolAvailable(toolId); if (!isAvailable) { throw new Error(`Tool ${toolId} is not available`); } // Use pattern-based analysis for now // In a real implementation, you would call the actual npm packages return this.analyzeWithPatterns(code, task, tool.type); } analyzeWithPatterns(code, task, toolType) { switch (toolType) { case 'code-analysis': return this.analyzeCodePatterns(code); case 'accessibility': return this.analyzeAccessibilityPatterns(code); case 'performance': return this.analyzePerformancePatterns(code); case 'seo': return this.analyzeSEOPatterns(code); case 'security': return this.analyzeSecurityPatterns(code); case 'linting': return this.analyzeLintingPatterns(code); default: return 'Analysis not available for this tool type'; } } analyzeCodePatterns(code) { const issues = []; const lines = code.split('\n'); // Real code analysis for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; // Check for var usage if (line.includes('var ')) { issues.push(`Line ${lineNum}: Use 'let' or 'const' instead of 'var' for better scoping`); } // Check for console.log in production code if (line.includes('console.log(')) { issues.push(`Line ${lineNum}: Remove console.log before production - use proper logging`); } // Check for loose equality if (line.includes(' == ') && !line.includes(' === ')) { issues.push(`Line ${lineNum}: Use strict equality (===) instead of loose equality (==)`); } // Check for eval usage if (line.includes('eval(')) { issues.push(`Line ${lineNum}: Avoid eval() for security reasons - use safer alternatives`); } // Check for function spacing if (line.includes('function(') && !line.includes('function (')) { issues.push(`Line ${lineNum}: Add space after 'function' keyword for consistency`); } // Check for unused variables (basic check) if (line.includes('let ') || line.includes('const ')) { const varName = line.match(/(?:let|const)\s+(\w+)/)?.[1]; if (varName && !code.includes(varName + ' ') && !code.includes(varName + ';') && !code.includes(varName + ')')) { issues.push(`Line ${lineNum}: Variable '${varName}' might be unused`); } } // Check for missing semicolons (if not using no-semi style) if (line.trim() && !line.trim().endsWith(';') && !line.trim().endsWith('{') && !line.trim().endsWith('}')) { if (line.includes('return ') || line.includes('break ') || line.includes('continue ')) { issues.push(`Line ${lineNum}: Consider adding semicolon for consistency`); } } // Check for long lines if (line.length > 80) { issues.push(`Line ${lineNum}: Line is ${line.length} characters long - consider breaking it up`); } } // Check for overall code structure if (!code.includes('use strict') && code.includes('function')) { issues.push('Consider adding "use strict" directive for better error checking'); } if (code.includes('setTimeout') && code.includes('0')) { issues.push('Consider using requestAnimationFrame instead of setTimeout(0) for better performance'); } if (issues.length > 0) { return `Code Analysis Results:\n\n${issues.map(issue => `• ${issue}`).join('\n')}\n\nTotal issues found: ${issues.length}`; } else { return 'Code Analysis Results:\n\n✅ Code looks good! No major issues found.'; } } analyzeAccessibilityPatterns(code) { const issues = []; const lines = code.split('\n'); // Real accessibility analysis for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; // Check for images without alt text if (line.includes('<img') && !line.includes('alt=')) { issues.push(`Line ${lineNum}: Image missing alt text - add alt="description" for screen readers`); } // Check for buttons without accessible text if (line.includes('<button') && !line.includes('>') && !line.includes('aria-label=')) { issues.push(`Line ${lineNum}: Button missing accessible text - add text content or aria-label="description"`); } // Check for form inputs without labels if ((line.includes('<input') || line.includes('<select>') || line.includes('<textarea')) && !line.includes('<label') && !line.includes('aria-label=') && !line.includes('aria-labelledby=')) { issues.push(`Line ${lineNum}: Form control missing label - add <label> or aria-label="description"`); } // Check for heading hierarchy if (line.match(/<h[1-6]/)) { const headingLevel = parseInt(line.match(/<h([1-6])/)?.[1] || '1'); if (headingLevel > 1 && !code.includes(`<h${headingLevel - 1}`)) { issues.push(`Line ${lineNum}: Heading hierarchy issue - h${headingLevel} should follow h${headingLevel - 1}`); } } // Check for color-only information if (line.includes('color:') && (line.includes('red') || line.includes('green') || line.includes('blue'))) { issues.push(`Line ${lineNum}: Color-only information - ensure information isn't conveyed by color alone`); } // Check for keyboard navigation if (line.includes('onclick=') && !line.includes('tabindex=')) { issues.push(`Line ${lineNum}: Interactive element should be keyboard accessible - add tabindex="0"`); } } // Check for overall document structure if (!code.includes('<main>') && !code.includes('<article>')) { issues.push('Document missing semantic landmarks - add <main> or <article> for better navigation'); } if (!code.includes('lang=')) { issues.push('HTML missing language attribute - add lang="en" to <html> tag'); } if (issues.length > 0) { return `Accessibility Analysis Results:\n\n${issues.map(issue => `• ${issue}`).join('\n')}\n\nTotal issues found: ${issues.length}`; } else { return 'Accessibility Analysis Results:\n\n✅ No accessibility issues found! Your code follows good accessibility practices.'; } } analyzePerformancePatterns(code) { const issues = []; const lines = code.split('\n'); // Real performance analysis for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; // Check for DOM queries in loops if (line.includes('querySelector') && (code.includes('for') || code.includes('forEach'))) { issues.push(`Line ${lineNum}: DOM queries in loops are expensive - cache selectors outside the loop`); } // Check for missing event listener cleanup if (line.includes('addEventListener') && !code.includes('removeEventListener')) { issues.push(`Line ${lineNum}: Consider removing event listeners to prevent memory leaks`); } // Check for slow DOM manipulation if (line.includes('innerHTML') || line.includes('outerHTML')) { issues.push(`Line ${lineNum}: innerHTML/outerHTML can be slow - consider using textContent or DOM manipulation`); } // Check for setTimeout(0) anti-pattern if (line.includes('setTimeout') && line.includes('0')) { issues.push(`Line ${lineNum}: setTimeout(0) can be replaced with requestAnimationFrame for better performance`); } // Check for synchronous operations if (line.includes('alert(') || line.includes('confirm(') || line.includes('prompt(')) { issues.push(`Line ${lineNum}: Synchronous operations block the UI - consider async alternatives`); } // Check for large loops if (line.includes('for(') && code.includes('length') && code.includes('i++')) { issues.push(`Line ${lineNum}: Large loops can block the main thread - consider chunking or Web Workers`); } } // Check for overall performance patterns if (code.includes('document.write(')) { issues.push('document.write() blocks rendering - use DOM manipulation instead'); } if (code.includes('eval(')) { issues.push('eval() is slow and dangerous - use safer alternatives'); } if (issues.length > 0) { return `Performance Analysis Results:\n\n${issues.map(issue => `• ${issue}`).join('\n')}\n\nTotal performance issues found: ${issues.length}`; } else { return 'Performance Analysis Results:\n\n✅ Good performance practices! No major issues found.'; } } analyzeSEOPatterns(code) { const issues = []; const lines = code.split('\n'); // Real SEO analysis for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; // Check for missing title tag if (line.includes('<title>') && line.trim() === '<title></title>') { issues.push(`Line ${lineNum}: Title tag is empty - add descriptive title for SEO`); } // Check for missing meta description if (line.includes('meta name="description"') && line.includes('content=""')) { issues.push(`Line ${lineNum}: Meta description is empty - add descriptive content for search results`); } // Check for missing h1 tag if (line.includes('<h1>') && line.trim() === '<h1></h1>') { issues.push(`Line ${lineNum}: H1 tag is empty - add main heading for SEO hierarchy`); } // Check for images without alt text if (line.includes('<img') && !line.includes('alt=')) { issues.push(`Line ${lineNum}: Image missing alt text - helps with image search and accessibility`); } // Check for non-semantic divs if (line.includes('<div>') && !code.includes('<main>') && !code.includes('<article>') && !code.includes('<section>')) { issues.push(`Line ${lineNum}: Consider using semantic HTML elements (main, article, section) for better SEO`); } // Check for missing language attribute if (line.includes('<html') && !line.includes('lang=')) { issues.push(`Line ${lineNum}: HTML missing language attribute - add lang="en" for better SEO`); } // Check for missing viewport meta tag if (line.includes('<head>') && !code.includes('viewport')) { issues.push(`Line ${lineNum}: Missing viewport meta tag - add for mobile SEO`); } } // Check for overall SEO patterns if (!code.includes('<title>')) { issues.push('Missing title tag - essential for SEO'); } if (!code.includes('meta name="description"')) { issues.push('Missing meta description - important for search results'); } if (!code.includes('<h1>')) { issues.push('Missing h1 tag - important for SEO hierarchy'); } if (code.includes('<img') && !code.includes('alt=')) { issues.push('Images missing alt text - helps with image search'); } if (code.includes('<div>') && !code.includes('<main>') && !code.includes('<article>')) { issues.push('Consider using semantic HTML elements (main, article, section)'); } if (issues.length > 0) { return `SEO Analysis Results:\n\n${issues.map(issue => `• ${issue}`).join('\n')}\n\nTotal SEO issues found: ${issues.length}`; } else { return 'SEO Analysis Results:\n\n✅ Good SEO practices! No major issues found.'; } } analyzeSecurityPatterns(code) { const issues = []; const lines = code.split('\n'); // Real security analysis for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; // Check for XSS vulnerabilities if (line.includes('innerHTML') || line.includes('outerHTML')) { issues.push(`Line ${lineNum}: Potential XSS vulnerability - use textContent instead of innerHTML`); } // Check for eval usage if (line.includes('eval(')) { issues.push(`Line ${lineNum}: Critical security risk - eval() can execute arbitrary code`); } // Check for inline event handlers if (line.includes('onclick=') || line.includes('onload=') || line.includes('onerror=')) { issues.push(`Line ${lineNum}: Inline event handlers can be security risks - use addEventListener`); } // Check for hardcoded secrets if (line.includes('password') || line.includes('secret') || line.includes('key') || line.includes('token')) { if (line.includes('"') || line.includes("'")) { issues.push(`Line ${lineNum}: Hardcoded secret detected - move to environment variables`); } } // Check for localStorage with sensitive data if (line.includes('localStorage') && (line.includes('password') || line.includes('token'))) { issues.push(`Line ${lineNum}: Sensitive data in localStorage - use secure storage or encryption`); } // Check for SQL injection patterns if (line.includes('query') && line.includes('+') && line.includes('"')) { issues.push(`Line ${lineNum}: Potential SQL injection - use parameterized queries`); } // Check for unsafe redirects if (line.includes('window.location') && line.includes('href') && line.includes('+')) { issues.push(`Line ${lineNum}: Unsafe redirect - validate and sanitize URLs`); } // Check for unsafe file operations if (line.includes('readFile') && !line.includes('path.join')) { issues.push(`Line ${lineNum}: Unsafe file path - use path.join() to prevent path traversal`); } } // Check for overall security patterns if (!code.includes('Content-Security-Policy')) { issues.push('Missing Content Security Policy - add CSP headers to prevent XSS'); } if (code.includes('http://') && !code.includes('localhost')) { issues.push('Insecure HTTP protocol detected - use HTTPS for production'); } if (issues.length > 0) { return `Security Analysis Results:\n\n${issues.map(issue => `• ${issue}`).join('\n')}\n\nTotal security issues found: ${issues.length}`; } else { return 'Security Analysis Results:\n\n✅ No security vulnerabilities found! Your code follows security best practices.'; } } analyzeLintingPatterns(code) { const issues = []; const lines = code.split('\n'); // Real code improvement analysis for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineNum = i + 1; // Check for inconsistent spacing if (line.includes('function(') && !line.includes('function (')) { issues.push(`Line ${lineNum}: Add space after 'function' keyword for consistency`); } if (line.includes('if(') && !line.includes('if (')) { issues.push(`Line ${lineNum}: Add space after 'if' keyword for consistency`); } if (line.includes('for(') && !line.includes('for (')) { issues.push(`Line ${lineNum}: Add space after 'for' keyword for consistency`); } // Check for inconsistent semicolon usage if (line.trim() && !line.trim().endsWith(';') && !line.trim().endsWith('{') && !line.trim().endsWith('}')) { if (line.includes('return ') || line.includes('break ') || line.includes('continue ')) { issues.push(`Line ${lineNum}: Consider adding semicolon for consistency`); } } // Check for inconsistent quote usage if (line.includes('"') && line.includes("'")) { issues.push(`Line ${lineNum}: Use consistent quote style - prefer single or double quotes`); } // Check for trailing whitespace if (line.endsWith(' ') || line.endsWith('\t')) { issues.push(`Line ${lineNum}: Remove trailing whitespace`); } // Check for inconsistent indentation const leadingSpaces = line.match(/^(\s*)/)?.[1].length || 0; if (leadingSpaces % 2 !== 0 && leadingSpaces > 0) { issues.push(`Line ${lineNum}: Use consistent indentation (2 or 4 spaces)`); } // Check for long lines if (line.length > 80) { issues.push(`Line ${lineNum}: Line is ${line.length} characters long - consider breaking it up`); } // Check for unused imports/variables if (line.includes('import ') || line.includes('require(')) { const importName = line.match(/(?:import|require).*?['"`]([^'"`]+)['"`]/)?.[1]; if (importName && !code.includes(importName.split('/').pop() || '')) { issues.push(`Line ${lineNum}: Unused import detected - remove if not needed`); } } } // Check for overall code style if (!code.includes('use strict') && code.includes('function')) { issues.push('Consider adding "use strict" directive for better error checking'); } if (code.includes('var ')) { issues.push('Use let/const instead of var for better scoping'); } if (code.includes('==') && !code.includes('===')) { issues.push('Use strict equality (===) instead of loose equality (==)'); } if (issues.length > 0) { return `Code Improvement Suggestions:\n\n${issues.map(issue => `• ${issue}`).join('\n')}\n\nTotal improvements found: ${issues.length}`; } else { return 'Code Improvement Analysis:\n\n✅ Code follows good style practices! No improvements needed.'; } } getAvailableTools() { return Array.from(this.tools.values()); } getToolInfo(toolId) { return this.tools.get(toolId); } async getToolStatus(toolId) { const tool = this.tools.get(toolId); if (!tool) { return { available: false, size: 0 }; } if (tool.bundled) { return { available: true, size: tool.size }; } return { available: false, size: 0 }; } } exports.HyperServerAIModelManager = HyperServerAIModelManager; //# sourceMappingURL=hyperserver-ai-model.js.map