fix(core): fix lock file pruning optional dependencies (#13830)

This commit is contained in:
Denis Frenademetz 2022-12-15 10:49:00 +01:00 committed by GitHub
parent 3149b66036
commit a2adf50786
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1498 additions and 15 deletions

View File

@ -22642,3 +22642,313 @@ export const lockFileV1YargsAndDevkitOnly = `{
} }
} }
`; `;
export const ssh2LockFileV1 = `{
"name": "test",
"version": "0.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"buildcheck": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz",
"integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==",
"optional": true
},
"cpu-features": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz",
"integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==",
"optional": true,
"requires": {
"buildcheck": "0.0.3",
"nan": "^2.15.0"
}
},
"nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"ssh2": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz",
"integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==",
"requires": {
"asn1": "^0.2.4",
"bcrypt-pbkdf": "^1.0.2",
"cpu-features": "~0.0.4",
"nan": "^2.16.0"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
}
}
}
`;
export const ssh2LockFileV2 = `{
"name": "test",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "test",
"version": "0.0.0",
"license": "ISC",
"dependencies": {
"ssh2": "1.11.0"
}
},
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"dependencies": {
"safer-buffer": "~2.1.0"
}
},
"node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"dependencies": {
"tweetnacl": "^0.14.3"
}
},
"node_modules/buildcheck": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz",
"integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==",
"optional": true,
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/cpu-features": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz",
"integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==",
"optional": true,
"hasInstallScript": true,
"dependencies": {
"buildcheck": "0.0.3",
"nan": "^2.15.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"optional": true
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/ssh2": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz",
"integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==",
"hasInstallScript": true,
"dependencies": {
"asn1": "^0.2.4",
"bcrypt-pbkdf": "^1.0.2"
},
"engines": {
"node": ">=10.16.0"
},
"optionalDependencies": {
"cpu-features": "~0.0.4",
"nan": "^2.16.0"
}
},
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
}
},
"dependencies": {
"asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"buildcheck": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz",
"integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==",
"optional": true
},
"cpu-features": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz",
"integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==",
"optional": true,
"requires": {
"buildcheck": "0.0.3",
"nan": "^2.15.0"
}
},
"nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"ssh2": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz",
"integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==",
"requires": {
"asn1": "^0.2.4",
"bcrypt-pbkdf": "^1.0.2",
"cpu-features": "~0.0.4",
"nan": "^2.16.0"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
}
}
}
`;
export const ssh2LockFileV3 = `{
"name": "test",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "test",
"version": "0.0.0",
"license": "ISC",
"dependencies": {
"ssh2": "1.11.0"
}
},
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"dependencies": {
"safer-buffer": "~2.1.0"
}
},
"node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"dependencies": {
"tweetnacl": "^0.14.3"
}
},
"node_modules/buildcheck": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz",
"integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==",
"optional": true,
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/cpu-features": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz",
"integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==",
"optional": true,
"hasInstallScript": true,
"dependencies": {
"buildcheck": "0.0.3",
"nan": "^2.15.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"optional": true
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/ssh2": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz",
"integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==",
"hasInstallScript": true,
"dependencies": {
"asn1": "^0.2.4",
"bcrypt-pbkdf": "^1.0.2"
},
"engines": {
"node": ">=10.16.0"
},
"optionalDependencies": {
"cpu-features": "~0.0.4",
"nan": "^2.16.0"
}
},
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
}
}
}
`;

View File

@ -6739,3 +6739,67 @@ packages:
yargs-parser: 21.1.1 yargs-parser: 21.1.1
dev: false dev: false
`; `;
export const ssh2LockFile = `lockfileVersion: 5.4
specifiers:
ssh2: 1.11.0
dependencies:
ssh2: 1.11.0
packages:
/asn1/0.2.6:
resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
dependencies:
safer-buffer: 2.1.2
dev: false
/bcrypt-pbkdf/1.0.2:
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
dependencies:
tweetnacl: 0.14.5
dev: false
/buildcheck/0.0.3:
resolution: {integrity: sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==}
engines: {node: '>=10.0.0'}
dev: false
optional: true
/cpu-features/0.0.4:
resolution: {integrity: sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==}
engines: {node: '>=10.0.0'}
requiresBuild: true
dependencies:
buildcheck: 0.0.3
nan: 2.17.0
dev: false
optional: true
/nan/2.17.0:
resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==}
dev: false
optional: true
/safer-buffer/2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
dev: false
/ssh2/1.11.0:
resolution: {integrity: sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==}
engines: {node: '>=10.16.0'}
requiresBuild: true
dependencies:
asn1: 0.2.6
bcrypt-pbkdf: 1.0.2
optionalDependencies:
cpu-features: 0.0.4
nan: 2.17.0
dev: false
/tweetnacl/0.14.5:
resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
dev: false
`;

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,9 @@ import {
lockFileV1JustTypescript, lockFileV1JustTypescript,
lockFileV1YargsAndDevkitOnly, lockFileV1YargsAndDevkitOnly,
lockFileV2YargsAndDevkitOnly, lockFileV2YargsAndDevkitOnly,
ssh2LockFileV2,
ssh2LockFileV3,
ssh2LockFileV1,
} from './__fixtures__/npm.lock'; } from './__fixtures__/npm.lock';
import { vol } from 'memfs'; import { vol } from 'memfs';
import { npmLockFileWithWorkspaces } from './__fixtures__/workspaces.lock'; import { npmLockFileWithWorkspaces } from './__fixtures__/workspaces.lock';
@ -38,6 +41,13 @@ const YargsAndDevkitPackage = {
version: '0.0.0', version: '0.0.0',
dependencies: { '@nrwl/devkit': '15.0.13', yargs: '17.6.2' }, dependencies: { '@nrwl/devkit': '15.0.13', yargs: '17.6.2' },
}; };
const Ssh2Package = {
name: 'test',
version: '0.0.0',
dependencies: {
ssh2: '1.11.0',
},
};
describe('npm LockFile utility', () => { describe('npm LockFile utility', () => {
describe('v3', () => { describe('v3', () => {
@ -158,6 +168,14 @@ describe('npm LockFile utility', () => {
) )
).toEqual(JSON.parse(lockFileV3YargsAndDevkitOnly)); ).toEqual(JSON.parse(lockFileV3YargsAndDevkitOnly));
}); });
it('should correctly prune lockfile with package that has optional dependencies', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parseNpmLockFile(ssh2LockFileV3), Ssh2Package)
)
).toEqual(ssh2LockFileV3);
});
}); });
describe('v2', () => { describe('v2', () => {
@ -284,6 +302,14 @@ describe('npm LockFile utility', () => {
JSON.parse(lockFileV2YargsAndDevkitOnly) JSON.parse(lockFileV2YargsAndDevkitOnly)
); );
}); });
it('should correctly prune lockfile with package that has optional dependencies', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parseNpmLockFile(ssh2LockFileV2), Ssh2Package)
)
).toEqual(ssh2LockFileV2);
});
}); });
describe('v1', () => { describe('v1', () => {
@ -404,6 +430,14 @@ describe('npm LockFile utility', () => {
JSON.parse(lockFileV1YargsAndDevkitOnly) JSON.parse(lockFileV1YargsAndDevkitOnly)
); );
}); });
it('should correctly prune lockfile with package that has optional dependencies', () => {
expect(
stringifyNpmLockFile(
pruneNpmLockFile(parseNpmLockFile(ssh2LockFileV1), Ssh2Package)
)
).toEqual(ssh2LockFileV1);
});
}); });
}); });
}); });

View File

@ -791,6 +791,8 @@ function setPackageMetaModifiers(
if (parent.devDependencies?.[packageName]) { if (parent.devDependencies?.[packageName]) {
packageMeta.dev = true; packageMeta.dev = true;
} else if (dependency.optional) {
packageMeta.optional = true;
} else if (parent.optionalDependencies?.[packageName]) { } else if (parent.optionalDependencies?.[packageName]) {
packageMeta.optional = true; packageMeta.optional = true;
} else if (parent.peerDependencies?.[packageName]) { } else if (parent.peerDependencies?.[packageName]) {

View File

@ -8,6 +8,7 @@ import {
lockFileJustTypescript, lockFileJustTypescript,
lockFileWithInlineSpecifiers, lockFileWithInlineSpecifiers,
lockFileYargsAndDevkit, lockFileYargsAndDevkit,
ssh2LockFile,
} from './__fixtures__/pnpm.lock'; } from './__fixtures__/pnpm.lock';
import { import {
pnpmLockFileWithInlineSpecifiersAndWorkspaces, pnpmLockFileWithInlineSpecifiersAndWorkspaces,
@ -24,6 +25,13 @@ const YargsAndDevkitPackage = {
version: '1.2.3', version: '1.2.3',
dependencies: { '@nrwl/devkit': '15.0.13', yargs: '17.6.2' }, dependencies: { '@nrwl/devkit': '15.0.13', yargs: '17.6.2' },
}; };
const Ssh2Package = {
name: 'test',
version: '0.0.0',
dependencies: {
ssh2: '1.11.0',
},
};
describe('pnpm LockFile utility', () => { describe('pnpm LockFile utility', () => {
describe('standard lock file', () => { describe('standard lock file', () => {
@ -153,6 +161,14 @@ describe('pnpm LockFile utility', () => {
) )
).toEqual(lockFileYargsAndDevkit); ).toEqual(lockFileYargsAndDevkit);
}); });
it('should correctly prune lockfile with package that has optional dependencies', () => {
expect(
stringifyPnpmLockFile(
prunePnpmLockFile(parsePnpmLockFile(ssh2LockFile), Ssh2Package)
)
).toEqual(ssh2LockFile);
});
}); });
it('should parse lockfile with time-based resolution and workspaces', () => { it('should parse lockfile with time-based resolution and workspaces', () => {

View File

@ -539,7 +539,10 @@ function pruneTransitiveDependencies(
rootVersion: false, rootVersion: false,
packageMeta: [packageMeta], packageMeta: [packageMeta],
}); });
if (parent.optionalDependencies?.[packageName]) { if (
parent.packageMeta[0].optional ||
parent.optionalDependencies?.[packageName]
) {
packageMeta.optional = true; packageMeta.optional = true;
} }
pruneTransitiveDependencies( pruneTransitiveDependencies(

View File

@ -3,6 +3,7 @@ export interface PackageDependency {
rootVersion?: boolean; rootVersion?: boolean;
packageMeta: any[]; packageMeta: any[];
dependencies?: Record<string, string>; dependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
name?: string; name?: string;
[key: string]: any; [key: string]: any;
} }

View File

@ -4,11 +4,13 @@ import {
stringifyYarnLockFile, stringifyYarnLockFile,
} from './yarn'; } from './yarn';
import { import {
lockFile,
berryLockFile, berryLockFile,
lockFileJustTypescript,
lockFileDevkitAndYargs,
berryLockFileDevkitAndYargs, berryLockFileDevkitAndYargs,
berrySsh2LockFile,
lockFile,
lockFileDevkitAndYargs,
lockFileJustTypescript,
ssh2LockFile,
} from './__fixtures__/yarn.lock'; } from './__fixtures__/yarn.lock';
const TypeScriptOnlyPackage = { const TypeScriptOnlyPackage = {
@ -30,6 +32,13 @@ const YargsDevkitTypescriptPackage = {
yargs: '17.6.2', yargs: '17.6.2',
}, },
}; };
const Ssh2Package = {
name: 'test',
version: '0.0.0',
dependencies: {
ssh2: '1.11.0',
},
};
describe('yarn LockFile utility', () => { describe('yarn LockFile utility', () => {
describe('classic', () => { describe('classic', () => {
@ -85,7 +94,7 @@ describe('yarn LockFile utility', () => {
expect(stringifyYarnLockFile(parsedLockFile)).toEqual(lockFile); expect(stringifyYarnLockFile(parsedLockFile)).toEqual(lockFile);
}); });
it('shold prune the lock file', () => { it('should prune the lock file', () => {
expect( expect(
Object.keys( Object.keys(
pruneYarnLockFile(parsedLockFile, TypeScriptOnlyPackage).dependencies pruneYarnLockFile(parsedLockFile, TypeScriptOnlyPackage).dependencies
@ -98,7 +107,7 @@ describe('yarn LockFile utility', () => {
).toEqual(36); ).toEqual(36);
}); });
it('shold correctly prune lockfile with single package', () => { it('should correctly prune lockfile with single package', () => {
expect( expect(
stringifyYarnLockFile( stringifyYarnLockFile(
pruneYarnLockFile(parsedLockFile, TypeScriptOnlyPackage) pruneYarnLockFile(parsedLockFile, TypeScriptOnlyPackage)
@ -106,13 +115,21 @@ describe('yarn LockFile utility', () => {
).toEqual(lockFileJustTypescript); ).toEqual(lockFileJustTypescript);
}); });
it('shold correctly prune lockfile with multiple packages', () => { it('should correctly prune lockfile with multiple packages', () => {
expect( expect(
stringifyYarnLockFile( stringifyYarnLockFile(
pruneYarnLockFile(parsedLockFile, YargsAndDevkitPackage) pruneYarnLockFile(parsedLockFile, YargsAndDevkitPackage)
) )
).toEqual(lockFileDevkitAndYargs); ).toEqual(lockFileDevkitAndYargs);
}); });
it('should correctly prune lockfile with package that has optional dependencies', () => {
expect(
stringifyYarnLockFile(
pruneYarnLockFile(parseYarnLockFile(ssh2LockFile), Ssh2Package)
)
).toEqual(ssh2LockFile);
});
}); });
describe('berry', () => { describe('berry', () => {
@ -179,7 +196,7 @@ describe('yarn LockFile utility', () => {
expect(removeComment(result)).toEqual(removeComment(berryLockFile)); expect(removeComment(result)).toEqual(removeComment(berryLockFile));
}); });
it('shold prune the lock file', () => { it('should prune the lock file', () => {
expect( expect(
Object.keys( Object.keys(
pruneYarnLockFile(parsedLockFile, YargsDevkitTypescriptPackage) pruneYarnLockFile(parsedLockFile, YargsDevkitTypescriptPackage)
@ -188,7 +205,7 @@ describe('yarn LockFile utility', () => {
).toEqual(37); ).toEqual(37);
}); });
it('shold correctly prune lockfile with multiple packages', () => { it('should correctly prune lockfile with multiple packages', () => {
const result = stringifyYarnLockFile( const result = stringifyYarnLockFile(
pruneYarnLockFile(parsedLockFile, YargsDevkitTypescriptPackage) pruneYarnLockFile(parsedLockFile, YargsDevkitTypescriptPackage)
); );
@ -197,7 +214,7 @@ describe('yarn LockFile utility', () => {
); );
}); });
it('shold correctly prune lockfile with multiple packages and custom name', () => { it('should correctly prune lockfile with multiple packages and custom name', () => {
const result = pruneYarnLockFile(parsedLockFile, { const result = pruneYarnLockFile(parsedLockFile, {
...YargsDevkitTypescriptPackage, ...YargsDevkitTypescriptPackage,
name: 'custom-name', name: 'custom-name',
@ -218,6 +235,16 @@ describe('yarn LockFile utility', () => {
} }
`); `);
}); });
it('should correctly prune lockfile with package that has optional dependencies', () => {
expect(
removeComment(
stringifyYarnLockFile(
pruneYarnLockFile(parseYarnLockFile(berrySsh2LockFile), Ssh2Package)
)
)
).toEqual(removeComment(berrySsh2LockFile));
});
}); });
}); });

View File

@ -296,11 +296,10 @@ function pruneTransitiveDependencies(
prunedDeps: LockFileData['dependencies'], prunedDeps: LockFileData['dependencies'],
value: PackageDependency value: PackageDependency
): void { ): void {
if (!value.dependencies) { [
return; ...Object.entries(value.dependencies ?? {}),
} ...Object.entries(value.optionalDependencies ?? {}),
].forEach(([packageName, version]) => {
Object.entries(value.dependencies).forEach(([packageName, version]) => {
if (dependencies[packageName]) { if (dependencies[packageName]) {
// check if package with given version exists in data // check if package with given version exists in data
// if yes, return key, value and version expression from packageMeta // if yes, return key, value and version expression from packageMeta