Files
homarr/packages/integrations/src/interfaces/downloads/download-client-items.ts
T

60 lines
2.2 KiB
TypeScript

import { z } from "zod/v4";
import type { Integration } from "@homarr/db/schema";
const usenetQueueState = ["downloading", "queued", "paused"] as const;
const usenetHistoryState = ["completed", "failed", "processing"] as const;
const torrentState = ["leeching", "stalled", "paused", "seeding"] as const;
/**
* DownloadClientItem
* Description:
* Normalized interface for downloading clients for Usenet and
* Torrents alike, using common properties and few extra optionals
* from each.
*/
export const downloadClientItemSchema = z.object({
/** Unique Identifier provided by client */
id: z.string(),
/** Position in queue */
index: z.number(),
/** Filename */
name: z.string(),
/** Download Client identifier */
type: z.enum(["torrent", "usenet", "miscellaneous"]),
/** Item size in Bytes */
size: z.number(),
/** Total uploaded in Bytes, only required for Torrent items */
sent: z.number().optional(),
/** Total downloaded in Bytes, only required for Torrent items */
received: z.number().optional(),
/** Download speed in Bytes/s, only required if not complete
* (Says 0 only if it should be downloading but isn't) */
downSpeed: z.number().optional(),
/** Upload speed in Bytes/s, only required for Torrent items */
upSpeed: z.number().optional(),
/** Positive = eta (until completion, 0 meaning infinite), Negative = time since completion, in milliseconds*/
time: z.number(),
/** Unix timestamp in milliseconds when the item was added to the client */
added: z.number().optional(),
/** Status message, mostly as information to display and not for logic */
state: z.enum(["unknown", ...usenetQueueState, ...usenetHistoryState, ...torrentState]),
/** Progress expressed between 0 and 1, can infer completion from progress === 1 */
progress: z.number().min(0).max(1),
/** Category given to the item */
category: z.string().or(z.array(z.string())).optional(),
});
export type DownloadClientItem = z.infer<typeof downloadClientItemSchema>;
export type ExtendedDownloadClientItem = {
integration: Pick<Integration, "id" | "name" | "kind">;
received: number;
ratio?: number;
actions?: {
resume: () => void;
pause: () => void;
delete: ({ fromDisk }: { fromDisk: boolean }) => void;
};
} & DownloadClientItem;