Something went wrong. Try again.
a Page to view some global statistics about Modrinth modrinth-statistics.tobinio.dev
Something went wrong. Try again.
2.9 kB · 127 lines
TypeScript
at icons
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128import consola from "consola";import type { VersionCategories } from "~~/server/utils/processing/gameVersions/types";import type { ProjectStats, ProjectStatsValue,} from "~~/server/utils/processing/projects/types";import { getLatestProjectStats, getProjectStats,} from "~~/server/utils/storage";import { dateToFormatted } from "~~/utils/date";
// maps database data to a format usable by the frontendfunction mapStats( stats: ProjectStats, fn: (value: ProjectStatsValue) => number,) { return { labels: stats.versions, data: stats.data.map((value) => { return { label: value.name, backgroundColor: getColorForLauncher(value.name), data: value.values.map((stat) => { if (stat === undefined) return 0;
return fn(stat); }), }; }), };}
// extract only versions in the given version rangefunction filterVersions( mappedStats: StatExport, versionTo: string | null, versionFrom: string | null,) { let to = mappedStats.labels.length; if (versionTo) { to = mappedStats.labels.indexOf(versionTo) + 1; }
let from = 0; if (versionFrom) { from = mappedStats.labels.indexOf(versionFrom); }
mappedStats.labels = mappedStats.labels.slice(from, to);
for (let i = 0; i < mappedStats.data.length; i++) { mappedStats.data[i].data = mappedStats.data[i].data.slice(from, to); }}
export async function exportStats( versionCategory: VersionCategories, type: ProjectTypes, exclusive: boolean, fn: (value: ProjectStatsValue) => number, versionTo: string | null, versionFrom: string | null,): Promise<StatExport> { const stats = await getLatestProjectStats(type, versionCategory, exclusive);
if (stats instanceof Error) { consola.error(stats.message);
return { labels: [], data: [], }; }
const mappedStats = mapStats(stats, fn);
filterVersions(mappedStats, versionTo, versionFrom);
return mappedStats;}
export async function exportStatsOverTime( versionCategory: VersionCategories, type: ProjectTypes, exclusive: boolean, firstDate: Date, version: string, fn: (value: ProjectStatsValue) => number,): Promise<StatExport> { const statsOverTime: ProjectStats = { versions: [], data: [], };
const date = firstDate;
while (true) { const stats = await getProjectStats(date, type, versionCategory, exclusive);
if (stats instanceof Error) { break; }
const index = stats.versions.indexOf(version);
statsOverTime.versions.splice(0, 0, dateToFormatted(date));
outer: for (const data of stats.data) { for (const dataOverTime of statsOverTime.data) { if (dataOverTime.name === data.name) { dataOverTime.values.splice(0, 0, data.values[index]); continue outer; } }
statsOverTime.data.push({ name: data.name, values: [data.values[index]], }); }
date.setUTCDate(date.getUTCDate() - 1); }
return mapStats(statsOverTime, fn);}