From 6e24307b875b0fad664bbe1ae35e177684d1f397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20G=C3=B6rg=C3=BCl=C3=BC?= Date: Thu, 1 Sep 2022 14:11:14 +0300 Subject: [PATCH] Add `keepQueryParameters` option (#173) Co-authored-by: Sindre Sorhus --- index.d.ts | 17 +++++++++++++++++ index.js | 12 +++++++++++- index.test-d.ts | 3 +++ readme.md | 16 ++++++++++++++++ test.js | 11 +++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index ac696a3..a5d1bfc 100644 --- a/index.d.ts +++ b/index.d.ts @@ -179,6 +179,23 @@ export interface Options { */ readonly removeQueryParameters?: ReadonlyArray | boolean; + /** + Keeps only query parameters that matches any of the provided strings or regexes. + + __Note__: It overrides the `removeQueryParameters` option. + + @default undefined + + @example + ``` + normalizeUrl('https://sindresorhus.com?foo=bar&ref=unicorn', { + keepQueryParameters: ['ref'] + }); + //=> 'https://sindresorhus.com/?ref=unicorn' + ``` + */ + readonly keepQueryParameters?: ReadonlyArray; + /** Removes trailing slash. diff --git a/index.js b/index.js index 1c5f9a1..ceca8cb 100644 --- a/index.js +++ b/index.js @@ -200,10 +200,20 @@ export default function normalizeUrl(urlString, options) { } } - if (options.removeQueryParameters === true) { + if (!Array.isArray(options.keepQueryParameters) && options.removeQueryParameters === true) { urlObject.search = ''; } + // Keep wanted query parameters + if (Array.isArray(options.keepQueryParameters) && options.keepQueryParameters.length > 0) { + // eslint-disable-next-line unicorn/no-useless-spread -- We are intentionally spreading to get a copy. + for (const key of [...urlObject.searchParams.keys()]) { + if (!testParameter(key, options.keepQueryParameters)) { + urlObject.searchParams.delete(key); + } + } + } + // Sort query parameters if (options.sortQueryParameters) { urlObject.searchParams.sort(); diff --git a/index.test-d.ts b/index.test-d.ts index 17c38b8..8898dce 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -21,6 +21,9 @@ normalizeUrl('www.sindresorhus.com?foo=bar', { normalizeUrl('www.sindresorhus.com?foo=bar&utm_medium=test&ref=test_ref', { removeQueryParameters: false, }); +normalizeUrl('www.sindresorhus.com?foo=bar&ref=test_ref', { + keepQueryParameters: ['ref', /test/], +}); normalizeUrl('http://sindresorhus.com/', {removeTrailingSlash: false}); normalizeUrl('http://sindresorhus.com/', {removeSingleSlash: false}); normalizeUrl('www.sindresorhus.com/foo/default.php', { diff --git a/readme.md b/readme.md index 784ef0b..3006c74 100644 --- a/readme.md +++ b/readme.md @@ -210,6 +210,22 @@ normalizeUrl('www.sindresorhus.com?foo=bar&utm_medium=test&ref=test_ref', { //=> 'http://www.sindresorhus.com/?foo=bar&ref=test_ref&utm_medium=test' ``` +##### keepQueryParameters + +Type: `Array`\ +Default: `undefined` + +Keeps only query parameters that matches any of the provided strings or regexes. + +**Note:** It overrides the `removeQueryParameters` option. + +```js +normalizeUrl('https://sindresorhus.com?foo=bar&ref=unicorn', { + keepQueryParameters: ['ref'] +}); +//=> 'https://sindresorhus.com/?ref=unicorn' +``` + ##### removeTrailingSlash Type: `boolean`\ diff --git a/test.js b/test.js index 4483b5b..df18e49 100644 --- a/test.js +++ b/test.js @@ -141,6 +141,17 @@ test('removeQueryParameters boolean `false` option', t => { t.is(normalizeUrl('www.sindresorhus.com?foo=bar&utm_medium=test&ref=test_ref', options), 'http://www.sindresorhus.com/?foo=bar&ref=test_ref&utm_medium=test'); }); +test('keepQueryParameters option', t => { + const options = { + stripWWW: false, + removeQueryParameters: false, + keepQueryParameters: [/^utm_\w+/i, 'ref'], + }; + t.is(normalizeUrl('https://sindresorhus.com', options), 'https://sindresorhus.com'); + t.is(normalizeUrl('www.sindresorhus.com?foo=bar', options), 'http://www.sindresorhus.com'); + t.is(normalizeUrl('www.sindresorhus.com?foo=bar&utm_medium=test&ref=test_ref', options), 'http://www.sindresorhus.com/?ref=test_ref&utm_medium=test'); +}); + test('forceHttp option', t => { const options = {forceHttp: true}; t.is(normalizeUrl('https://sindresorhus.com'), 'https://sindresorhus.com');