Files
router-lists-ui/frontend/src/lib/asn.js
T

87 lines
2.4 KiB
JavaScript

// Утилиты для получения названия ASN с кэшем в localStorage
const CACHE_KEY = 'asnNameCache.v1';
const DEFAULT_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 дней
function readCache() {
try {
const raw = localStorage.getItem(CACHE_KEY);
if (!raw) return {};
const data = JSON.parse(raw);
return typeof data === 'object' && data ? data : {};
} catch {
return {};
}
}
function writeCache(cache) {
try {
localStorage.setItem(CACHE_KEY, JSON.stringify(cache));
} catch { /* no-op */ }
}
function getCached(asn) {
const cache = readCache();
const entry = cache[String(asn)];
if (!entry) return null;
if (Date.now() > (entry.ts || 0)) return null;
return entry.name || null;
}
function setCached(asn, name, ttlMs = DEFAULT_TTL_MS) {
const cache = readCache();
cache[String(asn)] = { name: String(name || '').trim(), ts: Date.now() + ttlMs };
writeCache(cache);
}
async function fetchFromBGPView(asn) {
try {
const url = `https://api.bgpview.io/asn/AS${asn}`;
const res = await fetch(url, { method: 'GET' });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
const name = json?.data?.name || json?.data?.description || '';
return String(name || '').trim() || null;
} catch {
return null;
}
}
async function fetchFromRIPE(asn) {
try {
const url = `https://stat.ripe.net/data/as-overview/data.json?resource=AS${asn}`;
const res = await fetch(url, { method: 'GET' });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
const name = json?.data?.holder || json?.data?.name || '';
return String(name || '').trim() || null;
} catch {
return null;
}
}
export async function getAsnName(asn, { ttlMs = DEFAULT_TTL_MS } = {}) {
const key = String(asn).trim();
if (!/^[0-9]+$/.test(key)) return null;
const cached = getCached(key);
if (cached) return cached;
// попытаемся получить из провайдеров
const providers = [fetchFromBGPView, fetchFromRIPE];
for (const p of providers) {
const name = await p(key);
if (name) {
setCached(key, name, ttlMs);
return name;
}
}
// Закэшируем пустой ответ на короткое время, чтобы не долбить API
setCached(key, '', 60 * 60 * 1000); // 1 час
return null;
}
export function getAsnNameSync(asn) {
return getCached(asn);
}