UNPKG

growwapi

Version:
83 lines (82 loc) 2.62 kB
import fs from 'fs'; import fsPromises from 'fs/promises'; import path from 'path'; import os from 'os'; import crypto from 'crypto'; import { FILECACHE_TTL } from '../config'; const CACHE_FOLDER = 'csv-cache'; const memoryCache = {}; function getCacheFilePath(url) { const hash = crypto.createHash('md5').update(url).digest('hex'); const cacheDir = path.join(os.tmpdir(), CACHE_FOLDER); return path.join(cacheDir, `${hash}.csv`); } async function ensureCacheDir(filePath) { const dir = path.dirname(filePath); await fsPromises.mkdir(dir, { recursive: true }); } async function isCacheValid(filePath, ttl) { try { const stat = await fsPromises.stat(filePath); const age = Date.now() - new Date(stat.mtime).getTime(); return age < ttl; } catch { return false; } } async function deleteFileIfExists(filePath) { try { await fsPromises.unlink(filePath); } catch { return; } } async function downloadCSVToFile(url, filePath) { const response = await fetch(url); if (!response.ok || !response.body) { throw new Error(`Failed to fetch CSV: ${response.status} ${response.statusText}`); } const writer = fs.createWriteStream(filePath); const reader = response.body.getReader(); return new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); (async () => { try { while (true) { const { done, value } = await reader.read(); if (done) break; writer.write(Buffer.from(value)); } writer.end(); } catch (error) { writer.destroy(); reject(error); } })(); }); } export async function fetchCSV(url, ttl = FILECACHE_TTL) { const cacheFile = getCacheFilePath(url); await ensureCacheDir(cacheFile); const validCache = await isCacheValid(cacheFile, ttl); if (validCache) { if (memoryCache[cacheFile]) { return { fileContent: memoryCache[cacheFile] }; } else { const fileContent = await fsPromises.readFile(cacheFile, 'utf-8'); memoryCache[cacheFile] = fileContent; return { fileContent }; } } await deleteFileIfExists(cacheFile); await downloadCSVToFile(url, cacheFile); const fileContent = await fsPromises.readFile(cacheFile, 'utf-8'); memoryCache[cacheFile] = fileContent; return { fileContent }; }