-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPathResolver.ts
139 lines (121 loc) · 3.23 KB
/
PathResolver.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import path from "path";
/** A shared serialization flag class. */
class SerializeAbsoluteProperty {
/** The shared base path. */
readonly basePath: string;
/** True if the serialization should use absolute paths. */
useAbsolute: boolean;
constructor(basePath: string, useAbsolute: boolean)
{
this.basePath = basePath;
this.useAbsolute = useAbsolute;
}
}
/**
* This class exists to handle path resolution with both relative and absolute paths.
*/
export default class PathResolver
{
/** A shared serialization flag class. */
static readonly UseAbsolute = SerializeAbsoluteProperty;
/**
* Replacement for JSON.stringify which temporarily overrides useAbsolute
* @param absoluteSetting - the shared useAbsolute wrapper.
* @param useAbsolute - the overriding value for useAbsolute.
* @param args - arguments to pass to JSON.stringify()
* @returns the result from JSON.stringify()
*/
static stringify(
absoluteSetting: SerializeAbsoluteProperty,
useAbsolute: boolean,
...args: Parameters<JSON["stringify"]>
) : ReturnType<JSON["stringify"]>
{
return this.overrideForCallback(
absoluteSetting,
useAbsolute,
() => JSON.stringify(...args)
);
}
/**
* Run a callback with a temporary useAbsolute value.
* @param absoluteSetting - the shared useAbsolute wrapper.
* @param useAbsolute - the overriding value for useAbsolute.
* @param callback - a callback to execute.
* @returns
*/
static overrideForCallback<T>(
absoluteSetting: SerializeAbsoluteProperty,
useAbsolute: boolean,
callback: () => T
) : T
{
const oldValue = absoluteSetting.useAbsolute;
absoluteSetting.useAbsolute = useAbsolute;
try {
return callback();
}
finally {
absoluteSetting.useAbsolute = oldValue;
}
}
#relativePath = "";
readonly #serializeAbsolute: SerializeAbsoluteProperty
constructor(
absoluteProperty: SerializeAbsoluteProperty,
asAbsolute: boolean,
pathToFile: string,
)
{
this.#serializeAbsolute = absoluteProperty;
this.setPath(asAbsolute, pathToFile);
}
clone() : PathResolver {
return new PathResolver(
this.#serializeAbsolute,
false,
this.#relativePath
);
}
#normalize(newPath: string) : string
{
return path.normalize(path.resolve(
this.#serializeAbsolute.basePath, newPath
));
}
getPath(asAbsolute: boolean) : string
{
if (asAbsolute) {
return this.#normalize(this.#relativePath);
}
return this.#relativePath;
}
setPath(asAbsolute: boolean, newPath: string) : void
{
if (!asAbsolute) {
newPath = this.#normalize(newPath);
}
else {
newPath = path.normalize(newPath);
}
this.#relativePath = path.relative(
this.#serializeAbsolute.basePath,
newPath
);
}
isInBase(asAbsolute: boolean, newPath: string) : boolean
{
if (!asAbsolute) {
newPath = this.#normalize(newPath);
}
else {
newPath = path.normalize(newPath);
}
if (newPath === this.#serializeAbsolute.basePath)
return true;
return newPath.startsWith(this.#serializeAbsolute.basePath + path.sep);
}
toJSON() : string {
return this.getPath(this.#serializeAbsolute.useAbsolute);
}
}