CodeCommitsIssuesPull requestsActionsInsightsSecurity
master

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

app/lib/parse-url.js

67lines · modecode

1import {parse} from "url"
2
3const PARAM_PATTERN = /(\#|\?)/
4const PATH_DELIMITER_PATTERN = /[^\w+]/
5const PROTOCOL_PATTERN = /(^\S*:?)(\/\/)/
6const DEFAULT_PROTOCOL_MATCH = [null, "//", ""]
7
8const chunkIsPresent = chunk => chunk.value.length !== 0
9
10export default function parseURL(string) {
11 const [urlWithPath, paramDelimiter = "", paramString = ""] = string.split(PARAM_PATTERN) || []
12
13 const parsed = parse(urlWithPath, false, true)
14 const {host, pathname} = parsed
15 const pathCharacters = pathname.split("")
16 let url
17
18 if (parsed.protocol) {
19 url = [parsed.protocol, "//", host].join("")
20 }
21 else {
22 const [, protocol, delimiter] = urlWithPath.match(PROTOCOL_PATTERN) || DEFAULT_PROTOCOL_MATCH
23
24 url = [protocol, delimiter, host].join("")
25 }
26
27 const pathChunks = pathCharacters
28 .reduce((accumulator, character) => {
29 if (PATH_DELIMITER_PATTERN.test(character)) {
30 accumulator.push({type: "delimiter", value: character}, {type: "path", value: ""})
31 }
32 else {
33 accumulator[accumulator.length - 1].value += character
34 }
35
36 return accumulator
37 }, [{type: "path", value: ""}])
38 .filter(chunkIsPresent)
39
40 const paramChunks = []
41
42 paramString.split("&").forEach((param, index, paramArray) => {
43 const [key, value] = param.split("=")
44
45 paramChunks.push(
46 {type: "param-group", value: [
47 {type: "param-key", value: key},
48 {type: "delimiter", value: "="},
49 {type: "param-value", value}
50 ]}
51 )
52
53 if (index !== paramArray.length - 1) {
54 paramChunks.push({type: "delimiter", value: "&"})
55 }
56 })
57
58 if (paramChunks.length) {
59 paramChunks.unshift({type: "delimiter", value: paramDelimiter})
60 }
61
62 return [
63 {type: "url", value: url},
64 ...pathChunks,
65 ...paramChunks
66 ]
67}