import { API_URL, ApiError } from "../../lib/api-client"; import { getSessionToken } from "../../lib/session-token"; /** * Binary download for GET /files/items/:itemId/download. This cannot use * `apiFetch` (it parses JSON) or a bare anchor (the endpoint needs the * Authorization header, which anchors cannot send), so it replays the client's * auth rules: same base URL, Bearer token, cookie credentials — then streams * the body into a Blob and clicks a temporary anchor. */ export async function downloadGroupFile(itemId: string, fileName: string): Promise { const token = getSessionToken(); const response = await fetch(`${API_URL}/files/items/${encodeURIComponent(itemId)}/download`, { credentials: "include", headers: token === null ? {} : { Authorization: `Bearer ${token}` }, }); if (!response.ok) { if (response.status === 401) throw new ApiError(401, "Your session expired — sign in again.", null); throw new ApiError(response.status, `Download failed (HTTP ${response.status})`, null); } const blob = await response.blob(); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = fileName; document.body.append(anchor); anchor.click(); anchor.remove(); URL.revokeObjectURL(url); } /** * Derive the share id from a public tokenUrl of the form * `/files/shares/:token/download`, used for DELETE /files/shares/:shareId when * the POST response omits an explicit shareId. */ export function shareIdFromUrl(tokenUrl: string): string | null { const match = /\/files\/shares\/([^/?#]+)/.exec(tokenUrl); return match?.[1] !== undefined && match[1] !== "" ? match[1] : null; }