import { AdminProfile, AdminUserListResult, ApiError, ApiKey, LoginSession, PagedRequest, PagedResponse, PaymentOrder, Profile, SetPaymentConfigRequest, SiteInfoResponse, VoidFileResponse, } from "./index"; import { ProgressHandler, ProxyChallengeHandler, StateChangeHandler, VoidUploader, } from "./upload"; import { StreamUploader } from "./stream-uploader"; import { XHRUploader } from "./xhr-uploader"; export type AuthHandler = (url: string, method: string) => Promise; export class VoidApi { readonly #uri: string; readonly #auth?: AuthHandler; constructor(uri?: string, auth?: AuthHandler) { this.#uri = uri ?? ""; this.#auth = auth; } async #req(method: string, url: string, body?: object): Promise { const absoluteUrl = `${this.#uri}${url}`; const headers: HeadersInit = { Accept: "application/json", }; if (this.#auth) { headers["Authorization"] = await this.#auth(absoluteUrl, method); } if (body) { headers["Content-Type"] = "application/json"; } const res = await fetch(absoluteUrl, { method, headers, mode: "cors", body: body ? JSON.stringify(body) : undefined, }); const text = await res.text(); if (res.ok) { return text ? (JSON.parse(text) as T) : ({} as T); } else { throw new ApiError(res.status, text); } } /** * Get uploader for uploading files */ getUploader( file: File | Blob, stateChange?: StateChangeHandler, progress?: ProgressHandler, proxyChallenge?: ProxyChallengeHandler, chunkSize?: number, ): VoidUploader { if (StreamUploader.canUse()) { return new StreamUploader( this.#uri, file, stateChange, progress, proxyChallenge, this.#auth, chunkSize, ); } else { return new XHRUploader( this.#uri, file, stateChange, progress, proxyChallenge, this.#auth, chunkSize, ); } } /** * General site information */ info() { return this.#req("GET", "/info"); } fileInfo(id: string) { return this.#req("GET", `/upload/${id}`); } setPaymentConfig(id: string, cfg: SetPaymentConfigRequest) { return this.#req("POST", `/upload/${id}/payment`, cfg); } createOrder(id: string) { return this.#req("GET", `/upload/${id}/payment`); } getOrder(file: string, order: string) { return this.#req("GET", `/upload/${file}/payment/${order}`); } login(username: string, password: string, captcha?: string) { return this.#req("POST", `/auth/login`, { username, password, captcha, }); } register(username: string, password: string, captcha?: string) { return this.#req("POST", `/auth/register`, { username, password, captcha, }); } getUser(id: string) { return this.#req("GET", `/user/${id}`); } updateUser(u: Profile) { return this.#req("POST", `/user/${u.id}`, u); } listUserFiles(uid: string, pageReq: PagedRequest) { return this.#req>( "POST", `/user/${uid}/files`, pageReq, ); } submitVerifyCode(uid: string, code: string) { return this.#req("POST", `/user/${uid}/verify`, { code }); } sendNewCode(uid: string) { return this.#req("GET", `/user/${uid}/verify`); } updateFileMetadata(id: string, meta: any) { return this.#req("POST", `/upload/${id}/meta`, meta); } listApiKeys() { return this.#req>("GET", `/auth/api-key`); } createApiKey(req: any) { return this.#req("POST", `/auth/api-key`, req); } adminListFiles(pageReq: PagedRequest) { return this.#req>( "POST", "/admin/file", pageReq, ); } adminDeleteFile(id: string) { return this.#req("DELETE", `/admin/file/${id}`); } adminUserList(pageReq: PagedRequest) { return this.#req>( "POST", `/admin/users`, pageReq, ); } adminUpdateUser(u: AdminProfile) { return this.#req("POST", `/admin/update-user`, u); } }