220 lines
5.1 KiB
TypeScript
220 lines
5.1 KiB
TypeScript
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();
|
|
}
|