78 lines
5.0 KiB
TypeScript
78 lines
5.0 KiB
TypeScript
import {
|
|
backupJobResponseSchema,
|
|
backupScheduleSettingsDtoSchema,
|
|
backupStorageSettingsDtoSchema,
|
|
backupsListResponseSchema,
|
|
createBackupJobResponseSchema,
|
|
createBackupRequestSchema,
|
|
putBackupScheduleSettingsSchema,
|
|
putBackupStorageSettingsSchema,
|
|
restoreBackupResponseSchema,
|
|
syncBackupsResponseSchema,
|
|
} from "@mmapp/contracts/backups"
|
|
import type { BackupItemDto, BackupScheduleSettingsDto, PutBackupStorageSettings } from "@mmapp/contracts/backups"
|
|
import { requestBlob, requestJson } from "@/shared/api/http-client"
|
|
|
|
export type BackupItem = BackupItemDto
|
|
export type { CreateBackupJobResponse, BackupJobStatusResponse } from "@mmapp/contracts/backups"
|
|
|
|
function backupOptions(options?: RequestInit): RequestInit {
|
|
return { ...options, signal: AbortSignal.any([...(options?.signal ? [options.signal] : []), AbortSignal.timeout(30_000)]) }
|
|
}
|
|
function backupJson(baseUrl: string, path: string, options?: RequestInit) {
|
|
return requestJson<unknown>(baseUrl, path, backupOptions(options))
|
|
}
|
|
export async function listBackups(baseUrl: string, options?: RequestInit) {
|
|
return backupsListResponseSchema.parse(await backupJson(baseUrl, "/api/backups", { ...options, method: "GET" }))
|
|
}
|
|
export async function createBackupsAsync(baseUrl: string, payload: { serverIds: string[]; notes?: string }, options?: RequestInit) {
|
|
const body = createBackupRequestSchema.parse(payload)
|
|
const result = createBackupJobResponseSchema.parse(await backupJson(baseUrl, "/api/backups/create", { ...options, method: "POST", body: JSON.stringify(body) }))
|
|
if (result.total !== body.serverIds.length) throw new Error("Не подтверждено резервное копирование всех выбранных серверов")
|
|
return result
|
|
}
|
|
export async function getBackupJob(baseUrl: string, jobId: string, options?: RequestInit) {
|
|
const result = backupJobResponseSchema.parse(await backupJson(baseUrl, "/api/backups/jobs/" + encodeURIComponent(jobId), { ...options, method: "GET" }))
|
|
if (result.id !== jobId) throw new Error("Ответ относится к другой задаче резервного копирования")
|
|
return result
|
|
}
|
|
export async function deleteBackup(baseUrl: string, id: string, options?: RequestInit): Promise<void> {
|
|
const response = await requestBlob(baseUrl, "/api/backups/" + encodeURIComponent(id), backupOptions({ ...options, method: "DELETE" }))
|
|
if (response.status !== 204) throw new Error("Удаление резервной копии не подтверждено: ожидается HTTP 204")
|
|
}
|
|
export async function restoreBackup(baseUrl: string, id: string, options?: RequestInit) {
|
|
return restoreBackupResponseSchema.parse(await backupJson(baseUrl, "/api/backups/" + encodeURIComponent(id) + "/restore", { ...options, method: "POST" }))
|
|
}
|
|
export async function getBackupScheduleSettings(baseUrl: string, options?: RequestInit) {
|
|
return backupScheduleSettingsDtoSchema.parse(await backupJson(baseUrl, "/api/backups/schedule", { ...options, method: "GET" }))
|
|
}
|
|
function confirmSettings(result: Record<string, unknown>, payload: Record<string, unknown>) {
|
|
for (const [key, value] of Object.entries(payload)) {
|
|
if (value === undefined) continue
|
|
if (key === "s3SecretAccessKey") {
|
|
if (value && result.secretConfigured !== true) throw new Error("Сохранение ключа хранилища не подтверждено")
|
|
} else if (JSON.stringify(result[key]) !== JSON.stringify(value)) throw new Error("Сохранение настроек не подтверждено: ответ отличается от отправленных данных")
|
|
}
|
|
}
|
|
export async function putBackupScheduleSettings(baseUrl: string, payload: Partial<BackupScheduleSettingsDto>, options?: RequestInit) {
|
|
const body = putBackupScheduleSettingsSchema.parse(payload)
|
|
const result = backupScheduleSettingsDtoSchema.parse(await backupJson(baseUrl, "/api/backups/schedule", { ...options, method: "PUT", body: JSON.stringify(body) }))
|
|
confirmSettings(result, body)
|
|
return result
|
|
}
|
|
export async function getBackupStorageSettings(baseUrl: string, options?: RequestInit) {
|
|
return backupStorageSettingsDtoSchema.parse(await backupJson(baseUrl, "/api/backups/storage", { ...options, method: "GET" }))
|
|
}
|
|
export async function putBackupStorageSettings(baseUrl: string, payload: PutBackupStorageSettings, options?: RequestInit) {
|
|
const body = putBackupStorageSettingsSchema.parse(payload)
|
|
const result = backupStorageSettingsDtoSchema.parse(await backupJson(baseUrl, "/api/backups/storage", { ...options, method: "PUT", body: JSON.stringify(body) }))
|
|
confirmSettings(result, body)
|
|
return result
|
|
}
|
|
export async function testBackupStorage(baseUrl: string, options?: RequestInit) {
|
|
return backupStorageSettingsDtoSchema.parse(await backupJson(baseUrl, "/api/backups/storage/test", { ...options, method: "POST" }))
|
|
}
|
|
export async function syncBackupsFromStorage(baseUrl: string, options?: RequestInit) {
|
|
return syncBackupsResponseSchema.parse(await backupJson(baseUrl, "/api/backups/storage/sync", { ...options, method: "POST" }))
|
|
}
|