forked from vitest-dev/vitest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.ts
109 lines (88 loc) · 3.08 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { fileURLToPath, pathToFileURL } from 'url'
import { existsSync } from 'fs'
import { relative, resolve } from 'pathe'
import { isNodeBuiltin } from 'mlly'
import type { Arrayable, Nullable } from './types'
export const isWindows = process.platform === 'win32'
export function slash(str: string) {
return str.replace(/\\/g, '/')
}
export function mergeSlashes(str: string) {
return str.replace(/\/\//g, '/')
}
export function normalizeRequestId(id: string, base?: string): string {
if (base && id.startsWith(base))
id = `/${id.slice(base.length)}`
return id
.replace(/^\/@id\/__x00__/, '\0') // virtual modules start with `\0`
.replace(/^\/@id\//, '')
.replace(/^__vite-browser-external:/, '')
.replace(/^(node|file):/, '')
.replace(/^\/+/, '/') // remove duplicate leading slashes
.replace(/\?v=\w+/, '?') // remove ?v= query
.replace(/&v=\w+/, '') // remove &v= query
.replace(/\?t=\w+/, '?') // remove ?t= query
.replace(/&t=\w+/, '') // remove &t= query
.replace(/\?import/, '?') // remove ?import query
.replace(/&import/, '') // remove &import query
.replace(/\?&/, '?') // replace ?& with just ?
.replace(/\?+$/, '') // remove end query mark
}
export const queryRE = /\?.*$/s
export const hashRE = /#.*$/s
export const cleanUrl = (url: string): string =>
url.replace(hashRE, '').replace(queryRE, '')
export function normalizeModuleId(id: string) {
return id
.replace(/\\/g, '/')
.replace(/^\/@fs\//, '/')
.replace(/^file:\//, '/')
.replace(/^\/+/, '/')
}
export function isPrimitive(v: any) {
return v !== Object(v)
}
export function pathFromRoot(root: string, filename: string) {
if (isNodeBuiltin(filename))
return filename
// don't replace with "/" on windows, "/C:/foo" is not a valid path
filename = filename.replace(/^\/@fs\//, isWindows ? '' : '/')
if (!filename.startsWith(root))
return filename
const relativePath = relative(root, filename)
const segments = relativePath.split('/')
const startIndex = segments.findIndex(segment => segment !== '..' && segment !== '.')
return `/${segments.slice(startIndex).join('/')}`
}
export function toFilePath(id: string, root: string): string {
let absolute = (() => {
if (id.startsWith('/@fs/'))
return id.slice(4)
if (!id.startsWith(root) && id.startsWith('/')) {
const resolved = resolve(root, id.slice(1))
// The resolved path can have query values. Remove them before checking
// the file path.
if (existsSync(resolved.replace(/\?.*$/, '')))
return resolved
}
return id
})()
if (absolute.startsWith('//'))
absolute = absolute.slice(1)
// disambiguate the `<UNIT>:/` on windows: see nodejs/node#31710
return isWindows && absolute.startsWith('/')
? slash(fileURLToPath(pathToFileURL(absolute.slice(1)).href))
: absolute
}
/**
* Convert `Arrayable<T>` to `Array<T>`
*
* @category Array
*/
export function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
if (array === null || array === undefined)
array = []
if (Array.isArray(array))
return array
return [array]
}