chore: fix liniting issues

This commit is contained in:
Nicolas Meienberger 2026-01-05 19:29:07 +01:00
parent ba8ec2a6b9
commit dd0a87d244
32 changed files with 71 additions and 70 deletions

View file

@ -23,7 +23,7 @@ export const DirectoryBrowser = ({ onSelectPath, selectedPath }: Props) => {
return await queryClient.ensureQueryData(browseFilesystemOptions({ query: { path } })); return await queryClient.ensureQueryData(browseFilesystemOptions({ query: { path } }));
}, },
prefetchFolder: (path) => { prefetchFolder: (path) => {
queryClient.prefetchQuery(browseFilesystemOptions({ query: { path } })); void queryClient.prefetchQuery(browseFilesystemOptions({ query: { path } }));
}, },
}); });

View file

@ -30,7 +30,7 @@ export default function Layout({ loaderData }: Route.ComponentProps) {
const logout = useMutation({ const logout = useMutation({
...logoutMutation(), ...logoutMutation(),
onSuccess: async () => { onSuccess: async () => {
navigate("/login", { replace: true }); void navigate("/login", { replace: true });
}, },
onError: (error) => { onError: (error) => {
console.error(error); console.error(error);

View file

@ -83,7 +83,7 @@ export function RestoreForm({ snapshot, repository, snapshotId, returnPath }: Re
); );
}, },
prefetchFolder: (path) => { prefetchFolder: (path) => {
queryClient.prefetchQuery( void queryClient.prefetchQuery(
listSnapshotFilesOptions({ listSnapshotFilesOptions({
path: { id: repository.id, snapshotId }, path: { id: repository.id, snapshotId },
query: { path }, query: { path },
@ -102,7 +102,7 @@ export function RestoreForm({ snapshot, repository, snapshotId, returnPath }: Re
toast.success("Restore completed", { toast.success("Restore completed", {
description: `Successfully restored ${data.filesRestored} file(s). ${data.filesSkipped} file(s) skipped.`, description: `Successfully restored ${data.filesRestored} file(s). ${data.filesSkipped} file(s) skipped.`,
}); });
navigate(returnPath); void navigate(returnPath);
}, },
onError: (error) => { onError: (error) => {
toast.error("Restore failed", { description: error.message || "Failed to restore snapshot" }); toast.error("Restore failed", { description: error.message || "Failed to restore snapshot" });

View file

@ -50,7 +50,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
const deleteSnapshots = useMutation({ const deleteSnapshots = useMutation({
...deleteSnapshotsMutation(), ...deleteSnapshotsMutation(),
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["listSnapshots"] }); void queryClient.invalidateQueries({ queryKey: ["listSnapshots"] });
setShowBulkDeleteConfirm(false); setShowBulkDeleteConfirm(false);
setSelectedIds(new Set()); setSelectedIds(new Set());
}, },
@ -62,7 +62,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
setShowReTagDialog(false); setShowReTagDialog(false);
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["listSnapshots"] }); void queryClient.invalidateQueries({ queryKey: ["listSnapshots"] });
setShowReTagDialog(false); setShowReTagDialog(false);
setSelectedIds(new Set()); setSelectedIds(new Set());
setTargetScheduleId(""); setTargetScheduleId("");
@ -70,7 +70,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
}); });
const handleRowClick = (snapshotId: string) => { const handleRowClick = (snapshotId: string) => {
navigate(`/repositories/${repositoryId}/${snapshotId}`); void navigate(`/repositories/${repositoryId}/${snapshotId}`);
}; };
const toggleSelectAll = () => { const toggleSelectAll = () => {

View file

@ -46,7 +46,7 @@ export const VolumeFileBrowser = ({
); );
}, },
prefetchFolder: (path) => { prefetchFolder: (path) => {
queryClient.prefetchQuery( void queryClient.prefetchQuery(
listFilesOptions({ listFilesOptions({
path: { name: volumeName }, path: { name: volumeName },
query: { path }, query: { path },

View file

@ -87,8 +87,8 @@ export function useServerEvents() {
const data = JSON.parse(e.data) as BackupEvent; const data = JSON.parse(e.data) as BackupEvent;
console.log("[SSE] Backup completed:", data); console.log("[SSE] Backup completed:", data);
queryClient.invalidateQueries(); void queryClient.invalidateQueries();
queryClient.refetchQueries(); void queryClient.refetchQueries();
handlersRef.current.get("backup:completed")?.forEach((handler) => { handlersRef.current.get("backup:completed")?.forEach((handler) => {
handler(data); handler(data);
@ -117,7 +117,7 @@ export function useServerEvents() {
const data = JSON.parse(e.data) as VolumeEvent; const data = JSON.parse(e.data) as VolumeEvent;
console.log("[SSE] Volume updated:", data); console.log("[SSE] Volume updated:", data);
queryClient.invalidateQueries(); void queryClient.invalidateQueries();
handlersRef.current.get("volume:updated")?.forEach((handler) => { handlersRef.current.get("volume:updated")?.forEach((handler) => {
handler(data); handler(data);
@ -128,7 +128,7 @@ export function useServerEvents() {
const data = JSON.parse(e.data) as VolumeEvent; const data = JSON.parse(e.data) as VolumeEvent;
console.log("[SSE] Volume status updated:", data); console.log("[SSE] Volume status updated:", data);
queryClient.invalidateQueries(); void queryClient.invalidateQueries();
handlersRef.current.get("volume:updated")?.forEach((handler) => { handlersRef.current.get("volume:updated")?.forEach((handler) => {
handler(data); handler(data);
@ -149,7 +149,7 @@ export function useServerEvents() {
console.log("[SSE] Mirror copy completed:", data); console.log("[SSE] Mirror copy completed:", data);
// Invalidate queries to refresh mirror status in the UI // Invalidate queries to refresh mirror status in the UI
queryClient.invalidateQueries(); void queryClient.invalidateQueries();
handlersRef.current.get("mirror:completed")?.forEach((handler) => { handlersRef.current.get("mirror:completed")?.forEach((handler) => {
handler(data); handler(data);

View file

@ -42,7 +42,7 @@ export default function DownloadRecoveryKeyPage() {
window.URL.revokeObjectURL(url); window.URL.revokeObjectURL(url);
toast.success("Recovery key downloaded successfully!"); toast.success("Recovery key downloaded successfully!");
navigate("/volumes", { replace: true }); void navigate("/volumes", { replace: true });
}, },
onError: (error) => { onError: (error) => {
toast.error("Failed to download recovery key", { description: error.message }); toast.error("Failed to download recovery key", { description: error.message });

View file

@ -49,9 +49,9 @@ export default function LoginPage() {
...loginMutation(), ...loginMutation(),
onSuccess: async (data) => { onSuccess: async (data) => {
if (data.user && !data.user.hasDownloadedResticPassword) { if (data.user && !data.user.hasDownloadedResticPassword) {
navigate("/download-recovery-key"); void navigate("/download-recovery-key");
} else { } else {
navigate("/volumes"); void navigate("/volumes");
} }
}, },
onError: (error) => { onError: (error) => {

View file

@ -56,7 +56,7 @@ export default function OnboardingPage() {
...registerMutation(), ...registerMutation(),
onSuccess: async () => { onSuccess: async () => {
toast.success("Admin user created successfully!"); toast.success("Admin user created successfully!");
navigate("/download-recovery-key"); void navigate("/download-recovery-key");
}, },
onError: (error) => { onError: (error) => {
console.error(error); console.error(error);

View file

@ -728,7 +728,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
.filter(([key, value]) => key.startsWith("keep") && Boolean(value)) .filter(([key, value]) => key.startsWith("keep") && Boolean(value))
.map(([key, value]) => { .map(([key, value]) => {
const label = key.replace("keep", "").toLowerCase(); const label = key.replace("keep", "").toLowerCase();
return `${value} ${label}`; return `${value.toString()} ${label}`;
}) })
.join(", ") || "-"} .join(", ") || "-"}
</p> </p>

View file

@ -68,7 +68,7 @@ export const SnapshotFileBrowser = (props: Props) => {
); );
}, },
prefetchFolder: (path) => { prefetchFolder: (path) => {
queryClient.prefetchQuery( void queryClient.prefetchQuery(
listSnapshotFilesOptions({ listSnapshotFilesOptions({
path: { id: repositoryId, snapshotId: snapshot.short_id }, path: { id: repositoryId, snapshotId: snapshot.short_id },
query: { path }, query: { path },

View file

@ -120,7 +120,7 @@ export default function ScheduleDetailsPage({ params, loaderData }: Route.Compon
...deleteBackupScheduleMutation(), ...deleteBackupScheduleMutation(),
onSuccess: () => { onSuccess: () => {
toast.success("Backup schedule deleted successfully"); toast.success("Backup schedule deleted successfully");
navigate("/backups"); void navigate("/backups");
}, },
onError: (error) => { onError: (error) => {
toast.error("Failed to delete backup schedule", { description: parseError(error)?.message }); toast.error("Failed to delete backup schedule", { description: parseError(error)?.message });

View file

@ -59,7 +59,7 @@ export default function CreateBackup({ loaderData }: Route.ComponentProps) {
...createBackupScheduleMutation(), ...createBackupScheduleMutation(),
onSuccess: (data) => { onSuccess: (data) => {
toast.success("Backup job created successfully"); toast.success("Backup job created successfully");
navigate(`/backups/${data.id}`); void navigate(`/backups/${data.id}`);
}, },
onError: (error) => { onError: (error) => {
toast.error("Failed to create backup job", { toast.error("Failed to create backup job", {

View file

@ -33,7 +33,7 @@ export default function CreateNotification() {
...createNotificationDestinationMutation(), ...createNotificationDestinationMutation(),
onSuccess: () => { onSuccess: () => {
toast.success("Notification destination created successfully"); toast.success("Notification destination created successfully");
navigate(`/notifications`); void navigate(`/notifications`);
}, },
}); });

View file

@ -24,7 +24,7 @@ import { getNotificationDestination } from "~/client/api-client/sdk.gen";
import type { Route } from "./+types/notification-details"; import type { Route } from "./+types/notification-details";
import { cn } from "~/client/lib/utils"; import { cn } from "~/client/lib/utils";
import { Card, CardContent, CardHeader, CardTitle } from "~/client/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "~/client/components/ui/card";
import { Bell, Save, TestTube2, Trash2, X } from "lucide-react"; import { Bell, Save, TestTube2, Trash2 } from "lucide-react";
import { Alert, AlertDescription } from "~/client/components/ui/alert"; import { Alert, AlertDescription } from "~/client/components/ui/alert";
import { CreateNotificationForm, type NotificationFormValues } from "../components/create-notification-form"; import { CreateNotificationForm, type NotificationFormValues } from "../components/create-notification-form";
@ -66,7 +66,7 @@ export default function NotificationDetailsPage({ loaderData }: Route.ComponentP
...deleteNotificationDestinationMutation(), ...deleteNotificationDestinationMutation(),
onSuccess: () => { onSuccess: () => {
toast.success("Notification destination deleted successfully"); toast.success("Notification destination deleted successfully");
navigate("/notifications"); void navigate("/notifications");
}, },
onError: (error) => { onError: (error) => {
toast.error("Failed to delete notification destination", { toast.error("Failed to delete notification destination", {

View file

@ -36,7 +36,7 @@ export default function CreateRepository() {
...createRepositoryMutation(), ...createRepositoryMutation(),
onSuccess: (data) => { onSuccess: (data) => {
toast.success("Repository created successfully"); toast.success("Repository created successfully");
navigate(`/repositories/${data.repository.shortId}`); void navigate(`/repositories/${data.repository.shortId}`);
}, },
}); });

View file

@ -67,14 +67,14 @@ export default function RepositoryDetailsPage({ loaderData }: Route.ComponentPro
}); });
useEffect(() => { useEffect(() => {
queryClient.prefetchQuery(listSnapshotsOptions({ path: { id: data.id } })); void queryClient.prefetchQuery(listSnapshotsOptions({ path: { id: data.id } }));
}, [queryClient, data.id]); }, [queryClient, data.id]);
const deleteRepo = useMutation({ const deleteRepo = useMutation({
...deleteRepositoryMutation(), ...deleteRepositoryMutation(),
onSuccess: () => { onSuccess: () => {
toast.success("Repository deleted successfully"); toast.success("Repository deleted successfully");
navigate("/repositories"); void navigate("/repositories");
}, },
onError: (error) => { onError: (error) => {
toast.error("Failed to delete repository", { toast.error("Failed to delete repository", {

View file

@ -54,7 +54,7 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
const logout = useMutation({ const logout = useMutation({
...logoutMutation(), ...logoutMutation(),
onSuccess: () => { onSuccess: () => {
navigate("/login", { replace: true }); void navigate("/login", { replace: true });
}, },
}); });

View file

@ -33,7 +33,7 @@ export default function CreateVolume() {
...createVolumeMutation(), ...createVolumeMutation(),
onSuccess: (data) => { onSuccess: (data) => {
toast.success("Volume created successfully"); toast.success("Volume created successfully");
navigate(`/volumes/${data.name}`); void navigate(`/volumes/${data.name}`);
}, },
}); });

View file

@ -75,7 +75,7 @@ export default function VolumeDetails({ loaderData }: Route.ComponentProps) {
...deleteVolumeMutation(), ...deleteVolumeMutation(),
onSuccess: () => { onSuccess: () => {
toast.success("Volume deleted successfully"); toast.success("Volume deleted successfully");
navigate("/volumes"); void navigate("/volumes");
}, },
onError: (error) => { onError: (error) => {
toast.error("Failed to delete volume", { toast.error("Failed to delete volume", {

View file

@ -37,7 +37,7 @@ export const VolumeInfoTabContent = ({ volume, statfs }: Props) => {
setPendingValues(null); setPendingValues(null);
if (data.name !== volume.name) { if (data.name !== volume.name) {
navigate(`/volumes/${data.name}`); void navigate(`/volumes/${data.name}`);
} }
}, },
onError: (error) => { onError: (error) => {

View file

@ -27,11 +27,11 @@ export const links: Route.LinksFunction = () => [
const queryClient = new QueryClient({ const queryClient = new QueryClient({
mutationCache: new MutationCache({ mutationCache: new MutationCache({
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries(); void queryClient.invalidateQueries();
}, },
onError: (error) => { onError: (error) => {
console.error("Mutation error:", error); console.error("Mutation error:", error);
queryClient.invalidateQueries(); void queryClient.invalidateQueries();
}, },
}), }),
}); });

View file

@ -34,7 +34,7 @@ class SchedulerClass {
async stop() { async stop() {
for (const task of this.tasks) { for (const task of this.tasks) {
task.stop(); await task.stop();
} }
this.tasks = []; this.tasks = [];
logger.info("Scheduler stopped"); logger.info("Scheduler stopped");
@ -42,7 +42,7 @@ class SchedulerClass {
async clear() { async clear() {
for (const task of this.tasks) { for (const task of this.tasks) {
task.destroy(); await task.destroy();
} }
this.tasks = []; this.tasks = [];
logger.info("Scheduler cleared all tasks"); logger.info("Scheduler cleared all tasks");

View file

@ -22,7 +22,7 @@ runDbMigrations();
await retagSnapshots(); await retagSnapshots();
await validateRequiredMigrations(REQUIRED_MIGRATIONS); await validateRequiredMigrations(REQUIRED_MIGRATIONS);
startup(); void startup();
logger.info(`Server is running at http://localhost:${config.port}`); logger.info(`Server is running at http://localhost:${config.port}`);

View file

@ -3,7 +3,7 @@ import { authService } from "../modules/auth/auth.service";
export class CleanupSessionsJob extends Job { export class CleanupSessionsJob extends Job {
async run() { async run() {
authService.cleanupExpiredSessions(); await authService.cleanupExpiredSessions();
return { done: true, timestamp: new Date() }; return { done: true, timestamp: new Date() };
} }

View file

@ -101,7 +101,7 @@ describe("execute backup", () => {
}); });
// act // act
backupsService.executeBackup(schedule.id); void backupsService.executeBackup(schedule.id);
await new Promise((resolve) => setTimeout(resolve, 10)); await new Promise((resolve) => setTimeout(resolve, 10));
await backupsService.executeBackup(schedule.id); await backupsService.executeBackup(schedule.id);

View file

@ -28,7 +28,7 @@ const calculateNextRun = (cronExpression: string): number => {
return interval.next().getTime(); return interval.next().getTime();
} catch (error) { } catch (error) {
logger.error(`Failed to parse cron expression "${cronExpression}": ${error}`); logger.error(`Failed to parse cron expression "${cronExpression}": ${toMessage(error)}`);
const fallback = new Date(); const fallback = new Date();
fallback.setMinutes(fallback.getMinutes() + 1); fallback.setMinutes(fallback.getMinutes() + 1);
return fallback.getTime(); return fallback.getTime();

View file

@ -13,14 +13,14 @@ export const eventsController = new Hono().use(requireAuth).get("/", (c) => {
event: "connected", event: "connected",
}); });
const onBackupStarted = (data: { scheduleId: number; volumeName: string; repositoryName: string }) => { const onBackupStarted = async (data: { scheduleId: number; volumeName: string; repositoryName: string }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "backup:started", event: "backup:started",
}); });
}; };
const onBackupProgress = (data: { const onBackupProgress = async (data: {
scheduleId: number; scheduleId: number;
volumeName: string; volumeName: string;
repositoryName: string; repositoryName: string;
@ -32,60 +32,60 @@ export const eventsController = new Hono().use(requireAuth).get("/", (c) => {
bytes_done: number; bytes_done: number;
current_files: string[]; current_files: string[];
}) => { }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "backup:progress", event: "backup:progress",
}); });
}; };
const onBackupCompleted = (data: { const onBackupCompleted = async (data: {
scheduleId: number; scheduleId: number;
volumeName: string; volumeName: string;
repositoryName: string; repositoryName: string;
status: "success" | "error" | "stopped" | "warning"; status: "success" | "error" | "stopped" | "warning";
}) => { }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "backup:completed", event: "backup:completed",
}); });
}; };
const onVolumeMounted = (data: { volumeName: string }) => { const onVolumeMounted = async (data: { volumeName: string }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "volume:mounted", event: "volume:mounted",
}); });
}; };
const onVolumeUnmounted = (data: { volumeName: string }) => { const onVolumeUnmounted = async (data: { volumeName: string }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "volume:unmounted", event: "volume:unmounted",
}); });
}; };
const onVolumeUpdated = (data: { volumeName: string }) => { const onVolumeUpdated = async (data: { volumeName: string }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "volume:updated", event: "volume:updated",
}); });
}; };
const onMirrorStarted = (data: { scheduleId: number; repositoryId: string; repositoryName: string }) => { const onMirrorStarted = async (data: { scheduleId: number; repositoryId: string; repositoryName: string }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "mirror:started", event: "mirror:started",
}); });
}; };
const onMirrorCompleted = (data: { const onMirrorCompleted = async (data: {
scheduleId: number; scheduleId: number;
repositoryId: string; repositoryId: string;
repositoryName: string; repositoryName: string;
status: "success" | "error"; status: "success" | "error";
error?: string; error?: string;
}) => { }) => {
stream.writeSSE({ await stream.writeSSE({
data: JSON.stringify(data), data: JSON.stringify(data),
event: "mirror:completed", event: "mirror:completed",
}); });

View file

@ -3,7 +3,7 @@ import { sanitizeSensitiveData } from "./sanitize";
const { printf, combine, colorize } = format; const { printf, combine, colorize } = format;
const printConsole = printf((info) => `${info.level} > ${info.message}`); const printConsole = printf((info) => `${info.level} > ${String(info.message)}`);
const consoleFormat = combine(colorize(), printConsole); const consoleFormat = combine(colorize(), printConsole);
const getDefaultLevel = () => { const getDefaultLevel = () => {
@ -27,7 +27,7 @@ const log = (level: "info" | "warn" | "error" | "debug", messages: unknown[]) =>
return sanitizeSensitiveData(JSON.stringify(m, null, 2)); return sanitizeSensitiveData(JSON.stringify(m, null, 2));
} }
return sanitizeSensitiveData(String(m)); return sanitizeSensitiveData(String(JSON.stringify(m)));
}); });
winstonLogger.log(level, stringMessages.join(" ")); winstonLogger.log(level, stringMessages.join(" "));

View file

@ -1,5 +1,6 @@
import { $ } from "bun"; import { $ } from "bun";
import { logger } from "./logger"; import { logger } from "./logger";
import { toMessage } from "./errors";
/** /**
* List all configured rclone remotes * List all configured rclone remotes
@ -9,7 +10,7 @@ export async function listRcloneRemotes(): Promise<string[]> {
const result = await $`rclone listremotes`.nothrow(); const result = await $`rclone listremotes`.nothrow();
if (result.exitCode !== 0) { if (result.exitCode !== 0) {
logger.error(`Failed to list rclone remotes: ${result.stderr}`); logger.error(`Failed to list rclone remotes: ${result.stderr.toString()}`);
return []; return [];
} }
@ -36,7 +37,7 @@ export async function getRcloneRemoteInfo(
const result = await $`rclone config show ${remote}`.quiet(); const result = await $`rclone config show ${remote}`.quiet();
if (result.exitCode !== 0) { if (result.exitCode !== 0) {
logger.error(`Failed to get info for remote ${remote}: ${result.stderr}`); logger.error(`Failed to get info for remote ${remote}: ${result.stderr.toString()}`);
return null; return null;
} }
@ -70,7 +71,7 @@ export async function getRcloneRemoteInfo(
return { type, config }; return { type, config };
} catch (error) { } catch (error) {
logger.error(`Error getting remote info for ${remote}: ${error}`); logger.error(`Error getting remote info for ${remote}: ${toMessage(error)}`);
return null; return null;
} }
} }

View file

@ -358,8 +358,8 @@ const backup = async (
} }
}, },
finally: async () => { finally: async () => {
includeFile && (await fs.unlink(includeFile).catch(() => {})); if (includeFile) await fs.unlink(includeFile).catch(() => {});
excludeFile && (await fs.unlink(excludeFile).catch(() => {})); if (excludeFile) await fs.unlink(excludeFile).catch(() => {});
await cleanupTemporaryKeys(env); await cleanupTemporaryKeys(env);
}, },
}); });
@ -393,7 +393,7 @@ const backup = async (
const result = backupOutputSchema(summaryLine); const result = backupOutputSchema(summaryLine);
if (result instanceof type.errors) { if (result instanceof type.errors) {
logger.error(`Restic backup output validation failed: ${result}`); logger.error(`Restic backup output validation failed: ${result.summary}`);
return { result: null, exitCode: res.exitCode }; return { result: null, exitCode: res.exitCode };
} }
@ -484,7 +484,7 @@ const restore = async (
const result = restoreOutputSchema(resSummary); const result = restoreOutputSchema(resSummary);
if (result instanceof type.errors) { if (result instanceof type.errors) {
logger.warn(`Restic restore output validation failed: ${result}`); logger.warn(`Restic restore output validation failed: ${result.summary}`);
logger.info(`Restic restore completed for snapshot ${snapshotId} to target ${target}`); logger.info(`Restic restore completed for snapshot ${snapshotId} to target ${target}`);
return { return {
message_type: "summary" as const, message_type: "summary" as const,
@ -529,8 +529,8 @@ const snapshots = async (config: RepositoryConfig, options: { tags?: string[] }
const result = snapshotInfoSchema.array()(JSON.parse(res.stdout)); const result = snapshotInfoSchema.array()(JSON.parse(res.stdout));
if (result instanceof type.errors) { if (result instanceof type.errors) {
logger.error(`Restic snapshots output validation failed: ${result}`); logger.error(`Restic snapshots output validation failed: ${result.summary}`);
throw new Error(`Restic snapshots output validation failed: ${result}`); throw new Error(`Restic snapshots output validation failed: ${result.summary}`);
} }
return result; return result;
@ -712,8 +712,8 @@ const ls = async (config: RepositoryConfig, snapshotId: string, path?: string) =
const snapshot = lsSnapshotInfoSchema(snapshotLine); const snapshot = lsSnapshotInfoSchema(snapshotLine);
if (snapshot instanceof type.errors) { if (snapshot instanceof type.errors) {
logger.error(`Restic ls snapshot info validation failed: ${snapshot}`); logger.error(`Restic ls snapshot info validation failed: ${snapshot.summary}`);
throw new Error(`Restic ls snapshot info validation failed: ${snapshot}`); throw new Error(`Restic ls snapshot info validation failed: ${snapshot.summary}`);
} }
const nodes: Array<typeof lsNodeSchema.infer> = []; const nodes: Array<typeof lsNodeSchema.infer> = [];
@ -722,7 +722,7 @@ const ls = async (config: RepositoryConfig, snapshotId: string, path?: string) =
const nodeValidation = lsNodeSchema(nodeLine); const nodeValidation = lsNodeSchema(nodeLine);
if (nodeValidation instanceof type.errors) { if (nodeValidation instanceof type.errors) {
logger.warn(`Skipping invalid node: ${nodeValidation}`); logger.warn(`Skipping invalid node: ${nodeValidation.summary}`);
continue; continue;
} }

View file

@ -4,7 +4,7 @@ import path from "node:path";
import { cwd } from "node:process"; import { cwd } from "node:process";
import { db } from "~/server/db/db"; import { db } from "~/server/db/db";
mock.module("~/server/utils/logger", () => ({ void mock.module("~/server/utils/logger", () => ({
logger: { logger: {
debug: () => {}, debug: () => {},
info: () => {}, info: () => {},