From 8f68ac4ded8e752588c604b81033665169d12ed1 Mon Sep 17 00:00:00 2001 From: Yesterday17 Date: Fri, 5 Apr 2024 10:45:23 +0800 Subject: [PATCH] handle relative path correctly (#226) Co-authored-by: fyears <1142836+fyears@users.noreply.github.com> --- src/remoteForWebdav.ts | 53 ++++++++++++++++++++++++++++++++++++++---- src/sync.ts | 1 + 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/remoteForWebdav.ts b/src/remoteForWebdav.ts index 07f1923..1cafb19 100644 --- a/src/remoteForWebdav.ts +++ b/src/remoteForWebdav.ts @@ -173,6 +173,52 @@ const getWebdavPath = (fileOrFolderPath: string, remoteBaseDir: string) => { return key; }; +function extractPrefix(path: string) { + let startsWithSlash = false; + if (path.startsWith("/")) { + startsWithSlash = true; + path = path.slice(1); + } + + let endsWithSlash = false; + if (path.endsWith("/")) { + endsWithSlash = true; + path = path.slice(0, -1); + } + + const segments = path.split("/"); + + const prefix: string[] = []; + let pathString = "/"; + + let level = 0; + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + if (segment === ".") { + continue; + } else if (segment === "..") { + level--; + prefix.push(segment); + } else if (level < 0) { + level++; + prefix.push(segment); + } else { + const pathSegments = segments.slice(i); + pathString += pathSegments.join("/"); + if (endsWithSlash && pathSegments.length > 0) { + pathString += "/"; + } + break; + } + } + + const prefixString = (startsWithSlash ? "/" : "") + prefix.join("/"); + return { + path: pathString, + prefix: prefixString, + }; +} + const getNormPath = (fileOrFolderPath: string, remoteBaseDir: string) => { if ( !( @@ -184,14 +230,13 @@ const getNormPath = (fileOrFolderPath: string, remoteBaseDir: string) => { `"${fileOrFolderPath}" doesn't starts with "/${remoteBaseDir}/"` ); } - // if (fileOrFolderPath.startsWith("/")) { - // return fileOrFolderPath.slice(1); - // } + return fileOrFolderPath.slice(`/${remoteBaseDir}/`.length); }; const fromWebdavItemToEntity = (x: FileStat, remoteBaseDir: string) => { - let key = getNormPath(x.filename, remoteBaseDir); + const { shortPath, prefix } = extractPrefix(x.filename); + let key = getNormPath(shortPath, remoteBaseDir); if (x.type === "directory" && !key.endsWith("/")) { key = `${key}/`; } diff --git a/src/sync.ts b/src/sync.ts index 4c9d3db..dc72b66 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -147,6 +147,7 @@ const isSkipItemByName = ( return ( isHiddenPath(key, true, false) || (!syncUnderscoreItems && isHiddenPath(key, false, true)) || + key === "/" || key === DEFAULT_FILE_NAME_FOR_METADATAONREMOTE || key === DEFAULT_FILE_NAME_FOR_METADATAONREMOTE2 );