@north-light/crouter 0.3.245 → 0.3.246
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.
|
@@ -208,8 +208,9 @@ function commaList(arg) {
|
|
|
208
208
|
function shortPath(value) {
|
|
209
209
|
return value.startsWith('/') ? tildify(value) : value;
|
|
210
210
|
}
|
|
211
|
-
// Regex reduction — every real `cwd` gate is an anchored literal path,
|
|
212
|
-
//
|
|
211
|
+
// Regex reduction — every real `cwd` gate is an anchored literal path, whole or
|
|
212
|
+
// followed by one alternation of the projects it covers, and it should read as
|
|
213
|
+
// the directory or directories it means.
|
|
213
214
|
const META = new Set(['\\', '^', '$', '.', '|', '?', '*', '+', '(', ')', '[', ']', '{', '}']);
|
|
214
215
|
/** The pattern as the thing it demands: an anchored literal path collapsed to
|
|
215
216
|
* the directory it names, else the longest literal run it insists on, else an
|
|
@@ -225,6 +226,9 @@ export function readableRegex(source) {
|
|
|
225
226
|
const literal = unescapeLiteral(body);
|
|
226
227
|
if (literal !== null && literal !== '')
|
|
227
228
|
return shortPath(literal);
|
|
229
|
+
const branches = distributeAlternation(body);
|
|
230
|
+
if (branches !== null)
|
|
231
|
+
return branches.map((branch) => shortPath(branch)).join(' or ');
|
|
228
232
|
const run = longestLiteralRun(source);
|
|
229
233
|
return run === null ? 'a pattern' : `contains "${shortPath(run)}"`;
|
|
230
234
|
}
|
|
@@ -249,6 +253,73 @@ function unescapeLiteral(source) {
|
|
|
249
253
|
}
|
|
250
254
|
return out;
|
|
251
255
|
}
|
|
256
|
+
/** The paths a literal prefix followed by ONE alternation group means: each
|
|
257
|
+
* branch appended to the prefix, so the reader is handed directories they can
|
|
258
|
+
* actually be in rather than the prefix they all share. Null when the body is
|
|
259
|
+
* any other shape — a second group, text after the group, or a branch holding
|
|
260
|
+
* a metacharacter outside the glob vocabulary. */
|
|
261
|
+
function distributeAlternation(body) {
|
|
262
|
+
const open = body.indexOf('(');
|
|
263
|
+
if (open === -1 || !body.endsWith(')'))
|
|
264
|
+
return null;
|
|
265
|
+
const prefix = unescapeLiteral(body.slice(0, open));
|
|
266
|
+
if (prefix === null)
|
|
267
|
+
return null;
|
|
268
|
+
let inner = body.slice(open + 1, -1);
|
|
269
|
+
if (inner.startsWith('?:'))
|
|
270
|
+
inner = inner.slice(2);
|
|
271
|
+
// One group only: a nested group is a shape this reduction does not read.
|
|
272
|
+
if (inner.includes('(') || inner.includes(')'))
|
|
273
|
+
return null;
|
|
274
|
+
const branches = inner.split('|');
|
|
275
|
+
if (branches.length < 2)
|
|
276
|
+
return null;
|
|
277
|
+
const paths = [];
|
|
278
|
+
for (const branch of branches) {
|
|
279
|
+
const text = branchText(branch);
|
|
280
|
+
if (text === null)
|
|
281
|
+
return null;
|
|
282
|
+
paths.push(prefix + text);
|
|
283
|
+
}
|
|
284
|
+
return paths;
|
|
285
|
+
}
|
|
286
|
+
/** One branch as plain text, with a whole-segment wildcard rendered as the path
|
|
287
|
+
* glob it means. The vocabulary is exactly `[^/]+` and `.*`; any other
|
|
288
|
+
* metacharacter means the branch is not a path and the whole shape is
|
|
289
|
+
* abandoned. */
|
|
290
|
+
function branchText(branch) {
|
|
291
|
+
let out = '';
|
|
292
|
+
for (let i = 0; i < branch.length; i++) {
|
|
293
|
+
if (branch.startsWith('[^/]+', i)) {
|
|
294
|
+
out += '*';
|
|
295
|
+
i += 4;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (branch.startsWith('[^\\/]+', i)) {
|
|
299
|
+
out += '*';
|
|
300
|
+
i += 5;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (branch.startsWith('.*', i)) {
|
|
304
|
+
out += '*';
|
|
305
|
+
i += 1;
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
const ch = branch[i];
|
|
309
|
+
if (ch === '\\') {
|
|
310
|
+
const next = branch[i + 1];
|
|
311
|
+
if (next === undefined || (!META.has(next) && next !== '/' && next !== '-'))
|
|
312
|
+
return null;
|
|
313
|
+
out += next;
|
|
314
|
+
i++;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (META.has(ch))
|
|
318
|
+
return null;
|
|
319
|
+
out += ch;
|
|
320
|
+
}
|
|
321
|
+
return out;
|
|
322
|
+
}
|
|
252
323
|
/** The longest stretch of characters EVERY string the pattern accepts contains,
|
|
253
324
|
* or null when it guarantees nothing longer than a single character. Only text
|
|
254
325
|
* outside every group and character class counts: a group may be alternated or
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.246",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.246",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|