Forgot to add ts files
This commit is contained in:
parent
5a8ca3a50d
commit
4ea66b8bd3
18
frontend/src/api/commands.ts
Normal file
18
frontend/src/api/commands.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { removePrefix } from "./utils";
|
||||||
|
import { baseURL } from "@/utils/constants";
|
||||||
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
|
||||||
|
const ssl = window.location.protocol === "https:";
|
||||||
|
const protocol = ssl ? "wss:" : "ws:";
|
||||||
|
|
||||||
|
export default function command(url: string, command: string, onmessage: WebSocket["onmessage"], onclose: WebSocket["onclose"]) {
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
url = removePrefix(url);
|
||||||
|
url = `${protocol}//${window.location.host}${baseURL}/api/command${url}?auth=${authStore.jwt}`;
|
||||||
|
|
||||||
|
let conn = new window.WebSocket(url);
|
||||||
|
conn.onopen = () => conn.send(command);
|
||||||
|
conn.onmessage = onmessage;
|
||||||
|
conn.onclose = onclose;
|
||||||
|
}
|
||||||
208
frontend/src/api/files.ts
Normal file
208
frontend/src/api/files.ts
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
import { createURL, fetchURL, removePrefix } from "./utils";
|
||||||
|
import { baseURL } from "@/utils/constants";
|
||||||
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
import { upload as postTus, useTus } from "./tus";
|
||||||
|
|
||||||
|
export async function fetch(url: apiUrl) {
|
||||||
|
url = removePrefix(url);
|
||||||
|
|
||||||
|
const res = await fetchURL(`/api/resources${url}`, {});
|
||||||
|
|
||||||
|
let data = await res.json();
|
||||||
|
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: apiUrl, method: apiMethod, content?: any) {
|
||||||
|
debugger;
|
||||||
|
url = removePrefix(url);
|
||||||
|
|
||||||
|
let opts: apiOpts = {
|
||||||
|
method
|
||||||
|
};
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
opts.body = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetchURL(`/api/resources${url}`, opts);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(url: apiUrl) {
|
||||||
|
return resourceAction(url, "DELETE");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function put(url: apiUrl, 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 (let 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: apiUrl, content: apiContent = "", overwrite = false, onupload: Function = () => {}) {
|
||||||
|
// 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: apiUrl, 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) => {
|
||||||
|
let 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: item[], copy = false, overwrite = false, rename = false) {
|
||||||
|
let promises = [];
|
||||||
|
|
||||||
|
for (let 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function move(items: item[], overwrite = false, rename = false) {
|
||||||
|
return moveCopy(items, false, overwrite, rename);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function copy(items: item[], overwrite = false, rename = false) {
|
||||||
|
return moveCopy(items, true, overwrite, rename);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checksum(url: apiUrl, algo: algo) {
|
||||||
|
const data = await resourceAction(`${url}?checksum=${algo}`, "GET");
|
||||||
|
return (await data.json()).checksums[algo];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDownloadURL(file: file, inline: any) {
|
||||||
|
const params = {
|
||||||
|
...(inline && { inline: "true" }),
|
||||||
|
};
|
||||||
|
|
||||||
|
return createURL("api/raw" + file.path, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPreviewURL(file: file, size: string) {
|
||||||
|
const params = {
|
||||||
|
inline: "true",
|
||||||
|
key: Date.parse(file.modified),
|
||||||
|
};
|
||||||
|
|
||||||
|
return createURL("api/preview/" + size + file.path, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSubtitlesURL(file: file) {
|
||||||
|
const params = {
|
||||||
|
inline: "true",
|
||||||
|
};
|
||||||
|
|
||||||
|
const subtitles = [];
|
||||||
|
for (const sub of file.subtitles) {
|
||||||
|
subtitles.push(createURL("api/raw" + sub, params));
|
||||||
|
}
|
||||||
|
|
||||||
|
return subtitles;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function usage(url: apiUrl) {
|
||||||
|
url = removePrefix(url);
|
||||||
|
|
||||||
|
const res = await fetchURL(`/api/usage${url}`, {});
|
||||||
|
|
||||||
|
return await res.json();
|
||||||
|
}
|
||||||
9
frontend/src/api/index.ts
Normal file
9
frontend/src/api/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import * as files from "./files";
|
||||||
|
import * as share from "./share";
|
||||||
|
import * as users from "./users";
|
||||||
|
import * as settings from "./settings";
|
||||||
|
import * as pub from "./pub";
|
||||||
|
import search from "./search";
|
||||||
|
import commands from "./commands";
|
||||||
|
|
||||||
|
export { files, share, users, settings, pub, commands, search };
|
||||||
71
frontend/src/api/pub.ts
Normal file
71
frontend/src/api/pub.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { fetchURL, removePrefix, createURL } from "./utils";
|
||||||
|
import { baseURL } from "@/utils/constants";
|
||||||
|
|
||||||
|
export async function fetch(url: apiUrl, password: string = "") {
|
||||||
|
url = removePrefix(url);
|
||||||
|
|
||||||
|
const res = await fetchURL(
|
||||||
|
`/api/public/share${url}`,
|
||||||
|
{
|
||||||
|
headers: { "X-SHARE-PASSWORD": encodeURIComponent(password) },
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
let data = await res.json();
|
||||||
|
data.url = `/share${url}`;
|
||||||
|
|
||||||
|
if (data.isDir) {
|
||||||
|
if (!data.url.endsWith("/")) data.url += "/";
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this redundant code?
|
||||||
|
// export function download(format, hash, token, ...files) {
|
||||||
|
// let url = `${baseURL}/api/public/dl/${hash}`;
|
||||||
|
|
||||||
|
// if (files.length === 1) {
|
||||||
|
// url += encodeURIComponent(files[0]) + "?";
|
||||||
|
// } else {
|
||||||
|
// let arg = "";
|
||||||
|
|
||||||
|
// for (let file of files) {
|
||||||
|
// arg += encodeURIComponent(file) + ",";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// arg = arg.substring(0, arg.length - 1);
|
||||||
|
// arg = encodeURIComponent(arg);
|
||||||
|
// url += `/?files=${arg}&`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (format) {
|
||||||
|
// url += `algo=${format}&`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (token) {
|
||||||
|
// url += `token=${token}&`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// window.open(url);
|
||||||
|
// }
|
||||||
|
|
||||||
|
export function getDownloadURL(share: share, inline = false) {
|
||||||
|
const params = {
|
||||||
|
...(inline && { inline: "true" }),
|
||||||
|
...(share.token && { token: share.token }),
|
||||||
|
};
|
||||||
|
|
||||||
|
return createURL("api/public/dl/" + share.hash + share.path, params, false);
|
||||||
|
}
|
||||||
27
frontend/src/api/search.ts
Normal file
27
frontend/src/api/search.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { fetchURL, removePrefix } from "./utils";
|
||||||
|
import url from "../utils/url";
|
||||||
|
|
||||||
|
export default async function search(base: apiUrl, query: string) {
|
||||||
|
base = removePrefix(base);
|
||||||
|
query = encodeURIComponent(query);
|
||||||
|
|
||||||
|
if (!base.endsWith("/")) {
|
||||||
|
base += "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await fetchURL(`/api/search${base}?query=${query}`, {});
|
||||||
|
|
||||||
|
let data = await res.json();
|
||||||
|
|
||||||
|
data = data.map((item: item) => {
|
||||||
|
item.url = `/files${base}` + url.encodePath(item.path);
|
||||||
|
|
||||||
|
if (item.dir) {
|
||||||
|
item.url += "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
12
frontend/src/api/settings.ts
Normal file
12
frontend/src/api/settings.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { fetchURL, fetchJSON } from "./utils";
|
||||||
|
|
||||||
|
export function get() {
|
||||||
|
return fetchJSON(`/api/settings`, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function update(settings: settings) {
|
||||||
|
await fetchURL(`/api/settings`, {
|
||||||
|
method: "PUT",
|
||||||
|
body: JSON.stringify(settings),
|
||||||
|
});
|
||||||
|
}
|
||||||
40
frontend/src/api/share.ts
Normal file
40
frontend/src/api/share.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { fetchURL, fetchJSON, removePrefix, createURL } from "./utils";
|
||||||
|
|
||||||
|
export async function list() {
|
||||||
|
return fetchJSON("/api/shares");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function get(url: apiUrl) {
|
||||||
|
url = removePrefix(url);
|
||||||
|
return fetchJSON(`/api/share${url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(hash: string) {
|
||||||
|
await fetchURL(`/api/share/${hash}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function create(url: apiUrl, password = "", expires = "", unit = "hours") {
|
||||||
|
url = removePrefix(url);
|
||||||
|
url = `/api/share${url}`;
|
||||||
|
if (expires !== "") {
|
||||||
|
url += `?expires=${expires}&unit=${unit}`;
|
||||||
|
}
|
||||||
|
let body = "{}";
|
||||||
|
if (password != "" || expires !== "" || unit !== "hours") {
|
||||||
|
body = JSON.stringify({
|
||||||
|
password: password,
|
||||||
|
expires: expires.toString(), // backend expects string not number
|
||||||
|
unit: unit,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fetchJSON(url, {
|
||||||
|
method: "POST",
|
||||||
|
body: body,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getShareURL(share: share) {
|
||||||
|
return createURL("share/" + share.hash, {}, false);
|
||||||
|
}
|
||||||
96
frontend/src/api/tus.ts
Normal file
96
frontend/src/api/tus.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import * as tus from "tus-js-client";
|
||||||
|
import { baseURL, tusEndpoint, tusSettings } from "@/utils/constants";
|
||||||
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
import { removePrefix } from "@/api/utils";
|
||||||
|
import { fetchURL } from "./utils";
|
||||||
|
|
||||||
|
const RETRY_BASE_DELAY = 1000;
|
||||||
|
const RETRY_MAX_DELAY = 20000;
|
||||||
|
|
||||||
|
export async function upload(
|
||||||
|
filePath: string,
|
||||||
|
content: apiContent = "",
|
||||||
|
overwrite = false,
|
||||||
|
onupload: Function
|
||||||
|
) {
|
||||||
|
if (!tusSettings) {
|
||||||
|
// Shouldn't happen as we check for tus support before calling this function
|
||||||
|
throw new Error("Tus.io settings are not defined");
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath = removePrefix(filePath);
|
||||||
|
let resourcePath = `${tusEndpoint}${filePath}?override=${overwrite}`;
|
||||||
|
|
||||||
|
await createUpload(resourcePath);
|
||||||
|
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
// Exit early because of typescript, tus content can't be a string
|
||||||
|
if(content === "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return new Promise<void | string>((resolve, reject) => {
|
||||||
|
let upload = new tus.Upload(content, {
|
||||||
|
uploadUrl: `${baseURL}${resourcePath}`,
|
||||||
|
chunkSize: tusSettings.chunkSize,
|
||||||
|
retryDelays: computeRetryDelays(tusSettings),
|
||||||
|
parallelUploads: 1,
|
||||||
|
storeFingerprintForResuming: false,
|
||||||
|
headers: {
|
||||||
|
"X-Auth": authStore.jwt,
|
||||||
|
},
|
||||||
|
onError: function (error) {
|
||||||
|
reject("Upload failed: " + error);
|
||||||
|
},
|
||||||
|
onProgress: function (bytesUploaded) {
|
||||||
|
// Emulate ProgressEvent.loaded which is used by calling functions
|
||||||
|
// loaded is specified in bytes (https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/loaded)
|
||||||
|
if (typeof onupload === "function") {
|
||||||
|
onupload({ loaded: bytesUploaded });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess: function () {
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
upload.start();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createUpload(resourcePath: resourcePath) {
|
||||||
|
let headResp = await fetchURL(resourcePath, {
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
if (headResp.status !== 201) {
|
||||||
|
throw new Error(
|
||||||
|
`Failed to create an upload: ${headResp.status} ${headResp.statusText}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeRetryDelays(tusSettings: tusSettings): number[] | undefined{
|
||||||
|
if (!tusSettings.retryCount || tusSettings.retryCount < 1) {
|
||||||
|
// Disable retries altogether
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// The tus client expects our retries as an array with computed backoffs
|
||||||
|
// E.g.: [0, 3000, 5000, 10000, 20000]
|
||||||
|
const retryDelays = [];
|
||||||
|
let delay = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < tusSettings.retryCount; i++) {
|
||||||
|
retryDelays.push(Math.min(delay, RETRY_MAX_DELAY));
|
||||||
|
delay =
|
||||||
|
delay === 0 ? RETRY_BASE_DELAY : Math.min(delay * 2, RETRY_MAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retryDelays;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function useTus(content: apiContent) {
|
||||||
|
return isTusSupported() && content instanceof Blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTusSupported() {
|
||||||
|
return tus.isSupported === true;
|
||||||
|
}
|
||||||
41
frontend/src/api/users.ts
Normal file
41
frontend/src/api/users.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { fetchURL, fetchJSON } from "./utils";
|
||||||
|
|
||||||
|
export async function getAll() {
|
||||||
|
return fetchJSON(`/api/users`, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function get(id: number) {
|
||||||
|
return fetchJSON(`/api/users/${id}`, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function create(user: user) {
|
||||||
|
const res = await fetchURL(`/api/users`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
what: "user",
|
||||||
|
which: [],
|
||||||
|
data: user,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.status === 201) {
|
||||||
|
return res.headers.get("Location");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function update(user: user, which = ["all"]) {
|
||||||
|
await fetchURL(`/api/users/${user.id}`, {
|
||||||
|
method: "PUT",
|
||||||
|
body: JSON.stringify({
|
||||||
|
what: "user",
|
||||||
|
which: which,
|
||||||
|
data: user,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function remove(id: number) {
|
||||||
|
await fetchURL(`/api/users/${id}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
}
|
||||||
86
frontend/src/api/utils.ts
Normal file
86
frontend/src/api/utils.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
import { renew, logout } from "@/utils/auth";
|
||||||
|
import { baseURL } from "@/utils/constants";
|
||||||
|
import { encodePath } from "@/utils/url";
|
||||||
|
|
||||||
|
export async function fetchURL(url: apiUrl, opts: apiOpts, auth = true) {
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
opts = opts || {};
|
||||||
|
opts.headers = opts.headers || {};
|
||||||
|
|
||||||
|
let { headers, ...rest } = opts;
|
||||||
|
let res;
|
||||||
|
try {
|
||||||
|
res = await fetch(`${baseURL}${url}`, {
|
||||||
|
headers: {
|
||||||
|
"X-Auth": authStore.jwt,
|
||||||
|
...headers,
|
||||||
|
},
|
||||||
|
...rest,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
const error = new Error("000 No connection");
|
||||||
|
// @ts-ignore don't know yet how to solve
|
||||||
|
error.status = 0;
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth && res.headers.get("X-Renew-Token") === "true") {
|
||||||
|
await renew(authStore.jwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status < 200 || res.status > 299) {
|
||||||
|
const error = new Error(await res.text());
|
||||||
|
// @ts-ignore don't know yet how to solve
|
||||||
|
error.status = res.status;
|
||||||
|
|
||||||
|
if (auth && res.status == 401) {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchJSON(url: apiUrl, opts?: any) {
|
||||||
|
const res = await fetchURL(url, opts);
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
return res.json();
|
||||||
|
} else {
|
||||||
|
throw new Error(res.status.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removePrefix(url: apiUrl) {
|
||||||
|
url = url.split("/").splice(2).join("/");
|
||||||
|
|
||||||
|
if (url === "") url = "/";
|
||||||
|
if (url[0] !== "/") url = "/" + url;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createURL(endpoint: apiUrl, params = {}, auth = true) {
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
|
let prefix = baseURL;
|
||||||
|
if (!prefix.endsWith("/")) {
|
||||||
|
prefix = prefix + "/";
|
||||||
|
}
|
||||||
|
const url = new URL(prefix + encodePath(endpoint), origin);
|
||||||
|
|
||||||
|
const searchParams: searchParams = {
|
||||||
|
...(auth && { auth: authStore.jwt }),
|
||||||
|
...params,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key in searchParams) {
|
||||||
|
url.searchParams.set(key, searchParams[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
37
frontend/src/types/api.d.ts
vendored
Normal file
37
frontend/src/types/api.d.ts
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
type apiUrl = string // Can also be set as a path eg: "path1" | "path2"
|
||||||
|
|
||||||
|
type resourcePath = string
|
||||||
|
|
||||||
|
type apiMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
|
||||||
|
|
||||||
|
// type apiContent = string | Blob | File
|
||||||
|
type apiContent = Blob | File | Pick<ReadableStreamDefaultReader<any>, "read"> | ""
|
||||||
|
|
||||||
|
interface apiOpts {
|
||||||
|
method?: apiMethod,
|
||||||
|
headers?: object,
|
||||||
|
body?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface tusSettings {
|
||||||
|
retryCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type algo = any
|
||||||
|
|
||||||
|
type inline = any
|
||||||
|
|
||||||
|
interface share {
|
||||||
|
expire: any,
|
||||||
|
hash: string,
|
||||||
|
path: string,
|
||||||
|
userID: number,
|
||||||
|
token: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface settings {
|
||||||
|
any
|
||||||
|
}
|
||||||
|
|
||||||
|
type searchParams = any
|
||||||
|
|
||||||
40
frontend/src/types/file.d.ts
vendored
Normal file
40
frontend/src/types/file.d.ts
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
interface file {
|
||||||
|
name: string,
|
||||||
|
modified: string,
|
||||||
|
path: string,
|
||||||
|
subtitles: any[],
|
||||||
|
isDir: boolean,
|
||||||
|
size: number,
|
||||||
|
fullPath: string,
|
||||||
|
type: uploadType
|
||||||
|
}
|
||||||
|
|
||||||
|
interface item {
|
||||||
|
id: number,
|
||||||
|
path: string,
|
||||||
|
file: file,
|
||||||
|
url?: string,
|
||||||
|
dir?: boolean,
|
||||||
|
from?: string,
|
||||||
|
to?: string,
|
||||||
|
name?: string,
|
||||||
|
type?: uploadType
|
||||||
|
overwrite: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type uploadType = "video" | "audio" | "image" | "pdf" | "text" | "blob"
|
||||||
|
|
||||||
|
interface req {
|
||||||
|
isDir?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface uploads {
|
||||||
|
[key: string]: upload
|
||||||
|
}
|
||||||
|
|
||||||
|
interface upload {
|
||||||
|
id: number,
|
||||||
|
file: file,
|
||||||
|
type: string
|
||||||
|
}
|
||||||
5
frontend/src/types/layout.d.ts
vendored
Normal file
5
frontend/src/types/layout.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
interface LayoutValue {
|
||||||
|
prompt: boolean,
|
||||||
|
confirm: boolean,
|
||||||
|
action: boolean,
|
||||||
|
}
|
||||||
7
frontend/src/types/user.d.ts
vendored
Normal file
7
frontend/src/types/user.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
interface user {
|
||||||
|
id: number,
|
||||||
|
locale: string,
|
||||||
|
perm: any
|
||||||
|
}
|
||||||
|
|
||||||
|
type userKey = keyof user
|
||||||
1
frontend/src/types/utils.d.ts
vendored
Normal file
1
frontend/src/types/utils.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
type settings = any
|
||||||
1
frontend/src/vite-env.d.ts
vendored
Normal file
1
frontend/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
Loading…
Reference in New Issue
Block a user