// API module for fetching and caching Zenrus data
// Интерфейс для данных с Zenrus
export interface ZenrusData {
usd: string;
eur: string;
brent: string;
brentRub: string;
}
// Константа актуальности данных (60 минут в миллисекундах)
const CACHE_TTL_MS = 60 * 60 * 1000;
// Кеш данных
let cachedData: ZenrusData | null = null;
let cacheTimestamp: number | null = null;
// Функция парсинга данных из currents.js (экспортируется для тестирования)
export function parseZenrusData(jsContent: string): ZenrusData {
// Парсим JavaScript объект: var current = {0:81.08,1:94.15,2:62.17,...}
const match = jsContent.match(/var current = \{([^}]+)\}/);
if (!match) {
return {
usd: "N/A",
eur: "N/A",
brent: "N/A",
brentRub: "N/A",
};
}
// Парсим пары ключ:значение
const pairs = match[1].split(",");
const data: Record<number, number> = {};
pairs.forEach((pair) => {
const [key, value] = pair.split(":");
const keyNum = parseInt(key.trim());
const valueNum = parseFloat(value.trim());
if (!isNaN(keyNum) && !isNaN(valueNum)) {
data[keyNum] = valueNum;
}
});
// Индексы: 0 = USD, 1 = EUR, 2 = Brent (USD)
const usd = data[0];
const eur = data[1];
const brentUsd = data[2];
// Вычисляем Brent в рублях
const brentRub = usd && brentUsd ? Math.round(usd * brentUsd) : undefined;
return {
usd: usd !== undefined ? usd.toFixed(2) : "N/A",
eur: eur !== undefined ? eur.toFixed(2) : "N/A",
brent: brentUsd !== undefined ? brentUsd.toFixed(2) : "N/A",
brentRub: brentRub !== undefined ? brentRub.toString() : "N/A",
};
}
// Функция для получения данных с zenrus.ru с кешированием
export async function fetchZenrusData(): Promise<ZenrusData> {
const now = Date.now();
// Проверяем, есть ли актуальные данные в кеше
if (cachedData && cacheTimestamp && (now - cacheTimestamp) < CACHE_TTL_MS) {
return cachedData;
}
// Получаем данные из currents.js с Unix timestamp для cache busting
const timestamp = Math.floor(Date.now() / 1000);
const response = await fetch(`https://zenrus.ru/build/js/currents.js?v${timestamp}`);
const jsContent = await response.text();
// Парсим и кешируем данные
cachedData = parseZenrusData(jsContent);
cacheTimestamp = now;
return cachedData;
}
// Функция для очистки кеша (может быть полезна для тестирования)
export function clearCache(): void {
cachedData = null;
cacheTimestamp = null;
}
// Функция для получения информации о кеше
export function getCacheInfo(): { isCached: boolean; age: number | null } {
if (!cacheTimestamp) {
return { isCached: false, age: null };
}
const age = Date.now() - cacheTimestamp;
return { isCached: true, age };
}