diff --git a/server/api/stats/global.ts b/server/api/stats/global.ts index fe815d2..a21ddb2 100644 --- a/server/api/stats/global.ts +++ b/server/api/stats/global.ts @@ -1,17 +1,12 @@ -type Data = { - projects: number; - versions: number; - files: number; - authors: number; -}; - -export default defineEventHandler(async (event): Promise => { +export default defineEventHandler(async (event): Promise => { const query = getQuery(event); const storage = useStorage("statistics"); const dateKey = await storage.getItem("latestDate"); - const gameVersions = await storage.getItem(`globalStats${dateKey}`); + const gameVersions = await storage.getItem( + `globalStats${dateKey}`, + ); if (!gameVersions) { setResponseStatus(event, 500); diff --git a/server/api/stats/projects.ts b/server/api/stats/projects.ts index 7dfaa23..2a3b0a7 100644 --- a/server/api/stats/projects.ts +++ b/server/api/stats/projects.ts @@ -1,7 +1,7 @@ import consola from "consola"; type QueryData = { - stat: "versions" | "count" | "downloads"; + stat: ProjectStatCategory; mode: string; type: ProjectTypes; exclusive: string; @@ -25,7 +25,7 @@ export default defineCachedEventHandler( }; } - let typeFn: (value: StatsValue) => number; + let typeFn: (value: ProjectStatsValue) => number; switch (query.stat) { case "versions": { diff --git a/server/api/stats/time/global.ts b/server/api/stats/time/global.ts index d94f670..a142091 100644 --- a/server/api/stats/time/global.ts +++ b/server/api/stats/time/global.ts @@ -1,8 +1,7 @@ import consola from "consola"; -import { exportGlobalStatsOverTime } from "~~/server/utils/api/stats"; type QueryData = { - type: "projects" | "versions" | "files" | "authors"; + type: GlobalStatCategory; }; export default defineCachedEventHandler( diff --git a/server/api/stats/time/projects.ts b/server/api/stats/time/projects.ts index 0bbd2bf..5481bcc 100644 --- a/server/api/stats/time/projects.ts +++ b/server/api/stats/time/projects.ts @@ -1,8 +1,7 @@ import consola from "consola"; -import { exportGlobalStatsOverTime } from "~~/server/utils/api/stats"; type QueryData = { - stat: "versions" | "count" | "downloads"; + stat: ProjectStatCategory; mode: string; type: ProjectTypes; exclusive: string; @@ -25,7 +24,7 @@ export default defineCachedEventHandler( }; } - let typeFn: (value: StatsValue) => number; + let typeFn: (value: ProjectStatsValue) => number; switch (query.stat) { case "versions": { diff --git a/server/utils/api/globalStats.ts b/server/utils/api/globalStats.ts new file mode 100644 index 0000000..27f9b34 --- /dev/null +++ b/server/utils/api/globalStats.ts @@ -0,0 +1,38 @@ +import consola from "consola"; +import { dateToKey, keyToDate } from "~~/utils/date"; + +export async function exportGlobalStatsOverTime( + firstDateKey: string, + fn: (value: GlobalStats) => number, +): Promise { + const storage = useStorage("statistics"); + + const statsOverTime: StatExport = { + labels: [], + data: [], + }; + + const date = keyToDate(firstDateKey); + + while (true) { + const dateKey = dateToKey(date); + const key = `globalStats${dateKey}`; + const stats = await storage.getItem(key); + + if (!stats) { + break; + } + + statsOverTime.labels.splice(0, 0, dateKey); + + statsOverTime.data.push({ + label: "data", + backgroundColor: "#7ab0ee", + data: [fn(stats)], + }); + + date.setUTCDate(date.getUTCDate() - 1); + } + + return statsOverTime; +} diff --git a/server/utils/api/stats.ts b/server/utils/api/projectStats.ts similarity index 69% rename from server/utils/api/stats.ts rename to server/utils/api/projectStats.ts index e5df358..2c2d0c4 100644 --- a/server/utils/api/stats.ts +++ b/server/utils/api/projectStats.ts @@ -1,15 +1,6 @@ import consola from "consola"; import { dateToKey, keyToDate } from "~~/utils/date"; -export type StatExport = { - labels: string[]; - data: { - label: string; - backgroundColor: string; - data: number[]; - }[]; -}; - function getStorageKey( type: ProjectTypes, versionCategory: string, @@ -28,7 +19,10 @@ function getStorageKey( } // maps database data to a format usable by the frontend -function mapStats(stats: Stats, fn: (value: StatsValue) => number) { +function mapStats( + stats: ProjectStats, + fn: (value: ProjectStatsValue) => number, +) { return { labels: stats.versions, data: stats.data.map((value) => { @@ -71,14 +65,14 @@ export async function exportStats( type: ProjectTypes, exclusive: boolean, dateKey: string, - fn: (value: StatsValue) => number, + fn: (value: ProjectStatsValue) => number, versionTo: string | null, versionFrom: string | null, ): Promise { const key = getStorageKey(type, versionCategory, exclusive, dateKey); const storage = useStorage("statistics"); - const stats = await storage.getItem(key); + const stats = await storage.getItem(key); if (!stats) { consola.error(`could not find stats for key - "${key}"`); @@ -101,11 +95,11 @@ export async function exportStatsOverTime( exclusive: boolean, firstDateKey: string, version: string, - fn: (value: StatsValue) => number, + fn: (value: ProjectStatsValue) => number, ): Promise { const storage = useStorage("statistics"); - const statsOverTime: Stats = { + const statsOverTime: ProjectStats = { versions: [], data: [], }; @@ -115,7 +109,7 @@ export async function exportStatsOverTime( while (true) { const dateKey = dateToKey(date); const key = getStorageKey(type, versionCategory, exclusive, dateKey); - const stats = await storage.getItem(key); + const stats = await storage.getItem(key); if (!stats) { break; @@ -144,51 +138,3 @@ export async function exportStatsOverTime( return mapStats(statsOverTime, fn); } - -export async function exportGlobalStatsOverTime( - firstDateKey: string, - fn: (value: { - projects: number; - versions: number; - files: number; - authors: number; - }) => number, -): Promise { - const storage = useStorage("statistics"); - - const statsOverTime: StatExport = { - labels: [], - data: [], - }; - - const date = keyToDate(firstDateKey); - - type Data = { - projects: number; - versions: number; - files: number; - authors: number; - }; - - while (true) { - const dateKey = dateToKey(date); - const key = `globalStats${dateKey}`; - const stats = await storage.getItem(key); - - if (!stats) { - break; - } - - statsOverTime.labels.splice(0, 0, dateKey); - - statsOverTime.data.push({ - label: "data", - backgroundColor: "#7ab0ee", - data: [fn(stats)], - }); - - date.setUTCDate(date.getUTCDate() - 1); - } - - return statsOverTime; -} diff --git a/server/utils/statistics.ts b/server/utils/statistics.ts index d948e27..2087fbf 100644 --- a/server/utils/statistics.ts +++ b/server/utils/statistics.ts @@ -18,7 +18,7 @@ type StatsDataEntry = { }; type StatsData = { all: StatsDataEntry; exclusive: StatsDataEntry }; -type AllStatsEntry = { all: Stats; minor: Stats; major: Stats }; +type AllStatsEntry = { all: ProjectStats; minor: ProjectStats; major: ProjectStats }; type AllStats = { all: AllStatsEntry; exclusive: AllStatsEntry }; type GroupStats = { @@ -67,19 +67,19 @@ async function saveStats(stats: AllStats, type: ProjectTypes) { const storage = useStorage("statistics"); const dateKey = dateToKey(new Date()); - await storage.setItem(`${type}StatsAll${dateKey}`, stats.all.all); - await storage.setItem(`${type}StatsMinor${dateKey}`, stats.all.minor); - await storage.setItem(`${type}StatsMajor${dateKey}`, stats.all.major); + await storage.setItem(`${type}StatsAll${dateKey}`, stats.all.all); + await storage.setItem(`${type}StatsMinor${dateKey}`, stats.all.minor); + await storage.setItem(`${type}StatsMajor${dateKey}`, stats.all.major); - await storage.setItem( + await storage.setItem( `${type}StatsAllExclusive${dateKey}`, stats.exclusive.all, ); - await storage.setItem( + await storage.setItem( `${type}StatsMinorExclusive${dateKey}`, stats.exclusive.minor, ); - await storage.setItem( + await storage.setItem( `${type}StatsMajorExclusive${dateKey}`, stats.exclusive.major, ); @@ -142,7 +142,7 @@ async function getStatistics(type: ProjectTypes): Promise { }; } -function groupStatsToStats(groupStats: GroupStats): Stats { +function groupStatsToStats(groupStats: GroupStats): ProjectStats { return { versions: groupStats.versions, data: groupStats.data.map((value) => { diff --git a/server/utils/types/export.ts b/server/utils/types/export.ts new file mode 100644 index 0000000..8262628 --- /dev/null +++ b/server/utils/types/export.ts @@ -0,0 +1,8 @@ +export type StatExport = { + labels: string[]; + data: { + label: string; + backgroundColor: string; + data: number[]; + }[]; +}; diff --git a/server/utils/types/globalStats.ts b/server/utils/types/globalStats.ts new file mode 100644 index 0000000..8a468b8 --- /dev/null +++ b/server/utils/types/globalStats.ts @@ -0,0 +1,8 @@ +export type GlobalStats = { + projects: number; + versions: number; + files: number; + authors: number; +}; + +export type GlobalStatCategory = "projects" | "versions" | "files" | "authors"; diff --git a/server/utils/types/projectStats.ts b/server/utils/types/projectStats.ts new file mode 100644 index 0000000..df52085 --- /dev/null +++ b/server/utils/types/projectStats.ts @@ -0,0 +1,15 @@ +export type ProjectStats = { + versions: string[]; + data: { + name: string; + values: ProjectStatsValue[]; + }[]; +}; + +export type ProjectStatsValue = { + downloads: number; + versions: number; + count: number; +}; + +export type ProjectStatCategory = "versions" | "count" | "downloads"; diff --git a/server/utils/types/stats.ts b/server/utils/types/stats.ts deleted file mode 100644 index 615d134..0000000 --- a/server/utils/types/stats.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type Stats = { - versions: string[]; - data: { - name: string; - values: StatsValue[]; - }[]; -}; - -export type StatsValue = { downloads: number; versions: number; count: number };