diff --git a/.dockerignore b/.dockerignore index 7f89ad8..a517baa 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,7 @@ # Nuxt dev/build outputs .output .data +data .nuxt .nitro .cache diff --git a/.gitignore b/.gitignore index 4a7f73a..68f19bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Nuxt dev/build outputs .output .data +data .nuxt .nitro .cache diff --git a/app/components/Charts.vue b/app/components/Charts.vue index 9c4cbfd..b89da8f 100644 --- a/app/components/Charts.vue +++ b/app/components/Charts.vue @@ -14,42 +14,22 @@ const { data } = useFetch("/api/stats", { exclusive: exclusive, type: props.type, stat: props.stat, + versionTo: versionTo, + versionFrom: versionFrom, }, }); -const downloadData = computed(() => { - if (data.value) { - const chartData: StatExport = JSON.parse(JSON.stringify(data.value)); - - let to = data.value.labels.length; - if (versionTo.value) { - to = chartData.labels.indexOf(versionTo.value) + 1; - } - - let from = 0; - if (versionFrom.value) { - from = chartData.labels.indexOf(versionFrom.value); - } - - chartData.labels = chartData.labels.slice(from, to); - - for (let i = 0; i < chartData.data.length; i++) { - chartData.data[i].data = chartData.data[i].data.slice(from, to); - } - - return chartData; +const chartData = computed(() => { + if (!data.value) { + return { + labels: [], + datasets: [], + }; } return { - labels: [], - data: [], - }; -}); - -const chartData = computed(() => { - return { - labels: downloadData.value.labels, - datasets: downloadData.value.data.map((value) => { + labels: data.value.labels, + datasets: data.value.data.map((value) => { return { ...value, borderRadius: 3, diff --git a/server/api/stats.ts b/server/api/stats.ts index 932c2d0..917ec5e 100644 --- a/server/api/stats.ts +++ b/server/api/stats.ts @@ -1,11 +1,17 @@ import consola from "consola"; -export default defineEventHandler(async (event): Promise => { - const query = getQuery(event); +type QueryData = { + stat: "versions" | "count" | "downloads"; + mode: string; + type: ProjectTypes; + exclusive: string; + date: string | null; + versionFrom: string | null; + versionTo: string | null; +}; - const mode = query.mode as string; - const type = query.type as ProjectTypes; - const exclusive = query.exclusive === "true"; +export default defineEventHandler(async (event): Promise => { + const query = getQuery(event); let dateKey: string | null = query.date as string; @@ -23,33 +29,30 @@ export default defineEventHandler(async (event): Promise => { }; } + let typeFn: (value: StatsValue) => number; + switch (query.stat) { case "versions": { - return exportStats( - mode, - type, - exclusive, - dateKey, - (value) => value.versions, - ); + typeFn = (value) => value.versions; + break; } case "count": { - return exportStats( - mode, - type, - exclusive, - dateKey, - (value) => value.count, - ); + typeFn = (value) => value.count; + break; } default: { - return exportStats( - mode, - type, - exclusive, - dateKey, - (value) => value.downloads, - ); + typeFn = (value) => value.downloads; + break; } } + + return exportStats( + query.mode, + query.type, + query.exclusive === "true", + dateKey, + typeFn, + query.versionTo, + query.versionFrom, + ); }); diff --git a/server/utils/api/stats.ts b/server/utils/api/stats.ts index d2f5982..82c8cc1 100644 --- a/server/utils/api/stats.ts +++ b/server/utils/api/stats.ts @@ -9,15 +9,12 @@ export type StatExport = { }[]; }; -export async function exportStats( - versionCategory: string, +function getStorageKey( type: ProjectTypes, + versionCategory: string, exclusive: boolean, dateKey: string, - fn: (value: StatsValue) => number, -): Promise { - const storage = useStorage("statistics"); - +) { // key format: Stats let key = `${type}Stats${firstLetterUpperCase(versionCategory)}`; @@ -26,18 +23,10 @@ export async function exportStats( } key += dateKey; + return key; +} - const stats = await storage.getItem(key); - - if (!stats) { - consola.error(`could not find stats for key - "${key}"`); - - return { - labels: [], - data: [], - }; - } - +function mapStats(stats: Stats, fn: (value: StatsValue) => number) { return { labels: stats.versions, data: stats.data.map((value) => { @@ -51,3 +40,54 @@ export async function exportStats( }), }; } + +function 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: string, + type: ProjectTypes, + exclusive: boolean, + dateKey: string, + fn: (value: StatsValue) => 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); + + if (!stats) { + consola.error(`could not find stats for key - "${key}"`); + + return { + labels: [], + data: [], + }; + } + const mappedStats = mapStats(stats, fn); + + filterVersions(mappedStats, versionTo, versionFrom); + + return mappedStats; +}