feat(core): add prune lock file support for npm 2 and 3 (#13120)
This commit is contained in:
parent
b142f385c9
commit
fc8de9a4d3
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3,9 +3,9 @@
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map lock file v1 data to external nodes 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "c22918aa52c9fdce78bf82451d8114e00b6d4375a8e5b1d1d96c6cf4755dbe1a",
|
||||
"hash": "abdb9ef454702b3fae2f8002be40a8c2903514143b45592292ac8920e35cb60a",
|
||||
"packageName": "yargs",
|
||||
"version": "17.5.1",
|
||||
"version": "17.6.2",
|
||||
},
|
||||
"name": "npm:yargs",
|
||||
"type": "npm",
|
||||
@ -16,7 +16,7 @@ exports[`lock-file mapLockFileDataToExternalNodes npm should map lock file v1 da
|
||||
Array [
|
||||
Object {
|
||||
"source": "npm:yargs",
|
||||
"target": "npm:cliui",
|
||||
"target": "npm:cliui@8.0.1",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -55,9 +55,9 @@ Array [
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map lock file v2 data to external nodes 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "c22918aa52c9fdce78bf82451d8114e00b6d4375a8e5b1d1d96c6cf4755dbe1a",
|
||||
"hash": "abdb9ef454702b3fae2f8002be40a8c2903514143b45592292ac8920e35cb60a",
|
||||
"packageName": "yargs",
|
||||
"version": "17.5.1",
|
||||
"version": "17.6.2",
|
||||
},
|
||||
"name": "npm:yargs",
|
||||
"type": "npm",
|
||||
@ -68,7 +68,7 @@ exports[`lock-file mapLockFileDataToExternalNodes npm should map lock file v2 da
|
||||
Array [
|
||||
Object {
|
||||
"source": "npm:yargs",
|
||||
"target": "npm:cliui",
|
||||
"target": "npm:cliui@8.0.1",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -107,9 +107,9 @@ Array [
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map lock file v3 data to external nodes 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "c22918aa52c9fdce78bf82451d8114e00b6d4375a8e5b1d1d96c6cf4755dbe1a",
|
||||
"hash": "abdb9ef454702b3fae2f8002be40a8c2903514143b45592292ac8920e35cb60a",
|
||||
"packageName": "yargs",
|
||||
"version": "17.5.1",
|
||||
"version": "17.6.2",
|
||||
},
|
||||
"name": "npm:yargs",
|
||||
"type": "npm",
|
||||
@ -120,7 +120,7 @@ exports[`lock-file mapLockFileDataToExternalNodes npm should map lock file v3 da
|
||||
Array [
|
||||
Object {
|
||||
"source": "npm:yargs",
|
||||
"target": "npm:cliui",
|
||||
"target": "npm:cliui@8.0.1",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -156,12 +156,204 @@ Array [
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map successfully complex lock file v1 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "0e69266e94bbe89cb6c7555e1ab56fb9d4c0e4fe2cbb674b92fc1ee200053526",
|
||||
"packageName": "nx",
|
||||
"version": "15.0.13",
|
||||
},
|
||||
"name": "npm:nx",
|
||||
"type": "npm",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map successfully complex lock file v1 2`] = `
|
||||
Array [
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@nrwl/cli",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@nrwl/tao",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@parcel/watcher",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@yarnpkg/lockfile",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@yarnpkg/parsers",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@zkochan/js-yaml",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:axios",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chalk",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chokidar",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cli-cursor",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cli-spinners",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cliui",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:dotenv",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:enquirer",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:fast-glob",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:figures",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:flat",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:fs-extra",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:glob",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:ignore",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:js-yaml@4.1.0",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:jsonc-parser",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:minimatch@3.0.5",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:npm-run-path",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:open",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:semver",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:string-width",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:strong-log-transformer",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tar-stream",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tmp",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tsconfig-paths",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tslib",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:v8-compile-cache",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:yargs",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:yargs-parser",
|
||||
"type": "static",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map successfully complex lock file v2 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "8da365ef8d327d868461fda5c863f779c2f75acfe6a591e733b31a2882763af3",
|
||||
"hash": "64ba4128469ecb7d465d8dbed1ccd86be85c38177e85406f2cd6055f303758fa",
|
||||
"packageName": "nx",
|
||||
"version": "14.7.5",
|
||||
"version": "15.0.13",
|
||||
},
|
||||
"name": "npm:nx",
|
||||
"type": "npm",
|
||||
@ -187,7 +379,27 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chalk@4.1.0",
|
||||
"target": "npm:@yarnpkg/lockfile",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@yarnpkg/parsers",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@zkochan/js-yaml",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:axios",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chalk",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -252,7 +464,7 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:js-yaml",
|
||||
"target": "npm:js-yaml@4.1.0",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -262,7 +474,7 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:minimatch@3.0.5",
|
||||
"target": "npm:minimatch",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -285,6 +497,11 @@ Array [
|
||||
"target": "npm:string-width",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:strong-log-transformer",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tar-stream",
|
||||
@ -317,7 +534,7 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:yargs-parser@21.0.1",
|
||||
"target": "npm:yargs-parser",
|
||||
"type": "static",
|
||||
},
|
||||
]
|
||||
@ -326,9 +543,9 @@ Array [
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map successfully complex lock file v3 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "8da365ef8d327d868461fda5c863f779c2f75acfe6a591e733b31a2882763af3",
|
||||
"hash": "b661da6137e80c92cb5fa75b96780e12868eb81969dddaee67113a99f4ffd159",
|
||||
"packageName": "nx",
|
||||
"version": "14.7.5",
|
||||
"version": "15.0.13",
|
||||
},
|
||||
"name": "npm:nx",
|
||||
"type": "npm",
|
||||
@ -354,169 +571,22 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chalk@4.1.0",
|
||||
"target": "npm:@yarnpkg/lockfile",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chokidar",
|
||||
"target": "npm:@yarnpkg/parsers",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cli-cursor",
|
||||
"target": "npm:@zkochan/js-yaml",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cli-spinners",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cliui",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:dotenv",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:enquirer",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:fast-glob",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:figures",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:flat",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:fs-extra",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:glob",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:ignore",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:js-yaml",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:jsonc-parser",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:minimatch@3.0.5",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:npm-run-path",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:open",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:semver",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:string-width",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tar-stream",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tmp",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tsconfig-paths",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tslib",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:v8-compile-cache",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:yargs",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:yargs-parser@21.0.1",
|
||||
"type": "static",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map successfully complex npm lock file v1 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "62016caa192e50e3af6e4730fa1427455ad431a0e11ad807215c56bee04a8c8e",
|
||||
"packageName": "nx",
|
||||
"version": "14.7.5",
|
||||
},
|
||||
"name": "npm:nx",
|
||||
"type": "npm",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`lock-file mapLockFileDataToExternalNodes npm should map successfully complex npm lock file v1 2`] = `
|
||||
Array [
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@nrwl/cli",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@nrwl/tao",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@parcel/watcher",
|
||||
"target": "npm:axios",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -619,6 +689,11 @@ Array [
|
||||
"target": "npm:string-width",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:strong-log-transformer",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tar-stream",
|
||||
@ -651,7 +726,7 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:yargs-parser@21.0.1",
|
||||
"target": "npm:yargs-parser",
|
||||
"type": "static",
|
||||
},
|
||||
]
|
||||
@ -660,9 +735,9 @@ Array [
|
||||
exports[`lock-file mapLockFileDataToExternalNodes pnpm should map lock file data to external nodes 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "c22918aa52c9fdce78bf82451d8114e00b6d4375a8e5b1d1d96c6cf4755dbe1a",
|
||||
"hash": "abdb9ef454702b3fae2f8002be40a8c2903514143b45592292ac8920e35cb60a",
|
||||
"packageName": "yargs",
|
||||
"version": "17.5.1",
|
||||
"version": "17.6.2",
|
||||
},
|
||||
"name": "npm:yargs",
|
||||
"type": "npm",
|
||||
@ -712,9 +787,9 @@ Array [
|
||||
exports[`lock-file mapLockFileDataToExternalNodes pnpm should map successfully complex lock file 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "1e61b9db38c17534ce427d40ce84f9c03b4c439253f659e9a48513a10a52b465",
|
||||
"hash": "21f7648b65146104c6644fcde7073e2edc7e707731b2a38db83cd2882cb274df",
|
||||
"packageName": "nx",
|
||||
"version": "14.7.5",
|
||||
"version": "15.0.13",
|
||||
},
|
||||
"name": "npm:nx",
|
||||
"type": "npm",
|
||||
@ -738,6 +813,26 @@ Array [
|
||||
"target": "npm:@parcel/watcher",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@yarnpkg/lockfile",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@yarnpkg/parsers",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:@zkochan/js-yaml",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:axios",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:chalk",
|
||||
@ -760,7 +855,7 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:cliui",
|
||||
"target": "npm:cliui@7.0.4",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -838,6 +933,11 @@ Array [
|
||||
"target": "npm:string-width",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:strong-log-transformer",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tar-stream",
|
||||
@ -855,7 +955,7 @@ Array [
|
||||
},
|
||||
Object {
|
||||
"source": "npm:nx",
|
||||
"target": "npm:tslib",
|
||||
"target": "npm:tslib@2.4.1",
|
||||
"type": "static",
|
||||
},
|
||||
Object {
|
||||
@ -879,7 +979,7 @@ Array [
|
||||
exports[`lock-file mapLockFileDataToExternalNodes pnpm should map successfully complex lock file 3`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"hash": "6c5961e1a6ab89174727587860e480508f945407ce4c2cc7c9f1e46f181e6468",
|
||||
"hash": "601ac9f28fb76d7e6d1d15600097ca3d8f636990b659c73cf44d3e4030e68c56",
|
||||
"packageName": "@phenomnomnominal/tsquery",
|
||||
"version": "4.1.1",
|
||||
},
|
||||
|
||||
@ -14,6 +14,7 @@ Object {
|
||||
"dev": true,
|
||||
"optional": undefined,
|
||||
"path": "node_modules/@ampproject/remapping",
|
||||
"peer": undefined,
|
||||
},
|
||||
],
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||
@ -33,6 +34,7 @@ Object {
|
||||
"dev": true,
|
||||
"optional": undefined,
|
||||
"path": "node_modules/typescript",
|
||||
"peer": undefined,
|
||||
},
|
||||
],
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
||||
@ -59,6 +61,7 @@ Object {
|
||||
"dev": true,
|
||||
"optional": undefined,
|
||||
"path": "node_modules/@ampproject/remapping",
|
||||
"peer": undefined,
|
||||
},
|
||||
],
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||
@ -85,6 +88,7 @@ Object {
|
||||
"dev": true,
|
||||
"optional": undefined,
|
||||
"path": "node_modules/typescript",
|
||||
"peer": undefined,
|
||||
},
|
||||
],
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
||||
@ -111,6 +115,7 @@ Object {
|
||||
"dev": true,
|
||||
"optional": undefined,
|
||||
"path": "node_modules/@ampproject/remapping",
|
||||
"peer": undefined,
|
||||
},
|
||||
],
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||
@ -137,6 +142,7 @@ Object {
|
||||
"dev": true,
|
||||
"optional": undefined,
|
||||
"path": "node_modules/typescript",
|
||||
"peer": undefined,
|
||||
},
|
||||
],
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
||||
|
||||
@ -5,7 +5,7 @@ Object {
|
||||
"@ampproject/remapping@2.2.0": Object {
|
||||
"dependencies": Object {
|
||||
"@jridgewell/gen-mapping": "0.1.1",
|
||||
"@jridgewell/trace-mapping": "0.3.15",
|
||||
"@jridgewell/trace-mapping": "0.3.17",
|
||||
},
|
||||
"dev": true,
|
||||
"engines": Object {
|
||||
@ -16,7 +16,7 @@ Object {
|
||||
"dependencyDetails": Object {
|
||||
"dependencies": Object {
|
||||
"@jridgewell/gen-mapping": "0.1.1",
|
||||
"@jridgewell/trace-mapping": "0.3.15",
|
||||
"@jridgewell/trace-mapping": "0.3.17",
|
||||
},
|
||||
},
|
||||
"isDependency": false,
|
||||
@ -36,7 +36,7 @@ Object {
|
||||
|
||||
exports[`pnpm LockFile utility lock file with inline specifiers should parse lockfile (IS) 2`] = `
|
||||
Object {
|
||||
"typescript@4.8.3": Object {
|
||||
"typescript@4.8.4": Object {
|
||||
"dev": true,
|
||||
"engines": Object {
|
||||
"node": ">=4.2.0",
|
||||
@ -47,15 +47,15 @@ Object {
|
||||
"dependencyDetails": Object {},
|
||||
"isDependency": false,
|
||||
"isDevDependency": true,
|
||||
"key": "/typescript/4.8.3",
|
||||
"key": "/typescript/4.8.4",
|
||||
"specifier": "~4.8.2",
|
||||
},
|
||||
],
|
||||
"resolution": Object {
|
||||
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==",
|
||||
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
|
||||
},
|
||||
"rootVersion": true,
|
||||
"version": "4.8.3",
|
||||
"version": "4.8.4",
|
||||
},
|
||||
}
|
||||
`;
|
||||
@ -65,7 +65,7 @@ Object {
|
||||
"@ampproject/remapping@2.2.0": Object {
|
||||
"dependencies": Object {
|
||||
"@jridgewell/gen-mapping": "0.1.1",
|
||||
"@jridgewell/trace-mapping": "0.3.15",
|
||||
"@jridgewell/trace-mapping": "0.3.17",
|
||||
},
|
||||
"dev": true,
|
||||
"engines": Object {
|
||||
@ -76,7 +76,7 @@ Object {
|
||||
"dependencyDetails": Object {
|
||||
"dependencies": Object {
|
||||
"@jridgewell/gen-mapping": "0.1.1",
|
||||
"@jridgewell/trace-mapping": "0.3.15",
|
||||
"@jridgewell/trace-mapping": "0.3.17",
|
||||
},
|
||||
},
|
||||
"isDependency": false,
|
||||
@ -96,7 +96,7 @@ Object {
|
||||
|
||||
exports[`pnpm LockFile utility standard lock file should parse lockfile correctly 2`] = `
|
||||
Object {
|
||||
"typescript@4.8.3": Object {
|
||||
"typescript@4.8.4": Object {
|
||||
"dev": true,
|
||||
"engines": Object {
|
||||
"node": ">=4.2.0",
|
||||
@ -107,15 +107,15 @@ Object {
|
||||
"dependencyDetails": Object {},
|
||||
"isDependency": false,
|
||||
"isDevDependency": true,
|
||||
"key": "/typescript/4.8.3",
|
||||
"key": "/typescript/4.8.4",
|
||||
"specifier": "~4.8.2",
|
||||
},
|
||||
],
|
||||
"resolution": Object {
|
||||
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==",
|
||||
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
|
||||
},
|
||||
"rootVersion": true,
|
||||
"version": "4.8.3",
|
||||
"version": "4.8.4",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
lockFileV1 as npmLockFileV1,
|
||||
} from './__fixtures__/npm.lock';
|
||||
import {
|
||||
lockFileYargsOnly as pnpmLockFileYargsOnly,
|
||||
lockFileYargsAndDevkit as pnpmLockFileYargsAndDevkit,
|
||||
lockFile as pnpmLockFile,
|
||||
} from './__fixtures__/pnpm.lock';
|
||||
import {
|
||||
@ -131,7 +131,7 @@ describe('lock-file', () => {
|
||||
expect(partialGraph.dependencies['npm:nx']).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should map successfully complex npm lock file v1', () => {
|
||||
it('should map successfully complex lock file v1', () => {
|
||||
const lockFileData = parseNpmLockFile(npmLockFileV1);
|
||||
|
||||
const partialGraph = mapLockFileDataToPartialGraph(lockFileData, 'npm');
|
||||
@ -156,7 +156,7 @@ describe('lock-file', () => {
|
||||
});
|
||||
|
||||
it('should map lock file data to external nodes', () => {
|
||||
const lockFileData = parsePnpmLockFile(pnpmLockFileYargsOnly);
|
||||
const lockFileData = parsePnpmLockFile(pnpmLockFileYargsAndDevkit);
|
||||
|
||||
const partialGraph = mapLockFileDataToPartialGraph(
|
||||
lockFileData,
|
||||
|
||||
@ -164,16 +164,17 @@ export function writeLockFile(
|
||||
export function pruneLockFile(
|
||||
lockFile: LockFileData,
|
||||
packages: string[],
|
||||
projectName?: string,
|
||||
packageManager: PackageManager = detectPackageManager(workspaceRoot)
|
||||
): LockFileData {
|
||||
if (packageManager === 'yarn') {
|
||||
return pruneYarnLockFile(lockFile, packages);
|
||||
return pruneYarnLockFile(lockFile, packages, projectName);
|
||||
}
|
||||
if (packageManager === 'pnpm') {
|
||||
return prunePnpmLockFile(lockFile, packages);
|
||||
return prunePnpmLockFile(lockFile, packages, projectName);
|
||||
}
|
||||
if (packageManager === 'npm') {
|
||||
return pruneNpmLockFile(lockFile, packages);
|
||||
return pruneNpmLockFile(lockFile, packages, projectName);
|
||||
}
|
||||
throw Error(`Unknown package manager: ${packageManager}`);
|
||||
}
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
import { parseNpmLockFile, stringifyNpmLockFile } from './npm';
|
||||
import { lockFileV2, lockFileV1, lockFileV3 } from './__fixtures__/npm.lock';
|
||||
import {
|
||||
parseNpmLockFile,
|
||||
pruneNpmLockFile,
|
||||
stringifyNpmLockFile,
|
||||
} from './npm';
|
||||
import {
|
||||
lockFileV2,
|
||||
lockFileV1,
|
||||
lockFileV3,
|
||||
lockFileV3JustTypescript,
|
||||
lockFileV3YargsAndDevkitOnly,
|
||||
lockFileV2JustTypescript,
|
||||
lockFileV1JustTypescript,
|
||||
lockFileV1YargsAndDevkitOnly,
|
||||
lockFileV2YargsAndDevkitOnly,
|
||||
} from './__fixtures__/npm.lock';
|
||||
|
||||
describe('npm LockFile utility', () => {
|
||||
describe('v3', () => {
|
||||
@ -15,9 +29,9 @@ describe('npm LockFile utility', () => {
|
||||
},
|
||||
rootPackage: {
|
||||
devDependencies: {
|
||||
'@nrwl/cli': '14.7.5',
|
||||
'@nrwl/workspace': '14.7.5',
|
||||
nx: '14.7.5',
|
||||
'@nrwl/cli': '15.0.13',
|
||||
'@nrwl/workspace': '15.0.13',
|
||||
nx: '15.0.13',
|
||||
prettier: '^2.6.2',
|
||||
typescript: '~4.8.2',
|
||||
},
|
||||
@ -26,7 +40,7 @@ describe('npm LockFile utility', () => {
|
||||
version: '0.0.0',
|
||||
},
|
||||
});
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(324);
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(339);
|
||||
expect(
|
||||
parsedLockFile.dependencies['@ampproject/remapping']
|
||||
).toMatchSnapshot();
|
||||
@ -85,6 +99,34 @@ describe('npm LockFile utility', () => {
|
||||
it('should match the original file on stringification', () => {
|
||||
expect(stringifyNpmLockFile(parsedLockFile)).toEqual(lockFileV3);
|
||||
});
|
||||
|
||||
it('should prune the lock file', () => {
|
||||
expect(
|
||||
Object.keys(
|
||||
pruneNpmLockFile(parsedLockFile, ['typescript']).dependencies
|
||||
).length
|
||||
).toEqual(1);
|
||||
expect(
|
||||
Object.keys(
|
||||
pruneNpmLockFile(parsedLockFile, ['yargs', '@nrwl/devkit'])
|
||||
.dependencies
|
||||
).length
|
||||
).toEqual(136);
|
||||
});
|
||||
|
||||
it('should correctly prune lockfile with single package', () => {
|
||||
expect(
|
||||
stringifyNpmLockFile(pruneNpmLockFile(parsedLockFile, ['typescript']))
|
||||
).toEqual(lockFileV3JustTypescript);
|
||||
});
|
||||
|
||||
it('should correctly prune lockfile with multiple packages', () => {
|
||||
expect(
|
||||
stringifyNpmLockFile(
|
||||
pruneNpmLockFile(parsedLockFile, ['yargs', '@nrwl/devkit'])
|
||||
)
|
||||
).toEqual(lockFileV3YargsAndDevkitOnly);
|
||||
});
|
||||
});
|
||||
|
||||
describe('v2', () => {
|
||||
@ -100,9 +142,9 @@ describe('npm LockFile utility', () => {
|
||||
},
|
||||
rootPackage: {
|
||||
devDependencies: {
|
||||
'@nrwl/cli': '14.7.5',
|
||||
'@nrwl/workspace': '14.7.5',
|
||||
nx: '14.7.5',
|
||||
'@nrwl/cli': '15.0.13',
|
||||
'@nrwl/workspace': '15.0.13',
|
||||
nx: '15.0.13',
|
||||
prettier: '^2.6.2',
|
||||
typescript: '~4.8.2',
|
||||
},
|
||||
@ -111,7 +153,7 @@ describe('npm LockFile utility', () => {
|
||||
version: '0.0.0',
|
||||
},
|
||||
});
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(324);
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(339);
|
||||
expect(
|
||||
parsedLockFile.dependencies['@ampproject/remapping']
|
||||
).toMatchSnapshot();
|
||||
@ -170,6 +212,36 @@ describe('npm LockFile utility', () => {
|
||||
it('should match the original file on stringification', () => {
|
||||
expect(stringifyNpmLockFile(parsedLockFile)).toEqual(lockFileV2);
|
||||
});
|
||||
|
||||
it('should prune the lock file', () => {
|
||||
expect(
|
||||
Object.keys(
|
||||
pruneNpmLockFile(parsedLockFile, ['typescript']).dependencies
|
||||
).length
|
||||
).toEqual(1);
|
||||
expect(
|
||||
Object.keys(
|
||||
pruneNpmLockFile(parsedLockFile, ['yargs', '@nrwl/devkit'])
|
||||
.dependencies
|
||||
).length
|
||||
).toEqual(136);
|
||||
});
|
||||
|
||||
it('should correctly prune lockfile with single package', () => {
|
||||
expect(
|
||||
stringifyNpmLockFile(pruneNpmLockFile(parsedLockFile, ['typescript']))
|
||||
).toEqual(lockFileV2JustTypescript);
|
||||
});
|
||||
|
||||
it('should correctly prune lockfile with multiple packages', () => {
|
||||
const pruned = pruneNpmLockFile(parsedLockFile, [
|
||||
'yargs',
|
||||
'@nrwl/devkit',
|
||||
]);
|
||||
expect(stringifyNpmLockFile(pruned)).toEqual(
|
||||
lockFileV2YargsAndDevkitOnly
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('v1', () => {
|
||||
@ -184,7 +256,7 @@ describe('npm LockFile utility', () => {
|
||||
version: '0.0.0',
|
||||
},
|
||||
});
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(324);
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(339);
|
||||
expect(
|
||||
parsedLockFile.dependencies['@ampproject/remapping']
|
||||
).toMatchSnapshot();
|
||||
@ -243,5 +315,33 @@ describe('npm LockFile utility', () => {
|
||||
it('should match the original file on stringification', () => {
|
||||
expect(stringifyNpmLockFile(parsedLockFile)).toEqual(lockFileV1);
|
||||
});
|
||||
|
||||
xit('should prune the lock file', () => {
|
||||
expect(
|
||||
Object.keys(
|
||||
pruneNpmLockFile(parsedLockFile, ['typescript']).dependencies
|
||||
).length
|
||||
).toEqual(1);
|
||||
expect(
|
||||
Object.keys(
|
||||
pruneNpmLockFile(parsedLockFile, ['yargs', '@nrwl/devkit'])
|
||||
.dependencies
|
||||
).length
|
||||
).toEqual(136);
|
||||
});
|
||||
|
||||
xit('should correctly prune lockfile with single package', () => {
|
||||
expect(
|
||||
stringifyNpmLockFile(pruneNpmLockFile(parsedLockFile, ['typescript']))
|
||||
).toEqual(lockFileV1JustTypescript);
|
||||
});
|
||||
|
||||
xit('should correctly prune lockfile with multiple packages', () => {
|
||||
expect(
|
||||
stringifyNpmLockFile(
|
||||
pruneNpmLockFile(parsedLockFile, ['yargs', '@nrwl/devkit'])
|
||||
)
|
||||
).toEqual(lockFileV1YargsAndDevkitOnly);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import { satisfies } from 'semver';
|
||||
import {
|
||||
LockFileData,
|
||||
PackageDependency,
|
||||
PackageVersions,
|
||||
} from './lock-file-type';
|
||||
import { sortObject, hashString } from './utils';
|
||||
import { LockFileData, PackageDependency } from './lock-file-type';
|
||||
import { sortObject, hashString, TransitiveLookupFunctionInput } from './utils';
|
||||
|
||||
type PackageMeta = {
|
||||
path: string;
|
||||
@ -22,6 +18,7 @@ type NpmDependency = {
|
||||
requires?: Record<string, string>;
|
||||
dependencies?: Record<string, NpmDependency>;
|
||||
dev?: boolean;
|
||||
peer?: boolean;
|
||||
devOptional?: boolean;
|
||||
optional?: boolean;
|
||||
};
|
||||
@ -146,10 +143,12 @@ function mapPackageDependency(
|
||||
lockfileVersion: number,
|
||||
isRootVersion?: boolean
|
||||
) {
|
||||
const { dev, peer, optional } = value;
|
||||
const packageMeta = {
|
||||
path: packagePath,
|
||||
dev: value.dev,
|
||||
optional: value.optional,
|
||||
dev,
|
||||
peer,
|
||||
optional,
|
||||
};
|
||||
if (!mappedPackages[packageName][key]) {
|
||||
// const packageDependencies = lockfileVersion === 1 ? requires : dependencies;
|
||||
@ -262,17 +261,29 @@ export function stringifyNpmLockFile(lockFileData: LockFileData): string {
|
||||
|
||||
// remapping the package back to package-lock format
|
||||
function unmapPackage(packages: Dependencies, dependency: PackageDependency) {
|
||||
const { packageMeta, rootVersion, version, resolved, integrity, ...value } =
|
||||
dependency;
|
||||
const {
|
||||
packageMeta,
|
||||
rootVersion,
|
||||
version,
|
||||
resolved,
|
||||
integrity,
|
||||
dev,
|
||||
peer,
|
||||
optional,
|
||||
...value
|
||||
} = dependency;
|
||||
// we need to decompose value, to achieve particular field ordering
|
||||
|
||||
for (let i = 0; i < packageMeta.length; i++) {
|
||||
const { path } = packageMeta[i];
|
||||
const { path, dev, peer, optional } = packageMeta[i];
|
||||
// we are sorting the properties to get as close as possible to the original package-lock.json
|
||||
packages[path] = {
|
||||
version,
|
||||
resolved,
|
||||
integrity,
|
||||
dev,
|
||||
peer,
|
||||
optional,
|
||||
...value,
|
||||
};
|
||||
}
|
||||
@ -286,7 +297,7 @@ function unmapDependencies(
|
||||
const { version, resolved, integrity, devOptional } = value;
|
||||
|
||||
for (let i = 0; i < packageMeta.length; i++) {
|
||||
const { path, dev, optional } = packageMeta[i];
|
||||
const { path, dev, optional, peer } = packageMeta[i];
|
||||
const projectPath = path.split('node_modules/').slice(1);
|
||||
|
||||
const requires = unmapDependencyRequires(value);
|
||||
@ -303,6 +314,7 @@ function unmapDependencies(
|
||||
dev,
|
||||
devOptional,
|
||||
optional,
|
||||
peer,
|
||||
requires,
|
||||
...innerDeps[packageName],
|
||||
};
|
||||
@ -373,27 +385,55 @@ function sortDependencies(
|
||||
/**
|
||||
* Returns matching version of the dependency
|
||||
*/
|
||||
export function transitiveDependencyNpmLookup(
|
||||
packageName: string,
|
||||
parentPackage: string,
|
||||
versions: PackageVersions,
|
||||
version: string
|
||||
): PackageDependency {
|
||||
const nestedVersion = Object.values(versions).find((v) =>
|
||||
v.packageMeta.some(
|
||||
(p) =>
|
||||
p.path.indexOf(`${parentPackage}/node_modules/${packageName}`) !== -1
|
||||
)
|
||||
);
|
||||
export function transitiveDependencyNpmLookup({
|
||||
packageName,
|
||||
parentPackages,
|
||||
versions,
|
||||
version,
|
||||
}: TransitiveLookupFunctionInput): PackageDependency {
|
||||
const packageDependencies = Object.values(versions);
|
||||
|
||||
if (nestedVersion) {
|
||||
return nestedVersion;
|
||||
for (let i = 0; i < packageDependencies.length; i++) {
|
||||
if (satisfies(packageDependencies[i].version, version)) {
|
||||
const packageMeta = packageDependencies[i].packageMeta.find((p) =>
|
||||
isPathMatching(p.path, packageName, parentPackages)
|
||||
);
|
||||
if (packageMeta) {
|
||||
return {
|
||||
...packageDependencies[i],
|
||||
packageMeta: [packageMeta],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise search for the matching version
|
||||
// otherwise return the root version
|
||||
return Object.values(versions).find((v) => v.rootVersion);
|
||||
}
|
||||
|
||||
function isPathMatching(
|
||||
path: string,
|
||||
packageName: string,
|
||||
parentPackages: string[]
|
||||
): boolean {
|
||||
const packages = path.split(/\/?node_modules\//).slice(1);
|
||||
if (packages[packages.length - 1] !== packageName) {
|
||||
return false;
|
||||
}
|
||||
const locations = parentPackages
|
||||
.map((p) => packages.indexOf(p))
|
||||
.filter((p) => p !== -1);
|
||||
if (locations.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < locations.length - 2; i++) {
|
||||
if (locations[i] > locations[i + 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes the lock file data based on the list of packages and their transitive dependencies
|
||||
*
|
||||
@ -402,11 +442,199 @@ export function transitiveDependencyNpmLookup(
|
||||
*/
|
||||
export function pruneNpmLockFile(
|
||||
lockFileData: LockFileData,
|
||||
packages: string[]
|
||||
packages: string[],
|
||||
projectName?: string
|
||||
): LockFileData {
|
||||
// todo(meeroslav): This functionality has not been implemented yet
|
||||
// NPM V1 does not track full dependency list in the lock file,
|
||||
// so we can't reuse the lock file to generate a new one
|
||||
if (lockFileData.lockFileMetadata.metadata.lockfileVersion === 1) {
|
||||
console.warn(
|
||||
'Pruning package-lock.json is not yet implemented. Returning entire lock file'
|
||||
`npm v7 is required to prune lockfile. Please upgrade to npm v7 or run "npm i --package-lock-only" to generate pruned lockfile.
|
||||
Returning entire lock file.`
|
||||
);
|
||||
return lockFileData;
|
||||
}
|
||||
const dependencies = pruneDependencies(lockFileData.dependencies, packages);
|
||||
const lockFileMetadata = {
|
||||
...lockFileData.lockFileMetadata,
|
||||
...pruneRootPackage(lockFileData, packages, projectName),
|
||||
};
|
||||
let prunedLockFileData: LockFileData;
|
||||
prunedLockFileData = { dependencies, lockFileMetadata, hash: '' };
|
||||
return prunedLockFileData;
|
||||
}
|
||||
|
||||
function pruneRootPackage(
|
||||
lockFileData: LockFileData,
|
||||
packages: string[],
|
||||
projectName?: string
|
||||
): Record<string, any> {
|
||||
if (lockFileData.lockFileMetadata.metadata.lockfileVersion === 1) {
|
||||
return undefined;
|
||||
}
|
||||
const rootPackage = {
|
||||
name: projectName || lockFileData.lockFileMetadata.rootPackage.name,
|
||||
version: lockFileData.lockFileMetadata.rootPackage.version,
|
||||
...(lockFileData.lockFileMetadata.rootPackage.license && {
|
||||
license: lockFileData.lockFileMetadata.rootPackage.license,
|
||||
}),
|
||||
dependencies: {} as Record<string, string>,
|
||||
};
|
||||
for (const packageName of packages) {
|
||||
const version = Object.values(lockFileData.dependencies[packageName]).find(
|
||||
(v) => v.rootVersion
|
||||
).version;
|
||||
rootPackage.dependencies[packageName] = version;
|
||||
}
|
||||
rootPackage.dependencies = sortObject(rootPackage.dependencies);
|
||||
|
||||
return { rootPackage };
|
||||
}
|
||||
|
||||
// iterate over packages to collect the affected tree of dependencies
|
||||
function pruneDependencies(
|
||||
dependencies: LockFileData['dependencies'],
|
||||
packages: string[]
|
||||
): LockFileData['dependencies'] {
|
||||
const result: LockFileData['dependencies'] = {};
|
||||
|
||||
packages.forEach((packageName) => {
|
||||
if (dependencies[packageName]) {
|
||||
const [key, { packageMeta, dev, peer, optional, ...value }] =
|
||||
Object.entries(dependencies[packageName]).find(
|
||||
([_, v]) => v.rootVersion
|
||||
);
|
||||
|
||||
result[packageName] = result[packageName] || {};
|
||||
result[packageName][key] = Object.assign(value, {
|
||||
packageMeta: [{ path: `node_modules/${packageName}` }],
|
||||
});
|
||||
|
||||
pruneTransitiveDependencies(
|
||||
[packageName],
|
||||
dependencies,
|
||||
result,
|
||||
result[packageName][key]
|
||||
);
|
||||
} else {
|
||||
console.warn(
|
||||
`Could not find ${packageName} in the lock file. Skipping...`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// find all transitive dependencies of already pruned packages
|
||||
// and adds them to the collection
|
||||
// recursively prune their dependencies
|
||||
function pruneTransitiveDependencies(
|
||||
parentPackages: string[],
|
||||
dependencies: LockFileData['dependencies'],
|
||||
prunedDeps: LockFileData['dependencies'],
|
||||
value: PackageDependency,
|
||||
modifier?: 'dev' | 'optional' | 'peer'
|
||||
): void {
|
||||
if (!value.dependencies && !value.peerDependencies) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.entries({
|
||||
...value.dependencies,
|
||||
...value.devDependencies,
|
||||
...value.peerDependencies,
|
||||
...value.optionalDependencies,
|
||||
}).forEach(([packageName, version]: [string, string]) => {
|
||||
const versions = dependencies[packageName];
|
||||
if (versions) {
|
||||
const dependency = transitiveDependencyNpmLookup({
|
||||
packageName,
|
||||
parentPackages,
|
||||
versions,
|
||||
version,
|
||||
});
|
||||
if (dependency) {
|
||||
// dev/optional/peer dependencies can be changed during the pruning process
|
||||
// so we need to update them
|
||||
if (!prunedDeps[packageName]) {
|
||||
prunedDeps[packageName] = {};
|
||||
}
|
||||
const key = `${packageName}@${dependency.version}`;
|
||||
if (prunedDeps[packageName][key]) {
|
||||
const currentMeta = prunedDeps[packageName][key].packageMeta;
|
||||
|
||||
if (
|
||||
!currentMeta.find((p) => p.path === dependency.packageMeta[0].path)
|
||||
) {
|
||||
const packageMeta = setPackageMetaModifiers(
|
||||
packageName,
|
||||
dependency,
|
||||
value,
|
||||
modifier
|
||||
);
|
||||
currentMeta.push(packageMeta);
|
||||
currentMeta.sort();
|
||||
}
|
||||
} else {
|
||||
const packageMeta = setPackageMetaModifiers(
|
||||
packageName,
|
||||
dependency,
|
||||
value,
|
||||
modifier
|
||||
);
|
||||
|
||||
dependency.packageMeta = [packageMeta];
|
||||
prunedDeps[packageName][key] = dependency;
|
||||
// recurively collect dependencies
|
||||
pruneTransitiveDependencies(
|
||||
[...parentPackages, packageName],
|
||||
dependencies,
|
||||
prunedDeps,
|
||||
prunedDeps[packageName][key],
|
||||
getModifier(packageMeta)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getModifier(
|
||||
packageMeta: PackageMeta
|
||||
): 'dev' | 'optional' | 'peer' | undefined {
|
||||
if (packageMeta.dev) {
|
||||
return 'dev';
|
||||
} else if (packageMeta.optional) {
|
||||
return 'optional';
|
||||
} else if (packageMeta.peer) {
|
||||
return 'peer';
|
||||
}
|
||||
}
|
||||
|
||||
function setPackageMetaModifiers(
|
||||
packageName: string,
|
||||
dependency: PackageDependency,
|
||||
parent: PackageDependency,
|
||||
modifier?: 'dev' | 'optional' | 'peer'
|
||||
): PackageMeta {
|
||||
const packageMeta: PackageMeta = { path: dependency.packageMeta[0].path };
|
||||
|
||||
if (parent.devDependencies?.[packageName]) {
|
||||
packageMeta.dev = true;
|
||||
} else if (parent.optionalDependencies?.[packageName]) {
|
||||
packageMeta.optional = true;
|
||||
} else if (parent.peerDependencies?.[packageName]) {
|
||||
packageMeta.peer = true;
|
||||
} else if (modifier === 'dev') {
|
||||
packageMeta.dev = true;
|
||||
} else if (modifier === 'optional') {
|
||||
packageMeta.optional = true;
|
||||
}
|
||||
// peer is carried over from the parent
|
||||
if (modifier === 'peer') {
|
||||
packageMeta.peer = true;
|
||||
}
|
||||
|
||||
return packageMeta;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ describe('pnpm LockFile utility', () => {
|
||||
|
||||
it('should parse lockfile correctly', () => {
|
||||
expect(parsedLockFile.lockFileMetadata).toEqual({ lockfileVersion: 5.4 });
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(324);
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(339);
|
||||
expect(
|
||||
parsedLockFile.dependencies['@ampproject/remapping']
|
||||
).toMatchSnapshot();
|
||||
@ -78,7 +78,7 @@ describe('pnpm LockFile utility', () => {
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
(
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.3']
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.4']
|
||||
.packageMeta[0] as any
|
||||
).specifier
|
||||
).toEqual('~4.8.2');
|
||||
@ -94,7 +94,7 @@ describe('pnpm LockFile utility', () => {
|
||||
).toEqual(false);
|
||||
expect(
|
||||
(
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.3']
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.4']
|
||||
.packageMeta[0] as any
|
||||
).isDevDependency
|
||||
).toEqual(true);
|
||||
@ -112,7 +112,7 @@ describe('pnpm LockFile utility', () => {
|
||||
expect(parsedLockFile.lockFileMetadata).toEqual({
|
||||
lockfileVersion: '5.4-inlineSpecifiers',
|
||||
});
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(324);
|
||||
expect(Object.keys(parsedLockFile.dependencies).length).toEqual(339);
|
||||
expect(
|
||||
parsedLockFile.dependencies['@ampproject/remapping']
|
||||
).toMatchSnapshot();
|
||||
@ -170,7 +170,7 @@ describe('pnpm LockFile utility', () => {
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
(
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.3']
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.4']
|
||||
.packageMeta[0] as any
|
||||
).specifier
|
||||
).toEqual('~4.8.2');
|
||||
@ -186,7 +186,7 @@ describe('pnpm LockFile utility', () => {
|
||||
).toEqual(false);
|
||||
expect(
|
||||
(
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.3']
|
||||
parsedLockFile.dependencies['typescript']['typescript@4.8.4']
|
||||
.packageMeta[0] as any
|
||||
).isDevDependency
|
||||
).toEqual(true);
|
||||
|
||||
@ -4,7 +4,12 @@ import {
|
||||
PackageVersions,
|
||||
} from './lock-file-type';
|
||||
import { load, dump } from '@zkochan/js-yaml';
|
||||
import { sortObject, hashString, isRootVersion } from './utils';
|
||||
import {
|
||||
sortObject,
|
||||
hashString,
|
||||
isRootVersion,
|
||||
TransitiveLookupFunctionInput,
|
||||
} from './utils';
|
||||
import { satisfies } from 'semver';
|
||||
|
||||
type PackageMeta = {
|
||||
@ -276,12 +281,10 @@ function unmapLockFile(lockFileData: LockFileData): PnpmLockFile {
|
||||
/**
|
||||
* Returns matching version of the dependency
|
||||
*/
|
||||
export function transitiveDependencyPnpmLookup(
|
||||
packageName: string,
|
||||
parentPackage: string,
|
||||
versions: PackageVersions,
|
||||
version: string
|
||||
): PackageDependency {
|
||||
export function transitiveDependencyPnpmLookup({
|
||||
versions,
|
||||
version,
|
||||
}: TransitiveLookupFunctionInput): PackageDependency {
|
||||
// pnpm's dependencies always point to the exact version so this block is only for insurrance
|
||||
return Object.values(versions).find((v) => satisfies(v.version, version));
|
||||
}
|
||||
@ -294,11 +297,59 @@ export function transitiveDependencyPnpmLookup(
|
||||
*/
|
||||
export function prunePnpmLockFile(
|
||||
lockFileData: LockFileData,
|
||||
packages: string[]
|
||||
packages: string[],
|
||||
projectName?: string
|
||||
): LockFileData {
|
||||
// todo(meeroslav): This functionality has not been implemented yet
|
||||
console.warn(
|
||||
'Pruning pnpm-lock.yaml is not yet implemented. Returning entire lock file'
|
||||
`Pruning pnpm is not yet supported.
|
||||
Returning entire lock file.`
|
||||
);
|
||||
return lockFileData;
|
||||
// const dependencies = pruneDependencies(
|
||||
// lockFileData.dependencies,
|
||||
// packages,
|
||||
// projectName
|
||||
// );
|
||||
// const prunedLockFileData = {
|
||||
// lockFileMetadata: lockFileData.lockFileMetadata,
|
||||
// dependencies,
|
||||
// hash: '',
|
||||
// };
|
||||
// return prunedLockFileData;
|
||||
}
|
||||
|
||||
// iterate over packages to collect the affected tree of dependencies
|
||||
function pruneDependencies(
|
||||
dependencies: LockFileData['dependencies'],
|
||||
packages: string[],
|
||||
projectName?: string
|
||||
): LockFileData['dependencies'] {
|
||||
const result: LockFileData['dependencies'] = {};
|
||||
|
||||
packages.forEach((packageName) => {
|
||||
if (dependencies[packageName]) {
|
||||
const [key, value] = Object.entries(dependencies[packageName]).find(
|
||||
([_, v]) => v.rootVersion
|
||||
);
|
||||
result[packageName] = result[packageName] || {};
|
||||
result[packageName][key] = value;
|
||||
pruneTransitiveDependencies([packageName], dependencies, result, value);
|
||||
} else {
|
||||
console.warn(
|
||||
`Could not find ${packageName} in the lock file. Skipping...`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// find all transitive dependencies of already pruned packages
|
||||
// and adds them to the collection
|
||||
// recursively prune their dependencies
|
||||
function pruneTransitiveDependencies(
|
||||
parentPackages: string[],
|
||||
dependencies: LockFileData['dependencies'],
|
||||
prunedDeps: LockFileData['dependencies'],
|
||||
value: PackageDependency
|
||||
): void {}
|
||||
|
||||
@ -83,11 +83,15 @@ export function getNodeName(
|
||||
return rootVersion ? `npm:${dep}` : `npm:${dep}@${version}`;
|
||||
}
|
||||
|
||||
export type TransitiveLookupFunctionInput = {
|
||||
packageName: string;
|
||||
parentPackages: string[];
|
||||
versions: PackageVersions;
|
||||
version: string;
|
||||
};
|
||||
|
||||
type TransitiveLookupFunction = (
|
||||
packageName: string,
|
||||
parentPackage: string,
|
||||
versions: PackageVersions,
|
||||
version: string
|
||||
data: TransitiveLookupFunctionInput
|
||||
) => PackageDependency;
|
||||
|
||||
export function mapExternalNodes(
|
||||
@ -127,7 +131,7 @@ export function mapExternalNodes(
|
||||
if (combinedDependencies) {
|
||||
const nodeDependencies = [];
|
||||
const transitiveDeps = mapTransitiveDependencies(
|
||||
packageName,
|
||||
[packageName],
|
||||
lockFileData.dependencies,
|
||||
combinedDependencies,
|
||||
versionCache,
|
||||
@ -152,7 +156,7 @@ export function mapExternalNodes(
|
||||
// Finds the maching version of each dependency of the package and
|
||||
// maps each {package}:{versionRange} pair to "npm:{package}@{version}" (when transitive) or "npm:{package}" (when root)
|
||||
function mapTransitiveDependencies(
|
||||
parentPackage: string,
|
||||
parentPackages: string[],
|
||||
packages: Record<string, PackageVersions>,
|
||||
dependencies: Record<string, string>,
|
||||
versionCache: Record<string, string>,
|
||||
@ -164,35 +168,37 @@ function mapTransitiveDependencies(
|
||||
const result: string[] = [];
|
||||
|
||||
Object.keys(dependencies).forEach((packageName) => {
|
||||
const versions = packages[packageName];
|
||||
// some of the peer dependencies might not be installed,
|
||||
// we don't have them as nodes in externalNodes
|
||||
// so there's no need to map them as dependencies
|
||||
if (!packages[packageName]) {
|
||||
if (!versions) {
|
||||
return;
|
||||
}
|
||||
|
||||
// fix for pnpm versions that might have suffixes - `1.2.3_@babel+core@4.5.6`
|
||||
const cleanVersion = dependencies[packageName].split('_')[0];
|
||||
const key = `${packageName}@${cleanVersion}`;
|
||||
const version = dependencies[packageName].split('_')[0];
|
||||
const key = `${packageName}@${version}`;
|
||||
|
||||
// if we already processed this dependency, use the version from the cache
|
||||
if (versionCache[key]) {
|
||||
result.push(versionCache[key]);
|
||||
} else {
|
||||
const version = packages[packageName][`${packageName}@${cleanVersion}`]
|
||||
? cleanVersion
|
||||
: transitiveLookupFn(
|
||||
const matchedVersion = versions[`${packageName}@${version}`]
|
||||
? version
|
||||
: transitiveLookupFn({
|
||||
packageName,
|
||||
parentPackage,
|
||||
packages[packageName],
|
||||
cleanVersion
|
||||
)?.version;
|
||||
parentPackages,
|
||||
versions,
|
||||
version,
|
||||
})?.version;
|
||||
|
||||
// for some peer dependencies, we won't find installed version so we'll just ignore these
|
||||
if (version) {
|
||||
if (matchedVersion) {
|
||||
const nodeName = getNodeName(
|
||||
packageName,
|
||||
version,
|
||||
packages[packageName][`${packageName}@${version}`]?.rootVersion
|
||||
matchedVersion,
|
||||
versions[`${packageName}@${matchedVersion}`]?.rootVersion
|
||||
);
|
||||
result.push(nodeName);
|
||||
versionCache[key] = nodeName;
|
||||
|
||||
@ -5,8 +5,12 @@ import {
|
||||
PackageDependency,
|
||||
PackageVersions,
|
||||
} from './lock-file-type';
|
||||
import { sortObject, hashString, isRootVersion } from './utils';
|
||||
import { satisfies } from 'semver';
|
||||
import {
|
||||
sortObject,
|
||||
hashString,
|
||||
isRootVersion,
|
||||
TransitiveLookupFunctionInput,
|
||||
} from './utils';
|
||||
|
||||
type LockFileDependencies = Record<
|
||||
string,
|
||||
@ -155,12 +159,11 @@ function unmapPackages(
|
||||
/**
|
||||
* Returns matching version of the dependency
|
||||
*/
|
||||
export function transitiveDependencyYarnLookup(
|
||||
packageName: string,
|
||||
parentPackage: string,
|
||||
versions: PackageVersions,
|
||||
version: string
|
||||
): PackageDependency {
|
||||
export function transitiveDependencyYarnLookup({
|
||||
packageName,
|
||||
versions,
|
||||
version,
|
||||
}: TransitiveLookupFunctionInput): PackageDependency {
|
||||
return Object.values(versions).find((v) =>
|
||||
v.packageMeta.some(
|
||||
(p) =>
|
||||
@ -178,7 +181,8 @@ export function transitiveDependencyYarnLookup(
|
||||
*/
|
||||
export function pruneYarnLockFile(
|
||||
lockFileData: LockFileData,
|
||||
packages: string[]
|
||||
packages: string[],
|
||||
projectName?: string
|
||||
): LockFileData {
|
||||
const isBerry = !!lockFileData.lockFileMetadata?.__metadata;
|
||||
const prunedDependencies = pruneDependencies(
|
||||
@ -195,7 +199,8 @@ export function pruneYarnLockFile(
|
||||
workspacePackages: pruneWorkspacePackages(
|
||||
workspacePackages,
|
||||
prunedDependencies,
|
||||
packages
|
||||
packages,
|
||||
projectName
|
||||
),
|
||||
},
|
||||
dependencies: prunedDependencies,
|
||||
@ -257,7 +262,8 @@ function pruneTransitiveDependencies(
|
||||
version
|
||||
);
|
||||
if (dependencyTriplet) {
|
||||
const [key, { packageMeta, ...value }, metaVersion] = dependencyTriplet;
|
||||
const [key, { packageMeta, ...depValue }, metaVersion] =
|
||||
dependencyTriplet;
|
||||
if (!prunedDeps[packageName]) {
|
||||
prunedDeps[packageName] = {};
|
||||
}
|
||||
@ -270,7 +276,7 @@ function pruneTransitiveDependencies(
|
||||
}
|
||||
} else {
|
||||
prunedDeps[packageName][key] = {
|
||||
...value,
|
||||
...depValue,
|
||||
packageMeta: [metaVersion],
|
||||
};
|
||||
// recurively collect dependencies
|
||||
@ -289,7 +295,8 @@ function pruneTransitiveDependencies(
|
||||
function pruneWorkspacePackages(
|
||||
workspacePackages: LockFileDependencies,
|
||||
prunedDependencies: LockFileData['dependencies'],
|
||||
packages: string[]
|
||||
packages: string[],
|
||||
projectName?: string
|
||||
): LockFileDependencies {
|
||||
const result: LockFileDependencies = {};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user