-
Notifications
You must be signed in to change notification settings - Fork 112
/
path.ts
65 lines (53 loc) · 2.34 KB
/
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
import * as os from 'node:os';
import * as path from 'node:path';
import type { Pattern } from '../types';
const IS_WINDOWS_PLATFORM = os.platform() === 'win32';
const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\
/**
* All non-escaped special characters.
* Posix: ()*?[\]{|}, !+@ before (, ! at the beginning, \\ before non-special characters.
* Windows: (){}, !+@ before (, ! at the beginning.
*/
const POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(?<escape>\\?)(?<symbols>[()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
const WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(?<escape>\\?)(?<symbols>[(){}]|^!|[!+@](?=\())/g;
/**
* The device path (\\.\ or \\?\).
* https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths
*/
const DOS_DEVICE_PATH_RE = /^\\\\(?<path>[.?])/;
/**
* All backslashes except those escaping special characters.
* Windows: !()+@{}
* https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
*/
const WINDOWS_BACKSLASHES_RE = /\\(?![!()+@{}])/g;
export function makeAbsolute(cwd: string, filepath: string): string {
return path.resolve(cwd, filepath);
}
export function removeLeadingDotSegment(entry: string): string {
// We do not use `startsWith` because this is 10x slower than current implementation for some cases.
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
if (entry.charAt(0) === '.') {
const secondCharactery = entry.charAt(1);
if (secondCharactery === '/' || secondCharactery === '\\') {
return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT);
}
}
return entry;
}
export const escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath;
export function escapeWindowsPath(pattern: Pattern): Pattern {
return pattern.replaceAll(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2');
}
export function escapePosixPath(pattern: Pattern): Pattern {
return pattern.replaceAll(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2');
}
export const convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern;
export function convertWindowsPathToPattern(filepath: string): Pattern {
return escapeWindowsPath(filepath)
.replace(DOS_DEVICE_PATH_RE, '//$1')
.replaceAll(WINDOWS_BACKSLASHES_RE, '/');
}
export function convertPosixPathToPattern(filepath: string): Pattern {
return escapePosixPath(filepath);
}