diff --git a/src/utils.ts b/src/utils.ts index 6892118f..926efea3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -146,11 +146,19 @@ export function isNonEmptyURL(url: string) { return url && url !== "/"; } +const JOIN_LEADING_SLASH_RE = /^\.?\//; + export function joinURL(base: string, ...input: string[]): string { let url = base || ""; - for (const index of input.filter((url) => isNonEmptyURL(url))) { - url = url ? withTrailingSlash(url) + withoutLeadingSlash(index) : index; + for (const segment of input.filter((url) => isNonEmptyURL(url))) { + if (!url) { + url = segment; + } else { + // TODO: Handle .. when joining + const _segment = segment.replace(JOIN_LEADING_SLASH_RE, ""); + url = withTrailingSlash(url) + _segment; + } } return url; diff --git a/test/join.test.ts b/test/join.test.ts index 7f0d287a..e7c400bb 100644 --- a/test/join.test.ts +++ b/test/join.test.ts @@ -12,10 +12,14 @@ describe("joinURL", () => { { input: ["/", "/b"], out: "/b" }, { input: ["a", "b/", "c"], out: "a/b/c" }, { input: ["a", "b/", "/c"], out: "a/b/c" }, + { input: ["/", "./"], out: "/" }, + { input: ["/", "./foo"], out: "/foo" }, + { input: ["/", "./foo/"], out: "/foo/" }, + { input: ["/", "./foo", "bar"], out: "/foo/bar" }, ]; for (const t of tests) { - test(t.input.toString(), () => { + test(JSON.stringify(t.input), () => { expect(joinURL(...t.input)).toBe(t.out); }); }