const ApiBase = "/api"; async function ParseJsonOrThrow(Response) { const Body = await Response.json().catch(() => null); if (!Response.ok) { const Detail = Body && Body.detail ? Body.detail : Response.statusText; throw new Error(Detail); } return Body; } function FetchJson(Path, Options = {}) { return fetch(`${ApiBase}${Path}`, { credentials: "same-origin", ...Options }).then( ParseJsonOrThrow ); } function FetchText(Path, Options = {}) { return fetch(`${ApiBase}${Path}`, { credentials: "same-origin", ...Options }).then( (Response) => Response.text() ); } function JsonBody(Body) { return { headers: { "Content-Type": "application/json" }, body: JSON.stringify(Body) }; } export function FetchAuthStatus() { return FetchJson("/auth/status"); } export function Bootstrap(Username, Password) { return FetchJson("/auth/bootstrap", { method: "POST", ...JsonBody({ Username, Password }) }); } export function Login(Username, Password) { return FetchJson("/auth/login", { method: "POST", ...JsonBody({ Username, Password }) }); } export function Logout() { return FetchJson("/auth/logout", { method: "POST" }); } export function FetchMe() { return FetchJson("/auth/me"); } export function FetchUsers() { return FetchJson("/users"); } export function CreateUserAccount(Username, Password, IsAdmin, Colour) { return FetchJson("/users", { method: "POST", ...JsonBody({ Username, Password, IsAdmin, Colour }) }); } export function FetchProfileColourOptions() { return FetchJson("/profile/colours"); } export function UpdateProfileColour(Colour) { return FetchJson("/profile/colour", { method: "PUT", ...JsonBody({ Colour }) }); } export async function UploadAvatar(File) { const Form = new FormData(); Form.append("Avatar", File); const Response = await fetch(`${ApiBase}/profile/avatar`, { method: "POST", credentials: "same-origin", body: Form, }); return ParseJsonOrThrow(Response); } export function GetAvatarUrl(Username) { const Params = new URLSearchParams({ Username }); return `${ApiBase}/profile/avatar?${Params}`; } export function UpdateUsername(NewUsername) { return FetchJson("/profile/username", { method: "PUT", ...JsonBody({ NewUsername }) }); } export function ChangePassword(CurrentPassword, NewPassword) { return FetchJson("/profile/password", { method: "PUT", ...JsonBody({ CurrentPassword, NewPassword }), }); } export function FetchGroups() { return FetchJson("/groups"); } export function CreateGroupApi(Name) { return FetchJson("/groups", { method: "POST", ...JsonBody({ Name }) }); } export function DeleteGroupApi(Name) { const Params = new URLSearchParams({ Name }); return FetchJson(`/groups?${Params}`, { method: "DELETE" }); } export function SetGroupMembersApi(Name, Members) { const Params = new URLSearchParams({ Name }); return FetchJson(`/groups/members?${Params}`, { method: "PUT", ...JsonBody({ Members }) }); } export function FetchLocks() { return FetchJson("/locks"); } export function FetchLock(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/lock?${Params}`); } export function SetLock(RootName, RelativePath, Users, Groups) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/lock?${Params}`, { method: "PUT", ...JsonBody({ Users, Groups }) }); } export function RemoveLock(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/lock?${Params}`, { method: "DELETE" }); } export function FetchRoots() { return FetchJson("/roots"); } export function FetchTree(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/tree?${Params}`); } export function FetchFile(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchText(`/file?${Params}`); } export function FetchResolvedFile(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/file/resolved?${Params}`); } export function GetFileUrl(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return `${ApiBase}/file?${Params}`; } export function GetRawFileUrl(RootName, RelativePath) { const EncodedSegments = RelativePath.split("/").map(encodeURIComponent); return `${ApiBase}/raw/${encodeURIComponent(RootName)}/${EncodedSegments.join("/")}`; } export function SaveFile(RootName, RelativePath, Content) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/file?${Params}`, { method: "PUT", body: Content }); } export function FetchBook(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/book?${Params}`); } export function FetchBlame(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/blame?${Params}`); } export function CreateEntry(RootName, RelativePath, IsDirectory) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/tree?${Params}`, { method: "POST", ...JsonBody({ IsDirectory }) }); } export function RenameEntry(RootName, RelativePath, NewName) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/tree?${Params}`, { method: "PATCH", ...JsonBody({ NewName }) }); } export function MoveEntry(RootName, RelativePath, DestinationPath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/tree?${Params}`, { method: "PATCH", ...JsonBody({ DestinationPath }) }); } export function DeleteEntry(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/tree?${Params}`, { method: "DELETE" }); } export function EnsureDirectoryNote(RootName, RelativePath) { const Params = new URLSearchParams({ Root: RootName, Path: RelativePath }); return FetchJson(`/note?${Params}`, { method: "POST" }); } export function FetchSettings() { return FetchJson("/settings"); } export function SaveSettings(NewSettings) { return FetchJson("/settings", { method: "PUT", ...JsonBody(NewSettings) }); } export function FetchThemeNames() { return FetchJson("/themes"); } export function FetchTheme(Name) { const Params = new URLSearchParams({ Name }); return FetchJson(`/theme?${Params}`); } export function SaveTheme(Name, Palette) { const Params = new URLSearchParams({ Name }); return FetchJson(`/theme?${Params}`, { method: "PUT", ...JsonBody({ Palette }) }); } export function DeleteTheme(Name) { const Params = new URLSearchParams({ Name }); return FetchJson(`/theme?${Params}`, { method: "DELETE" }); }