虚拟前缀 /@alist/… 读到本地是 ENOENT,但 mkdir -p、复制 / 移动目标、写文件、回收站落点会在本机真建出 /@alist 并写入文件。统一守卫:任何本地写类操作参数是虚拟路径即抛 REMOTE_PATH_ON_LOCAL_FS (remote_path_on_local_fs),不落盘。 - adapters:fs/remote-guard.ts,接在 runFsOp、FsProxy.run(父进程拒绝不起子进程)、copyWithVerify、 crossDeviceMove、moveSafe、commitNoClobber、sweepStalePartials、writeRootSentinel - server:storage/local-fs.ts 带守卫的写函数,整理 / 替换 / 刮削 / 回收站 / 上传 / 字幕 / vfs 本地分支改用它 - 补字幕目标在 Alist 媒体库上返回失败原因,撤销同样拒绝 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
22 lines
1.1 KiB
TypeScript
22 lines
1.1 KiB
TypeScript
import { FsError } from "./errors.ts";
|
|
|
|
// 远端虚拟路径守卫(docs/design/storage-alist.md §0):Alist 路径在本系统里写成 /@alist/<存储 id>/<路径>。
|
|
// 本地 fs 读它只会 ENOENT,但写类操作(mkdir -p、复制 / 移动目标、写文件、回收站落点)会在本机真建出
|
|
// /@alist/... 并把文件写进去——静默写错位置。所有本地写入口先过这里:参数是远端路径就抛
|
|
// REMOTE_PATH_ON_LOCAL_FS,不落盘。
|
|
|
|
export const REMOTE_PATH_PREFIX = "/@alist";
|
|
export const isVirtualRemotePath = (p: unknown): boolean =>
|
|
typeof p === "string" && (p === REMOTE_PATH_PREFIX || p.startsWith(`${REMOTE_PATH_PREFIX}/`));
|
|
|
|
/** 任一路径是远端虚拟路径 → 抛 FsError("REMOTE_PATH_ON_LOCAL_FS") */
|
|
export function assertLocalPaths(op: string, ...paths: (string | null | undefined)[]): void {
|
|
const hit = paths.find(isVirtualRemotePath);
|
|
if (hit)
|
|
throw new FsError(
|
|
"REMOTE_PATH_ON_LOCAL_FS",
|
|
`remote_path_on_local_fs: 本地文件操作 ${op} 收到 Alist 路径,已拒绝:${hit}`,
|
|
{ path: hit },
|
|
);
|
|
}
|