/
parse.ts
73 lines (63 loc) 路 1.85 KB
/
parse.ts
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { decode } from './encoding'
import { hasProtocol } from './utils'
export interface ParsedURL {
protocol?: string
host?: string
auth?: string
pathname: string
hash: string
search: string
}
export interface ParsedAuth {
username: string
password: string
}
export interface ParsedHost {
hostname: string
port: string
}
export function parseURL (input: string = '', defaultProto?: string): ParsedURL {
if (!hasProtocol(input, true)) {
return defaultProto ? parseURL(defaultProto + input) : parsePath(input)
}
const [protocol = '', auth, hostAndPath = ''] = (input.replace(/\\/g, '/').match(/([^:/]+:)?\/\/([^/@]+@)?(.*)/) || []).splice(1)
const [host = '', path = ''] = (hostAndPath.match(/([^/?#]*)(.*)?/) || []).splice(1)
const { pathname, search, hash } = parsePath(path)
return {
protocol,
auth: auth ? auth.substr(0, auth.length - 1) : '',
host,
pathname,
search,
hash
}
}
export function parsePath (input: string = ''): ParsedURL {
const [pathname = '', search = '', hash = ''] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1)
return {
pathname,
search,
hash
}
}
export function parseAuth (input: string = ''): ParsedAuth {
const [username, password] = input.split(':')
return {
username: decode(username),
password: decode(password)
}
}
export function parseHost (input: string = ''): ParsedHost {
const [hostname, port] = (input.match(/([^/]*)(:0-9+)?/) || []).splice(1)
return {
hostname: decode(hostname),
port
}
}
export function stringifyParsedURL (parsed: ParsedURL) {
const fullpath = parsed.pathname + (parsed.search ? (parsed.search.startsWith('?') ? '' : '?') + parsed.search : '') + parsed.hash
if (!parsed.protocol) {
return fullpath
}
return parsed.protocol + '//' + (parsed.auth ? parsed.auth + '@' : '') + parsed.host + fullpath
}