You've already forked AstralRinth
forked from didirus/AstralRinth
refactor: Huge pyro servers composable cleanup (#3745)
* refactor: start refactor of pyro servers module-based class * refactor: finish modules * refactor: start on type checking + matching api * refactor: finish pyro servers composable refactor * refactor: pyro -> modrinth * fix: import not refactored * fix: broken power action enums * fix: remove pyro mentions * fix: lint * refactor: fix option pages * fix: error renames * remove empty pyro-servers.ts file --------- Signed-off-by: IMB11 <hendersoncal117@gmail.com> Co-authored-by: Prospector <prospectordev@gmail.com>
This commit is contained in:
79
apps/frontend/src/composables/servers/modules/backups.ts
Normal file
79
apps/frontend/src/composables/servers/modules/backups.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import type { Backup, AutoBackupSettings } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class BackupsModule extends ServerModule {
|
||||
data: Backup[] = [];
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
this.data = await useServersFetch<Backup[]>(`servers/${this.serverId}/backups`, {}, "backups");
|
||||
}
|
||||
|
||||
async create(backupName: string): Promise<string> {
|
||||
const response = await useServersFetch<{ id: string }>(`servers/${this.serverId}/backups`, {
|
||||
method: "POST",
|
||||
body: { name: backupName },
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
return response.id;
|
||||
}
|
||||
|
||||
async rename(backupId: string, newName: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}/rename`, {
|
||||
method: "POST",
|
||||
body: { name: newName },
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async delete(backupId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async restore(backupId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}/restore`, {
|
||||
method: "POST",
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async prepare(backupId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}/prepare-download`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
async lock(backupId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}/lock`, {
|
||||
method: "POST",
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async unlock(backupId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}/unlock`, {
|
||||
method: "POST",
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async retry(backupId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/backups/${backupId}/retry`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
async updateAutoBackup(autoBackup: "enable" | "disable", interval: number): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/autobackup`, {
|
||||
method: "POST",
|
||||
body: { set: autoBackup, interval },
|
||||
});
|
||||
}
|
||||
|
||||
async getAutoBackup(): Promise<AutoBackupSettings> {
|
||||
return await useServersFetch(`servers/${this.serverId}/autobackup`);
|
||||
}
|
||||
}
|
||||
15
apps/frontend/src/composables/servers/modules/base.ts
Normal file
15
apps/frontend/src/composables/servers/modules/base.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { ModrinthServer } from "../modrinth-servers.ts";
|
||||
|
||||
export abstract class ServerModule {
|
||||
protected server: ModrinthServer;
|
||||
|
||||
constructor(server: ModrinthServer) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
protected get serverId(): string {
|
||||
return this.server.serverId;
|
||||
}
|
||||
|
||||
abstract fetch(): Promise<void>;
|
||||
}
|
||||
36
apps/frontend/src/composables/servers/modules/content.ts
Normal file
36
apps/frontend/src/composables/servers/modules/content.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { Mod, ContentType } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class ContentModule extends ServerModule {
|
||||
data: Mod[] = [];
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
const mods = await useServersFetch<Mod[]>(`servers/${this.serverId}/mods`, {}, "content");
|
||||
this.data = mods.sort((a, b) => (a?.name ?? "").localeCompare(b?.name ?? ""));
|
||||
}
|
||||
|
||||
async install(contentType: ContentType, projectId: string, versionId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/mods`, {
|
||||
method: "POST",
|
||||
body: {
|
||||
rinth_ids: { project_id: projectId, version_id: versionId },
|
||||
install_as: contentType,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async remove(path: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/deleteMod`, {
|
||||
method: "POST",
|
||||
body: { path },
|
||||
});
|
||||
}
|
||||
|
||||
async reinstall(replace: string, projectId: string, versionId: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/mods/update`, {
|
||||
method: "POST",
|
||||
body: { replace, project_id: projectId, version_id: versionId },
|
||||
});
|
||||
}
|
||||
}
|
||||
224
apps/frontend/src/composables/servers/modules/fs.ts
Normal file
224
apps/frontend/src/composables/servers/modules/fs.ts
Normal file
@@ -0,0 +1,224 @@
|
||||
import type {
|
||||
FileUploadQuery,
|
||||
JWTAuth,
|
||||
DirectoryResponse,
|
||||
FilesystemOp,
|
||||
FSQueuedOp,
|
||||
} from "@modrinth/utils";
|
||||
import { ModrinthServerError } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class FSModule extends ServerModule {
|
||||
auth!: JWTAuth;
|
||||
ops: FilesystemOp[] = [];
|
||||
queuedOps: FSQueuedOp[] = [];
|
||||
opsQueuedForModification: string[] = [];
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
this.auth = await useServersFetch<JWTAuth>(`servers/${this.serverId}/fs`, {}, "fs");
|
||||
this.ops = [];
|
||||
this.queuedOps = [];
|
||||
this.opsQueuedForModification = [];
|
||||
}
|
||||
|
||||
private async retryWithAuth<T>(requestFn: () => Promise<T>): Promise<T> {
|
||||
try {
|
||||
return await requestFn();
|
||||
} catch (error) {
|
||||
if (error instanceof ModrinthServerError && error.statusCode === 401) {
|
||||
await this.fetch(); // Refresh auth
|
||||
return await requestFn();
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
listDirContents(path: string, page: number, pageSize: number): Promise<DirectoryResponse> {
|
||||
return this.retryWithAuth(async () => {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
return await useServersFetch(`/list?path=${encodedPath}&page=${page}&page_size=${pageSize}`, {
|
||||
override: this.auth,
|
||||
retry: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createFileOrFolder(path: string, type: "file" | "directory"): Promise<void> {
|
||||
return this.retryWithAuth(async () => {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
await useServersFetch(`/create?path=${encodedPath}&type=${type}`, {
|
||||
method: "POST",
|
||||
contentType: "application/octet-stream",
|
||||
override: this.auth,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
uploadFile(path: string, file: File): FileUploadQuery {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
const progressSubject = new EventTarget();
|
||||
const abortController = new AbortController();
|
||||
|
||||
const uploadPromise = new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.upload.addEventListener("progress", (e) => {
|
||||
if (e.lengthComputable) {
|
||||
const progress = (e.loaded / e.total) * 100;
|
||||
progressSubject.dispatchEvent(
|
||||
new CustomEvent("progress", {
|
||||
detail: { loaded: e.loaded, total: e.total, progress },
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
xhr.onload = () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
resolve(xhr.response);
|
||||
} else {
|
||||
reject(new Error(`Upload failed with status ${xhr.status}`));
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = () => reject(new Error("Upload failed"));
|
||||
xhr.onabort = () => reject(new Error("Upload cancelled"));
|
||||
|
||||
xhr.open("POST", `https://${this.auth.url}/create?path=${encodedPath}&type=file`);
|
||||
xhr.setRequestHeader("Authorization", `Bearer ${this.auth.token}`);
|
||||
xhr.setRequestHeader("Content-Type", "application/octet-stream");
|
||||
xhr.send(file);
|
||||
|
||||
abortController.signal.addEventListener("abort", () => xhr.abort());
|
||||
});
|
||||
|
||||
return {
|
||||
promise: uploadPromise,
|
||||
onProgress: (
|
||||
callback: (progress: { loaded: number; total: number; progress: number }) => void,
|
||||
) => {
|
||||
progressSubject.addEventListener("progress", ((e: CustomEvent) => {
|
||||
callback(e.detail);
|
||||
}) as EventListener);
|
||||
},
|
||||
cancel: () => abortController.abort(),
|
||||
} as FileUploadQuery;
|
||||
}
|
||||
|
||||
renameFileOrFolder(path: string, name: string): Promise<void> {
|
||||
const pathName = path.split("/").slice(0, -1).join("/") + "/" + name;
|
||||
return this.retryWithAuth(async () => {
|
||||
await useServersFetch(`/move`, {
|
||||
method: "POST",
|
||||
override: this.auth,
|
||||
body: { source: path, destination: pathName },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
updateFile(path: string, content: string): Promise<void> {
|
||||
const octetStream = new Blob([content], { type: "application/octet-stream" });
|
||||
return this.retryWithAuth(async () => {
|
||||
await useServersFetch(`/update?path=${path}`, {
|
||||
method: "PUT",
|
||||
contentType: "application/octet-stream",
|
||||
body: octetStream,
|
||||
override: this.auth,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
moveFileOrFolder(path: string, newPath: string): Promise<void> {
|
||||
return this.retryWithAuth(async () => {
|
||||
await this.server.createMissingFolders(newPath.substring(0, newPath.lastIndexOf("/")));
|
||||
await useServersFetch(`/move`, {
|
||||
method: "POST",
|
||||
override: this.auth,
|
||||
body: { source: path, destination: newPath },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
deleteFileOrFolder(path: string, recursive: boolean): Promise<void> {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
return this.retryWithAuth(async () => {
|
||||
await useServersFetch(`/delete?path=${encodedPath}&recursive=${recursive}`, {
|
||||
method: "DELETE",
|
||||
override: this.auth,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
downloadFile(path: string, raw?: boolean): Promise<any> {
|
||||
return this.retryWithAuth(async () => {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
const fileData = await useServersFetch(`/download?path=${encodedPath}`, {
|
||||
override: this.auth,
|
||||
});
|
||||
|
||||
if (fileData instanceof Blob) {
|
||||
return raw ? fileData : await fileData.text();
|
||||
}
|
||||
return fileData;
|
||||
});
|
||||
}
|
||||
|
||||
extractFile(
|
||||
path: string,
|
||||
override = true,
|
||||
dry = false,
|
||||
silentQueue = false,
|
||||
): Promise<{ modpack_name: string | null; conflicting_files: string[] }> {
|
||||
return this.retryWithAuth(async () => {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
|
||||
if (!silentQueue) {
|
||||
this.queuedOps.push({ op: "unarchive", src: path });
|
||||
setTimeout(() => this.removeQueuedOp("unarchive", path), 4000);
|
||||
}
|
||||
|
||||
try {
|
||||
return await useServersFetch(
|
||||
`/unarchive?src=${encodedPath}&trg=/&override=${override}&dry=${dry}`,
|
||||
{
|
||||
method: "POST",
|
||||
override: this.auth,
|
||||
version: 1,
|
||||
},
|
||||
undefined,
|
||||
"Error extracting file",
|
||||
);
|
||||
} catch (err) {
|
||||
this.removeQueuedOp("unarchive", path);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
modifyOp(id: string, action: "dismiss" | "cancel"): Promise<void> {
|
||||
return this.retryWithAuth(async () => {
|
||||
await useServersFetch(
|
||||
`/ops/${action}?id=${id}`,
|
||||
{
|
||||
method: "POST",
|
||||
override: this.auth,
|
||||
version: 1,
|
||||
},
|
||||
undefined,
|
||||
`Error ${action === "dismiss" ? "dismissing" : "cancelling"} filesystem operation`,
|
||||
);
|
||||
|
||||
this.opsQueuedForModification = this.opsQueuedForModification.filter((x: string) => x !== id);
|
||||
this.ops = this.ops.filter((x: FilesystemOp) => x.id !== id);
|
||||
});
|
||||
}
|
||||
|
||||
removeQueuedOp(op: FSQueuedOp["op"], src: string): void {
|
||||
this.queuedOps = this.queuedOps.filter((x: FSQueuedOp) => x.op !== op || x.src !== src);
|
||||
}
|
||||
|
||||
clearQueuedOps(): void {
|
||||
this.queuedOps = [];
|
||||
}
|
||||
}
|
||||
173
apps/frontend/src/composables/servers/modules/general.ts
Normal file
173
apps/frontend/src/composables/servers/modules/general.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import { $fetch } from "ofetch";
|
||||
import type { ServerGeneral, Project, PowerAction, JWTAuth } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class GeneralModule extends ServerModule implements ServerGeneral {
|
||||
server_id!: string;
|
||||
name!: string;
|
||||
net!: { ip: string; port: number; domain: string };
|
||||
game!: string;
|
||||
backup_quota!: number;
|
||||
used_backup_quota!: number;
|
||||
status!: string;
|
||||
suspension_reason!: string;
|
||||
loader!: string;
|
||||
loader_version!: string;
|
||||
mc_version!: string;
|
||||
upstream!: {
|
||||
kind: "modpack" | "mod" | "resourcepack";
|
||||
version_id: string;
|
||||
project_id: string;
|
||||
} | null;
|
||||
|
||||
motd?: string;
|
||||
image?: string;
|
||||
project?: Project;
|
||||
sftp_username!: string;
|
||||
sftp_password!: string;
|
||||
sftp_host!: string;
|
||||
datacenter?: string;
|
||||
notices?: any[];
|
||||
node!: { token: string; instance: string };
|
||||
flows?: { intro?: boolean };
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
const data = await useServersFetch<ServerGeneral>(`servers/${this.serverId}`, {}, "general");
|
||||
|
||||
if (data.upstream?.project_id) {
|
||||
const project = await $fetch(
|
||||
`https://api.modrinth.com/v2/project/${data.upstream.project_id}`,
|
||||
);
|
||||
data.project = project as Project;
|
||||
}
|
||||
|
||||
if (import.meta.client) {
|
||||
data.image = (await this.server.processImage(data.project?.icon_url)) ?? undefined;
|
||||
}
|
||||
|
||||
const motd = await this.getMotd();
|
||||
if (motd === "A Minecraft Server") {
|
||||
await this.setMotd(
|
||||
`§b${data.project?.title || data.loader + " " + data.mc_version} §f♦ §aModrinth Servers`,
|
||||
);
|
||||
}
|
||||
data.motd = motd;
|
||||
|
||||
// Copy data to this module
|
||||
Object.assign(this, data);
|
||||
}
|
||||
|
||||
async updateName(newName: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/name`, {
|
||||
method: "POST",
|
||||
body: { name: newName },
|
||||
});
|
||||
}
|
||||
|
||||
async power(action: PowerAction): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/power`, {
|
||||
method: "POST",
|
||||
body: { action },
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async reinstall(
|
||||
loader: boolean,
|
||||
projectId: string,
|
||||
versionId?: string,
|
||||
loaderVersionId?: string,
|
||||
hardReset: boolean = false,
|
||||
): Promise<void> {
|
||||
const hardResetParam = hardReset ? "true" : "false";
|
||||
if (loader) {
|
||||
if (projectId.toLowerCase() === "neoforge") {
|
||||
projectId = "NeoForge";
|
||||
}
|
||||
await useServersFetch(`servers/${this.serverId}/reinstall?hard=${hardResetParam}`, {
|
||||
method: "POST",
|
||||
body: { loader: projectId, loader_version: loaderVersionId, game_version: versionId },
|
||||
});
|
||||
} else {
|
||||
await useServersFetch(`servers/${this.serverId}/reinstall?hard=${hardResetParam}`, {
|
||||
method: "POST",
|
||||
body: { project_id: projectId, version_id: versionId },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async reinstallFromMrpack(mrpack: File, hardReset: boolean = false): Promise<void> {
|
||||
const hardResetParam = hardReset ? "true" : "false";
|
||||
const auth = await useServersFetch<JWTAuth>(`servers/${this.serverId}/reinstallFromMrpack`);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("file", mrpack);
|
||||
|
||||
const response = await fetch(
|
||||
`https://${auth.url}/reinstallMrpackMultiparted?hard=${hardResetParam}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
},
|
||||
body: formData,
|
||||
signal: AbortSignal.timeout(30 * 60 * 1000),
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`[pyroservers] native fetch err status: ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async suspend(status: boolean): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/suspend`, {
|
||||
method: "POST",
|
||||
body: { suspended: status },
|
||||
});
|
||||
}
|
||||
|
||||
async endIntro(): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/flows/intro`, {
|
||||
method: "DELETE",
|
||||
version: 1,
|
||||
});
|
||||
await this.fetch(); // Refresh this module
|
||||
}
|
||||
|
||||
async getMotd(): Promise<string | undefined> {
|
||||
try {
|
||||
const props = await this.server.fs.downloadFile("/server.properties");
|
||||
if (props) {
|
||||
const lines = props.split("\n");
|
||||
for (const line of lines) {
|
||||
if (line.startsWith("motd=")) {
|
||||
return line.slice(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async setMotd(motd: string): Promise<void> {
|
||||
const props = (await this.server.fetchConfigFile("ServerProperties")) as any;
|
||||
if (props) {
|
||||
props.motd = motd;
|
||||
const newProps = this.server.constructServerProperties(props);
|
||||
const octetStream = new Blob([newProps], { type: "application/octet-stream" });
|
||||
const auth = await useServersFetch<JWTAuth>(`servers/${this.serverId}/fs`);
|
||||
|
||||
await useServersFetch(`/update?path=/server.properties`, {
|
||||
method: "PUT",
|
||||
contentType: "application/octet-stream",
|
||||
body: octetStream,
|
||||
override: auth,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
8
apps/frontend/src/composables/servers/modules/index.ts
Normal file
8
apps/frontend/src/composables/servers/modules/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from "./base.ts";
|
||||
export * from "./backups.ts";
|
||||
export * from "./content.ts";
|
||||
export * from "./fs.ts";
|
||||
export * from "./general.ts";
|
||||
export * from "./network.ts";
|
||||
export * from "./startup.ts";
|
||||
export * from "./ws.ts";
|
||||
47
apps/frontend/src/composables/servers/modules/network.ts
Normal file
47
apps/frontend/src/composables/servers/modules/network.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { Allocation } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class NetworkModule extends ServerModule {
|
||||
allocations: Allocation[] = [];
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
this.allocations = await useServersFetch<Allocation[]>(
|
||||
`servers/${this.serverId}/allocations`,
|
||||
{},
|
||||
"network",
|
||||
);
|
||||
}
|
||||
|
||||
async reserveAllocation(name: string): Promise<Allocation> {
|
||||
return await useServersFetch<Allocation>(`servers/${this.serverId}/allocations?name=${name}`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
async updateAllocation(port: number, name: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/allocations/${port}?name=${name}`, {
|
||||
method: "PUT",
|
||||
});
|
||||
}
|
||||
|
||||
async deleteAllocation(port: number): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/allocations/${port}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
|
||||
async checkSubdomainAvailability(subdomain: string): Promise<boolean> {
|
||||
const result = (await useServersFetch(`subdomains/${subdomain}/isavailable`)) as {
|
||||
available: boolean;
|
||||
};
|
||||
return result.available;
|
||||
}
|
||||
|
||||
async changeSubdomain(subdomain: string): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/subdomain`, {
|
||||
method: "POST",
|
||||
body: { subdomain },
|
||||
});
|
||||
}
|
||||
}
|
||||
26
apps/frontend/src/composables/servers/modules/startup.ts
Normal file
26
apps/frontend/src/composables/servers/modules/startup.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { Startup, JDKVersion, JDKBuild } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class StartupModule extends ServerModule implements Startup {
|
||||
invocation!: string;
|
||||
original_invocation!: string;
|
||||
jdk_version!: JDKVersion;
|
||||
jdk_build!: JDKBuild;
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
const data = await useServersFetch<Startup>(`servers/${this.serverId}/startup`, {}, "startup");
|
||||
Object.assign(this, data);
|
||||
}
|
||||
|
||||
async update(invocation: string, jdkVersion: JDKVersion, jdkBuild: JDKBuild): Promise<void> {
|
||||
await useServersFetch(`servers/${this.serverId}/startup`, {
|
||||
method: "POST",
|
||||
body: {
|
||||
invocation: invocation || null,
|
||||
jdk_version: jdkVersion || null,
|
||||
jdk_build: jdkBuild || null,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
13
apps/frontend/src/composables/servers/modules/ws.ts
Normal file
13
apps/frontend/src/composables/servers/modules/ws.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { JWTAuth } from "@modrinth/utils";
|
||||
import { useServersFetch } from "../servers-fetch.ts";
|
||||
import { ServerModule } from "./base.ts";
|
||||
|
||||
export class WSModule extends ServerModule implements JWTAuth {
|
||||
url!: string;
|
||||
token!: string;
|
||||
|
||||
async fetch(): Promise<void> {
|
||||
const data = await useServersFetch<JWTAuth>(`servers/${this.serverId}/ws`, {}, "ws");
|
||||
Object.assign(this, data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user