-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
66 lines (51 loc) · 1.66 KB
/
index.js
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
const path = require('path')
const { isWindows } = require('which-runtime')
exports.fileURLToPath = function fileURLToPath (url) {
if (typeof url === 'string') {
url = new URL(url)
}
if (url.protocol !== 'file:') {
throw new Error('The URL must use the file: protocol')
}
if (isWindows) {
if (/%2f|%5c/i.test(url.pathname)) {
throw new Error('The file: URL path must not include encoded \\ or / characters')
}
} else {
if (url.hostname) {
throw new Error('The file: URL host must be \'localhost\' or empty')
}
if (/%2f/i.test(url.pathname)) {
throw new Error('The file: URL path must not include encoded / characters')
}
}
const pathname = path.normalize(decodeURIComponent(url.pathname))
if (isWindows) {
if (url.hostname) return '\\\\' + url.hostname + pathname
const letter = pathname.charCodeAt(1) | 0x20
if (letter < 0x61 /* a */ || letter > 0x7a /* z */ || pathname.charCodeAt(2) !== 0x3a /* : */) {
throw new Error('The file: URL path must be absolute')
}
return pathname.slice(1)
}
return pathname
}
exports.pathToFileURL = function pathToFileURL (pathname) {
let resolved = path.resolve(pathname)
if (pathname[pathname.length - 1] === '/') {
resolved += '/'
} else if (isWindows && pathname[pathname.length - 1 === '\\']) {
resolved += '\\'
}
resolved = resolved
.replaceAll('%', '%25') // Must be first
.replaceAll('#', '%23')
.replaceAll('?', '%3f')
.replaceAll('\n', '%0a')
.replaceAll('\r', '%0d')
.replaceAll('\t', '%09')
if (!isWindows) {
resolved = resolved.replaceAll('\\', '%5c')
}
return new URL('file:' + resolved)
}