Files

47 lines
1.7 KiB
JavaScript
Raw Permalink Normal View History

2026-10-29 11:57:29 +01:00
// Generated, do not edit. sha256:2f3082db0160d4179616e98a296a8ab4a5647a67cfd48f2cc38d5f27a7ead0fa
import { priceSeriesExport } from './data/price-history.js';
import { getBaseCurrency } from './data/portfolio.js';
export const CSV_COLUMNS = ['instrument', 'source', 'quote', 'unit', 'resolution', 'observed_at_utc', 'fetched_at_utc', 'price'];
const iso = (v) => {
if (!v) return '';
const ms = Date.parse(/[zZ]|[+-]\d\d:?\d\d$/.test(v) || v.length === 10 ? v : `${v}Z`);
return Number.isFinite(ms) ? new Date(ms).toISOString() : '';
};
const cel = (v) => {
const s = v == null ? '' : String(v);
return /[",\r\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
};
export function priceHistoryCsv(rows, quote) {
const regels = [CSV_COLUMNS.join(',')];
for (const r of rows) {
const observed = iso(r.observedAt);
const price = Number(r.fiatPrice);
if (!observed || !Number.isFinite(price) || price <= 0) continue;
regels.push([
`${r.kind}:${String(r.symbol || '').toUpperCase()}`, r.source, quote, r.kind === 'metal' ? 'g' : '',
r.resolution, observed, iso(r.createdAt), price,
].map(cel).join(','));
}
return regels.join('\n') + '\n';
}
function bestandsnaam() {
const d = new Date();
const p = n => String(n).padStart(2, '0');
return `koershistorie-${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}.csv`;
}
export function exportPriceHistory(res) {
const body = Buffer.from(priceHistoryCsv(priceSeriesExport(), getBaseCurrency()), 'utf-8');
res.writeHead(200, {
'Content-Type': 'text/csv; charset=utf-8',
'Content-Disposition': `attachment; filename="${bestandsnaam()}"`,
'Content-Length': body.length,
'Cache-Control': 'no-store',
'X-Content-Type-Options': 'nosniff',
});
res.end(body);
}