nice-path 0.1.1 → 3.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 +292 -22
- package/dist/index.d.ts +182 -0
- package/dist/index.js +350 -434
- package/package.json +13 -12
- package/tsconfig.json +3 -2
- package/dist/index.ts +0 -506
package/dist/index.js
CHANGED
|
@@ -1,477 +1,393 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
extendStatics(d, b);
|
|
11
|
-
function __() { this.constructor = d; }
|
|
12
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
13
|
-
};
|
|
14
|
-
})();
|
|
15
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
16
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
17
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
18
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
19
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
20
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
21
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
25
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
26
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
27
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
28
|
-
function step(op) {
|
|
29
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
30
|
-
while (_) try {
|
|
31
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
32
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
33
|
-
switch (op[0]) {
|
|
34
|
-
case 0: case 1: t = op; break;
|
|
35
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
36
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
37
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
38
|
-
default:
|
|
39
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
40
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
41
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
42
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
43
|
-
if (t[2]) _.ops.pop();
|
|
44
|
-
_.trys.pop(); continue;
|
|
45
|
-
}
|
|
46
|
-
op = body.call(thisArg, _);
|
|
47
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
48
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
|
52
|
-
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
53
|
-
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
54
|
-
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
55
|
-
r[k] = a[j];
|
|
56
|
-
return r;
|
|
57
|
-
};
|
|
58
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
59
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
60
|
-
};
|
|
61
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
function aOrAn(nextWord) {
|
|
67
|
-
return /^[aeiou]/i.test(nextWord) ? "an" : "a";
|
|
68
|
-
}
|
|
69
|
-
function pathKindErrorMessage(expected, actual) {
|
|
70
|
-
return "Expected to receive " + aOrAn(expected) + " " + expected + " path, but received " + aOrAn(actual) + " " + actual + " path instead";
|
|
3
|
+
exports.Path = void 0;
|
|
4
|
+
const WIN32_DRIVE_LETTER_REGEXP = /^[A-Za-z]:$/;
|
|
5
|
+
function isWin32DriveLetter(pathString) {
|
|
6
|
+
return WIN32_DRIVE_LETTER_REGEXP.test(pathString);
|
|
71
7
|
}
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
8
|
+
function validateSegments(segments, separator) {
|
|
9
|
+
return segments.filter((part, index) => {
|
|
10
|
+
// first part can be "" to represent left side of root "/"
|
|
11
|
+
// second part can be "" to support windows UNC paths
|
|
12
|
+
if (part === "" && index === 0) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
else if (part === "" &&
|
|
16
|
+
index === 1 &&
|
|
17
|
+
separator === "\\" &&
|
|
18
|
+
segments[0] === "") {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return Boolean(part);
|
|
22
|
+
});
|
|
79
23
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!
|
|
85
|
-
|
|
24
|
+
/** An object that represents a filesystem path. */
|
|
25
|
+
class Path {
|
|
26
|
+
/** Split one or more path strings into an array of path segments. */
|
|
27
|
+
static splitToSegments(inputParts) {
|
|
28
|
+
if (!Array.isArray(inputParts)) {
|
|
29
|
+
inputParts = [inputParts];
|
|
86
30
|
}
|
|
31
|
+
const separator = Path.detectSeparator(inputParts, "/");
|
|
32
|
+
return validateSegments(inputParts.map((part) => part.split(/(?:\/|\\)/g)).flat(1), separator);
|
|
87
33
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
.filter(function (segment) {
|
|
102
|
-
if (pathOrSegmentIndex === 0) {
|
|
103
|
-
return true;
|
|
34
|
+
/**
|
|
35
|
+
* Search the provided path string or strings for a path separator character
|
|
36
|
+
* (either forward slash or backslash), and return it. If none is found,
|
|
37
|
+
* return `fallback`.
|
|
38
|
+
*/
|
|
39
|
+
static detectSeparator(input, fallback) {
|
|
40
|
+
let testStr = input;
|
|
41
|
+
if (Array.isArray(input)) {
|
|
42
|
+
testStr = input.join("|");
|
|
43
|
+
}
|
|
44
|
+
for (const char of testStr) {
|
|
45
|
+
if (char === "/") {
|
|
46
|
+
return "/";
|
|
104
47
|
}
|
|
105
|
-
else {
|
|
106
|
-
return
|
|
48
|
+
else if (char === "\\") {
|
|
49
|
+
return "\\";
|
|
107
50
|
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
});
|
|
111
|
-
return trimmedSegments.join(sep);
|
|
112
|
-
}
|
|
113
|
-
function detectPathKind(pathString) {
|
|
114
|
-
var sep = getSeparator(pathString);
|
|
115
|
-
var segments = getSegments(pathString);
|
|
116
|
-
if (pathString.startsWith(sep) ||
|
|
117
|
-
pathString.startsWith("\\\\") ||
|
|
118
|
-
pathString.match(/^[A-Z]:/i)) {
|
|
119
|
-
return "absolute";
|
|
120
|
-
}
|
|
121
|
-
else if (segments[0] === "." || segments[0] === "..") {
|
|
122
|
-
return "relative";
|
|
51
|
+
}
|
|
52
|
+
return fallback;
|
|
123
53
|
}
|
|
124
|
-
|
|
125
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Concatenates the input path(s) and then resolves all non-leading `.` and
|
|
56
|
+
* `..` segments.
|
|
57
|
+
*/
|
|
58
|
+
static normalize(...inputs) {
|
|
59
|
+
return new Path(...inputs).normalize();
|
|
126
60
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Return whether the provided path is absolute; that is, whether it
|
|
63
|
+
* starts with either `/`, `\`, or a drive letter (ie `C:`).
|
|
64
|
+
*/
|
|
65
|
+
static isAbsolute(path) {
|
|
66
|
+
if (path instanceof Path) {
|
|
67
|
+
return path.isAbsolute();
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return new Path(path).isAbsolute();
|
|
71
|
+
}
|
|
132
72
|
}
|
|
133
|
-
|
|
134
|
-
|
|
73
|
+
/** Create a new Path object using the provided input(s). */
|
|
74
|
+
constructor(...inputs) {
|
|
75
|
+
const parts = inputs
|
|
76
|
+
.flat(1)
|
|
77
|
+
.map((part) => (typeof part === "string" ? part : part.segments))
|
|
78
|
+
.flat(1);
|
|
79
|
+
this.segments = Path.splitToSegments(parts);
|
|
80
|
+
this.separator = Path.detectSeparator(parts, "/");
|
|
135
81
|
}
|
|
136
|
-
|
|
137
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Create a new Path object using the provided segments and, optionally,
|
|
84
|
+
* separator.
|
|
85
|
+
*
|
|
86
|
+
* NOTE: this doesn't set the `segments` directly; it passes them through a
|
|
87
|
+
* filtering step first, to remove any double-slashes or etc. To set the
|
|
88
|
+
* `.segments` directly, use {@link fromRaw}.
|
|
89
|
+
*/
|
|
90
|
+
static from(segments, separator) {
|
|
91
|
+
const separatorToUse = separator || Path.detectSeparator(segments, "/");
|
|
92
|
+
const path = new Path();
|
|
93
|
+
path.segments = validateSegments(segments, separatorToUse);
|
|
94
|
+
path.separator = separatorToUse;
|
|
95
|
+
return path;
|
|
138
96
|
}
|
|
139
|
-
|
|
140
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Create a new Path object using the provided segments and separator.
|
|
99
|
+
*
|
|
100
|
+
* NOTE: this method doesn't do any sort of validation on `segments`; as such,
|
|
101
|
+
* it can be used to construct an invalid Path object. Consider using
|
|
102
|
+
* {@link from} instead.
|
|
103
|
+
*/
|
|
104
|
+
static fromRaw(segments, separator) {
|
|
105
|
+
const path = new Path();
|
|
106
|
+
path.segments = segments;
|
|
107
|
+
path.separator = separator;
|
|
108
|
+
return path;
|
|
141
109
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Resolve all non-leading `.` and `..` segments in this path.
|
|
112
|
+
*/
|
|
113
|
+
normalize() {
|
|
114
|
+
// we clone this cause we're gonna mutate it
|
|
115
|
+
const segments = [...this.segments];
|
|
116
|
+
const newSegments = [];
|
|
117
|
+
let currentSegment;
|
|
118
|
+
while (segments.length > 0) {
|
|
119
|
+
currentSegment = segments.shift();
|
|
120
|
+
switch (currentSegment) {
|
|
121
|
+
case ".": {
|
|
122
|
+
if (newSegments.length === 0) {
|
|
123
|
+
newSegments.push(currentSegment);
|
|
124
|
+
}
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case "..": {
|
|
128
|
+
if (newSegments.length === 0) {
|
|
129
|
+
newSegments.push(currentSegment);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
newSegments.pop();
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
default: {
|
|
137
|
+
if (currentSegment != null) {
|
|
138
|
+
newSegments.push(currentSegment);
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
156
143
|
}
|
|
144
|
+
return Path.fromRaw(newSegments, this.separator);
|
|
157
145
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Create a new Path by appending additional path segments onto the end of
|
|
148
|
+
* this Path's segments.
|
|
149
|
+
*
|
|
150
|
+
* The returned path will use this path's separator.
|
|
151
|
+
*/
|
|
152
|
+
concat(...others) {
|
|
153
|
+
const otherSegments = new Path(others.flat(1)).segments;
|
|
154
|
+
return Path.from(this.segments.concat(otherSegments), this.separator);
|
|
164
155
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Return whether this path is absolute; that is, whether it starts with
|
|
158
|
+
* either `/`, `\`, or a drive letter (ie `C:`).
|
|
159
|
+
*/
|
|
160
|
+
isAbsolute() {
|
|
161
|
+
const firstPart = this.segments[0];
|
|
162
|
+
// empty first component indicates that path starts with leading slash.
|
|
163
|
+
// could be unix fs root, or windows unc path
|
|
164
|
+
if (firstPart === "")
|
|
165
|
+
return true;
|
|
166
|
+
// windows drive
|
|
167
|
+
if (/^[A-Za-z]:/.test(firstPart))
|
|
168
|
+
return true;
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Make a second Path object containing the same segments and separator as
|
|
173
|
+
* this one.
|
|
174
|
+
*/
|
|
175
|
+
clone() {
|
|
176
|
+
const theClone = this.constructor.fromRaw([...this.segments], this.separator);
|
|
177
|
+
return theClone;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Express this path relative to `dir`.
|
|
181
|
+
*
|
|
182
|
+
* @param dir - The directory to create a new path relative to.
|
|
183
|
+
* @param options - Options that affect the resulting path.
|
|
184
|
+
*/
|
|
185
|
+
relativeTo(dir, options = {}) {
|
|
186
|
+
if (!(dir instanceof Path)) {
|
|
187
|
+
dir = new Path(dir);
|
|
179
188
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
throw new Error(pathKindErrorMessage("unqualified", kind));
|
|
189
|
+
const ownSegments = [...this.segments];
|
|
190
|
+
const dirSegments = [...dir.segments];
|
|
191
|
+
while (ownSegments[0] === dirSegments[0]) {
|
|
192
|
+
ownSegments.shift();
|
|
193
|
+
dirSegments.shift();
|
|
186
194
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return new AbsolutePath(raw);
|
|
194
|
-
case "relative":
|
|
195
|
-
return new RelativePath(raw);
|
|
196
|
-
case "unqualified":
|
|
197
|
-
return new UnqualifiedPath(raw);
|
|
198
|
-
default: {
|
|
199
|
-
throw new Error("Unable to detect path type from input string");
|
|
195
|
+
if (dirSegments.length === 0) {
|
|
196
|
+
if (options.noLeadingDot) {
|
|
197
|
+
return Path.from(ownSegments, this.separator);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
return Path.from([".", ...ownSegments], this.separator);
|
|
200
201
|
}
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
Path.prototype.isAbsolute = function () {
|
|
204
|
-
return this.kind === "absolute";
|
|
205
|
-
};
|
|
206
|
-
Path.prototype.isRelative = function () {
|
|
207
|
-
return this.kind === "relative";
|
|
208
|
-
};
|
|
209
|
-
Path.prototype.isUnqualified = function () {
|
|
210
|
-
return this.kind === "unqualified";
|
|
211
|
-
};
|
|
212
|
-
Path.prototype.hasTrailingSlash = function () {
|
|
213
|
-
var sep = getSeparator(this.raw);
|
|
214
|
-
return this.raw.endsWith(sep);
|
|
215
|
-
};
|
|
216
|
-
Path.prototype.removeTrailingSlash = function () {
|
|
217
|
-
if (!this.hasTrailingSlash()) {
|
|
218
|
-
return this;
|
|
219
202
|
}
|
|
220
203
|
else {
|
|
221
|
-
|
|
204
|
+
const dotDots = dirSegments.map((_) => "..");
|
|
205
|
+
return Path.from([...dotDots, ...ownSegments], this.separator);
|
|
222
206
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Turn this path into a string by joining its segments using its separator.
|
|
210
|
+
*/
|
|
211
|
+
toString() {
|
|
212
|
+
let result = this.segments.join(this.separator);
|
|
213
|
+
if (result == "") {
|
|
214
|
+
return "/";
|
|
228
215
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
Path.prototype.resolve = function () {
|
|
233
|
-
var segments = getSegments(this.raw);
|
|
234
|
-
var nextSegments = [];
|
|
235
|
-
for (var i = 0; i < segments.length; i++) {
|
|
236
|
-
var currentSegment = segments[i];
|
|
237
|
-
if (currentSegment === "." && i !== 0) {
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
else if (currentSegment === ".." && nextSegments.length > 0) {
|
|
241
|
-
nextSegments.pop();
|
|
216
|
+
else {
|
|
217
|
+
if (isWin32DriveLetter(result)) {
|
|
218
|
+
return result + this.separator;
|
|
242
219
|
}
|
|
243
220
|
else {
|
|
244
|
-
|
|
221
|
+
return result;
|
|
245
222
|
}
|
|
246
223
|
}
|
|
247
|
-
var nextRaw = reconsistuteAbsolutePath(this.raw, nextSegments);
|
|
248
|
-
return new Path(nextRaw, this.kind);
|
|
249
|
-
};
|
|
250
|
-
return Path;
|
|
251
|
-
}());
|
|
252
|
-
exports.Path = Path;
|
|
253
|
-
var AbsolutePath = /** @class */ (function (_super) {
|
|
254
|
-
__extends(AbsolutePath, _super);
|
|
255
|
-
function AbsolutePath(raw) {
|
|
256
|
-
return _super.call(this, raw, "absolute") || this;
|
|
257
224
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
225
|
+
/**
|
|
226
|
+
* Return the final path segment of this path. If this path has no path
|
|
227
|
+
* segments, the empty string is returned.
|
|
228
|
+
*/
|
|
229
|
+
basename() {
|
|
230
|
+
const last = this.segments[this.segments.length - 1];
|
|
231
|
+
return last || "";
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Return the trailing extension of this path. Set option `full` to `true` to
|
|
235
|
+
* get a compound extension like ".d.ts" instead of ".ts".
|
|
236
|
+
*/
|
|
237
|
+
extname(options = {}) {
|
|
238
|
+
const filename = this.basename();
|
|
239
|
+
const parts = filename.split(".");
|
|
240
|
+
if (parts.length === 1) {
|
|
241
|
+
return "";
|
|
270
242
|
}
|
|
271
|
-
if (
|
|
272
|
-
|
|
273
|
-
this.raw.slice(0, 1).toUpperCase() !==
|
|
274
|
-
relativeToString.slice(0, 1).toUpperCase()) {
|
|
275
|
-
throw new Error("The two paths being compared are not on the same drive; comparing " +
|
|
276
|
-
JSON.stringify(this.raw) +
|
|
277
|
-
" and " +
|
|
278
|
-
JSON.stringify(relativeToString));
|
|
243
|
+
if (options.full) {
|
|
244
|
+
return "." + parts.slice(1).join(".");
|
|
279
245
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (thisRootKind === "unc" &&
|
|
283
|
-
relativeToRootKind === "unc" &&
|
|
284
|
-
thisSegments[0] !== relativeToSegments[0]) {
|
|
285
|
-
throw new Error("The two paths being compared are not on the same UNC host; comparing " +
|
|
286
|
-
JSON.stringify(this.raw) +
|
|
287
|
-
" and " +
|
|
288
|
-
JSON.stringify(relativeToString));
|
|
246
|
+
else {
|
|
247
|
+
return "." + parts[parts.length - 1];
|
|
289
248
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Return a new Path containing all of the path segments in this one except
|
|
252
|
+
* for the last one; ie. the path to the directory that contains this path.
|
|
253
|
+
*/
|
|
254
|
+
dirname() {
|
|
255
|
+
return this.replaceLast([]);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Return whether this path starts with the provided value, by comparing one
|
|
259
|
+
* path segment at a time.
|
|
260
|
+
*
|
|
261
|
+
* The starting segments of this path must *exactly* match the segments in the
|
|
262
|
+
* provided value.
|
|
263
|
+
*
|
|
264
|
+
* This means that, given two Paths A and B:
|
|
265
|
+
*
|
|
266
|
+
* ```
|
|
267
|
+
* A: Path { /home/user/.config }
|
|
268
|
+
* B: Path { /home/user/.config2 }
|
|
269
|
+
* ```
|
|
270
|
+
*
|
|
271
|
+
* Path B does *not* start with Path A, because `".config" !== ".config2"`.
|
|
272
|
+
*/
|
|
273
|
+
startsWith(value) {
|
|
274
|
+
value = new Path(value);
|
|
275
|
+
return value.segments.every((segment, index) => this.segments[index] === segment);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Return whether this path ends with the provided value, by comparing one
|
|
279
|
+
* path segment at a time.
|
|
280
|
+
*
|
|
281
|
+
* The ending segments of this path must *exactly* match the segments in the
|
|
282
|
+
* provided value.
|
|
283
|
+
*
|
|
284
|
+
* This means that, given two Paths A and B:
|
|
285
|
+
*
|
|
286
|
+
* ```
|
|
287
|
+
* A: Path { /home/1user/.config }
|
|
288
|
+
* B: Path { user/.config }
|
|
289
|
+
* ```
|
|
290
|
+
*
|
|
291
|
+
* Path A does *not* end with Path B, because `"1user" !== "user"`.
|
|
292
|
+
*/
|
|
293
|
+
endsWith(value) {
|
|
294
|
+
value = new Path(value);
|
|
295
|
+
const valueSegmentsReversed = [...value.segments].reverse();
|
|
296
|
+
const ownSegmentsReversed = [...this.segments].reverse();
|
|
297
|
+
return valueSegmentsReversed.every((segment, index) => ownSegmentsReversed[index] === segment);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Return the path segment index at which `value` appears in this path, or
|
|
301
|
+
* `-1` if it doesn't appear in this path.
|
|
302
|
+
*
|
|
303
|
+
* @param value - The value to search for. If the value contains more than one path segment, the returned index will refer to the location of the value's first path segment.
|
|
304
|
+
* @param fromIndex - The index into this path's segments to begin searching at. Defaults to `0`.
|
|
305
|
+
*/
|
|
306
|
+
indexOf(value, fromIndex = 0) {
|
|
307
|
+
value = new Path(value);
|
|
308
|
+
const ownSegmentsLength = this.segments.length;
|
|
309
|
+
for (let i = fromIndex; i < ownSegmentsLength; i++) {
|
|
310
|
+
if (value.segments.every((valueSegment, valueIndex) => {
|
|
311
|
+
return this.segments[i + valueIndex] === valueSegment;
|
|
312
|
+
})) {
|
|
313
|
+
return i;
|
|
300
314
|
}
|
|
301
315
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
316
|
+
return -1;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Return whether `value` appears in this path.
|
|
320
|
+
*
|
|
321
|
+
* @param value - The value to search for.
|
|
322
|
+
* @param fromIndex - The index into this path's segments to begin searching at. Defaults to `0`.
|
|
323
|
+
*/
|
|
324
|
+
includes(value, fromIndex = 0) {
|
|
325
|
+
return this.indexOf(value, fromIndex) !== -1;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Return a new Path wherein the segments in `value` have been replaced with
|
|
329
|
+
* the segments in `replacement`. If the segments in `value` are not present
|
|
330
|
+
* in this path, a clone of this path is returned.
|
|
331
|
+
*
|
|
332
|
+
* Note that only the first match is replaced.
|
|
333
|
+
*
|
|
334
|
+
* @param value - What should be replaced
|
|
335
|
+
* @param replacement - What it should be replaced with
|
|
336
|
+
*
|
|
337
|
+
* NOTE: to remove segments, use an empty Array for `replacement`.
|
|
338
|
+
*/
|
|
339
|
+
replace(value, replacement) {
|
|
340
|
+
value = new Path(value);
|
|
341
|
+
replacement = new Path(replacement);
|
|
342
|
+
const matchIndex = this.indexOf(value);
|
|
343
|
+
if (matchIndex === -1) {
|
|
344
|
+
return this.clone();
|
|
307
345
|
}
|
|
308
346
|
else {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
var remainingRelativeToSegments = [];
|
|
316
|
-
for (var i = 0; i < relativeToSegments.length; i++) {
|
|
317
|
-
if (i > lastSharedSegmentIndex) {
|
|
318
|
-
remainingRelativeToSegments.push(thisSegments[i]);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
nextSegments.push.apply(nextSegments, __spreadArrays(remainingRelativeToSegments.map(function () { return ".."; }), remainingThisSegments));
|
|
322
|
-
}
|
|
323
|
-
if (nextSegments[0] !== "..") {
|
|
324
|
-
nextSegments = __spreadArrays(["."], nextSegments);
|
|
347
|
+
const newSegments = [
|
|
348
|
+
...this.segments.slice(0, matchIndex),
|
|
349
|
+
...replacement.segments,
|
|
350
|
+
...this.segments.slice(matchIndex + value.segments.length),
|
|
351
|
+
];
|
|
352
|
+
return Path.from(newSegments, this.separator);
|
|
325
353
|
}
|
|
326
|
-
var sep = getSeparator(this.raw);
|
|
327
|
-
var raw = safeJoin(nextSegments, sep);
|
|
328
|
-
return new RelativePath(raw);
|
|
329
|
-
};
|
|
330
|
-
AbsolutePath.prototype.append = function () {
|
|
331
|
-
var segments = [];
|
|
332
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
333
|
-
segments[_i] = arguments[_i];
|
|
334
|
-
}
|
|
335
|
-
var normalPath = _super.prototype.append.apply(this, segments);
|
|
336
|
-
return new AbsolutePath(normalPath.raw);
|
|
337
|
-
};
|
|
338
|
-
AbsolutePath.prototype.removeTrailingSlash = function () {
|
|
339
|
-
var normalPath = _super.prototype.removeTrailingSlash.call(this);
|
|
340
|
-
return new AbsolutePath(normalPath.raw);
|
|
341
|
-
};
|
|
342
|
-
AbsolutePath.prototype.resolve = function () {
|
|
343
|
-
var normalPath = _super.prototype.resolve.call(this);
|
|
344
|
-
return new AbsolutePath(normalPath.raw);
|
|
345
|
-
};
|
|
346
|
-
AbsolutePath.prototype.readdir = function (options) {
|
|
347
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
348
|
-
var dirs;
|
|
349
|
-
var _this = this;
|
|
350
|
-
return __generator(this, function (_a) {
|
|
351
|
-
switch (_a.label) {
|
|
352
|
-
case 0: return [4 /*yield*/, readdirP(this.raw, options)];
|
|
353
|
-
case 1:
|
|
354
|
-
dirs = _a.sent();
|
|
355
|
-
// @ts-ignore
|
|
356
|
-
return [2 /*return*/, dirs.map(function (dir) {
|
|
357
|
-
return new AbsolutePath(path_1.default.join(_this.raw, dir.toString("utf-8")));
|
|
358
|
-
})];
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
};
|
|
363
|
-
AbsolutePath.prototype.readdirSync = function (options) {
|
|
364
|
-
var _this = this;
|
|
365
|
-
var dirs = fs_1.default.readdirSync(this.raw, options);
|
|
366
|
-
// @ts-ignore
|
|
367
|
-
return dirs.map(function (dir) {
|
|
368
|
-
return new AbsolutePath(path_1.default.join(_this.raw, dir.toString("utf-8")));
|
|
369
|
-
});
|
|
370
|
-
};
|
|
371
|
-
AbsolutePath.prototype.parentDirectory = function () {
|
|
372
|
-
var segments = getSegments(this.raw);
|
|
373
|
-
var nextSegments = segments.slice(0, -1);
|
|
374
|
-
var nextRaw = reconsistuteAbsolutePath(this.raw, nextSegments);
|
|
375
|
-
return new AbsolutePath(nextRaw);
|
|
376
|
-
};
|
|
377
|
-
return AbsolutePath;
|
|
378
|
-
}(Path));
|
|
379
|
-
exports.AbsolutePath = AbsolutePath;
|
|
380
|
-
var RelativePath = /** @class */ (function (_super) {
|
|
381
|
-
__extends(RelativePath, _super);
|
|
382
|
-
function RelativePath(raw) {
|
|
383
|
-
return _super.call(this, raw, "relative") || this;
|
|
384
354
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
firstNonRelativeSegmentIndex++;
|
|
355
|
+
/**
|
|
356
|
+
* Return a new Path wherein all occurrences of the segments in `value` have
|
|
357
|
+
* been replaced with the segments in `replacement`. If the segments in
|
|
358
|
+
* `value` are not present in this path, a clone of this path is returned.
|
|
359
|
+
*
|
|
360
|
+
* @param value - What should be replaced
|
|
361
|
+
* @param replacement - What it should be replaced with
|
|
362
|
+
*/
|
|
363
|
+
replaceAll(value, replacement) {
|
|
364
|
+
replacement = new Path(replacement);
|
|
365
|
+
let searchIndex = 0;
|
|
366
|
+
let currentPath = this;
|
|
367
|
+
const ownLength = this.segments.length;
|
|
368
|
+
while (searchIndex < ownLength) {
|
|
369
|
+
const matchingIndex = this.indexOf(value, searchIndex);
|
|
370
|
+
if (matchingIndex === -1) {
|
|
371
|
+
break;
|
|
403
372
|
}
|
|
404
373
|
else {
|
|
405
|
-
|
|
374
|
+
currentPath = currentPath.replace(value, replacement);
|
|
375
|
+
searchIndex = matchingIndex + replacement.segments.length;
|
|
406
376
|
}
|
|
407
377
|
}
|
|
408
|
-
|
|
409
|
-
var newRaw = safeJoin(unqualifiedSegments, sep);
|
|
410
|
-
return new UnqualifiedPath(newRaw);
|
|
411
|
-
};
|
|
412
|
-
RelativePath.prototype.append = function () {
|
|
413
|
-
var segments = [];
|
|
414
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
415
|
-
segments[_i] = arguments[_i];
|
|
416
|
-
}
|
|
417
|
-
var normalPath = _super.prototype.append.apply(this, segments);
|
|
418
|
-
return new RelativePath(normalPath.raw);
|
|
419
|
-
};
|
|
420
|
-
RelativePath.prototype.removeTrailingSlash = function () {
|
|
421
|
-
var normalPath = _super.prototype.removeTrailingSlash.call(this);
|
|
422
|
-
return new RelativePath(normalPath.raw);
|
|
423
|
-
};
|
|
424
|
-
RelativePath.prototype.resolve = function () {
|
|
425
|
-
var normalPath = _super.prototype.resolve.call(this);
|
|
426
|
-
return new RelativePath(normalPath.raw);
|
|
427
|
-
};
|
|
428
|
-
return RelativePath;
|
|
429
|
-
}(Path));
|
|
430
|
-
exports.RelativePath = RelativePath;
|
|
431
|
-
var UnqualifiedPath = /** @class */ (function (_super) {
|
|
432
|
-
__extends(UnqualifiedPath, _super);
|
|
433
|
-
function UnqualifiedPath(raw) {
|
|
434
|
-
return _super.call(this, raw, "unqualified") || this;
|
|
378
|
+
return currentPath;
|
|
435
379
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
]
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}
|
|
451
|
-
var normalPath = _super.prototype.append.apply(this, segments);
|
|
452
|
-
return new UnqualifiedPath(normalPath.raw);
|
|
453
|
-
};
|
|
454
|
-
UnqualifiedPath.prototype.prepend = function () {
|
|
455
|
-
var segments = [];
|
|
456
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
457
|
-
segments[_i] = arguments[_i];
|
|
458
|
-
}
|
|
459
|
-
var sep = getSeparator(this.raw);
|
|
460
|
-
return new UnqualifiedPath(safeJoin(__spreadArrays(segments, [this.raw]), sep));
|
|
461
|
-
};
|
|
462
|
-
UnqualifiedPath.prototype.removeTrailingSlash = function () {
|
|
463
|
-
var normalPath = _super.prototype.removeTrailingSlash.call(this);
|
|
464
|
-
return new UnqualifiedPath(normalPath.raw);
|
|
465
|
-
};
|
|
466
|
-
UnqualifiedPath.prototype.resolve = function () {
|
|
467
|
-
var normalPath = _super.prototype.resolve.call(this);
|
|
468
|
-
return new UnqualifiedPath(normalPath.raw);
|
|
469
|
-
};
|
|
470
|
-
return UnqualifiedPath;
|
|
471
|
-
}(Path));
|
|
472
|
-
exports.UnqualifiedPath = UnqualifiedPath;
|
|
473
|
-
module.exports = Path;
|
|
474
|
-
module.exports.Path = Path;
|
|
475
|
-
module.exports.AbsolutePath = AbsolutePath;
|
|
476
|
-
module.exports.RelativePath = RelativePath;
|
|
477
|
-
module.exports.UnqualifiedPath = UnqualifiedPath;
|
|
380
|
+
/**
|
|
381
|
+
* Return a copy of this path but with the final segment replaced with `replacement`
|
|
382
|
+
*
|
|
383
|
+
* @param replacement - The new final segment(s) for the returned Path
|
|
384
|
+
*/
|
|
385
|
+
replaceLast(replacement) {
|
|
386
|
+
replacement = new Path(replacement);
|
|
387
|
+
const segments = [...this.segments];
|
|
388
|
+
segments.pop();
|
|
389
|
+
segments.push(...replacement.segments);
|
|
390
|
+
return Path.from(segments, this.separator);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
exports.Path = Path;
|