PronounsPage/server/admin.ts

54 lines
1.6 KiB
TypeScript

import SQL from 'sql-template-strings';
import { decodeTime } from 'ulid';
import type { Config } from '~/locale/config.ts';
import type { LocaleDescription } from '~/locale/locales.ts';
import type { Database } from '~/server/db.ts';
import type { LocaleStatsData, OverallStatsData } from '~/src/stats.ts';
export type LocalDescriptionWithConfig = Omit<LocaleDescription, 'matches' | 'fullName'> & { config: Config };
export interface StatRow {
id: string;
locale: string;
users: number;
data: string;
}
export interface Stats {
calculatedAt: number;
overall: { users: number } & OverallStatsData;
locales: Record<string, { users: number } & LocaleStatsData>;
}
export const fetchStats = async (db: Database): Promise<Stats | null> => {
const maxId = (await db.get<{ maxId: StatRow['id'] | null }>('SELECT MAX(id) AS maxId FROM stats'))!.maxId;
if (maxId === null) {
return null;
}
let overall: ({ users: number } & OverallStatsData) | null = null;
const locales: Record<string, { users: number } & LocaleStatsData> = {};
for (const statsRow of await db.all<Pick<StatRow, 'locale' | 'users' | 'data'>>(SQL`
SELECT locale, users, data FROM stats WHERE id = ${maxId}
`)) {
const stats = {
users: statsRow.users,
...JSON.parse(statsRow.data),
};
if (statsRow.locale === '_') {
overall = stats;
} else {
locales[statsRow.locale] = stats;
}
}
return {
calculatedAt: decodeTime(maxId) / 1000,
overall: overall!,
locales,
};
};