fix: properly catch before fallback mount

This commit is contained in:
Nicolas Meienberger 2026-01-11 16:24:28 +01:00
parent 583393eb47
commit 02fe55b533
8 changed files with 325 additions and 256 deletions

View file

@ -3,12 +3,7 @@
import { createSseClient } from "../core/serverSentEvents.gen";
import type { HttpMethod } from "../core/types.gen";
import { getValidRequestBody } from "../core/utils.gen";
import type {
Client,
Config,
RequestOptions,
ResolvedRequestOptions,
} from "./types.gen";
import type { Client, Config, RequestOptions, ResolvedRequestOptions } from "./types.gen";
import {
buildUrl,
createConfig,
@ -34,12 +29,7 @@ export const createClient = (config: Config = {}): Client => {
return getConfig();
};
const interceptors = createInterceptors<
Request,
Response,
unknown,
ResolvedRequestOptions
>();
const interceptors = createInterceptors<Request, Response, unknown, ResolvedRequestOptions>();
const beforeRequest = async (options: RequestOptions) => {
const opts = {
@ -105,12 +95,7 @@ export const createClient = (config: Config = {}): Client => {
for (const fn of interceptors.error.fns) {
if (fn) {
finalError = (await fn(
error,
undefined as any,
request,
opts,
)) as unknown;
finalError = (await fn(error, undefined as any, request, opts)) as unknown;
}
}
@ -143,14 +128,9 @@ export const createClient = (config: Config = {}): Client => {
if (response.ok) {
const parseAs =
(opts.parseAs === "auto"
? getParseAs(response.headers.get("Content-Type"))
: opts.parseAs) ?? "json";
(opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
if (
response.status === 204 ||
response.headers.get("Content-Length") === "0"
) {
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
let emptyData: any;
switch (parseAs) {
case "arrayBuffer":
@ -246,30 +226,28 @@ export const createClient = (config: Config = {}): Client => {
};
};
const makeMethodFn =
(method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
request({ ...options, method });
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) => request({ ...options, method });
const makeSseFn =
(method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
const { opts, url } = await beforeRequest(options);
return createSseClient({
...opts,
body: opts.body as BodyInit | null | undefined,
headers: opts.headers as unknown as Record<string, string>,
method,
onRequest: async (url, init) => {
let request = new Request(url, init);
for (const fn of interceptors.request.fns) {
if (fn) {
request = await fn(request, opts);
}
const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
const { opts, url } = await beforeRequest(options);
return createSseClient({
...opts,
body: opts.body as BodyInit | null | undefined,
headers: opts.headers as unknown as Record<string, string>,
method,
onRequest: async (url, init) => {
let request = new Request(url, init);
for (const fn of interceptors.request.fns) {
if (fn) {
request = await fn(request, opts);
}
return request;
},
url,
});
};
}
return request;
},
serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined,
url,
});
};
return {
buildUrl,

View file

@ -1,4 +1,217 @@
// This file is auto-generated by @hey-api/openapi-ts
export type * from "./types.gen";
export * from "./sdk.gen";
export {
browseFilesystem,
createBackupSchedule,
createNotificationDestination,
createRepository,
createVolume,
deleteBackupSchedule,
deleteNotificationDestination,
deleteRepository,
deleteSnapshot,
deleteSnapshots,
deleteVolume,
doctorRepository,
downloadResticPassword,
getBackupSchedule,
getBackupScheduleForVolume,
getMirrorCompatibility,
getNotificationDestination,
getRepository,
getScheduleMirrors,
getScheduleNotifications,
getSnapshotDetails,
getStatus,
getSystemInfo,
getUpdates,
getVolume,
healthCheckVolume,
listBackupSchedules,
listFiles,
listNotificationDestinations,
listRcloneRemotes,
listRepositories,
listSnapshotFiles,
listSnapshots,
listVolumes,
mountVolume,
type Options,
reorderBackupSchedules,
restoreSnapshot,
runBackupNow,
runForget,
stopBackup,
tagSnapshots,
testConnection,
testNotificationDestination,
unmountVolume,
updateBackupSchedule,
updateNotificationDestination,
updateRepository,
updateScheduleMirrors,
updateScheduleNotifications,
updateVolume,
} from "./sdk.gen";
export type {
BrowseFilesystemData,
BrowseFilesystemResponse,
BrowseFilesystemResponses,
ClientOptions,
CreateBackupScheduleData,
CreateBackupScheduleResponse,
CreateBackupScheduleResponses,
CreateNotificationDestinationData,
CreateNotificationDestinationResponse,
CreateNotificationDestinationResponses,
CreateRepositoryData,
CreateRepositoryResponse,
CreateRepositoryResponses,
CreateVolumeData,
CreateVolumeResponse,
CreateVolumeResponses,
DeleteBackupScheduleData,
DeleteBackupScheduleResponse,
DeleteBackupScheduleResponses,
DeleteNotificationDestinationData,
DeleteNotificationDestinationErrors,
DeleteNotificationDestinationResponse,
DeleteNotificationDestinationResponses,
DeleteRepositoryData,
DeleteRepositoryResponse,
DeleteRepositoryResponses,
DeleteSnapshotData,
DeleteSnapshotResponse,
DeleteSnapshotResponses,
DeleteSnapshotsData,
DeleteSnapshotsResponse,
DeleteSnapshotsResponses,
DeleteVolumeData,
DeleteVolumeResponse,
DeleteVolumeResponses,
DoctorRepositoryData,
DoctorRepositoryResponse,
DoctorRepositoryResponses,
DownloadResticPasswordData,
DownloadResticPasswordResponse,
DownloadResticPasswordResponses,
GetBackupScheduleData,
GetBackupScheduleForVolumeData,
GetBackupScheduleForVolumeResponse,
GetBackupScheduleForVolumeResponses,
GetBackupScheduleResponse,
GetBackupScheduleResponses,
GetMirrorCompatibilityData,
GetMirrorCompatibilityResponse,
GetMirrorCompatibilityResponses,
GetNotificationDestinationData,
GetNotificationDestinationErrors,
GetNotificationDestinationResponse,
GetNotificationDestinationResponses,
GetRepositoryData,
GetRepositoryResponse,
GetRepositoryResponses,
GetScheduleMirrorsData,
GetScheduleMirrorsResponse,
GetScheduleMirrorsResponses,
GetScheduleNotificationsData,
GetScheduleNotificationsResponse,
GetScheduleNotificationsResponses,
GetSnapshotDetailsData,
GetSnapshotDetailsResponse,
GetSnapshotDetailsResponses,
GetStatusData,
GetStatusResponse,
GetStatusResponses,
GetSystemInfoData,
GetSystemInfoResponse,
GetSystemInfoResponses,
GetUpdatesData,
GetUpdatesResponse,
GetUpdatesResponses,
GetVolumeData,
GetVolumeErrors,
GetVolumeResponse,
GetVolumeResponses,
HealthCheckVolumeData,
HealthCheckVolumeErrors,
HealthCheckVolumeResponse,
HealthCheckVolumeResponses,
ListBackupSchedulesData,
ListBackupSchedulesResponse,
ListBackupSchedulesResponses,
ListFilesData,
ListFilesResponse,
ListFilesResponses,
ListNotificationDestinationsData,
ListNotificationDestinationsResponse,
ListNotificationDestinationsResponses,
ListRcloneRemotesData,
ListRcloneRemotesResponse,
ListRcloneRemotesResponses,
ListRepositoriesData,
ListRepositoriesResponse,
ListRepositoriesResponses,
ListSnapshotFilesData,
ListSnapshotFilesResponse,
ListSnapshotFilesResponses,
ListSnapshotsData,
ListSnapshotsResponse,
ListSnapshotsResponses,
ListVolumesData,
ListVolumesResponse,
ListVolumesResponses,
MountVolumeData,
MountVolumeResponse,
MountVolumeResponses,
ReorderBackupSchedulesData,
ReorderBackupSchedulesResponse,
ReorderBackupSchedulesResponses,
RestoreSnapshotData,
RestoreSnapshotResponse,
RestoreSnapshotResponses,
RunBackupNowData,
RunBackupNowResponse,
RunBackupNowResponses,
RunForgetData,
RunForgetResponse,
RunForgetResponses,
StopBackupData,
StopBackupErrors,
StopBackupResponse,
StopBackupResponses,
TagSnapshotsData,
TagSnapshotsResponse,
TagSnapshotsResponses,
TestConnectionData,
TestConnectionResponse,
TestConnectionResponses,
TestNotificationDestinationData,
TestNotificationDestinationErrors,
TestNotificationDestinationResponse,
TestNotificationDestinationResponses,
UnmountVolumeData,
UnmountVolumeResponse,
UnmountVolumeResponses,
UpdateBackupScheduleData,
UpdateBackupScheduleResponse,
UpdateBackupScheduleResponses,
UpdateNotificationDestinationData,
UpdateNotificationDestinationErrors,
UpdateNotificationDestinationResponse,
UpdateNotificationDestinationResponses,
UpdateRepositoryData,
UpdateRepositoryErrors,
UpdateRepositoryResponse,
UpdateRepositoryResponses,
UpdateScheduleMirrorsData,
UpdateScheduleMirrorsResponse,
UpdateScheduleMirrorsResponses,
UpdateScheduleNotificationsData,
UpdateScheduleNotificationsResponse,
UpdateScheduleNotificationsResponses,
UpdateVolumeData,
UpdateVolumeErrors,
UpdateVolumeResponse,
UpdateVolumeResponses,
} from "./types.gen";

View file

@ -73,7 +73,7 @@ export type ListVolumesResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -100,8 +100,7 @@ export type ListVolumesResponses = {
}>;
};
export type ListVolumesResponse =
ListVolumesResponses[keyof ListVolumesResponses];
export type ListVolumesResponse = ListVolumesResponses[keyof ListVolumesResponses];
export type CreateVolumeData = {
body?: {
@ -143,7 +142,7 @@ export type CreateVolumeData = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -209,7 +208,7 @@ export type CreateVolumeResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -236,8 +235,7 @@ export type CreateVolumeResponses = {
};
};
export type CreateVolumeResponse =
CreateVolumeResponses[keyof CreateVolumeResponses];
export type CreateVolumeResponse = CreateVolumeResponses[keyof CreateVolumeResponses];
export type TestConnectionData = {
body?: {
@ -279,7 +277,7 @@ export type TestConnectionData = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -310,8 +308,7 @@ export type TestConnectionResponses = {
};
};
export type TestConnectionResponse =
TestConnectionResponses[keyof TestConnectionResponses];
export type TestConnectionResponse = TestConnectionResponses[keyof TestConnectionResponses];
export type DeleteVolumeData = {
body?: never;
@ -331,8 +328,7 @@ export type DeleteVolumeResponses = {
};
};
export type DeleteVolumeResponse =
DeleteVolumeResponses[keyof DeleteVolumeResponses];
export type DeleteVolumeResponse = DeleteVolumeResponses[keyof DeleteVolumeResponses];
export type GetVolumeData = {
body?: never;
@ -400,7 +396,7 @@ export type GetVolumeResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -471,7 +467,7 @@ export type UpdateVolumeData = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -546,7 +542,7 @@ export type UpdateVolumeResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -573,8 +569,7 @@ export type UpdateVolumeResponses = {
};
};
export type UpdateVolumeResponse =
UpdateVolumeResponses[keyof UpdateVolumeResponses];
export type UpdateVolumeResponse = UpdateVolumeResponses[keyof UpdateVolumeResponses];
export type MountVolumeData = {
body?: never;
@ -595,8 +590,7 @@ export type MountVolumeResponses = {
};
};
export type MountVolumeResponse =
MountVolumeResponses[keyof MountVolumeResponses];
export type MountVolumeResponse = MountVolumeResponses[keyof MountVolumeResponses];
export type UnmountVolumeData = {
body?: never;
@ -617,8 +611,7 @@ export type UnmountVolumeResponses = {
};
};
export type UnmountVolumeResponse =
UnmountVolumeResponses[keyof UnmountVolumeResponses];
export type UnmountVolumeResponse = UnmountVolumeResponses[keyof UnmountVolumeResponses];
export type HealthCheckVolumeData = {
body?: never;
@ -646,8 +639,7 @@ export type HealthCheckVolumeResponses = {
};
};
export type HealthCheckVolumeResponse =
HealthCheckVolumeResponses[keyof HealthCheckVolumeResponses];
export type HealthCheckVolumeResponse = HealthCheckVolumeResponses[keyof HealthCheckVolumeResponses];
export type ListFilesData = {
body?: never;
@ -709,8 +701,7 @@ export type BrowseFilesystemResponses = {
};
};
export type BrowseFilesystemResponse =
BrowseFilesystemResponses[keyof BrowseFilesystemResponses];
export type BrowseFilesystemResponse = BrowseFilesystemResponses[keyof BrowseFilesystemResponses];
export type ListRepositoriesData = {
body?: never;
@ -824,8 +815,7 @@ export type ListRepositoriesResponses = {
}>;
};
export type ListRepositoriesResponse =
ListRepositoriesResponses[keyof ListRepositoriesResponses];
export type ListRepositoriesResponse = ListRepositoriesResponses[keyof ListRepositoriesResponses];
export type CreateRepositoryData = {
body?: {
@ -938,8 +928,7 @@ export type CreateRepositoryResponses = {
};
};
export type CreateRepositoryResponse =
CreateRepositoryResponses[keyof CreateRepositoryResponses];
export type CreateRepositoryResponse = CreateRepositoryResponses[keyof CreateRepositoryResponses];
export type ListRcloneRemotesData = {
body?: never;
@ -958,8 +947,7 @@ export type ListRcloneRemotesResponses = {
}>;
};
export type ListRcloneRemotesResponse =
ListRcloneRemotesResponses[keyof ListRcloneRemotesResponses];
export type ListRcloneRemotesResponse = ListRcloneRemotesResponses[keyof ListRcloneRemotesResponses];
export type DeleteRepositoryData = {
body?: never;
@ -979,8 +967,7 @@ export type DeleteRepositoryResponses = {
};
};
export type DeleteRepositoryResponse =
DeleteRepositoryResponses[keyof DeleteRepositoryResponses];
export type DeleteRepositoryResponse = DeleteRepositoryResponses[keyof DeleteRepositoryResponses];
export type GetRepositoryData = {
body?: never;
@ -1096,8 +1083,7 @@ export type GetRepositoryResponses = {
};
};
export type GetRepositoryResponse =
GetRepositoryResponses[keyof GetRepositoryResponses];
export type GetRepositoryResponse = GetRepositoryResponses[keyof GetRepositoryResponses];
export type UpdateRepositoryData = {
body?: {
@ -1227,8 +1213,7 @@ export type UpdateRepositoryResponses = {
};
};
export type UpdateRepositoryResponse =
UpdateRepositoryResponses[keyof UpdateRepositoryResponses];
export type UpdateRepositoryResponse = UpdateRepositoryResponses[keyof UpdateRepositoryResponses];
export type DeleteSnapshotsData = {
body?: {
@ -1250,8 +1235,7 @@ export type DeleteSnapshotsResponses = {
};
};
export type DeleteSnapshotsResponse =
DeleteSnapshotsResponses[keyof DeleteSnapshotsResponses];
export type DeleteSnapshotsResponse = DeleteSnapshotsResponses[keyof DeleteSnapshotsResponses];
export type ListSnapshotsData = {
body?: never;
@ -1278,8 +1262,7 @@ export type ListSnapshotsResponses = {
}>;
};
export type ListSnapshotsResponse =
ListSnapshotsResponses[keyof ListSnapshotsResponses];
export type ListSnapshotsResponse = ListSnapshotsResponses[keyof ListSnapshotsResponses];
export type DeleteSnapshotData = {
body?: never;
@ -1300,8 +1283,7 @@ export type DeleteSnapshotResponses = {
};
};
export type DeleteSnapshotResponse =
DeleteSnapshotResponses[keyof DeleteSnapshotResponses];
export type DeleteSnapshotResponse = DeleteSnapshotResponses[keyof DeleteSnapshotResponses];
export type GetSnapshotDetailsData = {
body?: never;
@ -1327,8 +1309,7 @@ export type GetSnapshotDetailsResponses = {
};
};
export type GetSnapshotDetailsResponse =
GetSnapshotDetailsResponses[keyof GetSnapshotDetailsResponses];
export type GetSnapshotDetailsResponse = GetSnapshotDetailsResponses[keyof GetSnapshotDetailsResponses];
export type ListSnapshotFilesData = {
body?: never;
@ -1369,8 +1350,7 @@ export type ListSnapshotFilesResponses = {
};
};
export type ListSnapshotFilesResponse =
ListSnapshotFilesResponses[keyof ListSnapshotFilesResponses];
export type ListSnapshotFilesResponse = ListSnapshotFilesResponses[keyof ListSnapshotFilesResponses];
export type RestoreSnapshotData = {
body?: {
@ -1401,8 +1381,7 @@ export type RestoreSnapshotResponses = {
};
};
export type RestoreSnapshotResponse =
RestoreSnapshotResponses[keyof RestoreSnapshotResponses];
export type RestoreSnapshotResponse = RestoreSnapshotResponses[keyof RestoreSnapshotResponses];
export type DoctorRepositoryData = {
body?: never;
@ -1428,8 +1407,7 @@ export type DoctorRepositoryResponses = {
};
};
export type DoctorRepositoryResponse =
DoctorRepositoryResponses[keyof DoctorRepositoryResponses];
export type DoctorRepositoryResponse = DoctorRepositoryResponses[keyof DoctorRepositoryResponses];
export type TagSnapshotsData = {
body?: {
@ -1454,8 +1432,7 @@ export type TagSnapshotsResponses = {
};
};
export type TagSnapshotsResponse =
TagSnapshotsResponses[keyof TagSnapshotsResponses];
export type TagSnapshotsResponse = TagSnapshotsResponses[keyof TagSnapshotsResponses];
export type ListBackupSchedulesData = {
body?: never;
@ -1578,15 +1555,7 @@ export type ListBackupSchedulesResponses = {
name: string;
shortId: string;
status: "error" | "healthy" | "unknown" | null;
type:
| "azure"
| "gcs"
| "local"
| "r2"
| "rclone"
| "rest"
| "s3"
| "sftp";
type: "azure" | "gcs" | "local" | "r2" | "rclone" | "rest" | "s3" | "sftp";
updatedAt: number;
};
repositoryId: string;
@ -1641,7 +1610,7 @@ export type ListBackupSchedulesResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -1670,8 +1639,7 @@ export type ListBackupSchedulesResponses = {
}>;
};
export type ListBackupSchedulesResponse =
ListBackupSchedulesResponses[keyof ListBackupSchedulesResponses];
export type ListBackupSchedulesResponse = ListBackupSchedulesResponses[keyof ListBackupSchedulesResponses];
export type CreateBackupScheduleData = {
body?: {
@ -1734,8 +1702,7 @@ export type CreateBackupScheduleResponses = {
};
};
export type CreateBackupScheduleResponse =
CreateBackupScheduleResponses[keyof CreateBackupScheduleResponses];
export type CreateBackupScheduleResponse = CreateBackupScheduleResponses[keyof CreateBackupScheduleResponses];
export type DeleteBackupScheduleData = {
body?: never;
@ -1755,8 +1722,7 @@ export type DeleteBackupScheduleResponses = {
};
};
export type DeleteBackupScheduleResponse =
DeleteBackupScheduleResponses[keyof DeleteBackupScheduleResponses];
export type DeleteBackupScheduleResponse = DeleteBackupScheduleResponses[keyof DeleteBackupScheduleResponses];
export type GetBackupScheduleData = {
body?: never;
@ -1881,15 +1847,7 @@ export type GetBackupScheduleResponses = {
name: string;
shortId: string;
status: "error" | "healthy" | "unknown" | null;
type:
| "azure"
| "gcs"
| "local"
| "r2"
| "rclone"
| "rest"
| "s3"
| "sftp";
type: "azure" | "gcs" | "local" | "r2" | "rclone" | "rest" | "s3" | "sftp";
updatedAt: number;
};
repositoryId: string;
@ -1944,7 +1902,7 @@ export type GetBackupScheduleResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -1973,8 +1931,7 @@ export type GetBackupScheduleResponses = {
};
};
export type GetBackupScheduleResponse =
GetBackupScheduleResponses[keyof GetBackupScheduleResponses];
export type GetBackupScheduleResponse = GetBackupScheduleResponses[keyof GetBackupScheduleResponses];
export type UpdateBackupScheduleData = {
body?: {
@ -2038,8 +1995,7 @@ export type UpdateBackupScheduleResponses = {
};
};
export type UpdateBackupScheduleResponse =
UpdateBackupScheduleResponses[keyof UpdateBackupScheduleResponses];
export type UpdateBackupScheduleResponse = UpdateBackupScheduleResponses[keyof UpdateBackupScheduleResponses];
export type GetBackupScheduleForVolumeData = {
body?: never;
@ -2164,15 +2120,7 @@ export type GetBackupScheduleForVolumeResponses = {
name: string;
shortId: string;
status: "error" | "healthy" | "unknown" | null;
type:
| "azure"
| "gcs"
| "local"
| "r2"
| "rclone"
| "rest"
| "s3"
| "sftp";
type: "azure" | "gcs" | "local" | "r2" | "rclone" | "rest" | "s3" | "sftp";
updatedAt: number;
};
repositoryId: string;
@ -2227,7 +2175,7 @@ export type GetBackupScheduleForVolumeResponses = {
server: string;
share: string;
username: string;
vers?: "1.0" | "2.0" | "2.1" | "3.0";
vers?: "1.0" | "2.0" | "2.1" | "3.0" | "auto";
port?: number;
domain?: string;
readOnly?: boolean;
@ -2277,8 +2225,7 @@ export type RunBackupNowResponses = {
};
};
export type RunBackupNowResponse =
RunBackupNowResponses[keyof RunBackupNowResponses];
export type RunBackupNowResponse = RunBackupNowResponses[keyof RunBackupNowResponses];
export type StopBackupData = {
body?: never;
@ -2414,16 +2361,7 @@ export type GetScheduleNotificationsResponses = {
enabled: boolean;
id: number;
name: string;
type:
| "custom"
| "discord"
| "email"
| "generic"
| "gotify"
| "ntfy"
| "pushover"
| "slack"
| "telegram";
type: "custom" | "discord" | "email" | "generic" | "gotify" | "ntfy" | "pushover" | "slack" | "telegram";
updatedAt: number;
};
destinationId: number;
@ -2533,16 +2471,7 @@ export type UpdateScheduleNotificationsResponses = {
enabled: boolean;
id: number;
name: string;
type:
| "custom"
| "discord"
| "email"
| "generic"
| "gotify"
| "ntfy"
| "pushover"
| "slack"
| "telegram";
type: "custom" | "discord" | "email" | "generic" | "gotify" | "ntfy" | "pushover" | "slack" | "telegram";
updatedAt: number;
};
destinationId: number;
@ -2672,15 +2601,7 @@ export type GetScheduleMirrorsResponses = {
name: string;
shortId: string;
status: "error" | "healthy" | "unknown" | null;
type:
| "azure"
| "gcs"
| "local"
| "r2"
| "rclone"
| "rest"
| "s3"
| "sftp";
type: "azure" | "gcs" | "local" | "r2" | "rclone" | "rest" | "s3" | "sftp";
updatedAt: number;
};
repositoryId: string;
@ -2688,8 +2609,7 @@ export type GetScheduleMirrorsResponses = {
}>;
};
export type GetScheduleMirrorsResponse =
GetScheduleMirrorsResponses[keyof GetScheduleMirrorsResponses];
export type GetScheduleMirrorsResponse = GetScheduleMirrorsResponses[keyof GetScheduleMirrorsResponses];
export type UpdateScheduleMirrorsData = {
body?: {
@ -2811,15 +2731,7 @@ export type UpdateScheduleMirrorsResponses = {
name: string;
shortId: string;
status: "error" | "healthy" | "unknown" | null;
type:
| "azure"
| "gcs"
| "local"
| "r2"
| "rclone"
| "rest"
| "s3"
| "sftp";
type: "azure" | "gcs" | "local" | "r2" | "rclone" | "rest" | "s3" | "sftp";
updatedAt: number;
};
repositoryId: string;
@ -2827,8 +2739,7 @@ export type UpdateScheduleMirrorsResponses = {
}>;
};
export type UpdateScheduleMirrorsResponse =
UpdateScheduleMirrorsResponses[keyof UpdateScheduleMirrorsResponses];
export type UpdateScheduleMirrorsResponse = UpdateScheduleMirrorsResponses[keyof UpdateScheduleMirrorsResponses];
export type GetMirrorCompatibilityData = {
body?: never;
@ -2850,8 +2761,7 @@ export type GetMirrorCompatibilityResponses = {
}>;
};
export type GetMirrorCompatibilityResponse =
GetMirrorCompatibilityResponses[keyof GetMirrorCompatibilityResponses];
export type GetMirrorCompatibilityResponse = GetMirrorCompatibilityResponses[keyof GetMirrorCompatibilityResponses];
export type ReorderBackupSchedulesData = {
body?: {
@ -2871,8 +2781,7 @@ export type ReorderBackupSchedulesResponses = {
};
};
export type ReorderBackupSchedulesResponse =
ReorderBackupSchedulesResponses[keyof ReorderBackupSchedulesResponses];
export type ReorderBackupSchedulesResponse = ReorderBackupSchedulesResponses[keyof ReorderBackupSchedulesResponses];
export type ListNotificationDestinationsData = {
body?: never;
@ -2957,16 +2866,7 @@ export type ListNotificationDestinationsResponses = {
enabled: boolean;
id: number;
name: string;
type:
| "custom"
| "discord"
| "email"
| "generic"
| "gotify"
| "ntfy"
| "pushover"
| "slack"
| "telegram";
type: "custom" | "discord" | "email" | "generic" | "gotify" | "ntfy" | "pushover" | "slack" | "telegram";
updatedAt: number;
}>;
};
@ -3126,16 +3026,7 @@ export type CreateNotificationDestinationResponses = {
enabled: boolean;
id: number;
name: string;
type:
| "custom"
| "discord"
| "email"
| "generic"
| "gotify"
| "ntfy"
| "pushover"
| "slack"
| "telegram";
type: "custom" | "discord" | "email" | "generic" | "gotify" | "ntfy" | "pushover" | "slack" | "telegram";
updatedAt: number;
};
};
@ -3263,16 +3154,7 @@ export type GetNotificationDestinationResponses = {
enabled: boolean;
id: number;
name: string;
type:
| "custom"
| "discord"
| "email"
| "generic"
| "gotify"
| "ntfy"
| "pushover"
| "slack"
| "telegram";
type: "custom" | "discord" | "email" | "generic" | "gotify" | "ntfy" | "pushover" | "slack" | "telegram";
updatedAt: number;
};
};
@ -3442,16 +3324,7 @@ export type UpdateNotificationDestinationResponses = {
enabled: boolean;
id: number;
name: string;
type:
| "custom"
| "discord"
| "email"
| "generic"
| "gotify"
| "ntfy"
| "pushover"
| "slack"
| "telegram";
type: "custom" | "discord" | "email" | "generic" | "gotify" | "ntfy" | "pushover" | "slack" | "telegram";
updatedAt: number;
};
};
@ -3514,8 +3387,7 @@ export type GetSystemInfoResponses = {
};
};
export type GetSystemInfoResponse =
GetSystemInfoResponses[keyof GetSystemInfoResponses];
export type GetSystemInfoResponse = GetSystemInfoResponses[keyof GetSystemInfoResponses];
export type GetUpdatesData = {
body?: never;
@ -3559,5 +3431,4 @@ export type DownloadResticPasswordResponses = {
200: string;
};
export type DownloadResticPasswordResponse =
DownloadResticPasswordResponses[keyof DownloadResticPasswordResponses];
export type DownloadResticPasswordResponse = DownloadResticPasswordResponses[keyof DownloadResticPasswordResponses];

View file

@ -26,7 +26,7 @@ export const smbConfigSchema = type({
share: "string",
username: "string",
password: "string",
vers: type("'1.0' | '2.0' | '2.1' | '3.0'").default("3.0"),
vers: type("'1.0' | '2.0' | '2.1' | '3.0' | 'auto'").default("auto"),
domain: "string?",
port: type("string.integer").or(type("number")).to("1 <= number <= 65535").default(445),
readOnly: "boolean?",

View file

@ -54,10 +54,13 @@ const mount = async (config: BackendConfig, path: string) => {
logger.debug(`Mounting volume ${path}...`);
logger.info(`Executing mount: mount ${args.join(" ")}`);
await executeMount(args);
// Fallback with -i flag if the first mount fails using the mount helper
await executeMount(["-i", ...args]);
try {
await executeMount(args);
} catch (error) {
logger.warn(`Initial NFS mount failed, retrying with -i flag: ${toMessage(error)}`);
// Fallback with -i flag if the first mount fails using the mount helper
await executeMount(["-i", ...args]);
}
logger.info(`NFS volume at ${path} mounted successfully.`);
return { status: BACKEND_STATUS.mounted };

View file

@ -40,14 +40,11 @@ const mount = async (config: BackendConfig, path: string) => {
const source = `//${config.server}/${config.share}`;
const { uid, gid } = os.userInfo();
const options = [
`user=${config.username}`,
`pass=${password}`,
`vers=${config.vers}`,
`port=${config.port}`,
`uid=${uid}`,
`gid=${gid}`,
];
const options = [`user=${config.username}`, `pass=${password}`, `port=${config.port}`, `uid=${uid}`, `gid=${gid}`];
if (config.vers && config.vers !== "auto") {
options.push(`vers=${config.vers}`);
}
if (config.domain) {
options.push(`domain=${config.domain}`);
@ -62,10 +59,13 @@ const mount = async (config: BackendConfig, path: string) => {
logger.debug(`Mounting SMB volume ${path}...`);
logger.info(`Executing mount: mount ${args.join(" ")}`);
await executeMount(args);
// Fallback with -i flag if the first mount fails using the mount helper
await executeMount(["-i", ...args]);
try {
await executeMount(args);
} catch (error) {
logger.warn(`Initial SMB mount failed, retrying with -i flag: ${toMessage(error)}`);
// Fallback with -i flag if the first mount fails using the mount helper
await executeMount(["-i", ...args]);
}
logger.info(`SMB volume at ${path} mounted successfully.`);
return { status: BACKEND_STATUS.mounted };

View file

@ -7,10 +7,10 @@ import { logger } from "../../../utils/logger";
export const executeMount = async (args: string[]): Promise<void> => {
const shouldBeVerbose = process.env.LOG_LEVEL === "debug" || process.env.NODE_ENV !== "production";
const hasVerboseFlag = args.some((arg) => arg === "-v" || arg.startsWith("-vv"));
const effectiveArgs = shouldBeVerbose && !hasVerboseFlag ? ["-vvv", ...args] : args;
const effectiveArgs = shouldBeVerbose && !hasVerboseFlag ? ["-v", ...args] : args;
logger.debug(`Executing mount ${effectiveArgs.join(" ")}`);
const result = await $`mount ${effectiveArgs}`.nothrow();
let result = await $`mount ${effectiveArgs}`.nothrow();
const stdout = result.stdout.toString().trim();
const stderr = result.stderr.toString().trim();

View file

@ -58,10 +58,14 @@ const mount = async (config: BackendConfig, path: string) => {
logger.debug(`Mounting WebDAV volume ${path}...`);
const args = ["-t", "davfs", "-o", options.join(","), source, path];
await executeMount(args);
// Fallback with -i flag if the first mount fails using the mount helper
await executeMount(["-i", ...args]);
try {
await executeMount(args);
} catch (error) {
logger.warn(`Initial WebDAV mount failed, retrying with -i flag: ${toMessage(error)}`);
// Fallback with -i flag if the first mount fails using the mount helper
await executeMount(["-i", ...args]);
}
logger.info(`WebDAV volume at ${path} mounted successfully.`);
return { status: BACKEND_STATUS.mounted };