-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
path.ts
100 lines (82 loc) 路 2.57 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
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
import { posix, SEPARATOR } from "../../deps/path.ts";
/**
* Convert the Windows paths (that use the separator "\")
* to Posix paths (with the separator "/")
* and ensure it starts with "/".
*/
export function normalizePath(path: string, rootToRemove?: string) {
if (rootToRemove) {
path = path.replace(rootToRemove, "");
}
if (SEPARATOR !== "/") {
path = path.replaceAll(SEPARATOR, "/");
// Is absolute Windows path (C:/...)
if (path.includes(":/")) {
if (rootToRemove && path.startsWith(rootToRemove)) {
return posix.join("/", path.replace(rootToRemove, ""));
}
return path;
}
}
const absolute = posix.join("/", path);
return rootToRemove && absolute.startsWith(rootToRemove)
? posix.join("/", absolute.replace(rootToRemove, ""))
: absolute;
}
/** Check if the path is an URL */
export function isUrl(path: string): boolean {
return !!path.match(/^(https?|file):\/\//);
}
/** Check if the path is absolute */
export function isAbsolutePath(path: string): boolean {
return SEPARATOR !== "/" ? /^\w:[\/\\]/.test(path) : path.startsWith("/");
}
/** Replace the extension of a path */
export function replaceExtension(
path: string,
ext: string,
): string {
return path.replace(/\.\w+$/, ext);
}
/** Split a path to path + extension */
export function getPathAndExtension(path: string): [string, string] {
const extension = getExtension(path);
const pathWithoutExtension = path.slice(0, -extension.length);
return [pathWithoutExtension, extension];
}
/** Get the extension of a path (this works better than std/path) */
export function getExtension(path: string): string {
const match = path.match(/\.\w+$/);
return match ? match[0] : "";
}
export type Extensions = string[] | "*";
export function matchExtension(exts: Extensions, path: string): boolean {
if (exts === "*") {
return true;
}
return exts.some((ext) => path.endsWith(ext));
}
/**
* Resolve the path of an included file
* Used in the template engines and processors
*/
export function resolveInclude(
path: string,
includesDir: string,
fromDir?: string,
rootToRemove?: string,
): string {
if (isUrl(path)) {
return path;
}
if (path.startsWith(".")) {
if (!fromDir) {
throw new Error(`Cannot load "${path}" without a base directory`);
}
return normalizePath(posix.join(fromDir, path), rootToRemove);
}
const normalized = normalizePath(path, rootToRemove);
return normalized.startsWith(normalizePath(posix.join(includesDir, "/")))
? normalized
: normalizePath(posix.join(includesDir, normalized));
}