refactor: define overwrite mode in shared schema
This commit is contained in:
parent
f4a7f6f737
commit
7be290405f
6 changed files with 32 additions and 19 deletions
|
|
@ -23,9 +23,9 @@ import type { Snapshot, Volume } from "~/client/lib/types";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { listSnapshotFilesOptions, restoreSnapshotMutation } from "~/client/api-client/@tanstack/react-query.gen";
|
import { listSnapshotFilesOptions, restoreSnapshotMutation } from "~/client/api-client/@tanstack/react-query.gen";
|
||||||
import { useFileBrowser } from "~/client/hooks/use-file-browser";
|
import { useFileBrowser } from "~/client/hooks/use-file-browser";
|
||||||
|
import { OVERWRITE_MODES, type OverwriteMode } from "~/schemas/restic";
|
||||||
|
|
||||||
type RestoreLocation = "original" | "custom";
|
type RestoreLocation = "original" | "custom";
|
||||||
type OverwriteMode = "always" | "if-changed" | "if-newer" | "never";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
snapshot: Snapshot;
|
snapshot: Snapshot;
|
||||||
|
|
@ -297,19 +297,21 @@ export const SnapshotFileBrowser = (props: Props) => {
|
||||||
<SelectValue placeholder="Select overwrite behavior" />
|
<SelectValue placeholder="Select overwrite behavior" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="always">Always overwrite</SelectItem>
|
<SelectItem value={OVERWRITE_MODES.always}>Always overwrite</SelectItem>
|
||||||
<SelectItem value="if-changed">Only if content changed</SelectItem>
|
<SelectItem value={OVERWRITE_MODES.ifChanged}>Only if content changed</SelectItem>
|
||||||
<SelectItem value="if-newer">Only if snapshot is newer</SelectItem>
|
<SelectItem value={OVERWRITE_MODES.ifNewer}>Only if snapshot is newer</SelectItem>
|
||||||
<SelectItem value="never">Never overwrite</SelectItem>
|
<SelectItem value={OVERWRITE_MODES.never}>Never overwrite</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
{overwriteMode === "always" && "Existing files will always be replaced with the snapshot version."}
|
{overwriteMode === OVERWRITE_MODES.always &&
|
||||||
{overwriteMode === "if-changed" &&
|
"Existing files will always be replaced with the snapshot version."}
|
||||||
|
{overwriteMode === OVERWRITE_MODES.ifChanged &&
|
||||||
"Files are only replaced if their content differs from the snapshot."}
|
"Files are only replaced if their content differs from the snapshot."}
|
||||||
{overwriteMode === "if-newer" &&
|
{overwriteMode === OVERWRITE_MODES.ifNewer &&
|
||||||
"Files are only replaced if the snapshot version has a newer modification time."}
|
"Files are only replaced if the snapshot version has a newer modification time."}
|
||||||
{overwriteMode === "never" && "Existing files will never be replaced, only missing files are restored."}
|
{overwriteMode === OVERWRITE_MODES.never &&
|
||||||
|
"Existing files will never be replaced, only missing files are restored."}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,7 @@ import type { Repository } from "~/client/lib/types";
|
||||||
import { slugify } from "~/client/lib/utils";
|
import { slugify } from "~/client/lib/utils";
|
||||||
import { updateRepositoryMutation } from "~/client/api-client/@tanstack/react-query.gen";
|
import { updateRepositoryMutation } from "~/client/api-client/@tanstack/react-query.gen";
|
||||||
import type { UpdateRepositoryResponse } from "~/client/api-client/types.gen";
|
import type { UpdateRepositoryResponse } from "~/client/api-client/types.gen";
|
||||||
|
import type { CompressionMode } from "~/schemas/restic";
|
||||||
type CompressionMode = "off" | "auto" | "fastest" | "better" | "max";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
repository: Repository;
|
repository: Repository;
|
||||||
|
|
|
||||||
|
|
@ -105,3 +105,12 @@ export const REPOSITORY_STATUS = {
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type RepositoryStatus = keyof typeof REPOSITORY_STATUS;
|
export type RepositoryStatus = keyof typeof REPOSITORY_STATUS;
|
||||||
|
|
||||||
|
export const OVERWRITE_MODES = {
|
||||||
|
always: "always",
|
||||||
|
ifChanged: "if-changed",
|
||||||
|
ifNewer: "if-newer",
|
||||||
|
never: "never",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type OverwriteMode = (typeof OVERWRITE_MODES)[keyof typeof OVERWRITE_MODES];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
import { type } from "arktype";
|
import { type } from "arktype";
|
||||||
import { describeRoute, resolver } from "hono-openapi";
|
import { describeRoute, resolver } from "hono-openapi";
|
||||||
import { COMPRESSION_MODES, REPOSITORY_BACKENDS, REPOSITORY_STATUS, repositoryConfigSchema } from "~/schemas/restic";
|
import {
|
||||||
|
COMPRESSION_MODES,
|
||||||
|
OVERWRITE_MODES,
|
||||||
|
REPOSITORY_BACKENDS,
|
||||||
|
REPOSITORY_STATUS,
|
||||||
|
repositoryConfigSchema,
|
||||||
|
} from "~/schemas/restic";
|
||||||
|
|
||||||
export const repositorySchema = type({
|
export const repositorySchema = type({
|
||||||
id: "string",
|
id: "string",
|
||||||
|
|
@ -269,8 +275,7 @@ export const listSnapshotFilesDto = describeRoute({
|
||||||
/**
|
/**
|
||||||
* Restore a snapshot
|
* Restore a snapshot
|
||||||
*/
|
*/
|
||||||
export const overwriteModeSchema = type("'always' | 'if-changed' | 'if-newer' | 'never'");
|
export const overwriteModeSchema = type.valueOf(OVERWRITE_MODES);
|
||||||
export type OverwriteMode = typeof overwriteModeSchema.infer;
|
|
||||||
|
|
||||||
export const restoreSnapshotBody = type({
|
export const restoreSnapshotBody = type({
|
||||||
snapshotId: "string",
|
snapshotId: "string",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { toMessage } from "../../utils/errors";
|
||||||
import { generateShortId } from "../../utils/id";
|
import { generateShortId } from "../../utils/id";
|
||||||
import { restic } from "../../utils/restic";
|
import { restic } from "../../utils/restic";
|
||||||
import { cryptoUtils } from "../../utils/crypto";
|
import { cryptoUtils } from "../../utils/crypto";
|
||||||
import type { CompressionMode, RepositoryConfig } from "~/schemas/restic";
|
import type { CompressionMode, OverwriteMode, RepositoryConfig } from "~/schemas/restic";
|
||||||
|
|
||||||
const listRepositories = async () => {
|
const listRepositories = async () => {
|
||||||
const repositories = await db.query.repositoriesTable.findMany({});
|
const repositories = await db.query.repositoriesTable.findMany({});
|
||||||
|
|
@ -207,7 +207,7 @@ const restoreSnapshot = async (
|
||||||
excludeXattr?: string[];
|
excludeXattr?: string[];
|
||||||
delete?: boolean;
|
delete?: boolean;
|
||||||
targetPath?: string;
|
targetPath?: string;
|
||||||
overwrite?: "always" | "if-changed" | "if-newer" | "never";
|
overwrite?: OverwriteMode;
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
const repository = await db.query.repositoriesTable.findFirst({
|
const repository = await db.query.repositoriesTable.findFirst({
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { logger } from "./logger";
|
||||||
import { cryptoUtils } from "./crypto";
|
import { cryptoUtils } from "./crypto";
|
||||||
import type { RetentionPolicy } from "../modules/backups/backups.dto";
|
import type { RetentionPolicy } from "../modules/backups/backups.dto";
|
||||||
import { safeSpawn } from "./spawn";
|
import { safeSpawn } from "./spawn";
|
||||||
import type { CompressionMode, RepositoryConfig } from "~/schemas/restic";
|
import type { CompressionMode, RepositoryConfig, OverwriteMode } from "~/schemas/restic";
|
||||||
import { ResticError } from "./errors";
|
import { ResticError } from "./errors";
|
||||||
|
|
||||||
const backupOutputSchema = type({
|
const backupOutputSchema = type({
|
||||||
|
|
@ -361,8 +361,6 @@ const restoreOutputSchema = type({
|
||||||
bytes_skipped: "number",
|
bytes_skipped: "number",
|
||||||
});
|
});
|
||||||
|
|
||||||
type OverwriteMode = "always" | "if-changed" | "if-newer" | "never";
|
|
||||||
|
|
||||||
const restore = async (
|
const restore = async (
|
||||||
config: RepositoryConfig,
|
config: RepositoryConfig,
|
||||||
snapshotId: string,
|
snapshotId: string,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue