normalize-url 3.0.0 → 3.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.
Files changed (3) hide show
  1. package/index.js +48 -13
  2. package/package.json +4 -2
  3. package/readme.md +34 -12
package/index.js CHANGED
@@ -1,15 +1,18 @@
1
1
  'use strict';
2
- const {URL} = require('url');
2
+ // TODO: Use the `URL` global when targeting Node.js 10
3
+ const URLParser = typeof URL === 'undefined' ? require('url').URL : URL;
3
4
 
4
- function testParameter(name, filters) {
5
+ const testParameter = (name, filters) => {
5
6
  return filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
6
- }
7
+ };
7
8
 
8
9
  module.exports = (urlString, opts) => {
9
10
  opts = Object.assign({
11
+ defaultProtocol: 'http:',
10
12
  normalizeProtocol: true,
11
- normalizeHttps: false,
12
- stripFragment: true,
13
+ forceHttp: false,
14
+ forceHttps: false,
15
+ stripHash: true,
13
16
  stripWWW: true,
14
17
  removeQueryParameters: [/^utm_\w+/i],
15
18
  removeTrailingSlash: true,
@@ -17,6 +20,19 @@ module.exports = (urlString, opts) => {
17
20
  sortQueryParameters: true
18
21
  }, opts);
19
22
 
23
+ // Backwards compatibility
24
+ if (Reflect.has(opts, 'normalizeHttps')) {
25
+ opts.forceHttp = opts.normalizeHttps;
26
+ }
27
+
28
+ if (Reflect.has(opts, 'normalizeHttp')) {
29
+ opts.forceHttps = opts.normalizeHttp;
30
+ }
31
+
32
+ if (Reflect.has(opts, 'stripFragment')) {
33
+ opts.stripHash = opts.stripFragment;
34
+ }
35
+
20
36
  urlString = urlString.trim();
21
37
 
22
38
  const hasRelativeProtocol = urlString.startsWith('//');
@@ -24,23 +40,38 @@ module.exports = (urlString, opts) => {
24
40
 
25
41
  // Prepend protocol
26
42
  if (!isRelativeUrl) {
27
- urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, 'http://');
43
+ urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, opts.defaultProtocol);
28
44
  }
29
45
 
30
- const urlObj = new URL(urlString);
46
+ const urlObj = new URLParser(urlString);
47
+
48
+ if (opts.forceHttp && opts.forceHttps) {
49
+ throw new Error('The `forceHttp` and `forceHttps` options cannot be used together');
50
+ }
31
51
 
32
- if (opts.normalizeHttps && urlObj.protocol === 'https:') {
52
+ if (opts.forceHttp && urlObj.protocol === 'https:') {
33
53
  urlObj.protocol = 'http:';
34
54
  }
35
55
 
36
- // Remove fragment
37
- if (opts.stripFragment) {
56
+ if (opts.forceHttps && urlObj.protocol === 'http:') {
57
+ urlObj.protocol = 'https:';
58
+ }
59
+
60
+ // Remove hash
61
+ if (opts.stripHash) {
38
62
  urlObj.hash = '';
39
63
  }
40
64
 
41
- // Remove duplicate slashes
65
+ // Remove duplicate slashes if not preceded by a protocol
42
66
  if (urlObj.pathname) {
43
- urlObj.pathname = urlObj.pathname.replace(/\/{2,}/g, '/');
67
+ // TODO: Use the following instead when targeting Node.js 10
68
+ // `urlObj.pathname = urlObj.pathname.replace(/(?<!https?:)\/{2,}/g, '/');`
69
+ urlObj.pathname = urlObj.pathname.replace(/((?![https?:]).)\/{2,}/g, (_, p1) => {
70
+ if (/^(?!\/)/g.test(p1)) {
71
+ return `${p1}/`;
72
+ }
73
+ return '/';
74
+ });
44
75
  }
45
76
 
46
77
  // Decode URI octets
@@ -68,7 +99,11 @@ module.exports = (urlString, opts) => {
68
99
  urlObj.hostname = urlObj.hostname.replace(/\.$/, '');
69
100
 
70
101
  // Remove `www.`
71
- if (opts.stripWWW) {
102
+ // eslint-disable-next-line no-useless-escape
103
+ if (opts.stripWWW && /^www\.([a-z\-\d]{2,63})\.([a-z\.]{2,5})$/.test(urlObj.hostname)) {
104
+ // Each label should be max 63 at length (min: 2).
105
+ // The extension should be max 5 at length (min: 2).
106
+ // Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
72
107
  urlObj.hostname = urlObj.hostname.replace(/^www\./, '');
73
108
  }
74
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "normalize-url",
3
- "version": "3.0.0",
3
+ "version": "3.3.0",
4
4
  "description": "Normalize a URL",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/normalize-url",
@@ -13,7 +13,7 @@
13
13
  "node": ">=6"
14
14
  },
15
15
  "scripts": {
16
- "test": "xo && ava"
16
+ "test": "xo && nyc ava"
17
17
  },
18
18
  "files": [
19
19
  "index.js"
@@ -35,6 +35,8 @@
35
35
  ],
36
36
  "devDependencies": {
37
37
  "ava": "*",
38
+ "coveralls": "^3.0.0",
39
+ "nyc": "^12.0.2",
38
40
  "xo": "*"
39
41
  }
40
42
  }
package/readme.md CHANGED
@@ -1,4 +1,4 @@
1
- # normalize-url [![Build Status](https://travis-ci.org/sindresorhus/normalize-url.svg?branch=master)](https://travis-ci.org/sindresorhus/normalize-url)
1
+ # normalize-url [![Build Status](https://travis-ci.org/sindresorhus/normalize-url.svg?branch=master)](https://travis-ci.org/sindresorhus/normalize-url) [![Coverage Status](https://coveralls.io/repos/github/sindresorhus/normalize-url/badge.svg?branch=master)](https://coveralls.io/github/sindresorhus/normalize-url?branch=master)
2
2
 
3
3
  > [Normalize](https://en.wikipedia.org/wiki/URL_normalization) a URL
4
4
 
@@ -39,12 +39,17 @@ URL to normalize.
39
39
 
40
40
  Type: `Object`
41
41
 
42
+ ##### defaultProtocol
43
+
44
+ Type: `string`<br>
45
+ Default: `http:`
46
+
42
47
  ##### normalizeProtocol
43
48
 
44
49
  Type: `boolean`<br>
45
50
  Default: `true`
46
51
 
47
- Prepend `http:` to the URL if it's protocol-relative.
52
+ Prepends `defaultProtocol` to the URL if it's protocol-relative.
48
53
 
49
54
  ```js
50
55
  normalizeUrl('//sindresorhus.com:80/');
@@ -54,12 +59,12 @@ normalizeUrl('//sindresorhus.com:80/', {normalizeProtocol: false});
54
59
  //=> '//sindresorhus.com'
55
60
  ```
56
61
 
57
- ##### normalizeHttps
62
+ ##### forceHttp
58
63
 
59
64
  Type: `boolean`<br>
60
65
  Default: `false`
61
66
 
62
- Normalize `https:` URLs to `http:`.
67
+ Normalizes `https:` URLs to `http:`.
63
68
 
64
69
  ```js
65
70
  normalizeUrl('https://sindresorhus.com:80/');
@@ -69,18 +74,35 @@ normalizeUrl('https://sindresorhus.com:80/', {normalizeHttps: true});
69
74
  //=> 'http://sindresorhus.com'
70
75
  ```
71
76
 
72
- ##### stripFragment
77
+ ##### forceHttps
78
+
79
+ Type: `boolean`<br>
80
+ Default: `false`
81
+
82
+ Normalizes `http:` URLs to `https:`.
83
+
84
+ ```js
85
+ normalizeUrl('https://sindresorhus.com:80/');
86
+ //=> 'https://sindresorhus.com'
87
+
88
+ normalizeUrl('http://sindresorhus.com:80/', {normalizeHttp: true});
89
+ //=> 'https://sindresorhus.com'
90
+ ```
91
+
92
+ This option can't be used with the `forceHttp` option at the same time.
93
+
94
+ ##### stripHash
73
95
 
74
96
  Type: `boolean`<br>
75
97
  Default: `true`
76
98
 
77
- Remove the fragment at the end of the URL.
99
+ Removes hash from the URL.
78
100
 
79
101
  ```js
80
102
  normalizeUrl('sindresorhus.com/about.html#contact');
81
103
  //=> 'http://sindresorhus.com/about.html'
82
104
 
83
- normalizeUrl('sindresorhus.com/about.html#contact', {stripFragment: false});
105
+ normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: false});
84
106
  //=> 'http://sindresorhus.com/about.html#contact'
85
107
  ```
86
108
 
@@ -89,7 +111,7 @@ normalizeUrl('sindresorhus.com/about.html#contact', {stripFragment: false});
89
111
  Type: `boolean`<br>
90
112
  Default: `true`
91
113
 
92
- Remove `www.` from the URL.
114
+ Removes `www.` from the URL.
93
115
 
94
116
  ```js
95
117
  normalizeUrl('http://www.sindresorhus.com/about.html#contact');
@@ -104,7 +126,7 @@ normalizeUrl('http://www.sindresorhus.com/about.html#contact', {stripWWW: false}
104
126
  Type: `Array<RegExp|string>`<br>
105
127
  Default: `[/^utm_\w+/i]`
106
128
 
107
- Remove query parameters that matches any of the provided strings or regexes.
129
+ Removes query parameters that matches any of the provided strings or regexes.
108
130
 
109
131
  ```js
110
132
  normalizeUrl('www.sindresorhus.com?foo=bar&ref=test_ref', {
@@ -118,7 +140,7 @@ normalizeUrl('www.sindresorhus.com?foo=bar&ref=test_ref', {
118
140
  Type: `boolean`<br>
119
141
  Default: `true`
120
142
 
121
- Remove trailing slash.
143
+ Removes trailing slash.
122
144
 
123
145
  **Note:** Trailing slash is always removed if the URL doesn't have a pathname.
124
146
 
@@ -138,7 +160,7 @@ normalizeUrl('http://sindresorhus.com/', {removeTrailingSlash: false});
138
160
  Type: `boolean` `Array<RegExp|string>`<br>
139
161
  Default: `false`
140
162
 
141
- Remove 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.
163
+ 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.
142
164
 
143
165
  ```js
144
166
  normalizeUrl('www.sindresorhus.com/foo/default.php', {
@@ -152,7 +174,7 @@ normalizeUrl('www.sindresorhus.com/foo/default.php', {
152
174
  Type: `boolean`<br>
153
175
  Default: `true`
154
176
 
155
- Sort the query parameters alphabetically by key.
177
+ Sorts the query parameters alphabetically by key.
156
178
 
157
179
  ```js
158
180
  normalizeUrl('www.sindresorhus.com?b=two&a=one&c=three', {