mirror of
https://github.com/Stef-00012/Zipline-Android-App.git
synced 2025-05-11 18:35:58 +02:00
add some types & functions to manage zipline
This commit is contained in:
parent
ed5c91435d
commit
370194a486
20 changed files with 3170 additions and 97 deletions
35
functions/util.ts
Normal file
35
functions/util.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import mimetypesJSON from "@/assets/mimetypes.json";
|
||||
import type { Mimetypes } from "@/types/mimetypes";
|
||||
|
||||
const mimetypes = mimetypesJSON as Mimetypes;
|
||||
|
||||
export function generateRandomString(): string {
|
||||
return Math.random().toString(36).substring(2, 6);
|
||||
}
|
||||
|
||||
export function guessMimetype(
|
||||
mimetype: keyof Mimetypes,
|
||||
): Mimetypes[keyof Mimetypes] {
|
||||
if (!mimetype) return "so";
|
||||
|
||||
const mime = mimetypes[mimetype];
|
||||
if (!mime) return "so";
|
||||
|
||||
return mime;
|
||||
}
|
||||
|
||||
export function convertToBlob(data: string): Blob {
|
||||
const base64Data = data.split(",")[1];
|
||||
const mimetype = data.split(":")[1].split(";").shift();
|
||||
const string = atob(base64Data);
|
||||
const length = string.length;
|
||||
const bytes = new Uint8Array(length);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
bytes[i] = string.charCodeAt(i);
|
||||
}
|
||||
|
||||
const blob = new Blob([bytes], { type: mimetype || "image/png" });
|
||||
|
||||
return blob;
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type { APIRecentFiles, APIStats, APIUser } from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
export async function getUser() {
|
||||
const token = db.get("token")
|
||||
const url = db.get("url")
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user`, {
|
||||
headers: {
|
||||
Authorization: token
|
||||
}
|
||||
})
|
||||
|
||||
return res.data.user as APIUser;
|
||||
} catch(e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getRecentFiles() {
|
||||
const token = db.get("token")
|
||||
const url = db.get("url")
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/recent`, {
|
||||
headers: {
|
||||
Authorization: token
|
||||
}
|
||||
})
|
||||
|
||||
return res.data as APIRecentFiles;
|
||||
} catch(e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStats() {
|
||||
const token = db.get("token")
|
||||
const url = db.get("url")
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/stats`, {
|
||||
headers: {
|
||||
Authorization: token
|
||||
}
|
||||
})
|
||||
|
||||
return res.data as APIStats;
|
||||
} catch(e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserAvatar() {
|
||||
const token = db.get("token")
|
||||
const url = db.get("url")
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/avatar`, {
|
||||
headers: {
|
||||
Authorization: token
|
||||
}
|
||||
})
|
||||
|
||||
return res.data as string;
|
||||
} catch(e) {
|
||||
return null;
|
||||
}
|
||||
}
|
65
functions/zipline/exports.ts
Normal file
65
functions/zipline/exports.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type { APIExports } from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
|
||||
// GET /api/user/export
|
||||
export async function getUserExports(): Promise<APIExports | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/export`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data.user;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/user/export
|
||||
export async function createUserExport(): Promise<{ running: boolean } | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.post(`${url}/api/user/export`, null, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data.user;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/user/export?id=[id]
|
||||
export async function deleteUserExport(id: string): Promise<{ deleted: boolean } | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.delete(`${url}/api/user/export?id=${id}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data.user;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
257
functions/zipline/files.ts
Normal file
257
functions/zipline/files.ts
Normal file
|
@ -0,0 +1,257 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type { APIFile, APIFiles, APISettings } from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
import { getSettings } from "@/functions/zipline/settings";
|
||||
import bytesFn, { BytesOptions } from "bytes";
|
||||
import { convertToBlob, generateRandomString, guessMimetype } from "../util";
|
||||
import type { Mimetypes } from "@/types/mimetypes";
|
||||
|
||||
// GET /api/user/files
|
||||
export async function getFiles(page: number): Promise<APIFiles | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
page: String(page),
|
||||
});
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/files?${params}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/user/files/[id]
|
||||
export async function getFile(id: string): Promise<APIFile | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/files/${id}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/user/files/[id]
|
||||
export async function deleteFile(id: string): Promise<APIFile | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.delete(`${url}/api/user/files/${id}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateFileTagsOptions {
|
||||
add?: Array<string>;
|
||||
remove?: Array<string>;
|
||||
}
|
||||
// PATCH /api/user/files/[id]
|
||||
export async function updateFileTags(
|
||||
id: string,
|
||||
options: UpdateFileTagsOptions = {},
|
||||
): Promise<APIFile | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const file = await getFile(id);
|
||||
|
||||
let newTags = (file?.tags || []).map((tag) => tag.id);
|
||||
|
||||
if (options.remove)
|
||||
newTags = newTags.filter((tag) => !options.remove?.includes(tag));
|
||||
if (options.add) newTags.push(...options.add);
|
||||
|
||||
const res = await axios.patch(
|
||||
`${url}/api/user/files/${id}`,
|
||||
{
|
||||
tags: newTags,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface EditFileOptions {
|
||||
originalName?: string;
|
||||
maxViews?: number;
|
||||
password?: string;
|
||||
type?: string;
|
||||
favorite?: boolean;
|
||||
}
|
||||
// PATCH /api/user/files/[id]
|
||||
export async function editFile(
|
||||
id: string,
|
||||
options: EditFileOptions = {},
|
||||
): Promise<APIFile | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.patch(`${url}/api/user/files/${id}`, options, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface UploadFileOptions {
|
||||
text?: boolean;
|
||||
maxViews?: number;
|
||||
compression?: number;
|
||||
format?: APISettings["filesDefaultFormat"];
|
||||
password?: string;
|
||||
filename?: string;
|
||||
folder?: string;
|
||||
overrideDomain?: string;
|
||||
originalName?: boolean;
|
||||
expiresAt?: Date;
|
||||
}
|
||||
// POST /api/upload
|
||||
export async function uploadToZipline(
|
||||
file: string,
|
||||
options: UploadFileOptions = {},
|
||||
) {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
const blob = convertToBlob(file);
|
||||
|
||||
const settings = await getSettings();
|
||||
|
||||
const chunksMax = bytesFn(settings?.chunksMax || "95mb") || 95 * 1024 * 1024;
|
||||
const chunksSize =
|
||||
bytesFn(settings?.chunksSize || "25mb") || 25 * 1024 * 1024;
|
||||
|
||||
const headers: {
|
||||
[key: string]: string;
|
||||
} = {};
|
||||
|
||||
headers.Authorization = token;
|
||||
headers["X-Zipline-Format"] = options.format?.toLowerCase() || "random";
|
||||
|
||||
if (options.compression)
|
||||
headers["X-Zipline-Image-Compression-Percent"] = String(
|
||||
options.compression,
|
||||
);
|
||||
if (options.maxViews)
|
||||
headers["X-Zipline-Max-Views"] = String(options.maxViews);
|
||||
if (options.password) headers["X-Zipline-Password"] = options.password;
|
||||
if (options.folder) headers["X-Zipline-Folder"] = options.folder;
|
||||
if (options.overrideDomain)
|
||||
headers["X-Zipline-Domain"] = options.overrideDomain;
|
||||
if (options.expiresAt)
|
||||
headers["X-Zipline-Deletes-At"] = `date=${options.expiresAt.toISOString()}`;
|
||||
if (options.originalName) headers["X-Zipline-Original-Name"] = "true";
|
||||
if (options.filename) headers["X-Zipline-Filename"] = options.filename;
|
||||
|
||||
if (blob.size < chunksMax) {
|
||||
const filename = `${new Date().toISOString()}.${guessMimetype(blob.type as keyof Mimetypes) || "png"}`;
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
if (options.text)
|
||||
formData.append("file", blob, `${new Date().toISOString()}.txt`);
|
||||
else formData.append("file", blob, filename);
|
||||
|
||||
try {
|
||||
const res = await axios.post(`${url}/api/upload`, formData, {
|
||||
headers,
|
||||
});
|
||||
|
||||
const data = await res.data;
|
||||
|
||||
const fileUrl = data?.files?.[0]?.url;
|
||||
|
||||
if (fileUrl) return url;
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
const numberOfChunks = Math.ceil(blob.size / chunksSize);
|
||||
|
||||
const identifier = generateRandomString();
|
||||
const filename = `${new Date().toISOString()}.${(await guessMimetype(blob.type as keyof Mimetypes)) || "png"}`;
|
||||
|
||||
for (let i = numberOfChunks - 1; i >= 0; i--) {
|
||||
const chunkId = numberOfChunks - i;
|
||||
|
||||
const start = i * chunksSize;
|
||||
const end = Math.min(start + chunksSize, blob.size);
|
||||
|
||||
const chunk = blob.slice(start, end);
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append("file", chunk, filename);
|
||||
|
||||
headers["Content-Range"] = `bytes ${start}-${end - 1}/${blob.size}`;
|
||||
|
||||
headers["X-Zipline-P-Filename"] = filename;
|
||||
headers["X-Zipline-P-Lastchunk"] = i === 0 ? "true" : "false";
|
||||
headers["X-Zipline-P-Identifier"] = identifier;
|
||||
headers["X-Zipline-P-Mimetype"] = blob.type;
|
||||
|
||||
try {
|
||||
const response = await axios.post(`${url}/api/upload`, formData, {
|
||||
headers,
|
||||
});
|
||||
|
||||
const data = await response.data;
|
||||
|
||||
if (data.files?.length > 0) return data.files?.[0]?.url;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
147
functions/zipline/folders.ts
Normal file
147
functions/zipline/folders.ts
Normal file
|
@ -0,0 +1,147 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APIFoldersNoIncl,
|
||||
APIFolders,
|
||||
APIFolder,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /api/user/folders
|
||||
export async function getFolders<T extends boolean | undefined = undefined>(
|
||||
noIncl?: T,
|
||||
): Promise<T extends true ? APIFoldersNoIncl | null : APIFolders | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (noIncl) params.append("noincl", "true");
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/folders?${params}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/user/folders
|
||||
export async function createFolder(name: string, isPublic = false): Promise<APIFolder | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.post(`${url}/api/user/folders`, {
|
||||
name,
|
||||
isPublic
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH /api/user/folders/[id]
|
||||
export async function editFolder(id: string, isPublic: boolean): Promise<APIFolder | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.patch(`${url}/api/user/folders/${id}`, {
|
||||
isPublic
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/user/folders/[id]
|
||||
export async function deleteFolder(id: string): Promise<APIFolder | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.delete(`${url}/api/user/folders/${id}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
data: {
|
||||
delete: "folder"
|
||||
}
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/user/folders/[folderId]
|
||||
export async function removeFileFromFolder(folderId: string, fileId: string): Promise<APIFolder | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.delete(`${url}/api/user/folders/${folderId}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
data: {
|
||||
delete: "file",
|
||||
id: fileId
|
||||
}
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/user/folders/[folderId]
|
||||
export async function addFileToFolder(folderId: string, fileId: string): Promise<APIFolder | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.post(`${url}/api/user/folders/${folderId}`, {
|
||||
id: fileId
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
}
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
25
functions/zipline/invites.ts
Normal file
25
functions/zipline/invites.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APIInvites,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /api/auth/invites
|
||||
export async function getInvites(): Promise<APIInvites | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/auth/invites`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
47
functions/zipline/settings.ts
Normal file
47
functions/zipline/settings.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APISettings,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /api/server/settings
|
||||
export async function getSettings(): Promise<APISettings | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/server/settings`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH /api/server/settings
|
||||
export async function updateSettings(
|
||||
settings: Partial<APISettings> = {},
|
||||
): Promise<APISettings | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.patch(`${url}/api/server/settings`, settings, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
54
functions/zipline/stats.ts
Normal file
54
functions/zipline/stats.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APIUserStats,
|
||||
APIStats,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /api/stats
|
||||
export async function getStats(
|
||||
from?: string,
|
||||
to?: string,
|
||||
): Promise<APIStats | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (from) params.append("from", from);
|
||||
if (to) params.append("to", to);
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/stats?${params}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/user/stats
|
||||
export async function getUserStats(): Promise<APIUserStats | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/stats`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
117
functions/zipline/urls.ts
Normal file
117
functions/zipline/urls.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APIURLs,
|
||||
APIURL,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /user/urls
|
||||
export async function getURLs(): Promise<APIURLs | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/urls`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateURLParams {
|
||||
destination: string;
|
||||
vanity?: string;
|
||||
maxView?: number;
|
||||
}
|
||||
// POST /api/user/urls
|
||||
export async function createURL({
|
||||
destination,
|
||||
vanity,
|
||||
maxView,
|
||||
}: CreateURLParams): Promise<{
|
||||
url: string;
|
||||
} | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
const headers: { [key: string]: string | number } = {};
|
||||
|
||||
if (maxView) headers["X-Zipline-Max-Views"] = maxView;
|
||||
|
||||
try {
|
||||
const res = await axios.post(
|
||||
`${url}/api/user/urls`,
|
||||
{
|
||||
destination,
|
||||
vanity,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: token,
|
||||
...headers,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/user/urls/[id]
|
||||
export async function deleteURL(id: string): Promise<APIURL | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.delete(`${url}/api/user/urls/${id}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface editURLOptions {
|
||||
destination?: string;
|
||||
maxViews?: number;
|
||||
password?: string;
|
||||
}
|
||||
// PATCH /api/user/urls/[id]
|
||||
export async function editURL(
|
||||
id: string,
|
||||
options: editURLOptions = {},
|
||||
): Promise<APIURL | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.patch(`${url}/api/user/urls/${id}`, options, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
66
functions/zipline/user.ts
Normal file
66
functions/zipline/user.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APIRecentFiles,
|
||||
APISelfUser,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /api/user
|
||||
export async function getUser(): Promise<APISelfUser | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data.user;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/user/recent
|
||||
export async function getRecentFiles(): Promise<APIRecentFiles | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/recent`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/user/avatar
|
||||
export async function getUserAvatar(): Promise<string | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/user/avatar`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
141
functions/zipline/users.ts
Normal file
141
functions/zipline/users.ts
Normal file
|
@ -0,0 +1,141 @@
|
|||
import * as db from "@/functions/database";
|
||||
import type {
|
||||
APIUsersNoIncl,
|
||||
APIUsers,
|
||||
APIUser,
|
||||
APIUserQuota,
|
||||
} from "@/types/zipline";
|
||||
import axios from "axios";
|
||||
|
||||
// GET /api/users(?noincl=true)
|
||||
export async function getUsers<T extends boolean | undefined = undefined>(
|
||||
noIncl?: T,
|
||||
): Promise<T extends true ? APIUsersNoIncl | null : APIUsers | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (noIncl) params.append("noincl", "true");
|
||||
|
||||
try {
|
||||
const res = await axios.get(`${url}/api/users?${params}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/users
|
||||
export async function createUser(
|
||||
username: string,
|
||||
password: string,
|
||||
role: APIUser["role"],
|
||||
avatar?: string,
|
||||
) {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.post(
|
||||
`${url}/api/users`,
|
||||
{
|
||||
username,
|
||||
password,
|
||||
role,
|
||||
avatar,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/users/[id]
|
||||
export async function deleteUser(
|
||||
id: string,
|
||||
deleteData = false,
|
||||
): Promise<APIUser | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.delete(`${url}/api/users/${id}`, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
data: {
|
||||
delete: deleteData,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH /api/users/[id]
|
||||
export async function editUser(
|
||||
id: string,
|
||||
options: Partial<
|
||||
Omit<
|
||||
APIUser,
|
||||
| "id"
|
||||
| "createdAt"
|
||||
| "updatedAt"
|
||||
| "role"
|
||||
| "view"
|
||||
| "oauthProviders"
|
||||
| "totpSecret"
|
||||
| "passkeys"
|
||||
| "sessions"
|
||||
| "quota"
|
||||
> & {
|
||||
role?: Exclude<APIUser["role"], "SUPERADMIN">;
|
||||
quota?: Partial<
|
||||
Omit<
|
||||
APIUserQuota,
|
||||
"id" | "createdAt" | "updatedAt" | "filesQuota" | "userId"
|
||||
> & {
|
||||
filesType?: APIUserQuota["filesQuota"];
|
||||
}
|
||||
>;
|
||||
}
|
||||
> = {},
|
||||
): Promise<APIUser | null> {
|
||||
const token = db.get("token");
|
||||
const url = db.get("url");
|
||||
|
||||
if (!url || !token) return null;
|
||||
|
||||
try {
|
||||
const res = await axios.patch(`${url}/api/users/${id}`, options, {
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue