diff --git a/package-lock.json b/package-lock.json index 03fd86d779..91564946da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,7 @@ "snyk-gradle-plugin": "3.26.4", "snyk-module": "3.1.0", "snyk-mvn-plugin": "2.32.3", - "snyk-nodejs-lockfile-parser": "1.49.0", + "snyk-nodejs-lockfile-parser": "1.51.0", "snyk-nuget-plugin": "1.24.1", "snyk-php-plugin": "1.9.2", "snyk-policy": "^1.25.0", @@ -17567,9 +17567,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/snyk-nodejs-lockfile-parser": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.49.0.tgz", - "integrity": "sha512-73iqwHB8YSWex/PTx+TRUwtNPyKn5wP4n/kxEPbX9EfN3uSIcw6mSKiLm8gSKl5gtf8hcP0R0f1tBFjjdzQvRQ==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.51.0.tgz", + "integrity": "sha512-uepLn2WELhgAVoYZ7QOt3nFwBVZvJAUfdDyebhb2Wqn5ftTthELzUp5/kCqxOXWoXBSg2KQIjI42U7SRq8gxLg==", "dependencies": { "@snyk/dep-graph": "^2.3.0", "@snyk/graphlib": "2.1.9-patch.3", @@ -34680,9 +34680,9 @@ } }, "snyk-nodejs-lockfile-parser": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.49.0.tgz", - "integrity": "sha512-73iqwHB8YSWex/PTx+TRUwtNPyKn5wP4n/kxEPbX9EfN3uSIcw6mSKiLm8gSKl5gtf8hcP0R0f1tBFjjdzQvRQ==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.51.0.tgz", + "integrity": "sha512-uepLn2WELhgAVoYZ7QOt3nFwBVZvJAUfdDyebhb2Wqn5ftTthELzUp5/kCqxOXWoXBSg2KQIjI42U7SRq8gxLg==", "requires": { "@snyk/dep-graph": "^2.3.0", "@snyk/graphlib": "2.1.9-patch.3", diff --git a/package.json b/package.json index f7f4bbaa00..5f36bb18a9 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "snyk-gradle-plugin": "3.26.4", "snyk-module": "3.1.0", "snyk-mvn-plugin": "2.32.3", - "snyk-nodejs-lockfile-parser": "1.49.0", + "snyk-nodejs-lockfile-parser": "1.51.0", "snyk-nuget-plugin": "1.24.1", "snyk-php-plugin": "1.9.2", "snyk-policy": "^1.25.0", diff --git a/src/lib/plugins/nodejs-plugin/npm-lock-parser.ts b/src/lib/plugins/nodejs-plugin/npm-lock-parser.ts index 9184ecdead..ff92b87b33 100644 --- a/src/lib/plugins/nodejs-plugin/npm-lock-parser.ts +++ b/src/lib/plugins/nodejs-plugin/npm-lock-parser.ts @@ -122,13 +122,24 @@ async function buildDepGraph( return await lockFileParser.parseYarnLockV1Project( manifestFileContents, lockFileContents, - options, + { + includeDevDeps: options.includeDevDeps, + includeOptionalDeps: options.includeOptionalDeps, + includePeerDeps: options.includePeerDeps || false, + pruneLevel: 'withinTopLevelDeps', + strictOutOfSync: options.strictOutOfSync, + }, ); case NodeLockfileVersion.YarnLockV2: return await lockFileParser.parseYarnLockV2Project( manifestFileContents, lockFileContents, - options, + { + includeDevDeps: options.includeDevDeps, + includeOptionalDeps: options.includeOptionalDeps, + pruneWithinTopLevelDeps: true, + strictOutOfSync: options.strictOutOfSync, + }, ); case NodeLockfileVersion.NpmLockV2: case NodeLockfileVersion.NpmLockV3: diff --git a/src/lib/plugins/nodejs-plugin/yarn-workspaces-parser.ts b/src/lib/plugins/nodejs-plugin/yarn-workspaces-parser.ts index 8268f7269d..3972ec3a9a 100644 --- a/src/lib/plugins/nodejs-plugin/yarn-workspaces-parser.ts +++ b/src/lib/plugins/nodejs-plugin/yarn-workspaces-parser.ts @@ -12,6 +12,7 @@ import { } from '../get-multi-plugin-result'; import { getFileContents } from '../../get-file-contents'; import { NoSupportedManifestsFoundError } from '../../errors'; +import { DepGraph } from '@snyk/dep-graph'; export async function processYarnWorkspaces( root: string, @@ -51,7 +52,6 @@ export async function processYarnWorkspaces( }, scannedProjects: [], }; - let rootWorkspaceManifestContent = {}; // the folders must be ordered highest first for (const directory of Object.keys(yarnTargetFiles)) { debug(`Processing ${directory} as a potential Yarn workspace`); @@ -63,6 +63,7 @@ export async function processYarnWorkspaces( ...yarnWorkspacesMap, ...getWorkspacesMap(packageJson), }; + for (const workspaceRoot of Object.keys(yarnWorkspacesMap)) { const match = packageJsonBelongsToWorkspace( packageJsonFileName, @@ -78,7 +79,6 @@ export async function processYarnWorkspaces( } if (packageJsonFileName === workspaceRoot) { isRootPackageJson = true; - rootWorkspaceManifestContent = JSON.parse(packageJson.content); } } @@ -88,36 +88,57 @@ export async function processYarnWorkspaces( ); continue; } + try { const rootDir = isYarnWorkspacePackage ? pathUtil.dirname(yarnWorkspacesFilesMap[packageJsonFileName].root) : pathUtil.dirname(packageJsonFileName); const rootYarnLockfileName = pathUtil.join(rootDir, 'yarn.lock'); const yarnLock = getFileContents(root, rootYarnLockfileName); - - if ( - rootWorkspaceManifestContent.hasOwnProperty('resolutions') && - lockFileParser.getYarnLockfileType(yarnLock.content) === - lockFileParser.LockfileType.yarn2 - ) { - const parsedManifestContent = JSON.parse(packageJson.content); - packageJson.content = JSON.stringify({ - ...parsedManifestContent, - resolutions: rootWorkspaceManifestContent['resolutions'], - }); - } - - const res = await lockFileParser.buildDepTree( - packageJson.content, + const lockfileVersion = lockFileParser.getYarnLockfileVersion( yarnLock.content, - settings.dev, - lockFileParser.LockfileType.yarn, - settings.strictOutOfSync !== false, ); + + let res: DepGraph; + switch (lockfileVersion) { + case lockFileParser.NodeLockfileVersion.YarnLockV1: + res = await lockFileParser.parseYarnLockV1Project( + packageJson.content, + yarnLock.content, + { + includeDevDeps: settings.dev || false, + includeOptionalDeps: false, + includePeerDeps: false, + pruneLevel: 'withinTopLevelDeps', + strictOutOfSync: + settings.strictOutOfSync === undefined + ? true + : settings.strictOutOfSync, + }, + ); + break; + case lockFileParser.NodeLockfileVersion.YarnLockV2: + res = await lockFileParser.parseYarnLockV2Project( + packageJson.content, + yarnLock.content, + { + includeDevDeps: settings.dev || false, + includeOptionalDeps: false, + pruneWithinTopLevelDeps: true, + strictOutOfSync: + settings.strictOutOfSync === undefined + ? true + : settings.strictOutOfSync, + }, + ); + break; + default: + throw new Error('Failed to build dep graph from current project'); + } const project: ScannedProjectCustom = { packageManager: 'yarn', targetFile: pathUtil.relative(root, packageJson.fileName), - depTree: res as any, + depGraph: res as any, plugin: { name: 'snyk-nodejs-lockfile-parser', runtime: process.version, diff --git a/test/tap/cli-test/cli-test.yarn-workspaces.spec.ts b/test/tap/cli-test/cli-test.yarn-workspaces.spec.ts index e71fa65523..a98ef2abf3 100644 --- a/test/tap/cli-test/cli-test.yarn-workspaces.spec.ts +++ b/test/tap/cli-test/cli-test.yarn-workspaces.spec.ts @@ -22,7 +22,7 @@ export const YarnWorkspacesTests: AcceptanceTests = { t.equal( e.message, '\nTesting yarn-workspace-out-of-sync...\n\n' + - 'Dependency snyk was not found in yarn.lock.' + + 'Dependency snyk@1.320.0 was not found in yarn.lock.' + ' Your package.json and yarn.lock are probably out of sync.' + ' Please run "yarn install" and try again.', 'Contains enough info about err',