UNPKG

@dharshansr/gitgenius

Version:

AI-powered commit message generator with enhanced features

101 lines (95 loc) 3.85 kB
import axios from 'axios'; import { SecurityUtils } from '../utils/SecurityUtils.js'; import { SecurityManager } from '../core/SecurityConfig.js'; export class GeminiProvider { constructor(apiKey) { this.name = 'gemini'; // Validate API key if (!SecurityUtils.validateApiKey(apiKey)) { throw new Error('Invalid API key format'); } this.apiKey = apiKey; this.securityManager = new SecurityManager(); } async generateCommitMessage(diff, type, detailed) { const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=${this.apiKey}`; // Enforce HTTPS this.securityManager.validateUrl(apiUrl); // Check rate limiting if (!this.securityManager.checkRateLimit('gemini')) { throw new Error('Rate limit exceeded. Please try again later.'); } // Sanitize input const sanitizedDiff = this.securityManager.sanitizeInput(diff); const prompt = this.buildPrompt(sanitizedDiff, type, detailed); // Check API key rotation const rotationReminder = this.securityManager.checkApiKeyRotation('gemini'); if (rotationReminder) { console.warn(rotationReminder); } // Audit log this.securityManager.auditLog('ai_request', { provider: 'gemini', model: 'gemini-1.5-flash-latest', type: type || 'default', detailed: detailed || false }); try { const secureConfig = this.securityManager.getSecureRequestConfig(); const response = await axios.post(apiUrl, { contents: [ { parts: [ { text: prompt } ] } ], generationConfig: { temperature: 0.7, maxOutputTokens: detailed ? 300 : 150 } }, secureConfig); const message = response.data.candidates[0].content.parts[0].text.trim(); // Validate the generated commit message if (!SecurityUtils.validateCommitMessage(message)) { throw new Error('Generated commit message failed security validation'); } return message; } catch (error) { if (axios.isAxiosError(error)) { if (error.response?.status === 403) { throw new Error('Invalid Gemini API key'); } if (error.response?.status === 429) { throw new Error('Gemini API rate limit exceeded. Please try again later.'); } throw new Error(`Gemini API error: ${error.response?.data?.error?.message || error.message}`); } throw error; } } buildPrompt(diff, type, detailed) { const typePrefix = type ? `[${type.toUpperCase()}] ` : ''; if (detailed) { return `${typePrefix}Generate a detailed git commit message for the following changes. Follow conventional commits format with detailed description. Format: <type>(<scope>): <subject> <body> - <subject>: Brief summary (under 72 characters) - <body>: Detailed explanation of what changed, why it was changed, and any important notes Git diff: ${diff} Return the commit message only, no additional text.`; } return `${typePrefix}Generate a concise git commit message for the following changes. Follow conventional commits format and keep it under 72 characters. Only return the commit message, nothing else. Git diff: ${diff}`; } } //# sourceMappingURL=GeminiProvider.js.map