normalize-url 5.0.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -137,7 +137,7 @@ declare namespace normalizeUrl {
137
137
  /**
138
138
  Removes trailing slash.
139
139
 
140
- __Note__: Trailing slash is always removed if the URL doesn't have a pathname.
140
+ __Note__: Trailing slash is always removed if the URL doesn't have a pathname unless the `removeSingleSlash` option is set to `false`.
141
141
 
142
142
  @default true
143
143
 
@@ -155,6 +155,22 @@ declare namespace normalizeUrl {
155
155
  */
156
156
  readonly removeTrailingSlash?: boolean;
157
157
 
158
+ /**
159
+ Remove a sole `/` pathname in the output. This option is independant of `removeTrailingSlash`.
160
+
161
+ @default true
162
+
163
+ @example
164
+ ```
165
+ normalizeUrl('https://sindresorhus.com/');
166
+ //=> 'https://sindresorhus.com'
167
+
168
+ normalizeUrl('https://sindresorhus.com/', {removeSingleSlash: false});
169
+ //=> 'https://sindresorhus.com/'
170
+ ```
171
+ */
172
+ readonly removeSingleSlash?: boolean;
173
+
158
174
  /**
159
175
  Removes the default directory index file from path that matches any of the provided strings or regexes.
160
176
  When `true`, the regex `/^index\.[a-z]+$/` is used.
@@ -200,8 +216,8 @@ import normalizeUrl = require('normalize-url');
200
216
  normalizeUrl('sindresorhus.com');
201
217
  //=> 'http://sindresorhus.com'
202
218
 
203
- normalizeUrl('HTTP://xn--xample-hva.com:80/?b=bar&a=foo');
204
- //=> 'http://êxample.com/?a=foo&b=bar'
219
+ normalizeUrl('//www.sindresorhus.com:80/../baz?b=bar&a=foo');
220
+ //=> 'http://sindresorhus.com/baz?a=foo&b=bar'
205
221
  ```
206
222
  */
207
223
  declare function normalizeUrl(url: string, options?: normalizeUrl.Options): string;
package/index.js CHANGED
@@ -70,6 +70,7 @@ const normalizeUrl = (urlString, options) => {
70
70
  stripWWW: true,
71
71
  removeQueryParameters: [/^utm_\w+/i],
72
72
  removeTrailingSlash: true,
73
+ removeSingleSlash: true,
73
74
  removeDirectoryIndex: false,
74
75
  sortQueryParameters: true,
75
76
  ...options
@@ -82,6 +83,10 @@ const normalizeUrl = (urlString, options) => {
82
83
  return normalizeDataURL(urlString, options);
83
84
  }
84
85
 
86
+ if (/^view-source:/i.test(urlString)) {
87
+ throw new Error('`view-source:` is not supported as it is a non-standard protocol');
88
+ }
89
+
85
90
  const hasRelativeProtocol = urlString.startsWith('//');
86
91
  const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
87
92
 
@@ -117,7 +122,7 @@ const normalizeUrl = (urlString, options) => {
117
122
 
118
123
  // Remove duplicate slashes if not preceded by a protocol
119
124
  if (urlObj.pathname) {
120
- urlObj.pathname = urlObj.pathname.replace(/(?<!https?:)\/{2,}/g, '/');
125
+ urlObj.pathname = urlObj.pathname.replace(/(?<!\b(?:[a-z][a-z\d+\-.]{1,50}:))\/{2,}/g, '/');
121
126
  }
122
127
 
123
128
  // Decode URI octets
@@ -147,10 +152,11 @@ const normalizeUrl = (urlString, options) => {
147
152
  urlObj.hostname = urlObj.hostname.replace(/\.$/, '');
148
153
 
149
154
  // Remove `www.`
150
- if (options.stripWWW && /^www\.(?:[a-z\-\d]{2,63})\.(?:[a-z.]{2,5})$/.test(urlObj.hostname)) {
151
- // Each label should be max 63 at length (min: 2).
152
- // The extension should be max 5 at length (min: 2).
155
+ if (options.stripWWW && /^www\.(?!www\.)(?:[a-z\-\d]{1,63})\.(?:[a-z.\-\d]{2,63})$/.test(urlObj.hostname)) {
156
+ // Each label should be max 63 at length (min: 1).
153
157
  // Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
158
+ // Each TLD should be up to 63 characters long (min: 2).
159
+ // It is technically possible to have a single character TLD, but none currently exist.
154
160
  urlObj.hostname = urlObj.hostname.replace(/^www\./, '');
155
161
  }
156
162
  }
@@ -173,11 +179,17 @@ const normalizeUrl = (urlString, options) => {
173
179
  urlObj.pathname = urlObj.pathname.replace(/\/$/, '');
174
180
  }
175
181
 
182
+ const oldUrlString = urlString;
183
+
176
184
  // Take advantage of many of the Node `url` normalizations
177
185
  urlString = urlObj.toString();
178
186
 
179
- // Remove ending `/`
180
- if ((options.removeTrailingSlash || urlObj.pathname === '/') && urlObj.hash === '') {
187
+ if (!options.removeSingleSlash && urlObj.pathname === '/' && !oldUrlString.endsWith('/') && urlObj.hash === '') {
188
+ urlString = urlString.replace(/\/$/, '');
189
+ }
190
+
191
+ // Remove ending `/` unless removeSingleSlash is false
192
+ if ((options.removeTrailingSlash || urlObj.pathname === '/') && urlObj.hash === '' && options.removeSingleSlash) {
181
193
  urlString = urlString.replace(/\/$/, '');
182
194
  }
183
195
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "normalize-url",
3
- "version": "5.0.0",
3
+ "version": "5.3.0",
4
4
  "description": "Normalize a URL",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/normalize-url",
package/readme.md CHANGED
@@ -10,6 +10,8 @@ Useful when you need to display, store, deduplicate, sort, compare, etc, URLs.
10
10
  $ npm install normalize-url
11
11
  ```
12
12
 
13
+ *If you need to use this in the browser, use version 4: `npm i normalize-url@4`*
14
+
13
15
  ## Usage
14
16
 
15
17
  ```js
@@ -18,8 +20,8 @@ const normalizeUrl = require('normalize-url');
18
20
  normalizeUrl('sindresorhus.com');
19
21
  //=> 'http://sindresorhus.com'
20
22
 
21
- normalizeUrl('HTTP://xn--xample-hva.com:80/?b=bar&a=foo');
22
- //=> 'http://êxample.com/?a=foo&b=bar'
23
+ normalizeUrl('//www.sindresorhus.com:80/../baz?b=bar&a=foo');
24
+ //=> 'http://sindresorhus.com/baz?a=foo&b=bar'
23
25
  ```
24
26
 
25
27
  ## API
@@ -169,7 +171,7 @@ Default: `true`
169
171
 
170
172
  Remove trailing slash.
171
173
 
172
- **Note:** Trailing slash is always removed if the URL doesn't have a pathname.
174
+ **Note:** Trailing slash is always removed if the URL doesn't have a pathname unless the `removeSingleSlash` option is set to `false`.
173
175
 
174
176
  ```js
175
177
  normalizeUrl('http://sindresorhus.com/redirect/');
@@ -182,6 +184,22 @@ normalizeUrl('http://sindresorhus.com/', {removeTrailingSlash: false});
182
184
  //=> 'http://sindresorhus.com'
183
185
  ```
184
186
 
187
+ ##### removeSingleSlash
188
+
189
+ Type: `boolean`\
190
+ Default: `true`
191
+
192
+ Remove a sole `/` pathname in the output. This option is independant of `removeTrailingSlash`.
193
+
194
+ ```js
195
+ normalizeUrl('https://sindresorhus.com/');
196
+ //=> 'https://sindresorhus.com'
197
+
198
+ normalizeUrl('https://sindresorhus.com/', {removeSingleSlash: false});
199
+ //=> 'https://sindresorhus.com/'
200
+ ```
201
+
202
+
185
203
  ##### removeDirectoryIndex
186
204
 
187
205
  Type: `boolean | Array<RegExp | string>`\