From 894d1118e2d9181a4640ead2050a6a687765f054 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 5 Feb 2024 12:17:21 +0000 Subject: [PATCH 1/3] fix: stringify protocol-relative URLs --- src/parse.ts | 2 +- test/utilities.test.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/parse.ts b/src/parse.ts index fc8d34ec..a7281228 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -125,7 +125,7 @@ export function stringifyParsedURL(parsed: Partial): string { const hash = parsed.hash || ""; const auth = parsed.auth ? parsed.auth + "@" : ""; const host = parsed.host || ""; - const proto = parsed.protocol ? parsed.protocol + "//" : ""; + const proto = parsed.protocol || host ? (parsed.protocol || "") + "//" : ""; return proto + auth + host + pathname + search + hash; } diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 81240089..6852ea94 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -97,6 +97,7 @@ describe("stringifyParsedURL", () => { { input: "test?query=123#hash", out: "test?query=123#hash" }, { input: "/%c", out: "/%c" }, { input: "/%", out: "/%" }, + { input: "//test.com", out: "//test.com" }, { input: "http://foo.com/test?query=123#hash", out: "http://foo.com/test?query=123#hash", @@ -112,7 +113,7 @@ describe("stringifyParsedURL", () => { }, { input: { host: "google.com" }, - out: "google.com", + out: "//google.com", }, { input: { protocol: "https:", host: "google.com" }, From e9bb5d6af7aeb56fc313b90cea65bcdee3b57fd4 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 5 Feb 2024 13:40:16 +0000 Subject: [PATCH 2/3] fix: preserve protocol-relative state internally --- src/parse.ts | 5 ++++- test/parse.test.ts | 2 +- test/utilities.test.ts | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/parse.ts b/src/parse.ts index a7281228..0c78625b 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,5 +1,6 @@ import { decode } from "./encoding"; import { hasProtocol } from "./utils"; +const protocolRelative = Symbol.for("ufo:protocolRelative"); export interface ParsedURL { protocol?: string; host?: string; @@ -8,6 +9,7 @@ export interface ParsedURL { pathname: string; hash: string; search: string; + [protocolRelative]?: boolean; } export interface ParsedAuth { @@ -64,6 +66,7 @@ export function parseURL(input = "", defaultProto?: string): ParsedURL { pathname, search, hash, + [protocolRelative]: !protocol, }; } @@ -125,7 +128,7 @@ export function stringifyParsedURL(parsed: Partial): string { const hash = parsed.hash || ""; const auth = parsed.auth ? parsed.auth + "@" : ""; const host = parsed.host || ""; - const proto = parsed.protocol || host ? (parsed.protocol || "") + "//" : ""; + const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : ""; return proto + auth + host + pathname + search + hash; } diff --git a/test/parse.test.ts b/test/parse.test.ts index c796c509..419636c5 100644 --- a/test/parse.test.ts +++ b/test/parse.test.ts @@ -167,7 +167,7 @@ describe("parseURL", () => { for (const t of tests) { test(t.input.toString(), () => { - expect(parseURL(t.input)).toEqual(t.out); + expect(JSON.parse(JSON.stringify(parseURL(t.input)))).toEqual(t.out); }); } }); diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 6852ea94..27658d09 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -113,7 +113,7 @@ describe("stringifyParsedURL", () => { }, { input: { host: "google.com" }, - out: "//google.com", + out: "google.com", }, { input: { protocol: "https:", host: "google.com" }, From d07d5a8b5d84dcc06aa0658a7dae538caec073ca Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 5 Feb 2024 13:40:28 +0000 Subject: [PATCH 3/3] style: lint --- src/parse.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parse.ts b/src/parse.ts index 0c78625b..1e94fce0 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -128,7 +128,10 @@ export function stringifyParsedURL(parsed: Partial): string { const hash = parsed.hash || ""; const auth = parsed.auth ? parsed.auth + "@" : ""; const host = parsed.host || ""; - const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || "") + "//" : ""; + const proto = + parsed.protocol || parsed[protocolRelative] + ? (parsed.protocol || "") + "//" + : ""; return proto + auth + host + pathname + search + hash; }