import { useAuthStore } from "@/stores/auth"; import { useLayoutStore } from "@/stores/layout"; import { baseURL } from "@/utils/constants"; import { upload as postTus, useTus } from "./tus"; import { createURL, fetchURL, removePrefix } from "./utils"; export async function fetch(url: string) { url = removePrefix(url); const res = await fetchURL(`/api/resources${url}`, {}); const data = (await res.json()) as Resource; data.url = `/files${url}`; if (data.isDir) { if (!data.url.endsWith("/")) data.url += "/"; // Perhaps change the any data.items = data.items.map((item: any, index: any) => { item.index = index; item.url = `${data.url}${encodeURIComponent(item.name)}`; if (item.isDir) { item.url += "/"; } return item; }); } return data; } async function resourceAction(url: string, method: ApiMethod, content?: any) { url = removePrefix(url); const opts: ApiOpts = { method, }; if (content) { opts.body = content; } const res = await fetchURL(`/api/resources${url}`, opts); return res; } export async function remove(url: string) { return resourceAction(url, "DELETE"); } export async function put(url: string, content = "") { return resourceAction(url, "PUT", content); } export function download(format: any, ...files: string[]) { let url = `${baseURL}/api/raw`; if (files.length === 1) { url += removePrefix(files[0]) + "?"; } else { let arg = ""; for (const file of files) { arg += removePrefix(file) + ","; } arg = arg.substring(0, arg.length - 1); arg = encodeURIComponent(arg); url += `/?files=${arg}&`; } if (format) { url += `algo=${format}&`; } const authStore = useAuthStore(); if (authStore.jwt) { url += `auth=${authStore.jwt}&`; } window.open(url); } export async function post( url: string, content: ApiContent = "", overwrite = false, onupload: any = () => {} ) { // Use the pre-existing API if: const useResourcesApi = // a folder is being created url.endsWith("/") || // We're not using http(s) (content instanceof Blob && !["http:", "https:"].includes(window.location.protocol)) || // Tus is disabled / not applicable !(await useTus(content)); return useResourcesApi ? postResources(url, content, overwrite, onupload) : postTus(url, content, overwrite, onupload); } async function postResources( url: string, content: ApiContent = "", overwrite = false, onupload: any ) { url = removePrefix(url); let bufferContent: ArrayBuffer; if ( content instanceof Blob && !["http:", "https:"].includes(window.location.protocol) ) { bufferContent = await new Response(content).arrayBuffer(); } const authStore = useAuthStore(); return new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.open( "POST", `${baseURL}/api/resources${url}?override=${overwrite}`, true ); request.setRequestHeader("X-Auth", authStore.jwt); if (typeof onupload === "function") { request.upload.onprogress = onupload; } request.onload = () => { if (request.status === 200) { resolve(request.responseText); } else if (request.status === 409) { reject(request.status); } else { reject(request.responseText); } }; request.onerror = () => { reject(new Error("001 Connection aborted")); }; request.send(bufferContent || content); }); } function moveCopy( items: any[], copy = false, overwrite = false, rename = false ) { const layoutStore = useLayoutStore(); const promises = []; for (const item of items) { const from = item.from; const to = encodeURIComponent(removePrefix(item.to ?? "")); const url = `${from}?action=${ copy ? "copy" : "rename" }&destination=${to}&override=${overwrite}&rename=${rename}`; promises.push(resourceAction(url, "PATCH")); } layoutStore.closeHovers(); return Promise.all(promises); } export function move(items: any[], overwrite = false, rename = false) { return moveCopy(items, false, overwrite, rename); } export function copy(items: any[], overwrite = false, rename = false) { return moveCopy(items, true, overwrite, rename); } export async function checksum(url: string, algo: ChecksumAlg) { const data = await resourceAction(`${url}?checksum=${algo}`, "GET"); return (await data.json()).checksums[algo]; } export function getDownloadURL(file: ResourceItem, inline: any) { const params = { ...(inline && { inline: "true" }), }; return createURL("api/raw" + file.path, params); } export function getPreviewURL(file: ResourceItem, size: string) { const params = { inline: "true", key: Date.parse(file.modified), }; return createURL("api/preview/" + size + file.path, params); } export function getSubtitlesURL(file: ResourceItem) { const params = { inline: "true", }; return file.subtitles?.map((d) => createURL("api/subtitle" + d, params)); } export async function usage(url: string) { url = removePrefix(url); const res = await fetchURL(`/api/usage${url}`, {}); return await res.json(); }