import { request } from "$lib/api/client"; import type { FileShare, FileShareHit, ShareSubject } from "$lib/api/types"; import { accounts } from "$lib/stores/accounts.svelte"; export interface ShareSettings { expiresInSeconds: number | null; keepExpiry?: boolean; maxDownloads: number | null; } function subjectQuery(subject: ShareSubject): Record { const query: Record = { kind: subject.kind }; if (subject.mediaId !== undefined) { query.media_id = subject.mediaId; } if (subject.versionId !== undefined) { query.version_id = subject.versionId; } if (subject.peerId !== undefined) { query.peer_id = subject.peerId; } if (subject.storyId !== undefined) { query.story_id = subject.storyId; } return query; } export function listShares(activeOnly = false): Promise { return request("/shares", { account: true, query: { active_only: activeOnly, limit: 200 }, }); } export function lookupShare(subject: ShareSubject): Promise { return request("/shares/lookup", { account: true, query: subjectQuery(subject), }); } export function createShare( subject: ShareSubject, settings: ShareSettings ): Promise { return request("/shares", { method: "POST", body: { account_id: accounts.selectedId, kind: subject.kind, media_id: subject.mediaId ?? null, version_id: subject.versionId ?? null, peer_id: subject.peerId ?? null, story_id: subject.storyId ?? null, expires_in_seconds: settings.expiresInSeconds, max_downloads: settings.maxDownloads, }, }); } export function updateShare( id: number, settings: ShareSettings ): Promise { return request(`/shares/${id}`, { method: "PATCH", body: { expires_in_seconds: settings.expiresInSeconds, keep_expiry: settings.keepExpiry ?? false, max_downloads: settings.maxDownloads, }, }); } export function revokeShare(id: number): Promise { return request(`/shares/${id}/revoke`, { method: "POST" }); } export function reissueShare(id: number): Promise { return request(`/shares/${id}/reissue`, { method: "POST" }); } export function deleteShare(id: number): Promise { return request(`/shares/${id}`, { method: "DELETE" }); } export function listShareHits(id: number): Promise { return request(`/shares/${id}/hits`, { query: { limit: 50 }, }); } const TRAILING_SLASH = /\/$/; export function shareUrl(share: FileShare): string { const origin = typeof window === "undefined" ? "" : window.location.origin.replace(TRAILING_SLASH, ""); return `${origin}/f/${share.token}`; } export function shareState( share: FileShare ): "active" | "revoked" | "expired" | "exhausted" { if (share.revoked_at) { return "revoked"; } if (share.expires_at && Date.parse(share.expires_at) <= Date.now()) { return "expired"; } if ( share.max_downloads !== null && share.download_count >= share.max_downloads ) { return "exhausted"; } return "active"; }