diff --git a/pkg/dependency/parser/nodejs/npm/parse.go b/pkg/dependency/parser/nodejs/npm/parse.go index 05ce6301ff09..4956f9b1cd10 100644 --- a/pkg/dependency/parser/nodejs/npm/parse.go +++ b/pkg/dependency/parser/nodejs/npm/parse.go @@ -43,6 +43,7 @@ type Package struct { Dependencies map[string]string `json:"dependencies"` OptionalDependencies map[string]string `json:"optionalDependencies"` DevDependencies map[string]string `json:"devDependencies"` + PeerDependencies map[string]string `json:"peerDependencies"` Resolved string `json:"resolved"` Dev bool `json:"dev"` Link bool `json:"link"` @@ -91,7 +92,7 @@ func (p *Parser) parseV2(packages map[string]Package) ([]ftypes.Package, []ftype p.resolveLinks(packages) directDeps := make(map[string]struct{}) - for name, version := range lo.Assign(packages[""].Dependencies, packages[""].OptionalDependencies, packages[""].DevDependencies) { + for name, version := range lo.Assign(packages[""].Dependencies, packages[""].OptionalDependencies, packages[""].DevDependencies, packages[""].PeerDependencies) { pkgPath := joinPaths(nodeModulesDir, name) if _, ok := packages[pkgPath]; !ok { p.logger.Debug("Unable to find the direct dependency", @@ -165,7 +166,7 @@ func (p *Parser) parseV2(packages map[string]Package) ([]ftypes.Package, []ftype // └─┬ watchpack@1.7.5 // ├─┬ chokidar@3.5.3 - optional dependency // │ └── glob-parent@5.1. - dependencies := lo.Assign(pkg.Dependencies, pkg.OptionalDependencies) + dependencies := lo.Assign(pkg.Dependencies, pkg.OptionalDependencies, pkg.PeerDependencies) dependsOn := make([]string, 0, len(dependencies)) for depName, depVersion := range dependencies { depID, err := findDependsOn(pkgPath, depName, packages) diff --git a/pkg/dependency/parser/nodejs/npm/parse_test.go b/pkg/dependency/parser/nodejs/npm/parse_test.go index 7b0b5042c831..4400fab3201b 100644 --- a/pkg/dependency/parser/nodejs/npm/parse_test.go +++ b/pkg/dependency/parser/nodejs/npm/parse_test.go @@ -41,6 +41,12 @@ func TestParse(t *testing.T) { want: npmV3WithWorkspacePkgs, wantDeps: npmV3WithWorkspaceDeps, }, + { + name: "lock version v3 with peer dependencies", + file: "testdata/package-lock_v3_with_peer.json", + want: npmV3WithPeerDependenciesPkgs, + wantDeps: npmV3WithPeerDependenciesDeps, + }, { name: "lock file v3 contains same dev and non-dev dependencies", file: "testdata/package-lock_v3_with-same-dev-and-non-dev.json", diff --git a/pkg/dependency/parser/nodejs/npm/parse_testcase.go b/pkg/dependency/parser/nodejs/npm/parse_testcase.go index 01dcac6711f9..21e99e29c36b 100644 --- a/pkg/dependency/parser/nodejs/npm/parse_testcase.go +++ b/pkg/dependency/parser/nodejs/npm/parse_testcase.go @@ -1442,6 +1442,120 @@ var ( DependsOn: []string{"debug@2.6.9"}, }, } + // docker run --name node --rm -it node@sha256:51dd437f31812df71108b81385e2945071ec813d5815fa3403855669c8f3432b sh + // mkdir node_v3_with_peer && cd node_v3_with_peer + // npm init --force + // npm install --save winston-mail@2.0.0 + // npm install --save-peer lodash@4.17.21 + // npm update + // + // Delete unnecessary packages from package-lock.json + // Packages are filled manually + npmV3WithPeerDependenciesPkgs = []ftypes.Package{ + { + ID: "lodash@4.17.21", + Name: "lodash", + Version: "4.17.21", + Relationship: ftypes.RelationshipDirect, + ExternalReferences: []ftypes.ExternalRef{ + { + Type: ftypes.RefOther, + URL: "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + }, + }, + Locations: []ftypes.Location{ + { + StartLine: 30, + EndLine: 36, + }, + }, + }, + { + ID: "winston-mail@2.0.0", + Name: "winston-mail", + Version: "2.0.0", + Relationship: ftypes.RelationshipDirect, + ExternalReferences: []ftypes.ExternalRef{ + { + Type: ftypes.RefOther, + URL: "https://registry.npmjs.org/winston-mail/-/winston-mail-2.0.0.tgz", + }, + }, + Locations: []ftypes.Location{ + { + StartLine: 60, + EndLine: 74, + }, + }, + }, + { + ID: "mustache@2.3.2", + Name: "mustache", + Version: "2.3.2", + Relationship: ftypes.RelationshipIndirect, + ExternalReferences: []ftypes.ExternalRef{ + { + Type: ftypes.RefOther, + URL: "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", + }, + }, + Locations: []ftypes.Location{ + { + StartLine: 18, + EndLine: 29, + }, + }, + }, + { + ID: "triple-beam@1.4.1", + Name: "triple-beam", + Version: "1.4.1", + Relationship: ftypes.RelationshipIndirect, + ExternalReferences: []ftypes.ExternalRef{ + { + Type: ftypes.RefOther, + URL: "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + }, + }, + Locations: []ftypes.Location{ + { + StartLine: 37, + EndLine: 46, + }, + }, + }, + { + ID: "winston@3.17.0", + Name: "winston", + Version: "3.17.0", + Relationship: ftypes.RelationshipIndirect, + ExternalReferences: []ftypes.ExternalRef{ + { + Type: ftypes.RefOther, + URL: "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + }, + }, + Locations: []ftypes.Location{ + { + StartLine: 47, + EndLine: 59, + }, + }, + }, + } + npmV3WithPeerDependenciesDeps = []ftypes.Dependency{ + { + ID: "winston-mail@2.0.0", + DependsOn: []string{ + "mustache@2.3.2", + "winston@3.17.0", + }, + }, + { + ID: "winston@3.17.0", + DependsOn: []string{"triple-beam@1.4.1"}, + }, + } // docker run --name node --rm -it node@sha256:51dd437f31812df71108b81385e2945071ec813d5815fa3403855669c8f3432b sh // mkdir node_v3_without_direct_deps && cd node_v3_without_direct_deps diff --git a/pkg/dependency/parser/nodejs/npm/testdata/package-lock_v3_with_peer.json b/pkg/dependency/parser/nodejs/npm/testdata/package-lock_v3_with_peer.json new file mode 100644 index 000000000000..51e0b7351796 --- /dev/null +++ b/pkg/dependency/parser/nodejs/npm/testdata/package-lock_v3_with_peer.json @@ -0,0 +1,76 @@ +{ + "name": "node_v3_with_peer", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "node_v3_with_peer", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "winston-mail": "^2.0.0" + }, + "peerDependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/mustache": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", + "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + }, + "engines": { + "npm": ">=1.4.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT", + "peer": true + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", + "peer": true, + "dependencies": { + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-mail": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/winston-mail/-/winston-mail-2.0.0.tgz", + "integrity": "sha512-Wp+mKiieoV6FAZJNyNMS62Zsf5FBSxe17j0f4fpFYeA+rfW8nEZ2eBGGl7+vq+dr3dEpefV5D+ZI3d9jaqdRfw==", + "license": "MIT", + "dependencies": { + "mustache": "^2.2.1" + }, + "engines": { + "node": ">= 0.6.0" + }, + "peerDependencies": { + "winston": ">=0.5.0" + } + } + } +} \ No newline at end of file