-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
/
utils.ts
66 lines (57 loc) · 2.27 KB
/
utils.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
import * as pathe from 'pathe'
import { isWindows } from '../shared/utils'
export const decodeBase64 =
typeof atob !== 'undefined'
? atob
: (str: string) => Buffer.from(str, 'base64').toString('utf-8')
const CHAR_FORWARD_SLASH = 47
const CHAR_BACKWARD_SLASH = 92
const percentRegEx = /%/g
const backslashRegEx = /\\/g
const newlineRegEx = /\n/g
const carriageReturnRegEx = /\r/g
const tabRegEx = /\t/g
const questionRegex = /\?/g
const hashRegex = /#/g
function encodePathChars(filepath: string) {
if (filepath.indexOf('%') !== -1)
filepath = filepath.replace(percentRegEx, '%25')
// In posix, backslash is a valid character in paths:
if (!isWindows && filepath.indexOf('\\') !== -1)
filepath = filepath.replace(backslashRegEx, '%5C')
if (filepath.indexOf('\n') !== -1)
filepath = filepath.replace(newlineRegEx, '%0A')
if (filepath.indexOf('\r') !== -1)
filepath = filepath.replace(carriageReturnRegEx, '%0D')
if (filepath.indexOf('\t') !== -1)
filepath = filepath.replace(tabRegEx, '%09')
return filepath
}
export const posixDirname = pathe.dirname
export const posixResolve = pathe.resolve
export const normalizeString = pathe.normalizeString
export function posixPathToFileHref(posixPath: string): string {
let resolved = posixResolve(posixPath)
// path.resolve strips trailing slashes so we must add them back
const filePathLast = posixPath.charCodeAt(posixPath.length - 1)
if (
(filePathLast === CHAR_FORWARD_SLASH ||
(isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
resolved[resolved.length - 1] !== '/'
)
resolved += '/'
// Call encodePathChars first to avoid encoding % again for ? and #.
resolved = encodePathChars(resolved)
// Question and hash character should be included in pathname.
// Therefore, encoding is required to eliminate parsing them in different states.
// This is done as an optimization to not creating a URL instance and
// later triggering pathname setter, which impacts performance
if (resolved.indexOf('?') !== -1)
resolved = resolved.replace(questionRegex, '%3F')
if (resolved.indexOf('#') !== -1)
resolved = resolved.replace(hashRegex, '%23')
return new URL(`file://${resolved}`).href
}
export function toWindowsPath(path: string): string {
return path.replace(/\//g, '\\')
}