From 618fcf934f4925183b4bce3be33328930cf26792 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna <46787868+vamsikrishnamathala@users.noreply.github.com> Date: Thu, 3 Jul 2025 18:07:02 +0530 Subject: [PATCH] refactor: string url path (#7335) --- packages/utils/src/string.ts | 56 ++++++++++++------- .../components/settings/sidebar/nav-item.tsx | 2 +- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/packages/utils/src/string.ts b/packages/utils/src/string.ts index 068ca4e765..58822e1e90 100644 --- a/packages/utils/src/string.ts +++ b/packages/utils/src/string.ts @@ -319,14 +319,15 @@ export const copyTextToClipboard = async (text: string): Promise => { await navigator.clipboard.writeText(text); }; + /** - * @description Joins URL path segments properly, removing duplicate slashes + * @description Joins URL path segments properly, removing duplicate slashes using URL encoding * @param {...string} segments - URL path segments to join * @returns {string} Properly joined URL path * @example * joinUrlPath("/workspace", "/projects") => "/workspace/projects" * joinUrlPath("/workspace", "projects") => "/workspace/projects" - * joinUrlPath("workspace", "projects") => "workspace/projects" + * joinUrlPath("workspace", "projects") => "/workspace/projects" * joinUrlPath("/workspace/", "/projects/") => "/workspace/projects/" */ export const joinUrlPath = (...segments: string[]): string => { @@ -336,21 +337,38 @@ export const joinUrlPath = (...segments: string[]): string => { const validSegments = segments.filter((segment) => segment !== ""); if (validSegments.length === 0) return ""; - // Join segments and normalize slashes - const joined = validSegments - .map((segment, index) => { - // Remove leading slashes from all segments except the first - if (index > 0) { - segment = segment.replace(/^\/+/, ""); - } - // Remove trailing slashes from all segments except the last - if (index < validSegments.length - 1) { - segment = segment.replace(/\/+$/, ""); - } - return segment; - }) - .join("/"); + // Process segments to normalize slashes + const processedSegments = validSegments.map((segment, index) => { + let processed = segment; - // Clean up any duplicate slashes that might have been created - return joined.replace(/\/+/g, "/"); -}; + // Remove leading slashes from all segments except the first + if (index > 0) { + while (processed.startsWith("/")) { + processed = processed.substring(1); + } + } + + // Remove trailing slashes from all segments except the last + if (index < validSegments.length - 1) { + while (processed.endsWith("/")) { + processed = processed.substring(0, processed.length - 1); + } + } + + return processed; + }); + + // Join segments with single slash + const joined = processedSegments.join("/"); + + // Use URL constructor to normalize the path and handle double slashes + try { + // Create a dummy URL to leverage browser's URL normalization + const dummyUrl = new URL(`http://example.com/${joined}`); + return dummyUrl.pathname; + } catch { + // Fallback: manually handle double slashes by splitting and filtering + const pathParts = joined.split("/").filter((part) => part !== ""); + return pathParts.length > 0 ? `/${pathParts.join("/")}` : ""; + } +}; \ No newline at end of file diff --git a/web/core/components/settings/sidebar/nav-item.tsx b/web/core/components/settings/sidebar/nav-item.tsx index 529739e641..14bac592bd 100644 --- a/web/core/components/settings/sidebar/nav-item.tsx +++ b/web/core/components/settings/sidebar/nav-item.tsx @@ -73,7 +73,7 @@ const SettingsSidebarNavItem = observer((props: TSettingsSidebarNavItemProps) =>
{titleElement}
) : ( toggleSidebar(true)} >