diff --git a/index.d.ts b/index.d.ts index 2b73768..74f3403 100644 --- a/index.d.ts +++ b/index.d.ts @@ -137,7 +137,7 @@ declare namespace normalizeUrl { /** Removes trailing slash. - __Note__: Trailing slash is always removed if the URL doesn't have a pathname. + __Note__: Trailing slash is always removed if the URL doesn't have a pathname unless the `removeSingleSlash` option is set to `false`. @default true @@ -155,6 +155,22 @@ declare namespace normalizeUrl { */ readonly removeTrailingSlash?: boolean; + /** + Remove a sole `/` pathname in the output. This option is independant of `removeTrailingSlash`. + + @default true + + @example + ``` + normalizeUrl('https://sindresorhus.com/'); + //=> 'https://sindresorhus.com' + + normalizeUrl('https://sindresorhus.com/', {removeSingleSlash: false}); + //=> 'https://sindresorhus.com/' + ``` + */ + readonly removeSingleSlash?: boolean; + /** Removes the default directory index file from path that matches any of the provided strings or regexes. When `true`, the regex `/^index\.[a-z]+$/` is used. diff --git a/index.js b/index.js index e615cf8..8d4f989 100644 --- a/index.js +++ b/index.js @@ -70,6 +70,7 @@ const normalizeUrl = (urlString, options) => { stripWWW: true, removeQueryParameters: [/^utm_\w+/i], removeTrailingSlash: true, + removeSingleSlash: true, removeDirectoryIndex: false, sortQueryParameters: true, ...options @@ -177,8 +178,8 @@ const normalizeUrl = (urlString, options) => { // Take advantage of many of the Node `url` normalizations urlString = urlObj.toString(); - // Remove ending `/` - if ((options.removeTrailingSlash || urlObj.pathname === '/') && urlObj.hash === '') { + // Remove ending `/` unless removeSingleSlash is false + if ((options.removeTrailingSlash || urlObj.pathname === '/') && urlObj.hash === '' && options.removeSingleSlash) { urlString = urlString.replace(/\/$/, ''); } diff --git a/readme.md b/readme.md index d09d3f6..5a03c80 100644 --- a/readme.md +++ b/readme.md @@ -171,7 +171,7 @@ Default: `true` Remove trailing slash. -**Note:** Trailing slash is always removed if the URL doesn't have a pathname. +**Note:** Trailing slash is always removed if the URL doesn't have a pathname unless the `removeSingleSlash` option is set to `false`. ```js normalizeUrl('http://sindresorhus.com/redirect/'); @@ -184,6 +184,22 @@ normalizeUrl('http://sindresorhus.com/', {removeTrailingSlash: false}); //=> 'http://sindresorhus.com' ``` +##### removeSingleSlash + +Type: `boolean`\ +Default: `true` + +Remove a sole `/` pathname in the output. This option is independant of `removeTrailingSlash`. + +```js +normalizeUrl('https://sindresorhus.com/'); +//=> 'https://sindresorhus.com' + +normalizeUrl('https://sindresorhus.com/', {removeSingleSlash: false}); +//=> 'https://sindresorhus.com/' +``` + + ##### removeDirectoryIndex Type: `boolean | Array`\ diff --git a/test.js b/test.js index fc5b5c2..1d4fc08 100644 --- a/test.js +++ b/test.js @@ -124,6 +124,24 @@ test('removeTrailingSlash option', t => { t.is(normalizeUrl('http://sindresorhus.com/redirect/'), 'http://sindresorhus.com/redirect'); t.is(normalizeUrl('http://sindresorhus.com/redirect/', options), 'http://sindresorhus.com/redirect/'); t.is(normalizeUrl('http://sindresorhus.com/#/', options), 'http://sindresorhus.com/#/'); + t.is(normalizeUrl('http://sindresorhus.com/?unicorns=true'), 'http://sindresorhus.com/?unicorns=true'); + t.is(normalizeUrl('http://sindresorhus.com/?unicorns=true', options), 'http://sindresorhus.com/?unicorns=true'); +}); + +test('removeSingleSlash option', t => { + const options = {removeSingleSlash: false}; + t.is(normalizeUrl('https://sindresorhus.com/', options), 'https://sindresorhus.com/'); + t.is(normalizeUrl('https://sindresorhus.com/redirect/', options), 'https://sindresorhus.com/redirect'); + t.is(normalizeUrl('https://sindresorhus.com/#/', options), 'https://sindresorhus.com/#/'); + t.is(normalizeUrl('https://sindresorhus.com/?unicorns=true', options), 'https://sindresorhus.com/?unicorns=true'); +}); + +test('removeSingleSlash option combined with removeTrailingSlash option', t => { + const options = {removeTrailingSlash: true, removeSingleSlash: false}; + t.is(normalizeUrl('https://sindresorhus.com/', options), 'https://sindresorhus.com/'); + t.is(normalizeUrl('https://sindresorhus.com/redirect/', options), 'https://sindresorhus.com/redirect'); + t.is(normalizeUrl('https://sindresorhus.com/#/', options), 'https://sindresorhus.com/#/'); + t.is(normalizeUrl('https://sindresorhus.com/?unicorns=true', options), 'https://sindresorhus.com/?unicorns=true'); }); test('removeDirectoryIndex option', t => {