From e872f6eb9f80fa57ab92582d01beb5eb861c49b3 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 11:08:05 +0530 Subject: [PATCH 01/10] Add a `withHash` function Fixes #190 --- src/utils.ts | 6 ++++++ test/utilities.test.ts | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/utils.ts b/src/utils.ts index 8fa951bf..1797f9af 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -256,3 +256,9 @@ export function isEqual(a: string, b: string, options: CompareURLOptions = {}) { } return a === b; } + +export function withHash(input: string, hash: string): string { + const parsed = parseURL(input); + parsed.hash = hash === '' ? '' : '#' + encodeURIComponent(hash); + return stringifyParsedURL(parsed); +} diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 81240089..0c1bf0ef 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -10,6 +10,7 @@ import { withoutProtocol, withProtocol, isScriptProtocol, + withHash, } from "../src"; describe("hasProtocol", () => { @@ -256,3 +257,20 @@ describe("isEqual", () => { }); } }); + +describe('withHash', () => { + const tests = [ + { input: 'https://example.com', hash: 'foo', out: 'https://example.com#foo' }, + { input: 'https://example.com#bar', hash: 'foo', out: 'https://example.com#foo' }, + { input: 'https://example.com#bar', hash: '', out: 'https://example.com' }, + { input: 'https://example.com#bar', hash: '0', out: 'https://example.com#0' }, + { input: 'https://example.com#bar', hash: 'foo bar', out: 'https://example.com#foo%20bar' }, + { input: 'https://example.com?foo=bar', hash: 'baz', out: 'https://example.com?foo=bar#baz' }, + ]; + + for (const t of tests) { + test(`${t.input} + ${t.hash}`, () => { + expect(withHash(t.input, t.hash)).toBe(t.out); + }); + } +}) From c56dce09c71ddef0a32f6382b2b2ec09ec759d24 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 11:09:00 +0530 Subject: [PATCH 02/10] chore: run linter and formatter --- src/utils.ts | 2 +- test/utilities.test.ts | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 1797f9af..a9a0716a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -259,6 +259,6 @@ export function isEqual(a: string, b: string, options: CompareURLOptions = {}) { export function withHash(input: string, hash: string): string { const parsed = parseURL(input); - parsed.hash = hash === '' ? '' : '#' + encodeURIComponent(hash); + parsed.hash = hash === "" ? "" : "#" + encodeURIComponent(hash); return stringifyParsedURL(parsed); } diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 0c1bf0ef..3976b5c3 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -258,14 +258,34 @@ describe("isEqual", () => { } }); -describe('withHash', () => { +describe("withHash", () => { const tests = [ - { input: 'https://example.com', hash: 'foo', out: 'https://example.com#foo' }, - { input: 'https://example.com#bar', hash: 'foo', out: 'https://example.com#foo' }, - { input: 'https://example.com#bar', hash: '', out: 'https://example.com' }, - { input: 'https://example.com#bar', hash: '0', out: 'https://example.com#0' }, - { input: 'https://example.com#bar', hash: 'foo bar', out: 'https://example.com#foo%20bar' }, - { input: 'https://example.com?foo=bar', hash: 'baz', out: 'https://example.com?foo=bar#baz' }, + { + input: "https://example.com", + hash: "foo", + out: "https://example.com#foo", + }, + { + input: "https://example.com#bar", + hash: "foo", + out: "https://example.com#foo", + }, + { input: "https://example.com#bar", hash: "", out: "https://example.com" }, + { + input: "https://example.com#bar", + hash: "0", + out: "https://example.com#0", + }, + { + input: "https://example.com#bar", + hash: "foo bar", + out: "https://example.com#foo%20bar", + }, + { + input: "https://example.com?foo=bar", + hash: "baz", + out: "https://example.com?foo=bar#baz", + }, ]; for (const t of tests) { @@ -273,4 +293,4 @@ describe('withHash', () => { expect(withHash(t.input, t.hash)).toBe(t.out); }); } -}) +}); From 34874eda23618a22cc215b0a3b61dd09f8609b35 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 11:12:44 +0530 Subject: [PATCH 03/10] docs: add examples to readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 40cead91..235b34ca 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,19 @@ isEqual('/foo bar', '/foo%20bar', { encoding: true }) // false ``` +### `withHash` + +Add a hash to a URL + +```ts +withHash('/foo', 'bar') +// /foo#bar +withHash('/foo#bar', 'baz') +// /foo#baz +withHash('/foo#bar', '') +// /foo +``` + ## License [MIT](./LICENSE) From 7deefb1c031171af4b8dcd6b9ed8b6ecd7210b88 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 16:44:20 +0530 Subject: [PATCH 04/10] chore: rename function to `withFragment` --- README.md | 8 ++++---- src/utils.ts | 2 +- test/utilities.test.ts | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 235b34ca..d21a4f38 100644 --- a/README.md +++ b/README.md @@ -245,16 +245,16 @@ isEqual('/foo bar', '/foo%20bar', { encoding: true }) // false ``` -### `withHash` +### `withFragment` Add a hash to a URL ```ts -withHash('/foo', 'bar') +withFragment('/foo', 'bar') // /foo#bar -withHash('/foo#bar', 'baz') +withFragment('/foo#bar', 'baz') // /foo#baz -withHash('/foo#bar', '') +withFragment('/foo#bar', '') // /foo ``` diff --git a/src/utils.ts b/src/utils.ts index a9a0716a..f7594430 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -257,7 +257,7 @@ export function isEqual(a: string, b: string, options: CompareURLOptions = {}) { return a === b; } -export function withHash(input: string, hash: string): string { +export function withFragment(input: string, hash: string): string { const parsed = parseURL(input); parsed.hash = hash === "" ? "" : "#" + encodeURIComponent(hash); return stringifyParsedURL(parsed); diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 3976b5c3..38af207e 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -10,7 +10,7 @@ import { withoutProtocol, withProtocol, isScriptProtocol, - withHash, + withFragment, } from "../src"; describe("hasProtocol", () => { @@ -258,7 +258,7 @@ describe("isEqual", () => { } }); -describe("withHash", () => { +describe("withFragment", () => { const tests = [ { input: "https://example.com", @@ -290,7 +290,7 @@ describe("withHash", () => { for (const t of tests) { test(`${t.input} + ${t.hash}`, () => { - expect(withHash(t.input, t.hash)).toBe(t.out); + expect(withFragment(t.input, t.hash)).toBe(t.out); }); } }); From 23a0f7d25ec46806a507a277ec4f40378db841c9 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 16:45:28 +0530 Subject: [PATCH 05/10] test: add another test --- test/utilities.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 38af207e..4e4ddff4 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -270,6 +270,7 @@ describe("withFragment", () => { hash: "foo", out: "https://example.com#foo", }, + { input: "https://example.com", hash: "", out: "https://example.com" }, { input: "https://example.com#bar", hash: "", out: "https://example.com" }, { input: "https://example.com#bar", From 6eaadf85325fac9edb73957b6cc3580a1b6a0629 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 16:46:36 +0530 Subject: [PATCH 06/10] docs: add clarification --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d21a4f38..b818d551 100644 --- a/README.md +++ b/README.md @@ -247,7 +247,7 @@ isEqual('/foo bar', '/foo%20bar', { encoding: true }) ### `withFragment` -Add a hash to a URL +Add a fragment (or hash) to a URL: ```ts withFragment('/foo', 'bar') From fb8c1f1ff5fb10adeba2c5c73fc6a86a955bf5ef Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 16:47:28 +0530 Subject: [PATCH 07/10] test: change name of input param --- test/utilities.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/utilities.test.ts b/test/utilities.test.ts index 4e4ddff4..b2b33c34 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -262,36 +262,36 @@ describe("withFragment", () => { const tests = [ { input: "https://example.com", - hash: "foo", + fragment: "foo", out: "https://example.com#foo", }, { input: "https://example.com#bar", - hash: "foo", + fragment: "foo", out: "https://example.com#foo", }, - { input: "https://example.com", hash: "", out: "https://example.com" }, - { input: "https://example.com#bar", hash: "", out: "https://example.com" }, + { input: "https://example.com", fragment: "", out: "https://example.com" }, + { input: "https://example.com#bar", fragment: "", out: "https://example.com" }, { input: "https://example.com#bar", - hash: "0", + fragment: "0", out: "https://example.com#0", }, { input: "https://example.com#bar", - hash: "foo bar", + fragment: "foo bar", out: "https://example.com#foo%20bar", }, { input: "https://example.com?foo=bar", - hash: "baz", + fragment: "baz", out: "https://example.com?foo=bar#baz", }, ]; for (const t of tests) { - test(`${t.input} + ${t.hash}`, () => { - expect(withFragment(t.input, t.hash)).toBe(t.out); + test(`${t.input} + ${t.fragment}`, () => { + expect(withFragment(t.input, t.fragment)).toBe(t.out); }); } }); From b4fb55cfe36c5904158dbfd8be44b81975589475 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 21 Nov 2023 16:47:48 +0530 Subject: [PATCH 08/10] style: run prettier --- test/utilities.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/utilities.test.ts b/test/utilities.test.ts index b2b33c34..a6de18db 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -271,7 +271,11 @@ describe("withFragment", () => { out: "https://example.com#foo", }, { input: "https://example.com", fragment: "", out: "https://example.com" }, - { input: "https://example.com#bar", fragment: "", out: "https://example.com" }, + { + input: "https://example.com#bar", + fragment: "", + out: "https://example.com", + }, { input: "https://example.com#bar", fragment: "0", From 16acb719d7f81252d2d40611125ad0a826676c78 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 5 Feb 2024 16:39:36 +0100 Subject: [PATCH 09/10] Update src/utils.ts --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index f7594430..dc074f6d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -259,6 +259,6 @@ export function isEqual(a: string, b: string, options: CompareURLOptions = {}) { export function withFragment(input: string, hash: string): string { const parsed = parseURL(input); - parsed.hash = hash === "" ? "" : "#" + encodeURIComponent(hash); + parsed.hash = hash === "" ? "" : "#" + encodeURI(hash); return stringifyParsedURL(parsed); } From 7dbe05c31ad466afb9fa13a0e9c41df8b2a889b7 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 5 Feb 2024 17:18:01 +0100 Subject: [PATCH 10/10] add test --- test/utilities.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/utilities.test.ts b/test/utilities.test.ts index a6de18db..ba9a3af0 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -286,6 +286,11 @@ describe("withFragment", () => { fragment: "foo bar", out: "https://example.com#foo%20bar", }, + { + input: "https://example.com#bar", + fragment: "foo/bar", + out: "https://example.com#foo/bar", + }, { input: "https://example.com?foo=bar", fragment: "baz",