nhb-toolbox
Version:
A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.
70 lines (69 loc) • 2.48 kB
JavaScript
import { formatCurrency } from './utilities.js';
export class Currency {
#amount;
#code;
currency;
constructor(amount, code) {
this.#amount = Number(amount);
this.#code = code;
this.currency = this.format('en-US');
}
static #RATE_CACHE = new Map();
static clearRateCache() {
Currency.#RATE_CACHE.clear();
}
format(locale, code) {
return formatCurrency(this.#amount, code ?? this.#code, locale);
}
async convert(to, options) {
const key = `${this.#code}->${to}`;
if (!options?.forceRefresh && Currency.#RATE_CACHE.has(key)) {
const cachedRate = Currency.#RATE_CACHE.get(key);
return new Currency(this.#amount * cachedRate, to);
}
try {
const rate = await this.#fetchFromFrankfurter(to);
Currency.#RATE_CACHE.set(key, rate);
return new Currency(this.#amount * rate, to);
}
catch (error) {
if (options?.fallbackRate != null) {
console.warn(`Currency conversion failed (${this.#code} → ${to}): ${error?.message}. Using fallback rate...`);
return new Currency(this.#amount * options.fallbackRate, to);
}
else {
throw new Error(`Currency conversion failed (${this.#code} → ${to}): ${error?.message}`);
}
}
}
convertSync(to, rate) {
const key = `${this.#code}->${to}`;
const cachedRate = Currency.#RATE_CACHE.get(key);
if (cachedRate) {
return new Currency(this.#amount * cachedRate, to);
}
else if (rate) {
return new Currency(this.#amount * rate, to);
}
else {
return this;
}
}
async #fetchFromFrankfurter(to) {
const url = `https://api.frankfurter.app/latest?amount=1&from=${this.#code}`;
try {
const res = await fetch(url, { redirect: 'error' });
if (!res.ok) {
throw new Error(`FrankFurter Error: ${res.status}. "${res.statusText}"`);
}
const data = await res.json();
if (!data.rates?.[to]) {
throw new Error(`Currency "${to}" is not found in FrankFurter Database!`);
}
return data.rates[to];
}
catch (error) {
throw new Error(error?.message || `Failed to fetch data from FrankFurter API`);
}
}
}