UNPKG

cyclic-dependency-fixer

Version:

AI-powered tool to detect and fix circular dependencies in JavaScript/TypeScript projects. Features intelligent refactoring with Claude/GPT-4, codebase pattern learning, and context-aware fix recommendations

151 lines (143 loc) 5.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AIRefactoringGenerator = void 0; const types_1 = require("../../domain/models/types"); class AIRefactoringGenerator { constructor(aiProvider, fileSystem) { this.aiProvider = aiProvider; this.fileSystem = fileSystem; } async generateRefactoring(cycle, modules, strategy) { if (!this.aiProvider.isAvailable()) { return null; } const cycleCode = await this.extractFullCycleCode(cycle, modules); const prompt = this.buildRefactoringPrompt(cycle, cycleCode, strategy); const response = await this.aiProvider.generateCode({ prompt, maxTokens: 4096, temperature: 0.2, systemPrompt: `You are an expert TypeScript refactoring assistant. Generate complete, production-ready refactoring code that: 1. Fixes the circular dependency using the specified strategy 2. Maintains type safety 3. Follows SOLID principles 4. Preserves existing functionality 5. Uses clear, descriptive naming Respond in JSON format: { "strategy": "strategy name", "codeSnippets": [ { "filePath": "path/to/file.ts", "code": "complete code content", "description": "what this does", "isNewFile": boolean } ], "instructions": ["step 1", "step 2", ...], "explanation": "detailed explanation", "impact": "low|medium|high" }`, }); return this.parseRefactoringSuggestion(response.content); } async generateManualSteps(cycle, modules, strategy) { const suggestion = await this.generateRefactoring(cycle, modules, strategy); if (!suggestion) { return []; } return suggestion.codeSnippets.map((snippet) => ({ description: snippet.description, file: snippet.filePath, code: snippet.code, })); } async explainCycle(cycle, modules) { if (!this.aiProvider.isAvailable()) { return 'AI analysis not available. Configure an AI provider to get detailed explanations.'; } const cycleCode = await this.extractFullCycleCode(cycle, modules); const prompt = `Analyze this circular dependency and explain: 1. Why it exists (root cause) 2. What problems it might cause 3. How to prevent similar issues in the future **Circular Dependency:** ${this.describeCycle(cycle)} **Code:** ${cycleCode} Provide a clear, concise explanation for developers.`; const response = await this.aiProvider.analyze({ prompt, maxTokens: 1024, temperature: 0.4, }); return response.content; } async extractFullCycleCode(cycle, modules) { const codeSnippets = []; const uniquePaths = cycle.paths.slice(0, -1); for (const path of uniquePaths) { const module = modules.get(path); if (!module) continue; try { const content = await this.fileSystem.readFile(path); codeSnippets.push(`// File: ${path}\n${content}`); } catch { continue; } } return codeSnippets.join('\n\n// ============================================\n\n'); } buildRefactoringPrompt(cycle, cycleCode, strategy) { const strategyDescription = this.getStrategyDescription(strategy); return `Generate complete refactoring code to fix this circular dependency using the ${strategy} strategy. **Strategy:** ${strategy} ${strategyDescription} **Circular Dependency:** ${this.describeCycle(cycle)} **Current Code:** ${cycleCode} Generate COMPLETE, WORKING code for all files that need to be created or modified. Include proper TypeScript types and imports.`; } getStrategyDescription(strategy) { const descriptions = { [types_1.FixStrategy.EXTRACT_SHARED]: 'Extract common code into a new shared module that both files can import without creating a cycle.', [types_1.FixStrategy.DYNAMIC_IMPORT]: 'Convert static imports to dynamic imports to break the cycle at runtime.', [types_1.FixStrategy.DEPENDENCY_INJECTION]: 'Use dependency injection pattern to inject dependencies rather than importing them directly.', [types_1.FixStrategy.MOVE_CODE]: 'Move code between files to eliminate the circular reference while maintaining functionality.', [types_1.FixStrategy.BARREL_FILE]: 'Create a barrel file (index.ts) to centralize exports and break the cycle.', }; return descriptions[strategy] || 'Fix the circular dependency.'; } describeCycle(cycle) { const lines = []; lines.push(`Files involved: ${cycle.paths.length - 1}`); cycle.paths.forEach((path, i) => { if (i < cycle.paths.length - 1) { lines.push(` ${i + 1}. ${path}`); } }); lines.push('\nImport chain:'); cycle.edges.forEach((edge) => { lines.push(` ${edge.from} -> ${edge.to} (line ${edge.importInfo.line}, imports: ${edge.importInfo.identifiers.join(', ')})`); }); return lines.join('\n'); } parseRefactoringSuggestion(content) { try { const jsonMatch = content.match(/\{[\s\S]*\}/); if (jsonMatch) { return JSON.parse(jsonMatch[0]); } } catch { } return null; } } exports.AIRefactoringGenerator = AIRefactoringGenerator; //# sourceMappingURL=AIRefactoringGenerator.js.map