aboutsummaryrefslogtreecommitdiff
path: root/src/normalize-url.js
blob: c22e24382d901baeea7cfebbe70e2813b588450a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * Stripped down version of [normalize-url](https://github.com/sindresorhus/normalize-url)
 * by sindresorhus
 *
 * - always converts http => https
 * - removed unused options
 * - removed dataURL support
 */
export const normalizeUrl = (urlString) => {
  const urlObj = new URL(urlString)

  if (urlObj.protocol === 'http:') {
    urlObj.protocol = 'https:'
  }

  /*
  // Remove auth
  // TODO: Cloudflare Workers seems to have a subtle bug where if you set URL.username and
  // URL.password at all, it will include the @ authentication prefix in the resulting URL.
  // This does not repro in normal web or Node.js contexts.
  if (options.stripAuthentication) {
    urlObj.username = ''
    urlObj.password = ''
  }
  */

  // Remove duplicate slashes if not preceded by a protocol
  if (urlObj.pathname) {
    urlObj.pathname = urlObj.pathname.replace(/(?<!https?:)\/{2,}/g, '/')
  }

  // Decode URI octets
  if (urlObj.pathname) {
    urlObj.pathname = decodeURI(urlObj.pathname)
  }

  if (urlObj.hostname) {
    // Remove trailing dot
    urlObj.hostname = urlObj.hostname.replace(/\.$/, '')
  }

  // Sort query parameters
  urlObj.searchParams.sort()

  // Remove trailing `/`
  urlObj.pathname = urlObj.pathname.replace(/\/$/, '')

  urlString = urlObj.toString()

  // Remove trailing `/` for real this time
  if (urlObj.pathname === '/' && urlObj.hash === '') {
    urlString = urlString.replace(/\/$/, '')
  }

  urlString = urlString.replace(/https:%2F%2F/g, 'https%3A%2F%2F')

  return urlString
}