import { downloadSourceSchema } from "@main/events/helpers/validators"; import { DownloadSourceStatus } from "@shared"; import type { DownloadSource, GameRepack } from "@types"; import axios, { AxiosError, AxiosHeaders } from "axios"; import { z } from "zod"; export type DownloadSourceResponse = z.infer & { etag: string | null; status: DownloadSourceStatus; }; export const getUpdatedRepacks = async (downloadSources: DownloadSource[]) => { const results: DownloadSourceResponse[] = []; for (const downloadSource of downloadSources) { const headers = new AxiosHeaders(); if (downloadSource.etag) { headers.set("If-None-Match", downloadSource.etag); } try { const response = await axios.get(downloadSource.url, { headers, }); const source = downloadSourceSchema.parse(response.data); results.push({ ...downloadSource, downloads: source.downloads, etag: response.headers["etag"], status: DownloadSourceStatus.UpToDate, }); } catch (err: unknown) { const isNotModified = (err as AxiosError).response?.status === 304; results.push({ ...downloadSource, downloads: [], etag: null, status: isNotModified ? DownloadSourceStatus.UpToDate : DownloadSourceStatus.Errored, }); } } return results; }; export const validateDownloadSource = async ({ url, repacks, }: { url: string; repacks: GameRepack[]; }) => { const response = await axios.get(url); const source = downloadSourceSchema.parse(response.data); const existingUris = source.downloads .flatMap((download) => download.uris) .filter((uri) => repacks.some((repack) => repack.magnet === uri)); return { name: source.name, downloadCount: source.downloads.length - existingUris.length, }; };