github.com/google/osv-scalibr@v0.4.1/internal/dependencyfile/packagelockjson/packagelockjson.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package packagelockjson provides the structures for npm's package-lock.json lockfile format. 16 package packagelockjson 17 18 // LockFile is the npm package-lock.json lockfile. 19 type LockFile struct { 20 Version int `json:"lockfileVersion"` 21 // npm v1- lockfiles use "dependencies" 22 Dependencies map[string]Dependency `json:"dependencies,omitempty"` 23 // npm v2+ lockfiles use "packages" 24 Packages map[string]Package `json:"packages,omitempty"` 25 } 26 27 // Dependency is the representation of an installed dependency in lockfileVersion 1 28 type Dependency struct { 29 // For an aliased package, Version is like "npm:[name]@[version]" 30 Version string `json:"version"` 31 Resolved string `json:"resolved"` 32 33 Dev bool `json:"dev,omitempty"` 34 Optional bool `json:"optional,omitempty"` 35 36 Requires map[string]string `json:"requires,omitempty"` 37 Dependencies map[string]Dependency `json:"dependencies,omitempty"` 38 } 39 40 // DepGroups returns the list of groups this dependency belongs to. 41 // May be empty, or one or both of "dev", "optional". 42 func (dep Dependency) DepGroups() []string { 43 if dep.Dev && dep.Optional { 44 return []string{"dev", "optional"} 45 } 46 if dep.Dev { 47 return []string{"dev"} 48 } 49 if dep.Optional { 50 return []string{"optional"} 51 } 52 53 return nil 54 } 55 56 // Package is the representation of an installed dependency in lockfileVersion 2+ 57 type Package struct { 58 // For an aliased package, Name is the real package name 59 Name string `json:"name,omitempty"` 60 Version string `json:"version"` 61 Resolved string `json:"resolved"` 62 Link bool `json:"link,omitempty"` 63 64 Dev bool `json:"dev,omitempty"` 65 DevOptional bool `json:"devOptional,omitempty"` 66 Optional bool `json:"optional,omitempty"` 67 InBundle bool `json:"inBundle,omitempty"` 68 69 Dependencies map[string]string `json:"dependencies,omitempty"` 70 DevDependencies map[string]string `json:"devDependencies,omitempty"` 71 OptionalDependencies map[string]string `json:"optionalDependencies,omitempty"` 72 PeerDependencies map[string]string `json:"peerDependencies,omitempty"` 73 PeerDependenciesMeta map[string]struct { 74 Optional bool `json:"optional,omitempty"` 75 } `json:"peerDependenciesMeta,omitempty"` 76 } 77 78 // DepGroups returns the list of groups this package belongs to. 79 // Supported groups are "bundled", "dev", and "optional", with an 80 // empty group implying a production dependency. 81 func (pkg Package) DepGroups() []string { 82 var groups []string 83 84 if pkg.InBundle { 85 groups = []string{"bundled"} 86 } 87 88 if pkg.DevOptional { 89 groups = append(groups, "dev", "optional") 90 91 return groups 92 } 93 94 if pkg.Dev { 95 groups = append(groups, "dev") 96 } 97 if pkg.Optional { 98 groups = append(groups, "optional") 99 } 100 101 return groups 102 }