resetea.net/api/routes/stats.js

55 lines
1.6 KiB
JavaScript

'use strict';
const { get } = require('../services/stats');
// Whitelist estricta: solo claves conocidas salen en la respuesta
const PROVIDER_LABELS = {
instagram: 'Instagram',
facebook: 'Facebook',
twitter_x: 'X (Twitter)',
linkedin: 'LinkedIn',
tiktok: 'TikTok',
snapchat: 'Snapchat',
microsoft: 'Microsoft',
apple: 'Apple',
google: 'Google',
amazon: 'Amazon',
reddit: 'Reddit',
discord: 'Discord',
};
const VALID_DATE = /^\d{4}-\d{2}-\d{2}$/;
function safeInt(v) {
const n = Math.floor(Number(v));
return Number.isFinite(n) && n >= 0 ? n : 0;
}
module.exports = (req, res) => {
const raw = get();
// Solo proveedores de la whitelist — cualquier clave extraña en stats.json se descarta
const providers = Object.entries(raw.by_provider || {})
.filter(([key]) => Object.prototype.hasOwnProperty.call(PROVIDER_LABELS, key))
.map(([key, v]) => ({
name: PROVIDER_LABELS[key], // nombre viene de whitelist, no del fichero
icon_key: key, // clave corta para iconos en cliente (solo a-z_)
sent: safeInt(v.sent),
redirected: safeInt(v.redirected),
total: safeInt(v.sent) + safeInt(v.redirected),
}))
.sort((a, b) => b.total - a.total);
// updated: solo si es una fecha válida YYYY-MM-DD, si no null
const updated = typeof raw.updated === 'string' && VALID_DATE.test(raw.updated)
? raw.updated
: null;
res.json({
total_sent: safeInt(raw.total_sent),
total_redirected: safeInt(raw.total_redirected),
total_searches: safeInt(raw.total_searches),
providers,
updated,
});
};