growwapi
Version:
NodeJS SDK for Groww trading APIs
83 lines (82 loc) • 2.62 kB
JavaScript
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 };
}