UNPKG

@tamtamchik/exchanger

Version:

Simple and free npm library to get realtime currency exchange rates.

94 lines (92 loc) 3.1 kB
// src/errors.ts var ApplicationError = class extends Error { constructor(errorType, errorMessage) { super(errorMessage); this.name = errorType; this.captureStackTrace(); } captureStackTrace() { if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } }; var NetworkError = class extends ApplicationError { constructor(message) { super("NetworkError", message); } }; var ServerError = class extends ApplicationError { constructor(message) { super("ServerError", message); } }; var DataError = class extends ApplicationError { constructor(message) { super("DataError", message); } }; // src/index.ts var YAHOO_FINANCE_BASE_URL = "https://query1.finance.yahoo.com/v8/finance/chart/"; var YAHOO_FINANCE_QUERY_PARAMS = "=X?region=US&lang=en-US&includePrePost=false&interval=2m&useYfid=true&range=1d&corsDomain=finance.yahoo.com&.tsrc=finance"; var rateCache = /* @__PURE__ */ new Map(); function buildRateUrl(fromCurrency, toCurrency) { return `${YAHOO_FINANCE_BASE_URL}${fromCurrency.toUpperCase()}${toCurrency.toUpperCase()}${YAHOO_FINANCE_QUERY_PARAMS}`; } function isCacheValid(cachedRate, cacheDurationMs) { return Date.now() - cachedRate.timestamp < cacheDurationMs; } function getCachedRate(fromCurrency, toCurrency, cacheDurationMs) { if (!cacheDurationMs) return null; const cacheKey = `${fromCurrency}-${toCurrency}`; const cachedRate = rateCache.get(cacheKey); return cachedRate && isCacheValid(cachedRate, cacheDurationMs) ? cachedRate.value : null; } async function fetchExchangeRateResponse(rateUrl) { const response = await fetch(rateUrl); if (!response.ok) { throw new ServerError(`HTTP ${response.status}: ${response.statusText}`); } return response; } function extractRateFromResponse(response) { const rate = response.chart?.result[0]?.meta?.regularMarketPrice; if (typeof rate !== "number" || isNaN(rate)) { throw new DataError('Invalid or missing "regularMarketPrice" in response.'); } return rate; } async function fetchExchangeRate(rateUrl) { try { const response = await fetchExchangeRateResponse(rateUrl); const responseData = await response.json(); return extractRateFromResponse(responseData); } catch (error) { if (error instanceof ServerError || error instanceof DataError) { throw error; } throw new NetworkError( `Failed to fetch exchange rate: ${error instanceof Error ? error.message : String(error)}` ); } } async function getExchangeRate(fromCurrency, toCurrency, options = {}) { const { cacheDurationMs } = options; const cachedRate = getCachedRate(fromCurrency, toCurrency, cacheDurationMs); if (cachedRate !== null) { return cachedRate; } const rateUrl = buildRateUrl(fromCurrency, toCurrency); const rate = await fetchExchangeRate(rateUrl); if (cacheDurationMs) { const cacheKey = `${fromCurrency}-${toCurrency}`; rateCache.set(cacheKey, { value: rate, timestamp: Date.now() }); } return rate; } export { DataError, NetworkError, ServerError, getExchangeRate };