Import source: src/api/services/http-panel-service

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:10:03 +03:30
parent 5536933de0
commit ff949c7889
+125
View File
@@ -0,0 +1,125 @@
import type { ApiResponse, JobProgress, QueryParams } from "@/api/contracts/common";
import type { DnsRecord, Website } from "@/api/contracts/models";
const configuredApiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL?.trim();
export const hasConfiguredHttpApi = Boolean(configuredApiBaseUrl);
const apiBaseUrl = configuredApiBaseUrl?.replace(/\/$/, "");
type RequestOptions = {
method?: "GET" | "POST" | "PUT" | "DELETE";
body?: unknown;
params?: QueryParams;
};
function queryString(params?: QueryParams) {
const search = new URLSearchParams();
if (params?.search) search.set("search", params.search);
if (params?.pagination) {
search.set("page", String(params.pagination.page));
search.set("pageSize", String(params.pagination.pageSize));
}
const value = search.toString();
return value ? `?${value}` : "";
}
async function request<T>(path: string, options: RequestOptions = {}): Promise<ApiResponse<T>> {
if (!apiBaseUrl) {
throw new Error("NEXT_PUBLIC_API_BASE_URL is not configured.");
}
const url =
apiBaseUrl === "." || apiBaseUrl === "same-origin"
? path
: apiBaseUrl.endsWith("/api") && path.startsWith("/api/")
? `${apiBaseUrl}${path.slice(4)}`
: `${apiBaseUrl}${path}`;
const response = await fetch(`${url}${queryString(options.params)}`, {
method: options.method ?? "GET",
credentials: "include",
headers:
options.body === undefined
? undefined
: {
"Content-Type": "application/json",
},
body: options.body === undefined ? undefined : JSON.stringify(options.body),
cache: "no-store",
});
const json = (await response.json()) as ApiResponse<T>;
return json;
}
export const httpPanelService = {
auth: {
me: () => request("/api/auth/me"),
login: (email: string, password = "correct-password", code?: string) =>
request("/api/auth/login", {
method: "POST",
body: { email, password, code },
}),
logout: () => request("/api/auth/logout", { method: "POST" }),
},
dashboard: {
summary: () => request("/api/dashboard/summary"),
},
websites: {
list: (params?: QueryParams) => request("/api/websites", { params }),
create: (payload: Partial<Website>) =>
request("/api/websites", { method: "POST", body: payload }),
},
domains: {
list: (params?: QueryParams) => request("/api/domains", { params }),
records: () => request("/api/domains/dom-1/dns"),
saveRecord: (record: Partial<DnsRecord>) =>
record.id
? request(`/api/domains/dom-1/dns/${record.id}`, { method: "PUT", body: record })
: request("/api/domains/dom-1/dns", { method: "POST", body: record }),
},
files: {
list: (params?: QueryParams) => request("/api/files", { params }),
operation: (operation: string): Promise<ApiResponse<JobProgress>> =>
request("/api/files/operations", { method: "POST", body: { operation } }),
},
databases: {
list: (params?: QueryParams) => request("/api/databases", { params }),
create: (name: string) => request("/api/databases", { method: "POST", body: { name } }),
adminTools: () => request("/api/databases/admin-tools"),
},
email: {
list: (params?: QueryParams) => request("/api/email/accounts", { params }),
create: (address: string) =>
request("/api/email/accounts", { method: "POST", body: { address } }),
},
metrics: {
history: () => request("/api/metrics/history"),
},
security: {
findings: () => request("/api/security/findings"),
},
backups: {
list: () => request("/api/backups"),
create: (scope: string) =>
request<JobProgress>("/api/backups", { method: "POST", body: { scope } }),
},
automation: {
list: () => request("/api/automation"),
},
notifications: {
list: () => request("/api/notifications"),
},
audit: {
list: () => request("/api/audit-logs"),
},
software: {
runtimes: () => request("/api/software/runtimes"),
},
servers: {
list: () => request("/api/servers"),
services: () => request("/api/servers/services"),
},
system: {
discovery: () => request("/api/system/discovery"),
},
};