@expo/metro-file-map 56.0.2 → 56.0.3
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/build/lib/TreeFS.js +214 -185
- package/package.json +2 -2
package/build/lib/TreeFS.js
CHANGED
|
@@ -18,11 +18,14 @@ const normalizePathSeparatorsToPosix_1 = __importDefault(require("./normalizePat
|
|
|
18
18
|
const normalizePathSeparatorsToSystem_1 = __importDefault(require("./normalizePathSeparatorsToSystem"));
|
|
19
19
|
const fallback_1 = require("../crawlers/node/fallback");
|
|
20
20
|
function isDirectory(node) {
|
|
21
|
-
return node
|
|
21
|
+
return node != null && typeof node.get === 'function';
|
|
22
22
|
}
|
|
23
23
|
function isRegularFile(node) {
|
|
24
24
|
return node != null && node[constants_1.default.SYMLINK] === 0;
|
|
25
25
|
}
|
|
26
|
+
// POSIX SYMLOOP_MAX. Bounded counter instead of a per-walk `Set` of
|
|
27
|
+
// visited targets — cycles are rare; bailing after N follows is enough.
|
|
28
|
+
const SYMLOOP_MAX = 40;
|
|
26
29
|
/**
|
|
27
30
|
* OVERVIEW:
|
|
28
31
|
*
|
|
@@ -81,6 +84,32 @@ class TreeFS {
|
|
|
81
84
|
#rootPattern;
|
|
82
85
|
#roots;
|
|
83
86
|
#rootNode = new Map();
|
|
87
|
+
#followScratch = {
|
|
88
|
+
parentNode: new Map(),
|
|
89
|
+
ancestorOfRootIdx: undefined,
|
|
90
|
+
targetNormalPath: '',
|
|
91
|
+
fromIdx: 0,
|
|
92
|
+
unseenPathFromIdx: 0,
|
|
93
|
+
followedSymlinks: 0,
|
|
94
|
+
};
|
|
95
|
+
// Hier isn't recursive; pool entries are mutated in place per call.
|
|
96
|
+
#hierAncestorsBuf = [];
|
|
97
|
+
#hierAncestorsPool = [];
|
|
98
|
+
#pushHierAncestor = (node, normalPath, segmentName, ancestorOfRootIdx) => {
|
|
99
|
+
const i = this.#hierAncestorsBuf.length;
|
|
100
|
+
let entry = this.#hierAncestorsPool[i];
|
|
101
|
+
if (entry === undefined) {
|
|
102
|
+
entry = { ancestorOfRootIdx, node, normalPath, segmentName };
|
|
103
|
+
this.#hierAncestorsPool[i] = entry;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
entry.ancestorOfRootIdx = ancestorOfRootIdx;
|
|
107
|
+
entry.node = node;
|
|
108
|
+
entry.normalPath = normalPath;
|
|
109
|
+
entry.segmentName = segmentName;
|
|
110
|
+
}
|
|
111
|
+
this.#hierAncestorsBuf.push(entry);
|
|
112
|
+
};
|
|
84
113
|
constructor(opts) {
|
|
85
114
|
const { rootDir, files, processFile, fallbackFilesystem, roots, serverRoot } = opts;
|
|
86
115
|
this.#rootDir = rootDir;
|
|
@@ -468,15 +497,151 @@ class TreeFS {
|
|
|
468
497
|
* `opts.X` branches. Thin convenience wrappers below (`#lookup`,
|
|
469
498
|
* `#lookupNoFollow`, `#lookupFromNode`, `#walkAndStream`) cover the
|
|
470
499
|
* common call shapes.
|
|
500
|
+
*
|
|
501
|
+
* Symlink-follow logic is shared via `#followSymlink`.
|
|
502
|
+
*/
|
|
503
|
+
/**
|
|
504
|
+
* For `..`-prefixed symlink targets: match remainder's leading segments
|
|
505
|
+
* against root parts (`/A/B/C/D` + remainder `B/C/foo.js` collapses two
|
|
506
|
+
* `..`s away). TreeFS has no downward back-links, so we climb up once
|
|
507
|
+
* from `#rootNode` to build a stack, then index into it.
|
|
471
508
|
*/
|
|
472
|
-
#
|
|
473
|
-
|
|
509
|
+
#collapseAgainstRootParts(ancestorOfRootIdx, parentNode, remainder, onSegment) {
|
|
510
|
+
const ancestors = [this.#rootNode];
|
|
511
|
+
{
|
|
512
|
+
let n = this.#rootNode;
|
|
513
|
+
for (let k = 1; k <= ancestorOfRootIdx; k++) {
|
|
514
|
+
n = n.get('..') ?? new Map();
|
|
515
|
+
if (!isDirectory(n))
|
|
516
|
+
break;
|
|
517
|
+
ancestors.push(n);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
const rootParts = this.#pathUtils.getParts();
|
|
521
|
+
let cursorIdx = 0;
|
|
522
|
+
// Trimmed by `'/..'` per step; `'..'.slice(0, -3) === ''` covers K=1→0.
|
|
523
|
+
let collapsedPath;
|
|
524
|
+
while (ancestorOfRootIdx > 0 &&
|
|
525
|
+
cursorIdx < remainder.length &&
|
|
526
|
+
ancestors.length > ancestorOfRootIdx - 1) {
|
|
527
|
+
const nextSep = remainder.indexOf(path_1.default.sep, cursorIdx);
|
|
528
|
+
const segEnd = nextSep === -1 ? remainder.length : nextSep;
|
|
529
|
+
const segName = remainder.slice(cursorIdx, segEnd);
|
|
530
|
+
const expectedPart = rootParts[rootParts.length - ancestorOfRootIdx];
|
|
531
|
+
if (segName !== expectedPart) {
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
ancestorOfRootIdx--;
|
|
535
|
+
parentNode = ancestors[ancestorOfRootIdx];
|
|
536
|
+
cursorIdx = nextSep === -1 ? remainder.length : nextSep + 1;
|
|
537
|
+
if (onSegment != null) {
|
|
538
|
+
if (collapsedPath === undefined) {
|
|
539
|
+
collapsedPath = '';
|
|
540
|
+
for (let k = 0; k < ancestorOfRootIdx; k++) {
|
|
541
|
+
collapsedPath = k === 0 ? '..' : collapsedPath + path_1.default.sep + '..';
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
collapsedPath = collapsedPath.slice(0, -3);
|
|
546
|
+
}
|
|
547
|
+
onSegment(parentNode, collapsedPath, segName, ancestorOfRootIdx);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return { ancestorOfRootIdx, parentNode, cursorIdx };
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Resolve an interior symlink. Returns a `WalkResult` to return
|
|
554
|
+
* immediately, or `undefined` after writing continue-state to
|
|
555
|
+
* `#followScratch` for the caller to read.
|
|
556
|
+
*/
|
|
557
|
+
#followSymlink(symlinkNode, currentPath, segmentName, remainingTargetPath, followedSymlinks, onSegment, collectLinkPaths) {
|
|
558
|
+
const normalSymlinkTarget = this.#resolveSymlinkTargetToNormalPath(symlinkNode, currentPath);
|
|
559
|
+
if (normalSymlinkTarget == null) {
|
|
560
|
+
return {
|
|
561
|
+
canonicalMissingPath: currentPath,
|
|
562
|
+
exists: false,
|
|
563
|
+
missingSegmentName: segmentName,
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
else if (++followedSymlinks >= SYMLOOP_MAX) {
|
|
567
|
+
return {
|
|
568
|
+
canonicalMissingPath: normalSymlinkTarget,
|
|
569
|
+
exists: false,
|
|
570
|
+
missingSegmentName: segmentName,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
else if (collectLinkPaths != null) {
|
|
574
|
+
collectLinkPaths.add(this.#pathUtils.normalToAbsolute(currentPath));
|
|
575
|
+
}
|
|
576
|
+
// `onSegment: undefined` so target's interior dirs aren't emitted;
|
|
577
|
+
// only the destination is emitted (manually, below).
|
|
578
|
+
const subResult = this.#walkLookup(this.#rootNode, 0, 0, normalSymlinkTarget, undefined, collectLinkPaths, followedSymlinks);
|
|
579
|
+
if (!subResult.exists || remainingTargetPath === '') {
|
|
580
|
+
return subResult;
|
|
581
|
+
}
|
|
582
|
+
else if (!isDirectory(subResult.node)) {
|
|
583
|
+
return {
|
|
584
|
+
exists: false,
|
|
585
|
+
canonicalMissingPath: subResult.canonicalPath,
|
|
586
|
+
missingSegmentName: segmentName,
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
let parentNode = subResult.node;
|
|
590
|
+
let ancestorOfRootIdx = subResult.ancestorOfRootIdx;
|
|
591
|
+
if (onSegment != null) {
|
|
592
|
+
const subBaseStart = subResult.canonicalPath.lastIndexOf(path_1.default.sep) + 1;
|
|
593
|
+
const subBaseName = subResult.canonicalPath.slice(subBaseStart);
|
|
594
|
+
onSegment(parentNode, subResult.canonicalPath, subBaseName, ancestorOfRootIdx);
|
|
595
|
+
}
|
|
596
|
+
let cursorIdx = 0;
|
|
597
|
+
if (ancestorOfRootIdx != null && ancestorOfRootIdx > 0) {
|
|
598
|
+
const collapsed = this.#collapseAgainstRootParts(ancestorOfRootIdx, parentNode, remainingTargetPath, onSegment);
|
|
599
|
+
ancestorOfRootIdx = collapsed.ancestorOfRootIdx;
|
|
600
|
+
parentNode = collapsed.parentNode;
|
|
601
|
+
cursorIdx = collapsed.cursorIdx;
|
|
602
|
+
}
|
|
603
|
+
// Canonical-to-parentNode: `..`-string above root, empty at root, or
|
|
604
|
+
// sub-walk's canonical path inside the tree.
|
|
605
|
+
const realRemainder = remainingTargetPath.slice(cursorIdx);
|
|
606
|
+
let canonicalToParent;
|
|
607
|
+
if (ancestorOfRootIdx != null && ancestorOfRootIdx > 0) {
|
|
608
|
+
canonicalToParent = '..';
|
|
609
|
+
for (let k = 1; k < ancestorOfRootIdx; k++) {
|
|
610
|
+
canonicalToParent += path_1.default.sep + '..';
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
else if (ancestorOfRootIdx === 0) {
|
|
614
|
+
canonicalToParent = '';
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
canonicalToParent = subResult.canonicalPath;
|
|
618
|
+
}
|
|
619
|
+
const scratch = this.#followScratch;
|
|
620
|
+
scratch.parentNode = parentNode;
|
|
621
|
+
scratch.ancestorOfRootIdx = ancestorOfRootIdx;
|
|
622
|
+
scratch.followedSymlinks = followedSymlinks;
|
|
623
|
+
if (canonicalToParent === '') {
|
|
624
|
+
scratch.targetNormalPath = realRemainder;
|
|
625
|
+
scratch.fromIdx = 0;
|
|
626
|
+
scratch.unseenPathFromIdx = 0;
|
|
627
|
+
}
|
|
628
|
+
else if (realRemainder === '') {
|
|
629
|
+
scratch.targetNormalPath = canonicalToParent;
|
|
630
|
+
scratch.fromIdx = canonicalToParent.length;
|
|
631
|
+
scratch.unseenPathFromIdx = canonicalToParent.length;
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
scratch.targetNormalPath = canonicalToParent + path_1.default.sep + realRemainder;
|
|
635
|
+
scratch.fromIdx = canonicalToParent.length + 1;
|
|
636
|
+
scratch.unseenPathFromIdx = canonicalToParent.length + 1;
|
|
637
|
+
}
|
|
638
|
+
return undefined;
|
|
639
|
+
}
|
|
640
|
+
#walkLookup(startNode, startPathIdx, startAncestorOfRootIdx, requestedNormalPath, onSegment, collectLinkPaths, initialFollows) {
|
|
641
|
+
// Cycle counter as a local — faster than an instance-field read in
|
|
642
|
+
// the per-segment loop. Recursive sub-walk inherits via `initialFollows`.
|
|
474
643
|
let targetNormalPath = requestedNormalPath;
|
|
475
|
-
|
|
476
|
-
let seen;
|
|
477
|
-
// Set when a symlink is followed, to allow fallback population outside
|
|
478
|
-
// the boundary for paths reachable transitively through symlinks.
|
|
479
|
-
let followedSymlink = false;
|
|
644
|
+
let followedSymlinks = initialFollows;
|
|
480
645
|
let fromIdx = startPathIdx;
|
|
481
646
|
let parentNode = startNode;
|
|
482
647
|
let ancestorOfRootIdx = startAncestorOfRootIdx;
|
|
@@ -508,7 +673,7 @@ class TreeFS {
|
|
|
508
673
|
? fromIdx - segmentName.length - 1
|
|
509
674
|
: fromIdx - segmentName.length - 2;
|
|
510
675
|
const parentCanonicalPath = parentEnd > 0 ? targetNormalPath.slice(0, parentEnd) : '';
|
|
511
|
-
segmentNode = this.#populateFromFilesystem(parentNode, segmentName, parentCanonicalPath,
|
|
676
|
+
segmentNode = this.#populateFromFilesystem(parentNode, segmentName, parentCanonicalPath, followedSymlinks > 0);
|
|
512
677
|
if (segmentNode != null) {
|
|
513
678
|
ancestorOfRootIdx = undefined;
|
|
514
679
|
}
|
|
@@ -567,87 +732,17 @@ class TreeFS {
|
|
|
567
732
|
missingSegmentName: segmentName,
|
|
568
733
|
};
|
|
569
734
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
return {
|
|
574
|
-
canonicalMissingPath: currentPath,
|
|
575
|
-
exists: false,
|
|
576
|
-
missingSegmentName: segmentName,
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
if (collectLinkPaths != null) {
|
|
580
|
-
collectLinkPaths.add(this.#pathUtils.normalToAbsolute(currentPath));
|
|
581
|
-
}
|
|
582
|
-
const remainingTargetPath = isLastSegment ? '' : targetNormalPath.slice(fromIdx);
|
|
583
|
-
// Append any subsequent path segments to the symlink target, and reset
|
|
584
|
-
// with our new target.
|
|
585
|
-
const joinedResult = this.#pathUtils.joinNormalToRelative(normalSymlinkTarget, remainingTargetPath);
|
|
586
|
-
targetNormalPath = joinedResult.normalPath;
|
|
587
|
-
// Two special cases (covered by unit tests):
|
|
588
|
-
//
|
|
589
|
-
// If the symlink target is the root, the root should be counted as an
|
|
590
|
-
// ancestor. We'd otherwise miss it because new ancestors are only
|
|
591
|
-
// streamed when entering a directory.
|
|
592
|
-
//
|
|
593
|
-
// If the symlink target is an ancestor of the root *and* joining it
|
|
594
|
-
// with the remaining path results in collapsing segments, e.g:
|
|
595
|
-
// '../..' + 'parentofroot/root/foo.js' = 'foo.js', then we must yield
|
|
596
|
-
// parentofroot and root as ancestors.
|
|
597
|
-
if (onSegment != null &&
|
|
598
|
-
!isLastSegment &&
|
|
599
|
-
// No-op optimisation to bail out the common case of nothing to do.
|
|
600
|
-
((ancestorOfRootIdx =
|
|
601
|
-
this.#pathUtils.getAncestorOfRootIdx(normalSymlinkTarget) ?? undefined) === 0 ||
|
|
602
|
-
joinedResult.collapsedSegments > 0)) {
|
|
603
|
-
let node = this.#rootNode;
|
|
604
|
-
let collapsedPath = '';
|
|
605
|
-
const reverseAncestors = [];
|
|
606
|
-
for (let i = 0; i <= joinedResult.collapsedSegments && isDirectory(node); i++) {
|
|
607
|
-
if (
|
|
608
|
-
// Add the root only if the target is the root or we have
|
|
609
|
-
// collapsed segments.
|
|
610
|
-
i > 0 ||
|
|
611
|
-
ancestorOfRootIdx === 0 ||
|
|
612
|
-
joinedResult.collapsedSegments > 0) {
|
|
613
|
-
reverseAncestors.push({
|
|
614
|
-
ancestorOfRootIdx: i,
|
|
615
|
-
node,
|
|
616
|
-
normalPath: collapsedPath,
|
|
617
|
-
segmentName: this.#pathUtils.getBasenameOfNthAncestor(i),
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
node = node.get('..') ?? new Map();
|
|
621
|
-
collapsedPath = collapsedPath === '' ? '..' : collapsedPath + path_1.default.sep + '..';
|
|
622
|
-
}
|
|
623
|
-
// Emit in shallowest-first order, matching today's
|
|
624
|
-
// collectAncestors.push(...reverseAncestors.reverse()).
|
|
625
|
-
for (let i = reverseAncestors.length - 1; i >= 0; i--) {
|
|
626
|
-
const a = reverseAncestors[i];
|
|
627
|
-
onSegment(a.node, a.normalPath, a.segmentName, a.ancestorOfRootIdx);
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
// For the purpose of streaming ancestors: Ignore the traversal to the
|
|
631
|
-
// symlink target, and start yielding ancestors only from the target
|
|
632
|
-
// itself (i.e. the basename of the normal target path) onwards.
|
|
633
|
-
unseenPathFromIdx = normalSymlinkTarget.lastIndexOf(path_1.default.sep) + 1;
|
|
634
|
-
if (seen == null) {
|
|
635
|
-
// Optimisation: set this lazily only when we've encountered a symlink
|
|
636
|
-
seen = new Set([requestedNormalPath]);
|
|
735
|
+
const followResult = this.#followSymlink(segmentNode, currentPath, segmentName, isLastSegment ? '' : targetNormalPath.slice(fromIdx), followedSymlinks, onSegment, collectLinkPaths);
|
|
736
|
+
if (followResult !== undefined) {
|
|
737
|
+
return followResult;
|
|
637
738
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
seen.add(targetNormalPath);
|
|
647
|
-
followedSymlink = true;
|
|
648
|
-
fromIdx = 0;
|
|
649
|
-
parentNode = this.#rootNode;
|
|
650
|
-
ancestorOfRootIdx = 0;
|
|
739
|
+
const scratch = this.#followScratch;
|
|
740
|
+
parentNode = scratch.parentNode;
|
|
741
|
+
ancestorOfRootIdx = scratch.ancestorOfRootIdx;
|
|
742
|
+
targetNormalPath = scratch.targetNormalPath;
|
|
743
|
+
fromIdx = scratch.fromIdx;
|
|
744
|
+
unseenPathFromIdx = scratch.unseenPathFromIdx;
|
|
745
|
+
followedSymlinks = scratch.followedSymlinks;
|
|
651
746
|
}
|
|
652
747
|
}
|
|
653
748
|
(0, invariant_1.default)(parentNode === this.#rootNode, 'Unexpectedly escaped traversal');
|
|
@@ -668,8 +763,7 @@ class TreeFS {
|
|
|
668
763
|
*/
|
|
669
764
|
#walkLookupNoFollow(startNode, startPathIdx, startAncestorOfRootIdx, requestedNormalPath, onSegment, skipFallback) {
|
|
670
765
|
let targetNormalPath = requestedNormalPath;
|
|
671
|
-
let
|
|
672
|
-
let followedSymlink = false;
|
|
766
|
+
let followedSymlinks = 0;
|
|
673
767
|
let fromIdx = startPathIdx;
|
|
674
768
|
let parentNode = startNode;
|
|
675
769
|
let ancestorOfRootIdx = startAncestorOfRootIdx;
|
|
@@ -699,7 +793,7 @@ class TreeFS {
|
|
|
699
793
|
? fromIdx - segmentName.length - 1
|
|
700
794
|
: fromIdx - segmentName.length - 2;
|
|
701
795
|
const parentCanonicalPath = parentEnd > 0 ? targetNormalPath.slice(0, parentEnd) : '';
|
|
702
|
-
segmentNode = this.#populateFromFilesystem(parentNode, segmentName, parentCanonicalPath,
|
|
796
|
+
segmentNode = this.#populateFromFilesystem(parentNode, segmentName, parentCanonicalPath, followedSymlinks > 0);
|
|
703
797
|
if (segmentNode != null) {
|
|
704
798
|
ancestorOfRootIdx = undefined;
|
|
705
799
|
}
|
|
@@ -750,59 +844,17 @@ class TreeFS {
|
|
|
750
844
|
missingSegmentName: segmentName,
|
|
751
845
|
};
|
|
752
846
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
if (normalSymlinkTarget == null) {
|
|
757
|
-
return {
|
|
758
|
-
canonicalMissingPath: currentPath,
|
|
759
|
-
exists: false,
|
|
760
|
-
missingSegmentName: segmentName,
|
|
761
|
-
};
|
|
762
|
-
}
|
|
763
|
-
const remainingTargetPath = targetNormalPath.slice(fromIdx);
|
|
764
|
-
const joinedResult = this.#pathUtils.joinNormalToRelative(normalSymlinkTarget, remainingTargetPath);
|
|
765
|
-
targetNormalPath = joinedResult.normalPath;
|
|
766
|
-
if (onSegment != null &&
|
|
767
|
-
((ancestorOfRootIdx =
|
|
768
|
-
this.#pathUtils.getAncestorOfRootIdx(normalSymlinkTarget) ?? undefined) === 0 ||
|
|
769
|
-
joinedResult.collapsedSegments > 0)) {
|
|
770
|
-
let node = this.#rootNode;
|
|
771
|
-
let collapsedPath = '';
|
|
772
|
-
const reverseAncestors = [];
|
|
773
|
-
for (let i = 0; i <= joinedResult.collapsedSegments && isDirectory(node); i++) {
|
|
774
|
-
if (i > 0 || ancestorOfRootIdx === 0 || joinedResult.collapsedSegments > 0) {
|
|
775
|
-
reverseAncestors.push({
|
|
776
|
-
ancestorOfRootIdx: i,
|
|
777
|
-
node,
|
|
778
|
-
normalPath: collapsedPath,
|
|
779
|
-
segmentName: this.#pathUtils.getBasenameOfNthAncestor(i),
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
node = node.get('..') ?? new Map();
|
|
783
|
-
collapsedPath = collapsedPath === '' ? '..' : collapsedPath + path_1.default.sep + '..';
|
|
784
|
-
}
|
|
785
|
-
for (let i = reverseAncestors.length - 1; i >= 0; i--) {
|
|
786
|
-
const a = reverseAncestors[i];
|
|
787
|
-
onSegment(a.node, a.normalPath, a.segmentName, a.ancestorOfRootIdx);
|
|
788
|
-
}
|
|
847
|
+
const followResult = this.#followSymlink(segmentNode, currentPath, segmentName, targetNormalPath.slice(fromIdx), followedSymlinks, onSegment, undefined);
|
|
848
|
+
if (followResult !== undefined) {
|
|
849
|
+
return followResult;
|
|
789
850
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
exists: false,
|
|
798
|
-
missingSegmentName: segmentName,
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
seen.add(targetNormalPath);
|
|
802
|
-
followedSymlink = true;
|
|
803
|
-
fromIdx = 0;
|
|
804
|
-
parentNode = this.#rootNode;
|
|
805
|
-
ancestorOfRootIdx = 0;
|
|
851
|
+
const scratch = this.#followScratch;
|
|
852
|
+
parentNode = scratch.parentNode;
|
|
853
|
+
ancestorOfRootIdx = scratch.ancestorOfRootIdx;
|
|
854
|
+
targetNormalPath = scratch.targetNormalPath;
|
|
855
|
+
fromIdx = scratch.fromIdx;
|
|
856
|
+
unseenPathFromIdx = scratch.unseenPathFromIdx;
|
|
857
|
+
followedSymlinks = scratch.followedSymlinks;
|
|
806
858
|
}
|
|
807
859
|
}
|
|
808
860
|
(0, invariant_1.default)(parentNode === this.#rootNode, 'Unexpectedly escaped traversal');
|
|
@@ -823,7 +875,7 @@ class TreeFS {
|
|
|
823
875
|
*/
|
|
824
876
|
#walkAndMakeDirectories(startNode, startPathIdx, startAncestorOfRootIdx, requestedNormalPath, followLeaf, onSegment) {
|
|
825
877
|
let targetNormalPath = requestedNormalPath;
|
|
826
|
-
let
|
|
878
|
+
let followedSymlinks = 0;
|
|
827
879
|
let fromIdx = startPathIdx;
|
|
828
880
|
let parentNode = startNode;
|
|
829
881
|
let ancestorOfRootIdx = startAncestorOfRootIdx;
|
|
@@ -888,33 +940,17 @@ class TreeFS {
|
|
|
888
940
|
missingSegmentName: segmentName,
|
|
889
941
|
};
|
|
890
942
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
return {
|
|
895
|
-
canonicalMissingPath: currentPath,
|
|
896
|
-
exists: false,
|
|
897
|
-
missingSegmentName: segmentName,
|
|
898
|
-
};
|
|
899
|
-
}
|
|
900
|
-
const remainingTargetPath = isLastSegment ? '' : targetNormalPath.slice(fromIdx);
|
|
901
|
-
const joinedResult = this.#pathUtils.joinNormalToRelative(normalSymlinkTarget, remainingTargetPath);
|
|
902
|
-
targetNormalPath = joinedResult.normalPath;
|
|
903
|
-
unseenPathFromIdx = normalSymlinkTarget.lastIndexOf(path_1.default.sep) + 1;
|
|
904
|
-
if (seen == null) {
|
|
905
|
-
seen = new Set([requestedNormalPath]);
|
|
943
|
+
const followResult = this.#followSymlink(segmentNode, currentPath, segmentName, isLastSegment ? '' : targetNormalPath.slice(fromIdx), followedSymlinks, undefined, undefined);
|
|
944
|
+
if (followResult !== undefined) {
|
|
945
|
+
return followResult;
|
|
906
946
|
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
seen.add(targetNormalPath);
|
|
915
|
-
fromIdx = 0;
|
|
916
|
-
parentNode = this.#rootNode;
|
|
917
|
-
ancestorOfRootIdx = 0;
|
|
947
|
+
const scratch = this.#followScratch;
|
|
948
|
+
parentNode = scratch.parentNode;
|
|
949
|
+
ancestorOfRootIdx = scratch.ancestorOfRootIdx;
|
|
950
|
+
targetNormalPath = scratch.targetNormalPath;
|
|
951
|
+
fromIdx = scratch.fromIdx;
|
|
952
|
+
unseenPathFromIdx = scratch.unseenPathFromIdx;
|
|
953
|
+
followedSymlinks = scratch.followedSymlinks;
|
|
918
954
|
}
|
|
919
955
|
}
|
|
920
956
|
(0, invariant_1.default)(parentNode === this.#rootNode, 'Unexpectedly escaped traversal');
|
|
@@ -926,18 +962,18 @@ class TreeFS {
|
|
|
926
962
|
parentNode: undefined,
|
|
927
963
|
};
|
|
928
964
|
}
|
|
929
|
-
// Convenience wrappers
|
|
965
|
+
// Convenience wrappers. Top-level entries pass `0` for `initialFollows`.
|
|
930
966
|
#lookup(normalPath, collectLinkPaths) {
|
|
931
|
-
return this.#walkLookup(this.#rootNode, 0, 0, normalPath, undefined, collectLinkPaths);
|
|
967
|
+
return this.#walkLookup(this.#rootNode, 0, 0, normalPath, undefined, collectLinkPaths, 0);
|
|
932
968
|
}
|
|
933
969
|
#lookupNoFollow(normalPath) {
|
|
934
970
|
return this.#walkLookupNoFollow(this.#rootNode, 0, 0, normalPath, undefined, false);
|
|
935
971
|
}
|
|
936
972
|
#lookupFromNode(startNode, startPathIdx, startAncestorOfRootIdx, target, collectLinkPaths) {
|
|
937
|
-
return this.#walkLookup(startNode, startPathIdx, startAncestorOfRootIdx, target, undefined, collectLinkPaths);
|
|
973
|
+
return this.#walkLookup(startNode, startPathIdx, startAncestorOfRootIdx, target, undefined, collectLinkPaths, 0);
|
|
938
974
|
}
|
|
939
975
|
#walkAndStream(normalPath, onSegment, collectLinkPaths) {
|
|
940
|
-
return this.#walkLookup(this.#rootNode, 0, 0, normalPath, onSegment, collectLinkPaths);
|
|
976
|
+
return this.#walkLookup(this.#rootNode, 0, 0, normalPath, onSegment, collectLinkPaths, 0);
|
|
941
977
|
}
|
|
942
978
|
/**
|
|
943
979
|
* Given a start path (which need not exist), a subpath and type, and
|
|
@@ -963,18 +999,11 @@ class TreeFS {
|
|
|
963
999
|
* (subpath: node_modules/pkg, type: d) in Node.js resolution.
|
|
964
1000
|
*/
|
|
965
1001
|
hierarchicalLookup(mixedStartPath, subpath, opts) {
|
|
966
|
-
const ancestorsOfInput =
|
|
1002
|
+
const ancestorsOfInput = this.#hierAncestorsBuf;
|
|
1003
|
+
ancestorsOfInput.length = 0;
|
|
967
1004
|
const normalPath = this.#normalizePath(mixedStartPath);
|
|
968
1005
|
const invalidatedBy = opts.invalidatedBy ?? undefined;
|
|
969
|
-
const
|
|
970
|
-
ancestorsOfInput.push({
|
|
971
|
-
ancestorOfRootIdx,
|
|
972
|
-
node,
|
|
973
|
-
normalPath: normalPathOfDir,
|
|
974
|
-
segmentName,
|
|
975
|
-
});
|
|
976
|
-
};
|
|
977
|
-
const closestLookup = this.#walkAndStream(normalPath, onSegment, invalidatedBy);
|
|
1006
|
+
const closestLookup = this.#walkAndStream(normalPath, this.#pushHierAncestor, invalidatedBy);
|
|
978
1007
|
if (closestLookup.exists && isDirectory(closestLookup.node)) {
|
|
979
1008
|
const maybeAbsolutePathMatch = this.#checkCandidateHasSubpath(closestLookup.canonicalPath, subpath, opts.subpathType, invalidatedBy, {
|
|
980
1009
|
ancestorOfRootIdx: closestLookup.ancestorOfRootIdx,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/metro-file-map",
|
|
3
|
-
"version": "56.0.
|
|
3
|
+
"version": "56.0.3",
|
|
4
4
|
"description": "A metro-file-map fork for Expo used with the Metro bundler",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "f26be3dd9396bf7c399a1d607865d0fabdbc0d64",
|
|
46
46
|
"scripts": {
|
|
47
47
|
"build": "expo-module tsc",
|
|
48
48
|
"clean": "expo-module clean",
|