UNPKG

@mixxtor/currencyx-js

Version:

Modern TypeScript currency converter with type inference and multiple providers (Google Finance, Fixer.io). Framework agnostic with clean architecture.

389 lines (291 loc) 9.99 kB
# CurrencyX > Modern TypeScript currency converter with type inference and multiple exchanges. Framework agnostic with clean architecture and minimal dependencies. [![npm version](https://badge.fury.io/js/@mixxtor%2Fcurrencyx-js.svg)](https://badge.fury.io/js/@mixxtor%2Fcurrencyx-js) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## ✨ Features - 🚀 **Modern TypeScript** - Full type safety with intelligent inference - 🔄 **Multiple Exchanges** - Google Finance, Fixer.io, and extensible architecture - 🎯 **Type Inference** - Smart exchange and configuration type inference - 🧩 **Framework Agnostic** - Works with any JavaScript/TypeScript project - 📦 **Minimal Dependencies** - Only axios and cheerio for web scraping - 🔧 **Extensible** - Easy to add custom exchanges - 🌐 **Clean APIs** - Intuitive object-based and positional parameter APIs - ⚡ **High Performance** - Optimized for speed and memory efficiency ## 📦 Installation ```bash npm install @mixxtor/currencyx-js ``` ## 🚀 Quick Start ```typescript import { createCurrency, exchanges } from '@mixxtor/currencyx-js' // Create currency service with multiple exchanges const currency = createCurrency({ default: 'google', exchanges: { google: exchanges.google({ base: 'USD' }), fixer: exchanges.fixer({ accessKey: 'your-api-key' }), }, }) // Convert currency const result = await currency.convert({ amount: 100, from: 'USD', to: 'EUR', }) if (result.success) { console.log(`$100 USD = €${result.result} EUR`) console.log(`Exchange rate: ${result.info.rate}`) } ``` ## 📚 API Reference ### Core Methods (Object Parameters) #### `convert(params: ConvertParams)` Convert currency with explicit object parameters: ```typescript const result = await currency.convert({ amount: 100, from: 'USD', to: 'EUR', }) // Result structure interface ConversionResult { success: boolean query: { amount: number; from: string; to: string } result?: number info?: { rate: number; timestamp: number } date: string error?: { info: string; type?: string } } ``` #### `getExchangeRates(params: ExchangeRatesParams)` Get exchange rates with object parameters: ```typescript const rates = await currency.getExchangeRates({ base: 'USD', codes: ['EUR', 'GBP', 'JPY'], }) // Result structure interface ExchangeRatesResult { success: boolean base: string rates: Record<string, number> timestamp: number date: string error?: { info: string; type?: string } } ``` ### Convenience Methods (Positional Parameters) #### `latestRates({ base, codes })` Shorthand for getting rates: ```typescript const rates = await currency.latestRates({ base: 'USD', codes: ['EUR', 'GBP'] }) ``` ### Exchange Management ```typescript // Switch exchanges currency.use('fixer') // Get current exchange provider const current = currency.getCurrentExchange() // 'fixer' // List available exchanges const exchanges = currency.getAvailableExchanges() // ['google', 'fixer'] ``` ### Utility Methods ```typescript // Format currency (object parameters) const formatted = currency.formatCurrency({ amount: 1234.56, code: 'USD', locale: 'en-US' }) // Result: "$1,234.56" // Round values const rounded = currency.round(123.456789, { precision: 2, direction: 'up' }) // Result: 123.46 // Get supported currencies const currencies = await currency.getSupportedCurrencies() // Result: ['USD', 'EUR', 'GBP', 'JPY', ...] // Get current exchange provider const currentProvider = currency.getCurrentExchange() // Result: 'google' | 'fixer' | etc. // Get all available exchanges const exchanges = currency.getAvailableExchanges() // Result: ['google', 'fixer'] // Currency information utilities const allCurrencies = currency.getList() // Get all available currency information const usdInfo = currency.getByCode('USD') // Get currency info by ISO code const dollarCurrencies = currency.getBySymbol('$') // Get currency info by symbol const usCurrency = currency.getByCountry('US') // Get currency by country code const euroCurrencies = currency.filterByName('Euro') // Filter currencies by name const usCurrencies = currency.filterByCountry('US') // Filter currencies by country // Round money according to currency rules const rounded = currency.roundMoney(123.456, 'USD') // Automatically rounds according to USD rounding rules ``` ## 🔌 Exchanges ### Google Finance Exchange Free provider, no API key required: ```typescript const currency = createCurrency({ default: 'google', exchanges: { google: exchanges.google({ base: 'USD', // Base currency (default: 'USD') timeout: 5000, // Request timeout in ms (optional) }), }, }) ``` ### Fixer.io Exchange Requires API key from [fixer.io](https://fixer.io): ```typescript const currency = createCurrency({ default: 'fixer', exchanges: { fixer: exchanges.fixer({ accessKey: 'your-api-key', // Required: Your Fixer.io API key base: 'USD', // Base currency (default: 'USD' for this library, Fixer default: 'EUR') timeout: 10000, // Request timeout in ms (optional) }), }, }) ``` ## ⚙️ Configuration ### Multiple Exchanges Setup Configure multiple exchanges and switch between them: ```typescript const currency = createCurrency({ default: 'google', exchanges: { google: exchanges.google({ base: 'USD' }), fixer: exchanges.fixer({ accessKey: 'your-key' }), }, }) // Use Google Finance currency.use('google') const googleResult = await currency.convert({ amount: 100, from: 'USD', to: 'EUR' }) // Switch to Fixer.io currency.use('fixer') const fixerResult = await currency.convert({ amount: 100, from: 'USD', to: 'EUR' }) ``` ### Type Safety Full TypeScript support with intelligent type inference: ```typescript // Exchange names are type-safe const currency = createCurrency({ default: 'google', // ✅ Type-safe exchanges: { google: exchanges.google({ base: 'USD' }), fixer: exchanges.fixer({ accessKey: 'key' }), }, }) // Only valid exchange names are allowed currency.use('google') // ✅ Valid currency.use('invalid') // ❌ TypeScript error ``` ## 🛡️ Error Handling All methods return result objects with success indicators: ```typescript const result = await currency.convert({ amount: 100, from: 'USD', to: 'EUR', }) if (result.success) { console.log(`Converted: ${result.result}`) console.log(`Rate: ${result.info.rate}`) console.log(`Timestamp: ${result.info.timestamp}`) } else { console.error(`Error: ${result.error?.info}`) console.error(`Type: ${result.error?.type}`) } ``` ## 🔧 Custom Exchanges Extend the system with custom exchanges: ```typescript import { BaseCurrencyExchange } from '@mixxtor/currencyx-js' import type { ConvertParams, ExchangeRatesParams } from '@mixxtor/currencyx-js' class CustomExchange extends BaseCurrencyExchange { readonly name = 'custom' constructor(config: { base: string; apiKey?: string }) { super() this.base = config.base || 'USD' // Initialize with your config } async convert(params: ConvertParams) { try { // Your custom conversion logic const rate = await this.getConvertRate(params.from, params.to) const result = params.amount * rate return this.createConversionResult(params.amount, params.from, params.to, result, rate) } catch (error) { return this.createConversionResult(params.amount, params.from, params.to, undefined, undefined, { info: error.message, type: 'custom_error', }) } } async latestRates(params: ExchangeRatesParams) { try { // Your custom rates logic const rates = await this.fetchRatesFromAPI(params) return this.createExchangeRatesResult(params.base, rates) } catch (error) { return this.createExchangeRatesResult(params.base, {}, { info: error.message, type: 'custom_error' }) } } async getConvertRate(from: string, to: string): Promise<number> { // Implement your rate fetching logic return 0.85 // Example rate } private async fetchRatesFromAPI(params: { base: string; codes?: string[] }) { // Implement your API call logic return { EUR: 0.85, GBP: 0.73 } } } // Use your custom exchange const currency = createCurrency({ default: 'custom', exchanges: { custom: new CustomExchange({ base: 'USD', apiKey: 'your-key' }), }, }) ``` ## 📖 Examples Check the [examples](./examples) directory for more usage patterns: - [Selective API Demo](./examples/selective-api-demo.ts) - Demonstrates the API design principles ## 🔄 Migration Guide ### From v0.x to v1.x The API has been simplified and modernized: ```typescript // Old API (v0.x) const currency = new CurrencyService() currency.addProvider('google', new GoogleProvider()) const result = await currency.convert(100, 'USD', 'EUR') // New API (v1.x) const currency = createCurrency({ default: 'google', exchanges: { google: exchanges.google({ base: 'USD' }), }, }) const result = await currency.convert({ amount: 100, from: 'USD', to: 'EUR' }) ``` ## 📋 Requirements - **Node.js** >= 18.0.0 - **TypeScript** >= 4.5.0 (for TypeScript projects) ## Dependencies - **axios** - For HTTP requests to currency APIs - **cheerio** - For HTML parsing (Google Finance web scraping) ## 🤝 Contributing Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines. ## 📄 License MIT License - see [LICENSE](./LICENSE) file for details. ## 📝 Changelog See [CHANGELOG.md](./CHANGELOG.md) for version history and changes. --- <div align="center"> **[Documentation](https://github.com/mixxtor/currencyx-js#readme)** • **[Examples](./examples)** • **[Issues](https://github.com/mixxtor/currencyx-js/issues)** • **[Contributing](./CONTRIBUTING.md)** </div>