UNPKG

intellify

Version:

Detect JavaScript & TypeScript errors and make codes more optimized.

213 lines (160 loc) • 8.29 kB
import readline from 'readline'; import chalk from 'chalk'; import path from 'path'; import { fixComments } from '../analyzers/code.js'; import fs from 'fs'; export async function promptFix(results, projectPath) { if (results.syntaxErrors.length === 0 && results.unusedPackages.length === 0 && results.unusedVariables.length === 0 && (!results.comments || results.comments.length === 0)) { console.log(chalk.green.bold('✨ Your project looks clean! No issues found.')); return; } const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); const ask = (question) => { return new Promise((resolve) => { rl.question(question, (answer) => { resolve(answer.trim().toLowerCase()); }); }); }; console.log(chalk.cyan.bold('\nšŸ”§ Would you like to optimize your codebase?')); const optimize = await ask('šŸ’¬ (yes/no): '); if (optimize === 'yes' || optimize === 'y') { console.log(chalk.cyan('\nšŸ”§ Starting optimization process...')); if (results.comments && results.comments.length > 0) { console.log(chalk.cyan('\nšŸ’¬ Would you like to remove comments?')); const removeComments = await ask('šŸ’¬ (yes/no): '); if (removeComments === 'yes' || removeComments === 'y') { console.log(chalk.cyan('\nšŸ’¬ Attempting to remove comments...')); const commentsByFile = {}; results.comments.forEach(comment => { if (!commentsByFile[comment.file]) { commentsByFile[comment.file] = []; } commentsByFile[comment.file].push(comment); }); let totalRemoved = 0; let totalSkipped = 0; for (const [file, comments] of Object.entries(commentsByFile)) { try { const code = fs.readFileSync(file, 'utf-8'); const result = fixComments(code, comments); fs.writeFileSync(file, result.code, 'utf-8'); totalRemoved += result.stats.removed; totalSkipped += result.stats.skipped; if (result.stats.skipped > 0) { console.log(` Skipped ${result.stats.skipped} comment${result.stats.skipped !== 1 ? 's' : ''} in ${path.basename(file)} (potential syntax issue)`); } } catch (error) { console.error(` Error processing ${path.basename(file)}: ${error.message}`); totalSkipped += comments.length; } } if (totalSkipped > 0) { console.log(chalk.yellow(`āš ļø Skipped ${totalSkipped} comments due to potential syntax issues or batch failure.`)); } if (totalRemoved > 0) { console.log(chalk.green(`āœ… Successfully removed ${totalRemoved} comments.`)); } } } if (results.unusedVariables && results.unusedVariables.length > 0) { console.log(chalk.cyan('\nšŸ” Would you like to remove unused variables and imports?')); const removeUnused = await ask('šŸ’¬ (yes/no): '); if (removeUnused === 'yes' || removeUnused === 'y') { console.log(chalk.cyan('\nšŸ” Attempting to remove unused variables and imports...')); const unusedByFile = {}; results.unusedVariables.forEach(item => { if (!unusedByFile[item.file]) { unusedByFile[item.file] = []; } unusedByFile[item.file].push(item); }); let totalRemoved = 0; let totalSkipped = 0; for (const [file, items] of Object.entries(unusedByFile)) { try { const fileContent = fs.readFileSync(file, 'utf-8'); const lines = fileContent.split('\n'); const removals = []; items.forEach(item => { try { if (item.type === 'variable') { const lineIndex = item.line - 1; const line = lines[lineIndex]; if (line.includes(`let ${item.name}`) || line.includes(`var ${item.name}`) || line.includes(`const ${item.name}`)) { if (line.trim().startsWith('let') || line.trim().startsWith('var') || line.trim().startsWith('const')) { if (!line.includes(',')) { removals.push({ line: lineIndex, content: line }); } else { console.log(chalk.yellow(` āš ļø Skipped complex variable declaration: ${item.name} in ${path.basename(file)}:${item.line}`)); totalSkipped++; } } else { console.log(chalk.yellow(` āš ļø Skipped variable in complex context: ${item.name} in ${path.basename(file)}:${item.line}`)); totalSkipped++; } } else { console.log(chalk.yellow(` āš ļø Variable declaration not found as expected: ${item.name} in ${path.basename(file)}:${item.line}`)); totalSkipped++; } } else if (item.type === 'import' || item.type === 'require') { const lineIndex = item.line - 1; const line = lines[lineIndex]; if (item.type === 'import' && line.includes(`import ${item.name}`) || line.includes(`import { ${item.name}`) || line.includes(`import {${item.name}`)) { if (line.includes(',')) { console.log(chalk.yellow(` āš ļø Skipped complex import statement: ${item.name} in ${path.basename(file)}:${item.line}`)); totalSkipped++; } else { removals.push({ line: lineIndex, content: line }); } } else if (item.type === 'require' && line.includes(`= require('${item.source}')`)) { removals.push({ line: lineIndex, content: line }); } else { console.log(chalk.yellow(` āš ļø Import/require statement not found as expected: ${item.name} in ${path.basename(file)}:${item.line}`)); totalSkipped++; } } else { console.log(chalk.yellow(` āš ļø Unknown item type: ${item.type} for ${item.name} in ${path.basename(file)}:${item.line}`)); totalSkipped++; } } catch (itemError) { console.error(` Error processing item ${item.name} in ${path.basename(file)}: ${itemError.message}`); totalSkipped++; } }); if (removals.length > 0) { removals.sort((a, b) => b.line - a.line); for (const removal of removals) { lines.splice(removal.line, 1); totalRemoved++; } fs.writeFileSync(file, lines.join('\n'), 'utf-8'); console.log(chalk.green(` āœ… Removed ${removals.length} unused items from ${path.basename(file)}`)); } } catch (fileError) { console.error(` Error processing file ${path.basename(file)}: ${fileError.message}`); totalSkipped += items.length; } } if (totalSkipped > 0) { console.log(chalk.yellow(`āš ļø Skipped ${totalSkipped} unused items due to complexity or potential syntax issues.`)); } if (totalRemoved > 0) { console.log(chalk.green(`āœ… Successfully removed ${totalRemoved} unused items.`)); } } } console.log(chalk.green('\nāœ… All selected optimizations have been applied!')); console.log(chalk.cyan.bold('šŸš€ Your codebase is now faster and cleaner.')); } rl.close(); } export default promptFix;