Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
/**
|
|
* Ensures that a URL has a trailing slash while preserving query parameters and fragments
|
|
* @param url - The URL to process
|
|
* @returns The URL with a trailing slash added to the pathname (if not already present)
|
|
*/
|
|
export function ensureTrailingSlash(url: string): string {
|
|
try {
|
|
const fallbackBaseUrl =
|
|
typeof window !== "undefined" && window.location.origin ? window.location.origin : "http://dummy.com";
|
|
// Handle relative URLs by creating a URL object with a fallback base URL
|
|
const urlObj = new URL(url, fallbackBaseUrl);
|
|
|
|
// Don't modify root path
|
|
if (urlObj.pathname === "/") {
|
|
return url;
|
|
}
|
|
|
|
// Add trailing slash if it doesn't exist
|
|
if (!urlObj.pathname.endsWith("/")) {
|
|
urlObj.pathname += "/";
|
|
}
|
|
|
|
// For relative URLs, return just the path + search + hash
|
|
if (url.startsWith("/")) {
|
|
return urlObj.pathname + urlObj.search + urlObj.hash;
|
|
}
|
|
|
|
// For absolute URLs, return the full URL
|
|
return urlObj.toString();
|
|
} catch (error) {
|
|
// If URL parsing fails, return the original URL
|
|
console.warn("Failed to parse URL for trailing slash enforcement:", url, error);
|
|
return url;
|
|
}
|
|
}
|