Skip to content

Commit

Permalink
feat(joinURL): handle segments with ../ (#217)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Mar 11, 2024
1 parent aa54b6a commit 66c24d2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
15 changes: 12 additions & 3 deletions src/utils.ts
Expand Up @@ -14,6 +14,7 @@ const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
const PROTOCOL_SCRIPT_RE = /^[\s\0]*(blob|data|javascript|vbscript):$/i;
const TRAILING_SLASH_RE = /\/$|\/\?|\/#/;
const JOIN_LEADING_SLASH_RE = /^\.?\//;
const JOIN_LAST_SEGMENT_RE = /(?:^|\/)[^/]*\/?$/;

/**
* Check if a path starts with `./` or `../`.
Expand Down Expand Up @@ -323,9 +324,17 @@ export function joinURL(base: string, ...input: string[]): string {

for (const segment of input.filter((url) => isNonEmptyURL(url))) {
if (url) {
// TODO: Handle .. when joining
const _segment = segment.replace(JOIN_LEADING_SLASH_RE, "");
url = withTrailingSlash(url) + _segment;
const hasAbsoluteBase = url.startsWith("/");
let _segment = segment;
_segment = _segment.replace(JOIN_LEADING_SLASH_RE, "");
while (url.length > 0 && _segment.startsWith("../")) {
url = url.replace(JOIN_LAST_SEGMENT_RE, "");
_segment = _segment.slice(3).replace(JOIN_LEADING_SLASH_RE, "");
}
url =
!url && (!hasAbsoluteBase || _segment.startsWith("../"))
? _segment
: withTrailingSlash(url) + _segment;
} else {
url = segment;
}
Expand Down
12 changes: 12 additions & 0 deletions test/join.test.ts
Expand Up @@ -7,9 +7,21 @@ describe("joinURL", () => {
{ input: ["/"], out: "/" },
// eslint-disable-next-line unicorn/no-null
{ input: [null, "./"], out: "./" },
{ input: ["./", "a"], out: "./a" },
{ input: ["./a", "./b"], out: "./a/b" },
{ input: ["/a"], out: "/a" },
{ input: ["a", "b"], out: "a/b" },
{ input: ["/", "/b"], out: "/b" },
{ input: ["/a", "../b"], out: "/b" },
{ input: ["../a", "../b"], out: "../b" },
{ input: ["../a", "./../b"], out: "../b" },
{ input: ["../a", "./../../b"], out: "b" },
{ input: ["../a", "../../../b"], out: "../b" },
{ input: ["../a", "../../../../b"], out: "../../b" },
{ input: ["../a/", "../b"], out: "../b" },
{ input: ["/a/b/c", "../../d"], out: "/a/d" },
{ input: ["/c", "../../d"], out: "../d" },
{ input: ["/c", ".././../d"], out: "../d" },
{ input: ["a", "b/", "c"], out: "a/b/c" },
{ input: ["a", "b/", "/c"], out: "a/b/c" },
{ input: ["/", "./"], out: "/" },
Expand Down

0 comments on commit 66c24d2

Please sign in to comment.