UNPKG

intellify

Version:

Detect JavaScript & TypeScript errors and make codes more optimized.

272 lines (219 loc) • 9.81 kB
import chalk from 'chalk'; import boxen from 'boxen'; import path from 'path'; import util from 'util'; function safeInspect(obj, depth = 2) { return util.inspect(obj, { depth: depth, colors: false, maxArrayLength: 10, breakLength: 80 }); } function formatBytes(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } export function displayResults(results, stats) { try { console.log(chalk.blue.bold('\n✨ Analysis Complete ✨')); try { let statsText = `${chalk.white.bold('šŸ“ Files:')} ${chalk.white(stats.filesAnalyzed)}\n`; statsText += `${chalk.white.bold('šŸ“‹ Lines:')} ${chalk.white(stats.linesOfCode.toLocaleString())}\n`; statsText += `${chalk.white.bold('šŸ’¾ Size:')} ${chalk.white(formatBytes(stats.totalSize))}`; if (Object.keys(stats.fileTypes).length > 0) { statsText += `\n\n${chalk.white.bold('šŸ–¼ File Types:')}`; const sortedTypes = Object.entries(stats.fileTypes) .sort((a, b) => b[1] - a[1]) .slice(0, 4); sortedTypes.forEach(([ext, count]) => { const percent = Math.round((count / stats.filesAnalyzed) * 100); statsText += `\n ${chalk.white(ext.padEnd(5))} ${chalk.white(count + ' files')} ${chalk.gray(`(${percent}%)`)}`; }); } console.log(boxen(statsText, { title: 'Codebase Stats', titleAlignment: 'center', padding: 1, margin: {top:1, bottom:1}, borderStyle: 'round', borderColor: 'cyan' })); } catch (error) { console.error('[ERROR] Failed to display stats:', error.message); } try { console.log(chalk.magenta.bold('\nšŸ”Ž Issues Found')); const syntaxErrorsCount = results.syntaxErrors?.length || 0; const unusedPackagesCount = results.unusedPackages?.length || 0; const unusedVariablesCount = results.unusedVariables?.length || 0; const commentsCount = results.comments?.length || 0; const totalIssues = syntaxErrorsCount + unusedPackagesCount + unusedVariablesCount + commentsCount; if (totalIssues > 0) { const barWidth = 40; const syntaxErrorsWidth = Math.round((syntaxErrorsCount / totalIssues) * barWidth) || 0; const unusedPackagesWidth = Math.round((unusedPackagesCount / totalIssues) * barWidth) || 0; const unusedVariablesWidth = Math.round((unusedVariablesCount / totalIssues) * barWidth) || 0; const commentsWidth = Math.round((commentsCount / totalIssues) * barWidth) || 0; console.log( chalk.red('ā–ˆ'.repeat(syntaxErrorsWidth)) + chalk.yellow('ā–ˆ'.repeat(unusedPackagesWidth)) + chalk.magenta('ā–ˆ'.repeat(unusedVariablesWidth)) + chalk.green('ā–ˆ'.repeat(commentsWidth)) ); console.log( chalk.red(`Syntax Errors: ${syntaxErrorsCount} `) + chalk.yellow(`Unused Packages: ${unusedPackagesCount} `) + chalk.magenta(`Unused Variables: ${unusedVariablesCount} `) + chalk.green(`Comments: ${commentsCount}`) ); } else { console.log(chalk.green('No issues found! Your codebase is clean. āœ…')); } } catch (error) { console.error('[ERROR] Failed to display issues summary:', error.message); } try { if (results.analyzedFiles?.length > 0) { let filesTable = `${chalk.white.bold('Filename'.padEnd(20))} ${chalk.white.bold('Type'.padEnd(8))} ${chalk.white.bold('Size'.padEnd(10))} ${chalk.white.bold('Lines'.padEnd(10))}\n`; filesTable += chalk.gray('─'.repeat(50)) + '\n'; const topFiles = [...results.analyzedFiles] .sort((a, b) => b.size - a.size) .slice(0, 10); topFiles.forEach(file => { const filename = file.name.length > 19 ? file.name.substring(0, 16) + '...' : file.name; filesTable += `${chalk.white(filename.padEnd(20))} ` + `${chalk.yellow(file.type.padEnd(8))} ` + `${chalk.cyan(formatBytes(file.size).padEnd(10))} ` + `${chalk.green(file.lines.toString().padEnd(10))}\n`; }); console.log(boxen(filesTable, { title: 'Analyzed Files (Top by size)', titleAlignment: 'center', padding: 1, margin: {top:1, bottom:1}, borderStyle: 'round', borderColor: 'blue' })); } } catch (error) { console.error('[ERROR] Failed to display analyzed files:', error.message); } try { if (results.syntaxErrors?.length > 0) { console.log(chalk.red.bold('\nšŸ”„ Syntax Errors:')); results.syntaxErrors.forEach(error => { console.log(chalk.red(` • ${path.basename(error.file)} (line ${error.line}): ${error.message}`)); }); } } catch (error) { console.error('[ERROR] Failed to display syntax errors:', error.message); } try { if (results.unusedPackages?.length > 0) { console.log(chalk.yellow.bold('\nšŸ“¦ Unused Packages:')); results.unusedPackages.forEach(pkg => { console.log(chalk.yellow(` • ${pkg.name} (${pkg.type})`)); }); } } catch (error) { console.error('[ERROR] Failed to display unused packages:', error.message); } try { if (results.unusedVariables?.length > 0) { console.log(chalk.magenta.bold('\nšŸ” Unused Items:')); const unusedByType = { variable: [], import: [], require: [], other: [] }; results.unusedVariables.forEach(item => { if (item.type === 'variable') { unusedByType.variable.push(item); } else if (item.type === 'import') { unusedByType.import.push(item); } else if (item.type === 'require') { unusedByType.require.push(item); } else { unusedByType.other.push(item); } }); if (unusedByType.variable.length > 0) { console.log(chalk.magenta(' Variables:')); unusedByType.variable.slice(0, 5).forEach(variable => { console.log(chalk.magenta(` • ${variable.name} in ${path.basename(variable.file)} (line ${variable.line})`)); }); if (unusedByType.variable.length > 5) { console.log(chalk.magenta(` ... and ${unusedByType.variable.length - 5} more variables`)); } } if (unusedByType.import.length > 0) { console.log(chalk.magenta('\n ES6 Imports:')); unusedByType.import.slice(0, 5).forEach(item => { console.log(chalk.magenta(` • ${item.name} from '${item.source}' in ${path.basename(item.file)} (line ${item.line})`)); }); if (unusedByType.import.length > 5) { console.log(chalk.magenta(` ... and ${unusedByType.import.length - 5} more imports`)); } } if (unusedByType.require.length > 0) { console.log(chalk.magenta('\n CommonJS Requires:')); unusedByType.require.slice(0, 5).forEach(item => { console.log(chalk.magenta(` • ${item.name} from '${item.source}' in ${path.basename(item.file)} (line ${item.line})`)); }); if (unusedByType.require.length > 5) { console.log(chalk.magenta(` ... and ${unusedByType.require.length - 5} more requires`)); } } if (unusedByType.other.length > 0) { console.log(chalk.magenta('\n Other:')); unusedByType.other.slice(0, 5).forEach(item => { console.log(chalk.magenta(` • ${item.name} in ${path.basename(item.file)} (line ${item.line})`)); }); if (unusedByType.other.length > 5) { console.log(chalk.magenta(` ... and ${unusedByType.other.length - 5} more`)); } } } } catch (error) { console.error('[ERROR] Failed to display unused variables:', error.message); } try { if (results.comments?.length > 0) { console.log(chalk.green.bold('\nšŸ’¬ Comment Lines:')); console.log(chalk.green(` Found ${results.comments.length} comments across all files`)); const commentsByFile = {}; results.comments.forEach(comment => { const filename = path.basename(comment.file); if (!commentsByFile[filename]) { commentsByFile[filename] = 0; } commentsByFile[filename]++; }); const topCommentFiles = Object.entries(commentsByFile) .sort((a, b) => b[1] - a[1]) .slice(0, 5); if (topCommentFiles.length > 0) { console.log(chalk.green(' Top files with comments:')); topCommentFiles.forEach(([filename, count]) => { console.log(chalk.green(` • ${filename}: ${count} comments`)); }); } } } catch (error) { console.error('[ERROR] Failed to display comments:', error.message); } console.log(); } catch (error) { console.error('[CRITICAL] displayResults function failed:', error); console.log('\n✨ Analysis Complete ✨'); console.log('An error occurred while displaying detailed results.'); console.log('An error occurred while analyzing the project.'); } } export default displayResults;