/
wasi-path.ts
97 lines (87 loc) · 2.65 KB
/
wasi-path.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
import { isWindows } from './std/_util/os.ts'
const UPPERCASE_ALPHABET = [
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'P',
'Y',
'Z',
] as const
/** Type of all uppercase alphabet letters */
export type UppercaseAlphabet = typeof UPPERCASE_ALPHABET[number]
/**
* Functions resolve a WASI compatible path prefix from a Windows device letter
* @template WasiPathPrefix Return type
*/
export interface WindowsDeviceMapper<WasiPathPrefix extends string> {
/**
* @param device Windows device letter
* @returns WASI compatible path prefix
*/
(device: UppercaseAlphabet): WasiPathPrefix
}
/** Default device mapper to use */
export const DEFAULT_WINDOWS_DEVICE_MAPPER: WindowsDeviceMapper<`/mnt/${UppercaseAlphabet}`> = device =>
`/mnt/${device}` as const
/**
* Convert a Windows path to a WASI compatible path
* @template WasiAbsolutePathPrefix Return type of `getAbsolutePrefix`
* @param path Windows path
* @param getAbsolutePrefix Function that resolves a WASI compatible path prefix from a Windows device letter
* @returns WASI compatible path
*/
export function fromWindowsPath<WasiAbsolutePathPrefix extends string>(
path: string,
getAbsolutePrefix: WindowsDeviceMapper<WasiAbsolutePathPrefix>,
): string {
const [letter, colon, backSlash] = path
if (colon === ':' && backSlash === '\\' && UPPERCASE_ALPHABET.includes(letter as UppercaseAlphabet)) {
const prefix = getAbsolutePrefix(letter as UppercaseAlphabet)
const suffix = path.slice(3).replaceAll('\\', '/')
return `${prefix}/${suffix}` as const
} else {
return path.replaceAll('\\', '/')
}
}
/**
* Convert a POSIX path to a WASI compatible path
* @template Path Type of both input and output
* @param path POSIX path
* @returns WASI compatible path
*/
export const fromPosixPath = <Path extends string>(path: Path) => path
/** Convert a POSIX or Windows path to a WASI compatible path */
export const fromWindowsPosixPath = isWindows ? fromWindowsPath : fromPosixPath
interface PathConverter {
/**
* Convert a Windows/POSIX path to a WASI compatible path
* @param path Windows/POSIX path
* @param getAbsolutePrefixForWindows Define absolute path prefix should the host machine is Windows
* @returns WASI compatible path
*/
(path: string, getAbsolutePrefixForWindows?: WindowsDeviceMapper<string>): string
}
/** Convert a POSIX or Windows path to a WASI compatible path */
export const getWasiPath: PathConverter = isWindows
? (path, prefix = DEFAULT_WINDOWS_DEVICE_MAPPER) => fromWindowsPath(path, prefix)
: fromPosixPath
export default getWasiPath