diff --git a/src/utils.ts b/src/utils.ts index b2ac7fd3..fafa927d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -93,7 +93,7 @@ export function hasTrailingSlash( /** * Removes trailing slash from the URL or pathname. * - * If second argument is is true, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations. + * If second argument is true, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations. * * @example * @@ -123,10 +123,9 @@ export function withoutTrailingSlash( fragment = input.slice(fragmentIndex); } const [s0, ...s] = path.split("?"); + const cleanPath = s0.endsWith("/") ? s0.slice(0, -1) : s0; return ( - (s0.slice(0, -1) || "/") + - (s.length > 0 ? `?${s.join("?")}` : "") + - fragment + (cleanPath || "/") + (s.length > 0 ? `?${s.join("?")}` : "") + fragment ); } diff --git a/test/trailing-slash.test.ts b/test/trailing-slash.test.ts index 21a1e37b..af141d0a 100644 --- a/test/trailing-slash.test.ts +++ b/test/trailing-slash.test.ts @@ -57,6 +57,8 @@ describe("withoutTrailingSlash, queryParams: false", () => { "foo?123": "foo?123", "foo/?123": "foo/?123", "foo/?123#abc": "foo/?123#abc", + "foo/?k=v": "foo/?k=v", + "foo/?k=/": "foo/?k=", }; for (const input in tests) { @@ -81,6 +83,10 @@ describe("withoutTrailingSlash, queryParams: true", () => { "foo?123": "foo?123", "foo/?123": "foo?123", "foo/?123#abc": "foo?123#abc", + "foo/?k=123": "foo?k=123", + "foo?k=/": "foo?k=/", + "foo/?k=/": "foo?k=/", + "foo/?k=/&x=y#abc": "foo?k=/&x=y#abc", "/a/#abc": "/a#abc", "/#abc": "/#abc", };