UNPKG

ropods-cashify

Version:

Modern, lightweight currency conversion library with real-time exchange rates, INR support, and free API integration. Production-ready TypeScript library for RoPods organization with zero dependencies and comprehensive testing.

174 lines 5.8 kB
/** * RoPods Rate Fetcher Service * Fetches latest exchange rates from multiple sources */ export class RoPodsRateFetcher { static instance; cache = new Map(); cacheTimeout = 5 * 60 * 1000; // 5 minutes cache sources = [ { name: 'ExchangeRate-API', url: 'https://api.exchangerate-api.com/v4/latest/', }, { name: 'Fixer.io', url: 'http://data.fixer.io/api/latest', apiKey: process.env['FIXER_API_KEY'], }, { name: 'CurrencyAPI', url: 'https://api.currencyapi.com/v3/latest', apiKey: process.env['CURRENCY_API_KEY'], }, ]; static getInstance() { if (!RoPodsRateFetcher.instance) { RoPodsRateFetcher.instance = new RoPodsRateFetcher(); } return RoPodsRateFetcher.instance; } /** * Get latest exchange rates for RoPods * @param base Base currency (default: USD) * @param currencies Array of currencies to fetch * @returns Promise<ExchangeRates> */ async getLatestRates(base = 'USD', currencies = ['EUR', 'GBP', 'INR', 'JPY', 'CAD', 'AUD', 'CHF']) { const cacheKey = `${base}-${currencies.join(',')}`; const cached = this.cache.get(cacheKey); if (cached && this.isCacheValid(cached)) { console.log('[RoPods Cashify] Using cached rates'); return cached; } try { const rates = await this.fetchFromSources(base, currencies); this.cache.set(cacheKey, rates); console.log('[RoPods Cashify] Fetched fresh rates from', rates.source); return rates; } catch (error) { console.warn('[RoPods Cashify] Failed to fetch rates, using fallback'); return this.getFallbackRates(base); } } /** * Get RoPods specific currency rates (INR, USD focus) */ async getRoPodsRates() { const ropodsCurrencies = ['INR', 'USD', 'EUR', 'GBP', 'AED', 'SGD', 'JPY']; return this.getLatestRates('USD', ropodsCurrencies); } async fetchFromSources(base, currencies) { for (const source of this.sources) { try { const rates = await this.fetchFromSource(source, base, currencies); if (rates) return rates; } catch (error) { console.warn(`[RoPods Cashify] Failed to fetch from ${source.name}:`, error); continue; } } throw new Error('All rate sources failed'); } async fetchFromSource(source, base, currencies) { let url = source.url; if (source.name === 'ExchangeRate-API') { url = `${source.url}${base}`; } else if (source.name === 'Fixer.io' && source.apiKey) { url = `${source.url}?access_key=${source.apiKey}&base=${base}&symbols=${currencies.join(',')}`; } else if (source.name === 'CurrencyAPI' && source.apiKey) { url = `${source.url}?apikey=${source.apiKey}&base_currency=${base}&currencies=${currencies.join(',')}`; } const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const data = await response.json(); if (source.name === 'ExchangeRate-API') { return { base: data.base, rates: this.filterRates(data.rates, currencies), lastUpdated: new Date().toISOString(), source: source.name, }; } if (source.name === 'Fixer.io') { return { base: data.base, rates: this.filterRates(data.rates, currencies), lastUpdated: data.date || new Date().toISOString(), source: source.name, }; } return null; } filterRates(allRates, currencies) { const filtered = {}; for (const currency of currencies) { if (allRates[currency]) { filtered[currency] = allRates[currency]; } } return filtered; } isCacheValid(cached) { const cacheTime = new Date(cached.lastUpdated).getTime(); return Date.now() - cacheTime < this.cacheTimeout; } getFallbackRates(base) { // Fallback rates updated as of January 2025 (approximate) const fallbackRates = { USD: { EUR: 0.95, GBP: 0.82, INR: 85.20, JPY: 157.50, CAD: 1.44, AUD: 1.62, CHF: 0.92, AED: 3.67, SGD: 1.37, }, EUR: { USD: 1.05, GBP: 0.86, INR: 89.60, JPY: 165.40, CAD: 1.51, AUD: 1.70, CHF: 0.97, }, }; return { base, rates: fallbackRates[base] || fallbackRates['USD'] || {}, lastUpdated: new Date().toISOString(), source: 'RoPods Fallback', }; } /** * Clear cache to force fresh fetch */ clearCache() { this.cache.clear(); console.log('[RoPods Cashify] Cache cleared'); } /** * Get cache status */ getCacheInfo() { return Array.from(this.cache.entries()).map(([key, value]) => ({ key, lastUpdated: value.lastUpdated, source: value.source, })); } } // Export singleton instance export const ropodsRateFetcher = RoPodsRateFetcher.getInstance(); //# sourceMappingURL=rate-fetcher.js.map