Skip to content

Commit 5e2ba36

Browse files
d3xter666matz3
andauthored
fix: Normalize workspace paths in npm-shrinkwrap.json (#1231)
The published `@ui5/cli` package contained an `npm-shrinkwrap.json` with monorepo workspace paths like: ```json { "packages": { "packages/cli/node_modules/open": {...}, "packages/fs/node_modules/globby": {...} } } ``` Enahnce the shrinkwrap-extractor to normalize workspace-specific paths to standard npm format: - `packages/cli/node_modules/open` → `node_modules/open` - `packages/fs/node_modules/globby` → `node_modules/globby` Fixes #1227 --------- Co-authored-by: Matthias Osswald <[email protected]>
1 parent afe59cc commit 5e2ba36

File tree

3 files changed

+213
-190
lines changed

3 files changed

+213
-190
lines changed

internal/shrinkwrap-extractor/lib/convertPackageLockToShrinkwrap.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ export default async function convertPackageLockToShrinkwrap(workspaceRootDir, t
4848
path: workspaceRootDir,
4949
});
5050
const tree = await arb.loadVirtual();
51-
const cliNode = Array.from(tree.tops).find((node) => node.packageName === targetPackageName);
51+
const tops = Array.from(tree.tops.values());
52+
const cliNode = tops.find((node) => node.packageName === targetPackageName);
5253
if (!cliNode) {
5354
throw new Error(`Target package "${targetPackageName}" not found in workspace`);
5455
}
@@ -70,7 +71,10 @@ export default async function convertPackageLockToShrinkwrap(workspaceRootDir, t
7071
if (extractedPackages[packageLoc]) {
7172
throw new Error(`Duplicate root package entry for "${targetPackageName}"`);
7273
}
73-
} else if (!pkg.resolved) {
74+
} else {
75+
packageLoc = normalizePackageLocation(packageLoc, node, targetPackageName, tree.packageName);
76+
}
77+
if (packageLoc !== "" && !pkg.resolved) {
7478
// For all but the root package, ensure that "resolved" and "integrity" fields are present
7579
// These are always missing for locally linked packages, but sometimes also for others (e.g. if installed
7680
// from local cache)
@@ -100,6 +104,31 @@ export default async function convertPackageLockToShrinkwrap(workspaceRootDir, t
100104
return shrinkwrap;
101105
}
102106

107+
/**
108+
* Normalize package locations from workspace-specific paths to standard npm paths.
109+
* Examples (assuming @ui5/cli is the targetPackageName):
110+
* - packages/cli/node_modules/foo -> node_modules/foo
111+
* - packages/fs/node_modules/bar -> node_modules/@ui5/fs/node_modules/bar
112+
*
113+
* @param {string} location - Package location from arborist
114+
* @param {object} node - Package node from arborist
115+
* @param {string} targetPackageName - Target package name for shrinkwrap file
116+
* @param {string} rootPackageName - Root / workspace package name
117+
* @returns {string} - Normalized location for npm-shrinkwrap.json
118+
*/
119+
function normalizePackageLocation(location, node, targetPackageName, rootPackageName) {
120+
const topPackageName = node.top.packageName;
121+
if (topPackageName === targetPackageName) {
122+
// Remove location for packages within target package (e.g. @ui5/cli)
123+
return location.substring(node.top.location.length + 1);
124+
} else if (topPackageName !== rootPackageName) {
125+
// Add package within node_modules of actual package name (e.g. @ui5/fs)
126+
return `node_modules/${topPackageName}/${location.substring(node.top.location.length + 1)}`;
127+
}
128+
// If it's already within the root workspace package, keep as-is
129+
return location;
130+
}
131+
103132
function collectDependencies(node, relevantPackageLocations) {
104133
if (relevantPackageLocations.has(node.location)) {
105134
// Already processed

0 commit comments

Comments
 (0)