import { useQuery, useQueryClient } from "@tanstack/react-query"; const fetchApi = (subPath) => async () => fetch(`/api${subPath}`).then((res) => res.json()); const fetchApiCore = async (subPath, json, method = "POST", jsonify = false) => fetch(`/api${subPath}`, { method, headers: { "Content-Type": "application/json", }, body: JSON.stringify(json), }).then((res) => (jsonify ? res.json() : res)); const fetchApiPost = (subPath, json) => async () => fetch(`/api${subPath}`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(json), }).then((res) => res.json()); export const useServerStatus = (serverId) => useQuery({ queryKey: [`server-status-${serverId}`], queryFn: fetchApiPost("/server/status", { id: serverId }), }); export const useServerMetrics = (serverId) => useQuery({ queryKey: [`server-metrics-${serverId}`], queryFn: fetchApiPost("/server/metrics", { id: serverId }), refetchInterval: 10000, }); export const useStartServer = (serverId) => postJsonApi("/server/start", { id: serverId }, "server-instances"); export const useStopServer = (serverId) => postJsonApi("/server/stop", { id: serverId }, "server-instances"); export const useDeleteServer = (serverId) => postJsonApi("/server/delete", { id: serverId }, "server-instances", "DELETE"); export const useCreateServer = (spec) => postJsonApi("/server/create", spec, "server-list"); export const getServerFiles = async (serverId, path) => fetchApiCore("/files/list", { id: serverId, path }, "POST", true); export const createServerFolder = async (serverId, path) => fetchApiCore("/files/folder", { id: serverId, path, }); export const deleteServerItem = async (serverId, path, isDir) => fetchApiCore("/files/item", { id: serverId, path, isDir }, "DELETE"); export async function previewServerItem(serverId, path) { const resp = await fetchApiCore("/files/item", { id: serverId, path }); if (!resp.status === 200) return console.log("AHHHH"); const blob = await resp.blob(); return blob; } export const getServerItem = async (serverId, name, path) => fetchApiCore("/files/item", { id: serverId, path }) .then((resp) => resp.status === 200 ? resp.blob() : Promise.reject("something went wrong"), ) .then((blob) => { const url = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.style.display = "none"; a.href = url; a.download = name; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); }); export const useInvalidator = () => { const qc = useQueryClient(); return (q) => qc.invalidateQueries([q]); }; export const useServerList = () => useQuery({ queryKey: ["server-list"], queryFn: fetchApi("/server/list") }); export const useServerInstances = () => useQuery({ queryKey: ["server-instances"], queryFn: fetchApi("/server/instances"), refetchInterval: 5000, }); export const useSystemAvailable = () => useQuery({ queryKey: ["system-available"], queryFn: fetchApi("/system/available"), }); export const useVersionList = () => useQuery({ queryKey: ["minecraft-versions"], queryFn: () => fetch( "https://piston-meta.mojang.com/mc/game/version_manifest.json", ).then((r) => r.json()), }); const postJsonApi = (subPath, body, invalidate, method = "POST") => { const qc = useQueryClient(); return async () => { const res = await fetch(`/api${subPath}`, { method, headers: { "Content-Type": "application/json", }, body: JSON.stringify(body), }); if (invalidate) qc.invalidateQueries([invalidate]); }; };