Skip to content

Commit

Permalink
fix: respect fragment in trailing slash utils (#175)
Browse files Browse the repository at this point in the history
Co-authored-by: Pooya Parsa <[email protected]>
  • Loading branch information
TheAlexLichter and pi0 authored Nov 15, 2023
1 parent 11f161e commit f4c0400
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
49 changes: 38 additions & 11 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,38 +49,65 @@ export function isScriptProtocol(protocol?: string) {
return !!protocol && PROTOCOL_SCRIPT_RE.test(protocol);
}

const TRAILING_SLASH_RE = /\/$|\/\?/;
const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;

export function hasTrailingSlash(input = "", queryParameters = false): boolean {
if (!queryParameters) {
export function hasTrailingSlash(
input = "",
respectQueryAndFragment?: boolean
): boolean {
if (!respectQueryAndFragment) {
return input.endsWith("/");
}
return TRAILING_SLASH_RE.test(input);
}

export function withoutTrailingSlash(
input = "",
queryParameters = false
respectQueryAndFragment?: boolean
): string {
if (!queryParameters) {
if (!respectQueryAndFragment) {
return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
}
if (!hasTrailingSlash(input, true)) {
return input || "/";
}
const [s0, ...s] = input.split("?");
return (s0.slice(0, -1) || "/") + (s.length > 0 ? `?${s.join("?")}` : "");
let path = input;
let fragment = "";
const fragmentIndex = input.indexOf("#");
if (fragmentIndex >= 0) {
path = input.slice(0, fragmentIndex);
fragment = input.slice(fragmentIndex);
}
const [s0, ...s] = path.split("?");
return (
(s0.slice(0, -1) || "/") +
(s.length > 0 ? `?${s.join("?")}` : "") +
fragment
);
}

export function withTrailingSlash(input = "", queryParameters = false): string {
if (!queryParameters) {
export function withTrailingSlash(
input = "",
respectQueryAndFragment?: boolean
): string {
if (!respectQueryAndFragment) {
return input.endsWith("/") ? input : input + "/";
}
if (hasTrailingSlash(input, true)) {
return input || "/";
}
const [s0, ...s] = input.split("?");
return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "");
let path = input;
let fragment = "";
const fragmentIndex = input.indexOf("#");
if (fragmentIndex >= 0) {
path = input.slice(0, fragmentIndex);
fragment = input.slice(fragmentIndex);
if (!path) {
return fragment;
}
}
const [s0, ...s] = path.split("?");
return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "") + fragment;
}

export function hasLeadingSlash(input = ""): boolean {
Expand Down
15 changes: 14 additions & 1 deletion test/trailing-slash.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ describe("withTrailingSlash, queryParams: false", () => {
const tests = {
"": "/",
bar: "bar/",
"bar#abc": "bar#abc/",
"bar/": "bar/",
"foo?123": "foo?123/",
"foo/?123": "foo/?123/",
"foo/?123#abc": "foo/?123#abc/",
};

for (const input in tests) {
Expand All @@ -28,6 +30,10 @@ describe("withTrailingSlash, queryParams: true", () => {
"bar/": "bar/",
"foo?123": "foo/?123",
"foo/?123": "foo/?123",
"foo?123#abc": "foo/?123#abc",
"/#abc": "/#abc",
"#abc": "#abc",
"#": "#",
};

for (const input in tests) {
Expand All @@ -46,9 +52,11 @@ describe("withoutTrailingSlash, queryParams: false", () => {
"": "/",
"/": "/",
bar: "bar",
"bar/": "bar",
"bar#abc": "bar#abc",
"bar/#abc": "bar/#abc",
"foo?123": "foo?123",
"foo/?123": "foo/?123",
"foo/?123#abc": "foo/?123#abc",
};

for (const input in tests) {
Expand All @@ -68,8 +76,13 @@ describe("withoutTrailingSlash, queryParams: true", () => {
"/": "/",
bar: "bar",
"bar/": "bar",
"bar#abc": "bar#abc",
"bar/#abc": "bar#abc",
"foo?123": "foo?123",
"foo/?123": "foo?123",
"foo/?123#abc": "foo?123#abc",
"/a/#abc": "/a#abc",
"/#abc": "/#abc",
};

for (const input in tests) {
Expand Down

0 comments on commit f4c0400

Please sign in to comment.