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/dist/index.js
CHANGED
|
@@ -1,477 +1,372 @@
|
|
|
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";
|
|
51
|
+
}
|
|
52
|
+
return fallback;
|
|
120
53
|
}
|
|
121
|
-
|
|
122
|
-
|
|
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();
|
|
123
60
|
}
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
}
|
|
126
72
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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, "/");
|
|
132
81
|
}
|
|
133
|
-
|
|
134
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Create a new Path object using the provided segments and separator.
|
|
84
|
+
*/
|
|
85
|
+
static fromRaw(segments, separator) {
|
|
86
|
+
const path = new Path();
|
|
87
|
+
path.segments = validateSegments(segments, separator);
|
|
88
|
+
path.separator = separator;
|
|
89
|
+
return path;
|
|
135
90
|
}
|
|
136
|
-
|
|
137
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Resolve all non-leading `.` and `..` segments in this path.
|
|
93
|
+
*/
|
|
94
|
+
normalize() {
|
|
95
|
+
// we clone this cause we're gonna mutate it
|
|
96
|
+
const segments = [...this.segments];
|
|
97
|
+
const newSegments = [];
|
|
98
|
+
let currentSegment;
|
|
99
|
+
while (segments.length > 0) {
|
|
100
|
+
currentSegment = segments.shift();
|
|
101
|
+
switch (currentSegment) {
|
|
102
|
+
case ".": {
|
|
103
|
+
if (newSegments.length === 0) {
|
|
104
|
+
newSegments.push(currentSegment);
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "..": {
|
|
109
|
+
if (newSegments.length === 0) {
|
|
110
|
+
newSegments.push(currentSegment);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
newSegments.pop();
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
default: {
|
|
118
|
+
if (currentSegment != null) {
|
|
119
|
+
newSegments.push(currentSegment);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return Path.fromRaw(newSegments, this.separator);
|
|
138
126
|
}
|
|
139
|
-
|
|
140
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Create a new Path by appending additional path segments onto the end of
|
|
129
|
+
* this Path's segments.
|
|
130
|
+
*
|
|
131
|
+
* The returned path will use this path's separator.
|
|
132
|
+
*/
|
|
133
|
+
concat(...others) {
|
|
134
|
+
const otherSegments = new Path(others.flat(1)).segments;
|
|
135
|
+
return Path.fromRaw(this.segments.concat(otherSegments), this.separator);
|
|
141
136
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
137
|
+
/**
|
|
138
|
+
* Return whether this path is absolute; that is, whether it starts with
|
|
139
|
+
* either `/`, `\`, or a drive letter (ie `C:`).
|
|
140
|
+
*/
|
|
141
|
+
isAbsolute() {
|
|
142
|
+
const firstPart = this.segments[0];
|
|
143
|
+
// empty first component indicates that path starts with leading slash.
|
|
144
|
+
// could be unix fs root, or windows unc path
|
|
145
|
+
if (firstPart === "")
|
|
146
|
+
return true;
|
|
147
|
+
// windows drive
|
|
148
|
+
if (/^[A-Za-z]:/.test(firstPart))
|
|
149
|
+
return true;
|
|
150
|
+
return false;
|
|
157
151
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.
|
|
152
|
+
/**
|
|
153
|
+
* Make a second Path object containing the same segments and separator as
|
|
154
|
+
* this one.
|
|
155
|
+
*/
|
|
156
|
+
clone() {
|
|
157
|
+
const theClone = this.constructor.fromRaw(this.segments, this.separator);
|
|
158
|
+
return theClone;
|
|
164
159
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
};
|
|
175
|
-
Path.fromRelativePathString = function (relativePath) {
|
|
176
|
-
var kind = detectPathKind(relativePath);
|
|
177
|
-
if (kind !== "relative") {
|
|
178
|
-
throw new Error(pathKindErrorMessage("relative", kind));
|
|
160
|
+
/**
|
|
161
|
+
* Express this path relative to `dir`.
|
|
162
|
+
*
|
|
163
|
+
* @param dir - The directory to create a new path relative to.
|
|
164
|
+
* @param options - Options that affect the resulting path.
|
|
165
|
+
*/
|
|
166
|
+
relativeTo(dir, options = {}) {
|
|
167
|
+
if (!(dir instanceof Path)) {
|
|
168
|
+
dir = new Path(dir);
|
|
179
169
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
throw new Error(pathKindErrorMessage("unqualified", kind));
|
|
170
|
+
const ownSegments = [...this.segments];
|
|
171
|
+
const dirSegments = [...dir.segments];
|
|
172
|
+
while (ownSegments[0] === dirSegments[0]) {
|
|
173
|
+
ownSegments.shift();
|
|
174
|
+
dirSegments.shift();
|
|
186
175
|
}
|
|
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");
|
|
176
|
+
if (dirSegments.length === 0) {
|
|
177
|
+
if (options.noLeadingDot) {
|
|
178
|
+
return Path.fromRaw(ownSegments, this.separator);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
return Path.fromRaw([".", ...ownSegments], this.separator);
|
|
200
182
|
}
|
|
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
183
|
}
|
|
220
184
|
else {
|
|
221
|
-
|
|
185
|
+
const dotDots = dirSegments.map((_) => "..");
|
|
186
|
+
return Path.fromRaw([...dotDots, ...ownSegments], this.separator);
|
|
222
187
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Turn this path into a string by joining its segments using its separator.
|
|
191
|
+
*/
|
|
192
|
+
toString() {
|
|
193
|
+
let result = this.segments.join(this.separator);
|
|
194
|
+
if (result == "") {
|
|
195
|
+
return "/";
|
|
228
196
|
}
|
|
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();
|
|
197
|
+
else {
|
|
198
|
+
if (isWin32DriveLetter(result)) {
|
|
199
|
+
return result + this.separator;
|
|
242
200
|
}
|
|
243
201
|
else {
|
|
244
|
-
|
|
202
|
+
return result;
|
|
245
203
|
}
|
|
246
204
|
}
|
|
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
205
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Return the final path segment of this path. If this path has no path
|
|
208
|
+
* segments, the empty string is returned.
|
|
209
|
+
*/
|
|
210
|
+
basename() {
|
|
211
|
+
const last = this.segments[this.segments.length - 1];
|
|
212
|
+
return last || "";
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Return the trailing extension of this path. Set option `full` to `true` to
|
|
216
|
+
* get a compound extension like ".d.ts" instead of ".ts".
|
|
217
|
+
*/
|
|
218
|
+
extname(options = {}) {
|
|
219
|
+
const filename = this.basename();
|
|
220
|
+
const parts = filename.split(".");
|
|
221
|
+
if (parts.length === 1) {
|
|
222
|
+
return "";
|
|
270
223
|
}
|
|
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));
|
|
224
|
+
if (options.full) {
|
|
225
|
+
return "." + parts.slice(1).join(".");
|
|
279
226
|
}
|
|
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));
|
|
227
|
+
else {
|
|
228
|
+
return "." + parts[parts.length - 1];
|
|
289
229
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Return a new Path containing all of the path segments in this one except
|
|
233
|
+
* for the last one; ie. the path to the directory that contains this path.
|
|
234
|
+
*/
|
|
235
|
+
dirname() {
|
|
236
|
+
return this.replaceLast([]);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Return whether this path starts with the provided value, by comparing one
|
|
240
|
+
* path segment at a time.
|
|
241
|
+
*
|
|
242
|
+
* The starting segments of this path must *exactly* match the segments in the
|
|
243
|
+
* provided value.
|
|
244
|
+
*
|
|
245
|
+
* This means that, given two Paths A and B:
|
|
246
|
+
*
|
|
247
|
+
* ```
|
|
248
|
+
* A: Path { /home/user/.config }
|
|
249
|
+
* B: Path { /home/user/.config2 }
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* Path B does *not* start with Path A, because `".config" !== ".config2"`.
|
|
253
|
+
*/
|
|
254
|
+
startsWith(value) {
|
|
255
|
+
value = new Path(value);
|
|
256
|
+
return value.segments.every((segment, index) => this.segments[index] === segment);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Return whether this path ends with the provided value, by comparing one
|
|
260
|
+
* path segment at a time.
|
|
261
|
+
*
|
|
262
|
+
* The ending segments of this path must *exactly* match the segments in the
|
|
263
|
+
* provided value.
|
|
264
|
+
*
|
|
265
|
+
* This means that, given two Paths A and B:
|
|
266
|
+
*
|
|
267
|
+
* ```
|
|
268
|
+
* A: Path { /home/1user/.config }
|
|
269
|
+
* B: Path { user/.config }
|
|
270
|
+
* ```
|
|
271
|
+
*
|
|
272
|
+
* Path A does *not* end with Path B, because `"1user" !== "user"`.
|
|
273
|
+
*/
|
|
274
|
+
endsWith(value) {
|
|
275
|
+
value = new Path(value);
|
|
276
|
+
const valueSegmentsReversed = [...value.segments].reverse();
|
|
277
|
+
const ownSegmentsReversed = [...this.segments].reverse();
|
|
278
|
+
return valueSegmentsReversed.every((segment, index) => ownSegmentsReversed[index] === segment);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Return the path segment index at which `value` appears in this path, or
|
|
282
|
+
* `-1` if it doesn't appear in this path.
|
|
283
|
+
*
|
|
284
|
+
* @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.
|
|
285
|
+
* @param fromIndex - The index into this path's segments to begin searching at. Defaults to `0`.
|
|
286
|
+
*/
|
|
287
|
+
indexOf(value, fromIndex = 0) {
|
|
288
|
+
value = new Path(value);
|
|
289
|
+
const ownSegmentsLength = this.segments.length;
|
|
290
|
+
for (let i = fromIndex; i < ownSegmentsLength; i++) {
|
|
291
|
+
if (value.segments.every((valueSegment, valueIndex) => {
|
|
292
|
+
return this.segments[i + valueIndex] === valueSegment;
|
|
293
|
+
})) {
|
|
294
|
+
return i;
|
|
300
295
|
}
|
|
301
296
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
return -1;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Return whether `value` appears in this path.
|
|
301
|
+
*
|
|
302
|
+
* @param value - The value to search for.
|
|
303
|
+
* @param fromIndex - The index into this path's segments to begin searching at. Defaults to `0`.
|
|
304
|
+
*/
|
|
305
|
+
includes(value, fromIndex = 0) {
|
|
306
|
+
return this.indexOf(value, fromIndex) !== -1;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Return a new Path wherein the segments in `value` have been replaced with
|
|
310
|
+
* the segments in `replacement`. If the segments in `value` are not present
|
|
311
|
+
* in this path, a clone of this path is returned.
|
|
312
|
+
*
|
|
313
|
+
* Note that only the first match is replaced.
|
|
314
|
+
*
|
|
315
|
+
* @param value - What should be replaced
|
|
316
|
+
* @param replacement - What it should be replaced with
|
|
317
|
+
*/
|
|
318
|
+
replace(value, replacement) {
|
|
319
|
+
value = new Path(value);
|
|
320
|
+
replacement = new Path(replacement);
|
|
321
|
+
const matchIndex = this.indexOf(value);
|
|
322
|
+
if (matchIndex === -1) {
|
|
323
|
+
return this.clone();
|
|
307
324
|
}
|
|
308
325
|
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));
|
|
326
|
+
const newSegments = [
|
|
327
|
+
...this.segments.slice(0, matchIndex),
|
|
328
|
+
...replacement.segments,
|
|
329
|
+
...this.segments.slice(matchIndex + value.segments.length),
|
|
330
|
+
];
|
|
331
|
+
return Path.fromRaw(newSegments, this.separator);
|
|
322
332
|
}
|
|
323
|
-
if (nextSegments[0] !== "..") {
|
|
324
|
-
nextSegments = __spreadArrays(["."], nextSegments);
|
|
325
|
-
}
|
|
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
333
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
firstNonRelativeSegmentIndex++;
|
|
334
|
+
/**
|
|
335
|
+
* Return a new Path wherein all occurrences of the segments in `value` have
|
|
336
|
+
* been replaced with the segments in `replacement`. If the segments in
|
|
337
|
+
* `value` are not present in this path, a clone of this path is returned.
|
|
338
|
+
*
|
|
339
|
+
* @param value - What should be replaced
|
|
340
|
+
* @param replacement - What it should be replaced with
|
|
341
|
+
*/
|
|
342
|
+
replaceAll(value, replacement) {
|
|
343
|
+
replacement = new Path(replacement);
|
|
344
|
+
let searchIndex = 0;
|
|
345
|
+
let currentPath = this;
|
|
346
|
+
const ownLength = this.segments.length;
|
|
347
|
+
while (searchIndex < ownLength) {
|
|
348
|
+
const matchingIndex = this.indexOf(value, searchIndex);
|
|
349
|
+
if (matchingIndex === -1) {
|
|
350
|
+
break;
|
|
403
351
|
}
|
|
404
352
|
else {
|
|
405
|
-
|
|
353
|
+
currentPath = currentPath.replace(value, replacement);
|
|
354
|
+
searchIndex = matchingIndex + replacement.segments.length;
|
|
406
355
|
}
|
|
407
356
|
}
|
|
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;
|
|
357
|
+
return currentPath;
|
|
435
358
|
}
|
|
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;
|
|
359
|
+
/**
|
|
360
|
+
* Return a copy of this path but with the final segment replaced with `replacement`
|
|
361
|
+
*
|
|
362
|
+
* @param replacement - The new final segment(s) for the returned Path
|
|
363
|
+
*/
|
|
364
|
+
replaceLast(replacement) {
|
|
365
|
+
replacement = new Path(replacement);
|
|
366
|
+
const segments = [...this.segments];
|
|
367
|
+
segments.pop();
|
|
368
|
+
segments.push(...replacement.segments);
|
|
369
|
+
return Path.fromRaw(segments, this.separator);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
exports.Path = Path;
|