@yarnpkg/pnpify
Version:
73 lines (72 loc) • 3.18 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveNodeModulesPath = void 0;
const fslib_1 = require("@yarnpkg/fslib");
const fslib_2 = require("@yarnpkg/fslib");
const NODE_MODULES = `node_modules`;
var LinkType;
(function (LinkType) {
LinkType["HARD"] = "HARD";
LinkType["SOFT"] = "SOFT";
})(LinkType || (LinkType = {}));
/**
* Resolves paths containing `/node_modules` inside PnP projects. If path is outside PnP
* project it is not changed.
*
* @param inputPath full path containing `node_modules`
*
* @returns resolved path
*/
const resolveNodeModulesPath = (inputPath, nodeModulesTree) => {
const result = { resolvedPath: inputPath };
const segments = inputPath.split(fslib_2.ppath.sep);
const firstIdx = segments.indexOf(NODE_MODULES);
if (firstIdx < 0)
return result;
let lastIdx = segments.lastIndexOf(NODE_MODULES);
if (typeof segments[lastIdx + 1] !== `undefined`)
// We have the situation .../node_modules/{something or @something}
lastIdx++;
if (segments[lastIdx][0] === `@` && typeof segments[lastIdx + 1] !== `undefined`)
// We have the situation .../node_modules/@something/{foo}
lastIdx++;
// We lookup all the path substrings that end on [firstIdx..lastIdx] in the node_modules tree
// and follow them if they are symlinks
let locationCandidate = fslib_2.npath.toPortablePath(segments.slice(0, firstIdx).join(fslib_2.ppath.sep));
let node, lastNode, lastNodeLocation;
let curIdx = firstIdx;
let request = fslib_1.PortablePath.dot;
while (curIdx <= lastIdx) {
const curSegment = segments[curIdx];
locationCandidate = fslib_2.ppath.join(locationCandidate, curSegment);
node = nodeModulesTree.get(locationCandidate);
if (node) {
if (node.linkType === LinkType.SOFT)
locationCandidate = node.target;
lastNode = node;
request = fslib_1.PortablePath.dot;
lastNodeLocation = node.dirList ? locationCandidate : node.target;
}
else {
request = fslib_2.ppath.join(request, curSegment);
}
curIdx++;
}
request = fslib_2.ppath.join(request, ...segments.slice(lastIdx + 1).map(x => x));
if (lastNode) {
if (!lastNode.dirList || request !== fslib_1.PortablePath.dot) {
result.resolvedPath = fslib_2.ppath.join(lastNodeLocation, request);
result.isSymlink = lastNode && lastNode.linkType === LinkType.SOFT && request === fslib_1.PortablePath.dot;
}
else if (request === fslib_1.PortablePath.dot) {
result.dirList = lastNode.dirList;
result.forwardedDirPath = fslib_2.npath.toPortablePath(segments.slice(0, firstIdx).join(fslib_2.ppath.sep));
// If node_modules is inside .zip archive, we use parent folder as a statPath instead
if (result.forwardedDirPath.endsWith(`.zip`)) {
result.forwardedDirPath = fslib_2.ppath.dirname(result.forwardedDirPath);
}
}
}
return result;
};
exports.resolveNodeModulesPath = resolveNodeModulesPath;
;