diff --git a/app/server/modules/backups/__tests__/backups.execution.test.ts b/app/server/modules/backups/__tests__/backups.execution.test.ts index a0e03207..e24397bc 100644 --- a/app/server/modules/backups/__tests__/backups.execution.test.ts +++ b/app/server/modules/backups/__tests__/backups.execution.test.ts @@ -14,7 +14,7 @@ import { restic } from "~/server/utils/restic"; import { NotFoundError, BadRequestError } from "http-errors-enhanced"; const resticBackupMock = mock(() => Promise.resolve({ exitCode: 0, summary: generateBackupOutput(), error: "" })); -const resticForgetMock = mock(() => Promise.resolve({ success: true })); +const resticForgetMock = mock(() => Promise.resolve({ success: true, data: null })); const resticCopyMock = mock(() => Promise.resolve({ success: true, output: "" })); beforeEach(() => { diff --git a/app/server/modules/backups/__tests__/backups.patterns.test.ts b/app/server/modules/backups/__tests__/backups.patterns.test.ts index 841a71f6..2e26a990 100644 --- a/app/server/modules/backups/__tests__/backups.patterns.test.ts +++ b/app/server/modules/backups/__tests__/backups.patterns.test.ts @@ -15,7 +15,7 @@ const backupMock = mock(() => Promise.resolve({ exitCode: 0, result: JSON.parse( beforeEach(() => { backupMock.mockClear(); spyOn(restic, "backup").mockImplementation(backupMock); - spyOn(restic, "forget").mockImplementation(mock(() => Promise.resolve({ success: true }))); + spyOn(restic, "forget").mockImplementation(mock(() => Promise.resolve({ success: true, data: null }))); spyOn(context, "getOrganizationId").mockReturnValue(TEST_ORG_ID); }); diff --git a/app/server/modules/repositories/repositories.service.ts b/app/server/modules/repositories/repositories.service.ts index 2f4292e6..62a0c6ef 100644 --- a/app/server/modules/repositories/repositories.service.ts +++ b/app/server/modules/repositories/repositories.service.ts @@ -629,7 +629,7 @@ const getRetentionCategories = async (repositoryId: string, scheduleId?: string) } const categories = parseRetentionCategories(dryRunResults.data); - cache.set(cacheKey, categories); + cache.set(cacheKey, Object.fromEntries(categories)); return categories; } catch (error) { diff --git a/app/server/utils/restic.ts b/app/server/utils/restic.ts index 16f312a4..f0c1b76e 100644 --- a/app/server/utils/restic.ts +++ b/app/server/utils/restic.ts @@ -13,6 +13,7 @@ import { safeSpawn, exec } from "./spawn"; import type { CompressionMode, RepositoryConfig, OverwriteMode, BandwidthLimit } from "~/schemas/restic"; import { ResticError } from "./errors"; import { db } from "../db/db"; +import { safeJsonParse } from "./json"; const backupOutputSchema = type({ message_type: "'summary'", @@ -565,17 +566,17 @@ export interface ForgetGroup { export interface Snapshot { time: string; - parent: string; + parent?: string; tree: string; paths: string[]; hostname: string; - username: string; - uid: number; - gid: number; + username?: string; + uid?: number; + gid?: number; excludes?: string[] | null; tags?: string[] | null; - program_version: string; - summary: SnapshotSummary; + program_version?: string; + summary?: SnapshotSummary; id: string; short_id: string; } @@ -653,7 +654,7 @@ const forget = async ( } const lines = res.stdout.split("\n").filter((line) => line.trim()); - const result = extra.dryRun ? (JSON.parse(lines.at(-1) ?? "[]") as ResticForgetResponse) : null; + const result = extra.dryRun ? safeJsonParse(lines.at(-1) ?? "[]") : null; return { success: true, data: result }; };