|
|
|
@@ -1,9 +1,19 @@
|
|
|
|
|
import { ApiClientError } from "@/shared/api/http-client"
|
|
|
|
|
import { configuredBackendUrl } from "@/lib/backend-url"
|
|
|
|
|
|
|
|
|
|
const MAX_RESTORE_BYTES = 512 * 1024 * 1024
|
|
|
|
|
|
|
|
|
|
function trimBaseUrl(baseUrl: string): string {
|
|
|
|
|
return baseUrl.replace(/\/$/, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resolveDatabaseApiUrl(baseUrl: string, path: string): string {
|
|
|
|
|
if (configuredBackendUrl().kind === "same-origin") {
|
|
|
|
|
return path
|
|
|
|
|
}
|
|
|
|
|
return `${trimBaseUrl(baseUrl)}${path}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function parseFilename(contentDisposition: string | null, fallback: string): string {
|
|
|
|
|
if (!contentDisposition) return fallback
|
|
|
|
|
const utfMatch = /filename\*=UTF-8''([^;]+)/i.exec(contentDisposition)
|
|
|
|
@@ -22,7 +32,7 @@ function parseFilename(contentDisposition: string | null, fallback: string): str
|
|
|
|
|
export async function downloadSystemDatabaseBackup(
|
|
|
|
|
baseUrl: string,
|
|
|
|
|
): Promise<{ blob: Blob; filename: string }> {
|
|
|
|
|
const res = await fetch(`${trimBaseUrl(baseUrl)}/api/system/database/backup`)
|
|
|
|
|
const res = await fetch(resolveDatabaseApiUrl(baseUrl, "/api/system/database/backup"))
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
const payload = await res.json().catch(() => undefined)
|
|
|
|
|
const msg =
|
|
|
|
@@ -40,8 +50,14 @@ export async function downloadSystemDatabaseBackup(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function restoreSystemDatabaseBackup(baseUrl: string, file: File): Promise<void> {
|
|
|
|
|
if (file.size > MAX_RESTORE_BYTES) {
|
|
|
|
|
throw new ApiClientError(
|
|
|
|
|
`Файл больше ${MAX_RESTORE_BYTES / (1024 * 1024)} МБ — уменьшите бэкап или обратитесь к администратору`,
|
|
|
|
|
413,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
const body = await file.arrayBuffer()
|
|
|
|
|
const res = await fetch(`${trimBaseUrl(baseUrl)}/api/system/database/restore`, {
|
|
|
|
|
const res = await fetch(resolveDatabaseApiUrl(baseUrl, "/api/system/database/restore"), {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "Content-Type": "application/octet-stream" },
|
|
|
|
|
body,
|
|
|
|
|