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