UNPKG

epd

Version:

Enhanced peer dependency resolution for npm, yarn, and pnpm

125 lines (120 loc) 4.25 kB
/** * Enhanced Peer Dependencies (epd) * Copyright (c) 2024 Enhanced Peer Dependencies (epd) * Licensed under the MIT License */ export class AIResolver { apiKey; endpoint = 'https://api.openai.com/v1/chat/completions'; constructor(apiKey) { this.apiKey = apiKey || process.env.EPD_AI_API_KEY; } async resolveConflicts(request) { if (!this.apiKey) { return this.fallbackResolution(request); } try { const prompt = this.buildPrompt(request); const response = await this.callAI(prompt); return this.parseAIResponse(response, request.conflicts); } catch (error) { console.warn('⚠️ AI resolution failed, using fallback:', error?.message || error); return this.fallbackResolution(request); } } buildPrompt(request) { const { conflicts, projectContext, preferences } = request; return `You are an expert JavaScript dependency resolver. Analyze these peer dependency conflicts and provide optimal resolutions. PROJECT CONTEXT: - Package Manager: ${projectContext.packageManager} - Monorepo: ${projectContext.isMonorepo} - Framework: ${projectContext.framework || 'Unknown'} CONFLICTS: ${conflicts.map(c => ` Package: ${c.package} Required Versions: ${c.requiredVersions.join(', ')} Required By: ${c.requiredBy.join(', ')} Current: ${c.currentVersion || 'Not installed'} `).join('\n')} PREFERENCES: - Prefer Stable: ${preferences?.preferStable ?? true} - Risk Tolerance: ${preferences?.riskTolerance ?? 'medium'} Provide JSON response with this structure: { "resolutions": [ { "package": "package-name", "recommendedVersion": "1.2.3", "confidence": 0.95, "reasoning": "Brief explanation", "alternatives": [ { "version": "1.2.2", "pros": ["Compatible with all requirements"], "cons": ["Older version"] } ] } ] } Focus on compatibility, stability, and minimal breaking changes.`; } async callAI(prompt) { const response = await fetch(this.endpoint, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'gpt-3.5-turbo', messages: [{ role: 'user', content: prompt }], temperature: 0.1, max_tokens: 2000 }) }); if (!response.ok) { throw new Error(`AI API error: ${response.status}`); } const data = await response.json(); return data.choices[0]?.message?.content || ''; } parseAIResponse(response, conflicts) { try { const parsed = JSON.parse(response); return parsed.resolutions || []; } catch { // Fallback if JSON parsing fails return this.fallbackResolution({ conflicts }); } } fallbackResolution(request) { return request.conflicts.map(conflict => ({ package: conflict.package, recommendedVersion: this.selectBestVersion(conflict.requiredVersions), confidence: 0.7, reasoning: 'Selected most compatible version using heuristics', alternatives: conflict.requiredVersions.slice(0, 2).map(v => ({ version: v, pros: ['Available option'], cons: ['May have compatibility issues'] })) })); } selectBestVersion(versions) { // Simple heuristic: prefer the highest version that satisfies most requirements return versions.sort((a, b) => this.compareVersions(b, a))[0]; } compareVersions(a, b) { const cleanA = a.replace(/[^0-9.]/g, ''); const cleanB = b.replace(/[^0-9.]/g, ''); return cleanA.localeCompare(cleanB, undefined, { numeric: true }); } } export async function resolveWithAI(conflicts, projectContext, preferences) { const resolver = new AIResolver(); return resolver.resolveConflicts({ conflicts, projectContext, preferences }); } //# sourceMappingURL=ai-resolver.js.map