From a517d18a517f3123a19a321c72e4054bae467944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Gro=C3=9Fe?= Date: Wed, 22 Nov 2023 11:49:33 +0100 Subject: [PATCH] fix(npm8+): refactor symlinking to support npm 9+ --- lib/npm.js | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 71c7f1d..273f6ea 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -45,25 +45,30 @@ var NPMIST = npmist.prototype */ async function resolveLinkedWorkspaces(dirPath) { let fixedLinks = 0; - const files = await fs.readdirAsync(dirPath, { withFileTypes: true }); - const dirPromises = []; - for (const file of files) { - const filePath = path.join(dirPath, file.name); - if (file.isSymbolicLink()) { - const linkTarget = await fs.readlinkAsync(filePath); - debug('Fix symlink for ', filePath, 'with target', linkTarget); - await fs.unlinkAsync(filePath); + const packageLockJson = JSON.parse(fs.readFileSync(path.join(dirPath, 'package-lock.json')).toString()); + await Promise.all(Object.entries(packageLockJson.packages) + .filter(([pkgPath, pkg]) => pkg.link === true) + .map(async ([pkgPath, pkg]) => { + const linkTarget = path.join( + ...pkgPath.split('/').slice(0, -1).map(() => '..'), + pkg.resolved + ); + const linkPath = path.join(dirPath, pkgPath); + + debug('Create symlink for ', linkPath, 'with target', linkTarget); + if (await fs.accessAsync(linkPath, fs.constants.F_OK).then(() => true).catch(() => false)) { + await fs.unlinkAsync(linkPath); + } + try { - await fs.symlinkAsync(linkTarget, filePath, 'junction'); + await fs.symlinkAsync(linkTarget, linkPath, 'junction'); } catch (e) { - await fs.renameAsync(path.join(dirPath, linkTarget), filePath); + await fs.renameAsync(path.join(dirPath, linkTarget), linkPath); } fixedLinks++; - } else if (file.isDirectory()) { - dirPromises.push(resolveLinkedWorkspaces(filePath)); - } - } - return (await Promise.all(dirPromises)).reduce((sum, num) => sum + num, fixedLinks); + })); + + return fixedLinks; } /** @@ -326,7 +331,7 @@ NPMIST.install = function(v,done){ .then(() => { if (semver.gte(version, '8.0.0')) { debug('Fix symlinks for npm version >= 8'); - return resolveLinkedWorkspaces(path.join(archivePath, 'node_modules')) + return resolveLinkedWorkspaces(path.join(archivePath)) .then(fixedLinks => { debug(`Fixed ${fixedLinks} symlinks for npm node_modules`); });