normalize-url 7.2.0 → 8.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.d.ts +13 -11
  2. package/index.js +27 -4
  3. package/package.json +13 -8
  4. package/readme.md +11 -21
package/index.d.ts CHANGED
@@ -1,10 +1,8 @@
1
- export interface Options {
1
+ export type Options = {
2
2
  /**
3
- @default 'http:'
4
-
5
- Values: `'https:' | 'http:'`
3
+ @default 'http'
6
4
  */
7
- readonly defaultProtocol?: string; // TODO: Make this `'https:' | 'http:'` in the next major version.
5
+ readonly defaultProtocol?: 'https' | 'http';
8
6
 
9
7
  /**
10
8
  Prepends `defaultProtocol` to the URL if it's protocol-relative.
@@ -23,7 +21,7 @@ export interface Options {
23
21
  readonly normalizeProtocol?: boolean;
24
22
 
25
23
  /**
26
- Normalizes `https:` URLs to `http:`.
24
+ Normalizes HTTPS URLs to HTTP.
27
25
 
28
26
  @default false
29
27
 
@@ -39,9 +37,9 @@ export interface Options {
39
37
  readonly forceHttp?: boolean;
40
38
 
41
39
  /**
42
- Normalizes `http:` URLs to `https:`.
40
+ Normalizes HTTP URLs to HTTPS.
43
41
 
44
- This option can't be used with the `forceHttp` option at the same time.
42
+ This option cannot be used with the `forceHttp` option at the same time.
45
43
 
46
44
  @default false
47
45
 
@@ -63,10 +61,10 @@ export interface Options {
63
61
 
64
62
  @example
65
63
  ```
66
- normalizeUrl('user:password@sindresorhus.com');
64
+ normalizeUrl('https://user:password@sindresorhus.com');
67
65
  //=> 'https://sindresorhus.com'
68
66
 
69
- normalizeUrl('user:password@sindresorhus.com', {stripAuthentication: false});
67
+ normalizeUrl('https://user:password@sindresorhus.com', {stripAuthentication: false});
70
68
  //=> 'https://user:password@sindresorhus.com'
71
69
  ```
72
70
  */
@@ -280,11 +278,15 @@ export interface Options {
280
278
  ```
281
279
  */
282
280
  readonly sortQueryParameters?: boolean;
283
- }
281
+ };
284
282
 
285
283
  /**
286
284
  [Normalize](https://en.wikipedia.org/wiki/URL_normalization) a URL.
287
285
 
286
+ URLs with custom protocols are not normalized and just passed through by default. Supported protocols are: `https`, `http`, `file`, and `data`.
287
+
288
+ Human-friendly URLs with basic auth (for example, `user:password@sindresorhus.com`) are not handled because basic auth conflicts with custom protocols. [Basic auth URLs are also deprecated.](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#access_using_credentials_in_the_url)
289
+
288
290
  @param url - URL to normalize, including [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs).
289
291
 
290
292
  @example
package/index.js CHANGED
@@ -4,6 +4,24 @@ const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
4
4
 
5
5
  const testParameter = (name, filters) => filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
6
6
 
7
+ const supportedProtocols = new Set([
8
+ 'https:',
9
+ 'http:',
10
+ 'file:',
11
+ ]);
12
+
13
+ const hasCustomProtocol = urlString => {
14
+ try {
15
+ const {protocol} = new URL(urlString);
16
+
17
+ return protocol.endsWith(':')
18
+ && !protocol.includes('.')
19
+ && !supportedProtocols.has(protocol);
20
+ } catch {
21
+ return false;
22
+ }
23
+ };
24
+
7
25
  const normalizeDataURL = (urlString, {stripHash}) => {
8
26
  const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString);
9
27
 
@@ -22,7 +40,7 @@ const normalizeDataURL = (urlString, {stripHash}) => {
22
40
  }
23
41
 
24
42
  // Lowercase MIME type
25
- const mimeType = (mediaType.shift() || '').toLowerCase();
43
+ const mimeType = mediaType.shift()?.toLowerCase() ?? '';
26
44
  const attributes = mediaType
27
45
  .map(attribute => {
28
46
  let [key, value = ''] = attribute.split('=').map(string => string.trim());
@@ -57,7 +75,7 @@ const normalizeDataURL = (urlString, {stripHash}) => {
57
75
 
58
76
  export default function normalizeUrl(urlString, options) {
59
77
  options = {
60
- defaultProtocol: 'http:',
78
+ defaultProtocol: 'http',
61
79
  normalizeProtocol: true,
62
80
  forceHttp: false,
63
81
  forceHttps: false,
@@ -74,6 +92,11 @@ export default function normalizeUrl(urlString, options) {
74
92
  ...options,
75
93
  };
76
94
 
95
+ // Legacy: Append `:` to the protocol if missing.
96
+ if (typeof options.defaultProtocol === 'string' && !options.defaultProtocol.endsWith(':')) {
97
+ options.defaultProtocol = `${options.defaultProtocol}:`;
98
+ }
99
+
77
100
  urlString = urlString.trim();
78
101
 
79
102
  // Data URL
@@ -81,8 +104,8 @@ export default function normalizeUrl(urlString, options) {
81
104
  return normalizeDataURL(urlString, options);
82
105
  }
83
106
 
84
- if (/^view-source:/i.test(urlString)) {
85
- throw new Error('`view-source:` is not supported as it is a non-standard protocol');
107
+ if (hasCustomProtocol(urlString)) {
108
+ return urlString;
86
109
  }
87
110
 
88
111
  const hasRelativeProtocol = urlString.startsWith('//');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "normalize-url",
3
- "version": "7.2.0",
3
+ "version": "8.0.1",
4
4
  "description": "Normalize a URL",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/normalize-url",
@@ -11,12 +11,17 @@
11
11
  "url": "https://sindresorhus.com"
12
12
  },
13
13
  "type": "module",
14
- "exports": "./index.js",
14
+ "exports": {
15
+ "types": "./index.d.ts",
16
+ "default": "./index.js"
17
+ },
18
+ "sideEffects": false,
15
19
  "engines": {
16
- "node": ">=12.20"
20
+ "node": ">=14.16"
17
21
  },
18
22
  "scripts": {
19
- "test": "xo && c8 ava && tsd"
23
+ "//test": "xo && c8 ava && tsd",
24
+ "test": "c8 ava && tsd"
20
25
  },
21
26
  "files": [
22
27
  "index.js",
@@ -38,10 +43,10 @@
38
43
  "canonical"
39
44
  ],
40
45
  "devDependencies": {
41
- "ava": "^4.0.1",
42
- "c8": "^7.11.0",
43
- "tsd": "^0.19.1",
44
- "xo": "^0.47.0"
46
+ "ava": "^5.0.1",
47
+ "c8": "^7.12.0",
48
+ "tsd": "^0.24.1",
49
+ "xo": "^0.52.4"
45
50
  },
46
51
  "c8": {
47
52
  "reporter": [
package/readme.md CHANGED
@@ -12,8 +12,6 @@ Useful when you need to display, store, deduplicate, sort, compare, etc, URLs.
12
12
  npm install normalize-url
13
13
  ```
14
14
 
15
- *If you need Safari support, use version 4: `npm i normalize-url@4`*
16
-
17
15
  ## Usage
18
16
 
19
17
  ```js
@@ -30,6 +28,10 @@ normalizeUrl('//www.sindresorhus.com:80/../baz?b=bar&a=foo');
30
28
 
31
29
  ### normalizeUrl(url, options?)
32
30
 
31
+ URLs with custom protocols are not normalized and just passed through by default. Supported protocols are: `https`, `http`, `file`, and `data`.
32
+
33
+ Human-friendly URLs with basic auth (for example, `user:password@sindresorhus.com`) are not handled because basic auth conflicts with custom protocols. [Basic auth URLs are also deprecated.](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#access_using_credentials_in_the_url)
34
+
33
35
  #### url
34
36
 
35
37
  Type: `string`
@@ -43,8 +45,8 @@ Type: `object`
43
45
  ##### defaultProtocol
44
46
 
45
47
  Type: `string`\
46
- Default: `http:`\
47
- Values: `'https:' | 'http:'`
48
+ Default: `'http'`\
49
+ Values: `'https' | 'http'`
48
50
 
49
51
  ##### normalizeProtocol
50
52
 
@@ -66,7 +68,7 @@ normalizeUrl('//sindresorhus.com', {normalizeProtocol: false});
66
68
  Type: `boolean`\
67
69
  Default: `false`
68
70
 
69
- Normalize `https:` to `http:`.
71
+ Normalize HTTPS to HTTP.
70
72
 
71
73
  ```js
72
74
  normalizeUrl('https://sindresorhus.com');
@@ -81,7 +83,7 @@ normalizeUrl('https://sindresorhus.com', {forceHttp: true});
81
83
  Type: `boolean`\
82
84
  Default: `false`
83
85
 
84
- Normalize `http:` to `https:`.
86
+ Normalize HTTP to HTTPS.
85
87
 
86
88
  ```js
87
89
  normalizeUrl('http://sindresorhus.com');
@@ -91,7 +93,7 @@ normalizeUrl('http://sindresorhus.com', {forceHttps: true});
91
93
  //=> 'https://sindresorhus.com'
92
94
  ```
93
95
 
94
- This option can't be used with the `forceHttp` option at the same time.
96
+ This option cannot be used with the `forceHttp` option at the same time.
95
97
 
96
98
  ##### stripAuthentication
97
99
 
@@ -101,10 +103,10 @@ Default: `true`
101
103
  Strip the [authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) part of the URL.
102
104
 
103
105
  ```js
104
- normalizeUrl('user:password@sindresorhus.com');
106
+ normalizeUrl('https://user:password@sindresorhus.com');
105
107
  //=> 'https://sindresorhus.com'
106
108
 
107
- normalizeUrl('user:password@sindresorhus.com', {stripAuthentication: false});
109
+ normalizeUrl('https://user:password@sindresorhus.com', {stripAuthentication: false});
108
110
  //=> 'https://user:password@sindresorhus.com'
109
111
  ```
110
112
 
@@ -308,15 +310,3 @@ normalizeUrl('www.sindresorhus.com?b=two&a=one&c=three', {
308
310
  ## Related
309
311
 
310
312
  - [compare-urls](https://github.com/sindresorhus/compare-urls) - Compare URLs by first normalizing them
311
-
312
- ---
313
-
314
- <div align="center">
315
- <b>
316
- <a href="https://tidelift.com/subscription/pkg/npm-normalize-url?utm_source=npm-normalize-url&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
317
- </b>
318
- <br>
319
- <sub>
320
- Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
321
- </sub>
322
- </div>