nice-path 0.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.node-version +1 -0
- package/LICENSE +1 -1
- package/README.md +288 -22
- package/dist/index.d.ts +167 -0
- package/dist/index.js +329 -434
- package/package.json +13 -12
- package/tsconfig.json +3 -2
- package/dist/index.ts +0 -506
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nice-path",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/suchipi/nice-path.git"
|
|
9
|
+
},
|
|
10
|
+
"author": "Lily Skye <me@suchipi.com>",
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"keywords": [
|
|
9
13
|
"path",
|
|
@@ -13,17 +17,14 @@
|
|
|
13
17
|
"file"
|
|
14
18
|
],
|
|
15
19
|
"devDependencies": {
|
|
16
|
-
"@types/
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"prettier": "^1.18.2",
|
|
21
|
-
"ts-jest": "^24.1.0",
|
|
22
|
-
"typescript": "^3.6.4"
|
|
20
|
+
"@types/node": "^20.11.0",
|
|
21
|
+
"prettier": "^3.2.2",
|
|
22
|
+
"typescript": "^5.3.3",
|
|
23
|
+
"vitest": "^1.2.0"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
25
|
-
"build": "rm -rf dist && tsc
|
|
26
|
+
"build": "rm -rf dist && tsc",
|
|
26
27
|
"build:watch": "tsc -w",
|
|
27
|
-
"test": "
|
|
28
|
+
"test": "vitest"
|
|
28
29
|
}
|
|
29
30
|
}
|
package/tsconfig.json
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
"exclude": ["./src/**/*.test.ts"],
|
|
4
4
|
|
|
5
5
|
"compilerOptions": {
|
|
6
|
-
"lib": ["
|
|
7
|
-
"target": "
|
|
6
|
+
"lib": ["es2020"],
|
|
7
|
+
"target": "es2020",
|
|
8
8
|
"module": "commonjs",
|
|
9
9
|
"outDir": "./dist",
|
|
10
|
+
"declaration": true,
|
|
10
11
|
|
|
11
12
|
"strict": true,
|
|
12
13
|
"noImplicitAny": true,
|
package/dist/index.ts
DELETED
|
@@ -1,506 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import util from "util";
|
|
4
|
-
|
|
5
|
-
const readdirP = util.promisify(fs.readdir);
|
|
6
|
-
|
|
7
|
-
function aOrAn(nextWord: string) {
|
|
8
|
-
return /^[aeiou]/i.test(nextWord) ? "an" : "a";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function pathKindErrorMessage(expected: string, actual: string): string {
|
|
12
|
-
return `Expected to receive ${aOrAn(
|
|
13
|
-
expected
|
|
14
|
-
)} ${expected} path, but received ${aOrAn(actual)} ${actual} path instead`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function comparisonRootKindMismatchErrorMessage(
|
|
18
|
-
firstPath: string,
|
|
19
|
-
secondPath: string
|
|
20
|
-
) {
|
|
21
|
-
const firstRootKind = detectRootKind(firstPath);
|
|
22
|
-
const secondRootKind = detectRootKind(secondPath);
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
`The two paths being compared are not in the same namespace; ` +
|
|
26
|
-
`the first path (${JSON.stringify(
|
|
27
|
-
firstPath
|
|
28
|
-
)}) has root kind ${JSON.stringify(firstRootKind)} ` +
|
|
29
|
-
`but the second path (${JSON.stringify(secondPath)}) has root kind ` +
|
|
30
|
-
`'${JSON.stringify(secondRootKind)}'.`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function getSeparator(pathString: string): string {
|
|
35
|
-
let sep = "/";
|
|
36
|
-
if (!pathString.includes(sep)) {
|
|
37
|
-
sep = "\\";
|
|
38
|
-
if (!pathString.includes(sep)) {
|
|
39
|
-
sep = path.sep;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return sep;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function getSegments(pathString: string): Array<string> {
|
|
46
|
-
const sep = getSeparator(pathString);
|
|
47
|
-
const segments = pathString.split(sep).filter(Boolean);
|
|
48
|
-
return segments;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Normal path.join always uses path.sep and removes leading . or .. segments,
|
|
52
|
-
// so this is a safer alternative.
|
|
53
|
-
function safeJoin(pathsOrSegments: Array<string>, sep: string) {
|
|
54
|
-
const trimmedSegments = pathsOrSegments.map(
|
|
55
|
-
(pathOrSegment, pathOrSegmentIndex) =>
|
|
56
|
-
pathOrSegment
|
|
57
|
-
.split(sep)
|
|
58
|
-
.filter((segment) => {
|
|
59
|
-
if (pathOrSegmentIndex === 0) {
|
|
60
|
-
return true;
|
|
61
|
-
} else {
|
|
62
|
-
return Boolean(segment);
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
.join(sep)
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
return trimmedSegments.join(sep);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function detectPathKind(pathString: string) {
|
|
72
|
-
const sep = getSeparator(pathString);
|
|
73
|
-
const segments = getSegments(pathString);
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
pathString.startsWith(sep) ||
|
|
77
|
-
pathString.startsWith("\\\\") ||
|
|
78
|
-
pathString.match(/^[A-Z]:/i)
|
|
79
|
-
) {
|
|
80
|
-
return "absolute";
|
|
81
|
-
} else if (segments[0] === "." || segments[0] === "..") {
|
|
82
|
-
return "relative";
|
|
83
|
-
} else {
|
|
84
|
-
return "unqualified";
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function detectRootKind(
|
|
89
|
-
pathString: string
|
|
90
|
-
): "leading-slash" | "letter-drive" | "unc" {
|
|
91
|
-
const sep = getSeparator(pathString);
|
|
92
|
-
if (pathString.match(/^[A-Z]:/i)) {
|
|
93
|
-
return "letter-drive";
|
|
94
|
-
} else if (pathString.startsWith("\\\\")) {
|
|
95
|
-
return "unc";
|
|
96
|
-
} else if (pathString.startsWith(sep)) {
|
|
97
|
-
return "leading-slash";
|
|
98
|
-
} else {
|
|
99
|
-
throw new Error(
|
|
100
|
-
`Unable to detect root kind from path string: '${pathString}'. Is it an absolute path?`
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function reconsistuteAbsolutePath(
|
|
106
|
-
originalRaw: string,
|
|
107
|
-
newSegments: Array<string>
|
|
108
|
-
) {
|
|
109
|
-
const sep = getSeparator(originalRaw);
|
|
110
|
-
const rootKind = detectRootKind(originalRaw);
|
|
111
|
-
|
|
112
|
-
let suffix = safeJoin(newSegments, sep);
|
|
113
|
-
|
|
114
|
-
let prefix = "";
|
|
115
|
-
switch (rootKind) {
|
|
116
|
-
case "leading-slash": {
|
|
117
|
-
prefix = sep;
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
case "unc": {
|
|
121
|
-
prefix = sep.repeat(2);
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return prefix + suffix;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export class Path<Kind extends "absolute" | "relative" | "unqualified"> {
|
|
130
|
-
kind: Kind;
|
|
131
|
-
raw: string;
|
|
132
|
-
|
|
133
|
-
constructor(raw: string, kind: Kind) {
|
|
134
|
-
this.raw = raw;
|
|
135
|
-
this.kind = kind;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
toString() {
|
|
139
|
-
return this.raw;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
static fromAbsolutePathString(absolutePath: string): AbsolutePath {
|
|
143
|
-
const kind = detectPathKind(absolutePath);
|
|
144
|
-
if (kind !== "absolute") {
|
|
145
|
-
throw new Error(pathKindErrorMessage("absolute", kind));
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return new AbsolutePath(absolutePath);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
static fromRelativePathString(relativePath: string) {
|
|
152
|
-
const kind = detectPathKind(relativePath);
|
|
153
|
-
if (kind !== "relative") {
|
|
154
|
-
throw new Error(pathKindErrorMessage("relative", kind));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return new RelativePath(relativePath);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
static fromUnqualifiedPathString(unqualifiedPath: string) {
|
|
161
|
-
const kind = detectPathKind(unqualifiedPath);
|
|
162
|
-
if (kind !== "unqualified") {
|
|
163
|
-
throw new Error(pathKindErrorMessage("unqualified", kind));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return new UnqualifiedPath(unqualifiedPath);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
static from(raw: string) {
|
|
170
|
-
const kind = detectPathKind(raw);
|
|
171
|
-
switch (kind) {
|
|
172
|
-
case "absolute":
|
|
173
|
-
return new AbsolutePath(raw);
|
|
174
|
-
case "relative":
|
|
175
|
-
return new RelativePath(raw);
|
|
176
|
-
case "unqualified":
|
|
177
|
-
return new UnqualifiedPath(raw);
|
|
178
|
-
default: {
|
|
179
|
-
throw new Error("Unable to detect path type from input string");
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
isAbsolute(): this is AbsolutePath {
|
|
185
|
-
return this.kind === "absolute";
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
isRelative(): this is RelativePath {
|
|
189
|
-
return this.kind === "relative";
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
isUnqualified(): this is UnqualifiedPath {
|
|
193
|
-
return this.kind === "unqualified";
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
hasTrailingSlash(): boolean {
|
|
197
|
-
const sep = getSeparator(this.raw);
|
|
198
|
-
return this.raw.endsWith(sep);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
removeTrailingSlash(): Path<Kind> {
|
|
202
|
-
if (!this.hasTrailingSlash()) {
|
|
203
|
-
return this;
|
|
204
|
-
} else {
|
|
205
|
-
return new Path<Kind>(this.raw.replace(/(?:[/\\])+$/, ""), this.kind);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
append(...segments: Array<string>): Path<Kind> {
|
|
210
|
-
const sep = getSeparator(this.raw);
|
|
211
|
-
return new Path<Kind>(safeJoin([this.raw, ...segments], sep), this.kind);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
resolve(): Path<Kind> {
|
|
215
|
-
const segments = getSegments(this.raw);
|
|
216
|
-
const nextSegments = [];
|
|
217
|
-
|
|
218
|
-
for (let i = 0; i < segments.length; i++) {
|
|
219
|
-
const currentSegment = segments[i];
|
|
220
|
-
|
|
221
|
-
if (currentSegment === "." && i !== 0) {
|
|
222
|
-
continue;
|
|
223
|
-
} else if (currentSegment === ".." && nextSegments.length > 0) {
|
|
224
|
-
nextSegments.pop();
|
|
225
|
-
} else {
|
|
226
|
-
nextSegments.push(currentSegment);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const nextRaw = reconsistuteAbsolutePath(this.raw, nextSegments);
|
|
231
|
-
return new Path<Kind>(nextRaw, this.kind);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export class AbsolutePath extends Path<"absolute"> {
|
|
236
|
-
constructor(raw: string) {
|
|
237
|
-
super(raw, "absolute");
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
relativeTo(relativeTo: AbsolutePath | string) {
|
|
241
|
-
if (typeof relativeTo === "string") {
|
|
242
|
-
const pathKind = detectPathKind(relativeTo);
|
|
243
|
-
if (pathKind !== "absolute") {
|
|
244
|
-
throw new Error(pathKindErrorMessage("absolute", pathKind));
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
let relativeToString =
|
|
249
|
-
typeof relativeTo === "string" ? relativeTo : relativeTo.raw;
|
|
250
|
-
|
|
251
|
-
const thisRootKind = detectRootKind(this.raw);
|
|
252
|
-
const relativeToRootKind = detectRootKind(relativeToString);
|
|
253
|
-
|
|
254
|
-
if (thisRootKind !== relativeToRootKind) {
|
|
255
|
-
throw new Error(
|
|
256
|
-
comparisonRootKindMismatchErrorMessage(this.raw, relativeToString)
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (
|
|
261
|
-
thisRootKind === "letter-drive" &&
|
|
262
|
-
relativeToRootKind === "letter-drive" &&
|
|
263
|
-
this.raw.slice(0, 1).toUpperCase() !==
|
|
264
|
-
relativeToString.slice(0, 1).toUpperCase()
|
|
265
|
-
) {
|
|
266
|
-
throw new Error(
|
|
267
|
-
`The two paths being compared are not on the same drive; comparing ` +
|
|
268
|
-
JSON.stringify(this.raw) +
|
|
269
|
-
" and " +
|
|
270
|
-
JSON.stringify(relativeToString)
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const thisSegments = getSegments(this.raw);
|
|
275
|
-
const relativeToSegments = getSegments(relativeToString);
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
thisRootKind === "unc" &&
|
|
279
|
-
relativeToRootKind === "unc" &&
|
|
280
|
-
thisSegments[0] !== relativeToSegments[0]
|
|
281
|
-
) {
|
|
282
|
-
throw new Error(
|
|
283
|
-
"The two paths being compared are not on the same UNC host; comparing " +
|
|
284
|
-
JSON.stringify(this.raw) +
|
|
285
|
-
" and " +
|
|
286
|
-
JSON.stringify(relativeToString)
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const longerLength = Math.max(
|
|
291
|
-
thisSegments.length,
|
|
292
|
-
relativeToSegments.length
|
|
293
|
-
);
|
|
294
|
-
let lastSharedSegmentIndex = -1;
|
|
295
|
-
for (let i = 0; i < longerLength; i++) {
|
|
296
|
-
const thisSegment = thisSegments[i];
|
|
297
|
-
const relativeToSegment = relativeToSegments[i];
|
|
298
|
-
|
|
299
|
-
if (thisSegment === relativeToSegment) {
|
|
300
|
-
lastSharedSegmentIndex = i;
|
|
301
|
-
} else {
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
let nextSegments = [];
|
|
307
|
-
if (lastSharedSegmentIndex === -1) {
|
|
308
|
-
// No shared commonality between the paths
|
|
309
|
-
nextSegments = relativeToSegments.map(() => "..");
|
|
310
|
-
nextSegments.push(...thisSegments);
|
|
311
|
-
} else {
|
|
312
|
-
const remainingThisSegments = [];
|
|
313
|
-
for (let i = 0; i < thisSegments.length; i++) {
|
|
314
|
-
if (i > lastSharedSegmentIndex) {
|
|
315
|
-
remainingThisSegments.push(thisSegments[i]);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const remainingRelativeToSegments = [];
|
|
320
|
-
|
|
321
|
-
for (let i = 0; i < relativeToSegments.length; i++) {
|
|
322
|
-
if (i > lastSharedSegmentIndex) {
|
|
323
|
-
remainingRelativeToSegments.push(thisSegments[i]);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
nextSegments.push(
|
|
328
|
-
...remainingRelativeToSegments.map(() => ".."),
|
|
329
|
-
...remainingThisSegments
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (nextSegments[0] !== "..") {
|
|
334
|
-
nextSegments = [".", ...nextSegments];
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const sep = getSeparator(this.raw);
|
|
338
|
-
const raw = safeJoin(nextSegments, sep);
|
|
339
|
-
|
|
340
|
-
return new RelativePath(raw);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
append(...segments: Array<string>): AbsolutePath {
|
|
344
|
-
const normalPath = super.append(...segments);
|
|
345
|
-
return new AbsolutePath(normalPath.raw);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
removeTrailingSlash(): AbsolutePath {
|
|
349
|
-
const normalPath = super.removeTrailingSlash();
|
|
350
|
-
return new AbsolutePath(normalPath.raw);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
resolve(): AbsolutePath {
|
|
354
|
-
const normalPath = super.resolve();
|
|
355
|
-
return new AbsolutePath(normalPath.raw);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
async readdir(
|
|
359
|
-
options?:
|
|
360
|
-
| {
|
|
361
|
-
encoding: string | null;
|
|
362
|
-
}
|
|
363
|
-
| string
|
|
364
|
-
| null
|
|
365
|
-
| undefined
|
|
366
|
-
): Promise<Array<AbsolutePath>> {
|
|
367
|
-
const dirs = await readdirP(this.raw, options);
|
|
368
|
-
// @ts-ignore
|
|
369
|
-
return dirs.map(
|
|
370
|
-
(dir: string | Buffer) =>
|
|
371
|
-
new AbsolutePath(path.join(this.raw, dir.toString("utf-8")))
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
readdirSync(
|
|
376
|
-
options?:
|
|
377
|
-
| {
|
|
378
|
-
encoding: string | null;
|
|
379
|
-
}
|
|
380
|
-
| string
|
|
381
|
-
| null
|
|
382
|
-
| undefined
|
|
383
|
-
): Array<AbsolutePath> {
|
|
384
|
-
const dirs = fs.readdirSync(this.raw, options);
|
|
385
|
-
// @ts-ignore
|
|
386
|
-
return dirs.map(
|
|
387
|
-
(dir: string | Buffer) =>
|
|
388
|
-
new AbsolutePath(path.join(this.raw, dir.toString("utf-8")))
|
|
389
|
-
);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
parentDirectory(): AbsolutePath {
|
|
393
|
-
const segments = getSegments(this.raw);
|
|
394
|
-
const nextSegments = segments.slice(0, -1);
|
|
395
|
-
const nextRaw = reconsistuteAbsolutePath(this.raw, nextSegments);
|
|
396
|
-
|
|
397
|
-
return new AbsolutePath(nextRaw);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
export class RelativePath extends Path<"relative"> {
|
|
402
|
-
constructor(raw: string) {
|
|
403
|
-
super(raw, "relative");
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
toAbsolute(contextDir: AbsolutePath | string) {
|
|
407
|
-
const contextDirPath =
|
|
408
|
-
typeof contextDir === "string"
|
|
409
|
-
? Path.fromAbsolutePathString(contextDir)
|
|
410
|
-
: contextDir;
|
|
411
|
-
|
|
412
|
-
let thisSegments = getSegments(this.raw);
|
|
413
|
-
|
|
414
|
-
let nextSegments = [
|
|
415
|
-
contextDirPath.removeTrailingSlash().raw,
|
|
416
|
-
...thisSegments,
|
|
417
|
-
];
|
|
418
|
-
|
|
419
|
-
return new AbsolutePath(
|
|
420
|
-
safeJoin(nextSegments, getSeparator(contextDirPath.raw))
|
|
421
|
-
).resolve();
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
toUnqualified() {
|
|
425
|
-
const segments = getSegments(this.raw);
|
|
426
|
-
const sep = getSeparator(this.raw);
|
|
427
|
-
|
|
428
|
-
let firstNonRelativeSegmentIndex = 0;
|
|
429
|
-
for (const segment of segments) {
|
|
430
|
-
if (segment === "." || segment === "..") {
|
|
431
|
-
firstNonRelativeSegmentIndex++;
|
|
432
|
-
} else {
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const unqualifiedSegments = segments.slice(firstNonRelativeSegmentIndex);
|
|
438
|
-
const newRaw = safeJoin(unqualifiedSegments, sep);
|
|
439
|
-
return new UnqualifiedPath(newRaw);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
append(...segments: Array<string>): RelativePath {
|
|
443
|
-
const normalPath = super.append(...segments);
|
|
444
|
-
return new RelativePath(normalPath.raw);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
removeTrailingSlash(): RelativePath {
|
|
448
|
-
const normalPath = super.removeTrailingSlash();
|
|
449
|
-
return new RelativePath(normalPath.raw);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
resolve(): RelativePath {
|
|
453
|
-
const normalPath = super.resolve();
|
|
454
|
-
return new RelativePath(normalPath.raw);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
export class UnqualifiedPath extends Path<"unqualified"> {
|
|
459
|
-
constructor(raw: string) {
|
|
460
|
-
super(raw, "unqualified");
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
toAbsolute(contextDir: AbsolutePath | string) {
|
|
464
|
-
const contextDirPath =
|
|
465
|
-
typeof contextDir === "string"
|
|
466
|
-
? Path.fromAbsolutePathString(contextDir)
|
|
467
|
-
: contextDir;
|
|
468
|
-
|
|
469
|
-
let thisSegments = getSegments(this.raw);
|
|
470
|
-
|
|
471
|
-
let nextSegments = [
|
|
472
|
-
contextDirPath.removeTrailingSlash().raw,
|
|
473
|
-
...thisSegments,
|
|
474
|
-
];
|
|
475
|
-
|
|
476
|
-
return new AbsolutePath(
|
|
477
|
-
safeJoin(nextSegments, getSeparator(contextDirPath.raw))
|
|
478
|
-
).resolve();
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
append(...segments: Array<string>): UnqualifiedPath {
|
|
482
|
-
const normalPath = super.append(...segments);
|
|
483
|
-
return new UnqualifiedPath(normalPath.raw);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
prepend(...segments: Array<string>): UnqualifiedPath {
|
|
487
|
-
const sep = getSeparator(this.raw);
|
|
488
|
-
return new UnqualifiedPath(safeJoin([...segments, this.raw], sep));
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
removeTrailingSlash(): UnqualifiedPath {
|
|
492
|
-
const normalPath = super.removeTrailingSlash();
|
|
493
|
-
return new UnqualifiedPath(normalPath.raw);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
resolve(): UnqualifiedPath {
|
|
497
|
-
const normalPath = super.resolve();
|
|
498
|
-
return new UnqualifiedPath(normalPath.raw);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
module.exports = Path;
|
|
503
|
-
module.exports.Path = Path;
|
|
504
|
-
module.exports.AbsolutePath = AbsolutePath;
|
|
505
|
-
module.exports.RelativePath = RelativePath;
|
|
506
|
-
module.exports.UnqualifiedPath = UnqualifiedPath;
|