normalize-url 1.8.0 → 2.0.1

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 (4) hide show
  1. package/index.js +58 -52
  2. package/license +4 -16
  3. package/package.json +5 -9
  4. package/readme.md +33 -2
package/index.js CHANGED
@@ -1,24 +1,23 @@
1
1
  'use strict';
2
- var url = require('url');
3
- var punycode = require('punycode');
4
- var queryString = require('query-string');
5
- var prependHttp = require('prepend-http');
6
- var sortKeys = require('sort-keys');
7
- var objectAssign = require('object-assign');
8
-
9
- var DEFAULT_PORTS = {
2
+ const url = require('url');
3
+ const punycode = require('punycode');
4
+ const queryString = require('query-string');
5
+ const prependHttp = require('prepend-http');
6
+ const sortKeys = require('sort-keys');
7
+
8
+ const DEFAULT_PORTS = {
10
9
  'http:': 80,
11
10
  'https:': 443,
12
11
  'ftp:': 21
13
12
  };
14
13
 
15
- // protocols that always contain a `//`` bit
16
- var slashedProtocol = {
17
- 'http': true,
18
- 'https': true,
19
- 'ftp': true,
20
- 'gopher': true,
21
- 'file': true,
14
+ // Protocols that always contain a `//`` bit
15
+ const slashedProtocol = {
16
+ http: true,
17
+ https: true,
18
+ ftp: true,
19
+ gopher: true,
20
+ file: true,
22
21
  'http:': true,
23
22
  'https:': true,
24
23
  'ftp:': true,
@@ -27,81 +26,84 @@ var slashedProtocol = {
27
26
  };
28
27
 
29
28
  function testParameter(name, filters) {
30
- return filters.some(function (filter) {
31
- return filter instanceof RegExp ? filter.test(name) : filter === name;
32
- });
29
+ return filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
33
30
  }
34
31
 
35
- module.exports = function (str, opts) {
36
- opts = objectAssign({
32
+ module.exports = (str, opts) => {
33
+ opts = Object.assign({
37
34
  normalizeProtocol: true,
35
+ normalizeHttps: false,
38
36
  stripFragment: true,
39
37
  stripWWW: true,
40
38
  removeQueryParameters: [/^utm_\w+/i],
41
39
  removeTrailingSlash: true,
42
- removeDirectoryIndex: false
40
+ removeDirectoryIndex: false,
41
+ sortQueryParameters: true
43
42
  }, opts);
44
43
 
45
44
  if (typeof str !== 'string') {
46
45
  throw new TypeError('Expected a string');
47
46
  }
48
47
 
49
- var hasRelativeProtocol = str.indexOf('//') === 0;
48
+ const hasRelativeProtocol = str.startsWith('//');
50
49
 
51
- // prepend protocol
50
+ // Prepend protocol
52
51
  str = prependHttp(str.trim()).replace(/^\/\//, 'http://');
53
52
 
54
- var urlObj = url.parse(str);
53
+ const urlObj = url.parse(str);
54
+
55
+ if (opts.normalizeHttps && urlObj.protocol === 'https:') {
56
+ urlObj.protocol = 'http:';
57
+ }
55
58
 
56
59
  if (!urlObj.hostname && !urlObj.pathname) {
57
60
  throw new Error('Invalid URL');
58
61
  }
59
62
 
60
- // prevent these from being used by `url.format`
63
+ // Prevent these from being used by `url.format`
61
64
  delete urlObj.host;
62
65
  delete urlObj.query;
63
66
 
64
- // remove fragment
67
+ // Remove fragment
65
68
  if (opts.stripFragment) {
66
69
  delete urlObj.hash;
67
70
  }
68
71
 
69
- // remove default port
70
- var port = DEFAULT_PORTS[urlObj.protocol];
72
+ // Remove default port
73
+ const port = DEFAULT_PORTS[urlObj.protocol];
71
74
  if (Number(urlObj.port) === port) {
72
75
  delete urlObj.port;
73
76
  }
74
77
 
75
- // remove duplicate slashes
78
+ // Remove duplicate slashes
76
79
  if (urlObj.pathname) {
77
80
  urlObj.pathname = urlObj.pathname.replace(/\/{2,}/g, '/');
78
81
  }
79
82
 
80
- // decode URI octets
83
+ // Decode URI octets
81
84
  if (urlObj.pathname) {
82
85
  urlObj.pathname = decodeURI(urlObj.pathname);
83
86
  }
84
87
 
85
- // remove directory index
88
+ // Remove directory index
86
89
  if (opts.removeDirectoryIndex === true) {
87
90
  opts.removeDirectoryIndex = [/^index\.[a-z]+$/];
88
91
  }
89
92
 
90
- if (Array.isArray(opts.removeDirectoryIndex) && opts.removeDirectoryIndex.length) {
91
- var pathComponents = urlObj.pathname.split('/');
92
- var lastComponent = pathComponents[pathComponents.length - 1];
93
+ if (Array.isArray(opts.removeDirectoryIndex) && opts.removeDirectoryIndex.length > 0) {
94
+ let pathComponents = urlObj.pathname.split('/');
95
+ const lastComponent = pathComponents[pathComponents.length - 1];
93
96
 
94
97
  if (testParameter(lastComponent, opts.removeDirectoryIndex)) {
95
98
  pathComponents = pathComponents.slice(0, pathComponents.length - 1);
99
+ urlObj.pathname = pathComponents.slice(1).join('/') + '/';
96
100
  }
97
-
98
- urlObj.pathname = pathComponents.slice(1).join('/') + '/';
99
101
  }
100
102
 
101
- // resolve relative paths, but only for slashed protocols
103
+ // Resolve relative paths, but only for slashed protocols
102
104
  if (slashedProtocol[urlObj.protocol]) {
103
- var domain = urlObj.protocol + '//' + urlObj.hostname;
104
- var relative = url.resolve(domain, urlObj.pathname);
105
+ const domain = urlObj.protocol + '//' + urlObj.hostname;
106
+ const relative = url.resolve(domain, urlObj.pathname);
105
107
  urlObj.pathname = relative.replace(domain, '');
106
108
  }
107
109
 
@@ -109,46 +111,50 @@ module.exports = function (str, opts) {
109
111
  // IDN to Unicode
110
112
  urlObj.hostname = punycode.toUnicode(urlObj.hostname).toLowerCase();
111
113
 
112
- // remove trailing dot
114
+ // Remove trailing dot
113
115
  urlObj.hostname = urlObj.hostname.replace(/\.$/, '');
114
116
 
115
- // remove `www.`
117
+ // Remove `www.`
116
118
  if (opts.stripWWW) {
117
119
  urlObj.hostname = urlObj.hostname.replace(/^www\./, '');
118
120
  }
119
121
  }
120
122
 
121
- // remove URL with empty query string
123
+ // Remove URL with empty query string
122
124
  if (urlObj.search === '?') {
123
125
  delete urlObj.search;
124
126
  }
125
127
 
126
- var queryParameters = queryString.parse(urlObj.search);
128
+ const queryParameters = queryString.parse(urlObj.search);
127
129
 
128
- // remove query unwanted parameters
130
+ // Remove query unwanted parameters
129
131
  if (Array.isArray(opts.removeQueryParameters)) {
130
- for (var key in queryParameters) {
132
+ for (const key in queryParameters) {
131
133
  if (testParameter(key, opts.removeQueryParameters)) {
132
134
  delete queryParameters[key];
133
135
  }
134
136
  }
135
137
  }
136
138
 
137
- // sort query parameters
138
- urlObj.search = queryString.stringify(sortKeys(queryParameters));
139
+ // Sort query parameters
140
+ if (opts.sortQueryParameters) {
141
+ urlObj.search = queryString.stringify(sortKeys(queryParameters));
142
+ }
139
143
 
140
- // decode query parameters
141
- urlObj.search = decodeURIComponent(urlObj.search);
144
+ // Decode query parameters
145
+ if (urlObj.search !== null) {
146
+ urlObj.search = decodeURIComponent(urlObj.search);
147
+ }
142
148
 
143
- // take advantage of many of the Node `url` normalizations
149
+ // Take advantage of many of the Node `url` normalizations
144
150
  str = url.format(urlObj);
145
151
 
146
- // remove ending `/`
152
+ // Remove ending `/`
147
153
  if (opts.removeTrailingSlash || urlObj.pathname === '/') {
148
154
  str = str.replace(/\/$/, '');
149
155
  }
150
156
 
151
- // restore relative protocol, if applicable
157
+ // Restore relative protocol, if applicable
152
158
  if (hasRelativeProtocol && !opts.normalizeProtocol) {
153
159
  str = str.replace(/^http:\/\//, '//');
154
160
  }
package/license CHANGED
@@ -1,21 +1,9 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
3
  Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
11
6
 
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14
8
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "normalize-url",
3
- "version": "1.8.0",
3
+ "version": "2.0.1",
4
4
  "description": "Normalize a URL",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/normalize-url",
@@ -24,12 +24,9 @@
24
24
  "uri",
25
25
  "address",
26
26
  "string",
27
- "str",
28
- "normalise",
29
27
  "normalization",
30
28
  "normalisation",
31
29
  "query",
32
- "string",
33
30
  "querystring",
34
31
  "unicode",
35
32
  "simplify",
@@ -38,13 +35,12 @@
38
35
  "canonical"
39
36
  ],
40
37
  "dependencies": {
41
- "object-assign": "^4.0.1",
42
- "prepend-http": "^1.0.0",
43
- "query-string": "^4.1.0",
44
- "sort-keys": "^1.0.0"
38
+ "prepend-http": "^2.0.0",
39
+ "query-string": "^5.0.1",
40
+ "sort-keys": "^2.0.0"
45
41
  },
46
42
  "devDependencies": {
47
43
  "ava": "*",
48
- "xo": "^0.16.0"
44
+ "xo": "*"
49
45
  }
50
46
  }
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # normalize-url [![Build Status](https://travis-ci.org/sindresorhus/normalize-url.svg?branch=master)](https://travis-ci.org/sindresorhus/normalize-url)
2
2
 
3
- > [Normalize](http://en.wikipedia.org/wiki/URL_normalization) a URL
3
+ > [Normalize](https://en.wikipedia.org/wiki/URL_normalization) a URL
4
4
 
5
5
  Useful when you need to display, store, deduplicate, sort, compare, etc, URLs.
6
6
 
@@ -8,7 +8,7 @@ Useful when you need to display, store, deduplicate, sort, compare, etc, URLs.
8
8
  ## Install
9
9
 
10
10
  ```
11
- $ npm install --save normalize-url
11
+ $ npm install normalize-url
12
12
  ```
13
13
 
14
14
 
@@ -37,6 +37,8 @@ URL to normalize.
37
37
 
38
38
  #### options
39
39
 
40
+ Type: `Object`
41
+
40
42
  ##### normalizeProtocol
41
43
 
42
44
  Type: `boolean`<br>
@@ -52,6 +54,21 @@ normalizeUrl('//sindresorhus.com:80/', {normalizeProtocol: false});
52
54
  //=> '//sindresorhus.com'
53
55
  ```
54
56
 
57
+ ##### normalizeHttps
58
+
59
+ Type: `boolean`<br>
60
+ Default: `false`
61
+
62
+ Normalize `https:` URLs to `http:`.
63
+
64
+ ```js
65
+ normalizeUrl('https://sindresorhus.com:80/');
66
+ //=> 'https://sindresorhus.com'
67
+
68
+ normalizeUrl('https://sindresorhus.com:80/', {normalizeHttps: true});
69
+ //=> 'http://sindresorhus.com'
70
+ ```
71
+
55
72
  ##### stripFragment
56
73
 
57
74
  Type: `boolean`<br>
@@ -130,6 +147,20 @@ normalizeUrl('www.sindresorhus.com/foo/default.php', {
130
147
  //=> 'http://sindresorhus.com/foo'
131
148
  ```
132
149
 
150
+ ##### sortQueryParameters
151
+
152
+ Type: `boolean`<br>
153
+ Default: `true`
154
+
155
+ Sort the query parameters alphabetically by key.
156
+
157
+ ```js
158
+ normalizeUrl('www.sindresorhus.com?b=two&a=one&c=three', {
159
+ sortQueryParameters: false
160
+ });
161
+ //=> 'http://sindresorhus.com/?b=two&a=one&c=three'
162
+ ```
163
+
133
164
 
134
165
  ## Related
135
166