mirror of
https://github.com/aquasecurity/trivy.git
synced 2026-02-10 10:43:18 +08:00
feat(nodejs): add a bun.lock analyzer (#8897)
Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
8939451174
commit
7ca656d54b
@@ -31,6 +31,7 @@ On the other hand, when the target is a post-build artifact, like a container im
|
||||
| [Node.js](nodejs.md) | package-lock.json | - | - | ✅ | ✅ |
|
||||
| | yarn.lock | - | - | ✅ | ✅ |
|
||||
| | pnpm-lock.yaml | - | - | ✅ | ✅ |
|
||||
| | bun.lock | - | - | ✅ | ✅ |
|
||||
| | package.json | ✅ | ✅ | - | - |
|
||||
| [.NET](dotnet.md) | packages.lock.json | ✅ | ✅ | ✅ | ✅ |
|
||||
| | packages.config | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
@@ -18,7 +18,7 @@ The following table provides an outline of the features Trivy offers.
|
||||
| npm | package-lock.json | ✓ | [Excluded](#npm) | ✓ | ✓ |
|
||||
| Yarn | yarn.lock | ✓ | [Excluded](#yarn) | ✓ | ✓ |
|
||||
| pnpm | pnpm-lock.yaml | ✓ | [Excluded](#lock-file-v9-version) | ✓ | - |
|
||||
| Bun | yarn.lock | ✓ | [Excluded](#yarn) | ✓ | ✓ |
|
||||
| Bun | bun.lock | ✓ | [Excluded](#bun) | ✓ | ✓ |
|
||||
|
||||
In addition, Trivy scans installed packages with `package.json`.
|
||||
|
||||
@@ -72,7 +72,13 @@ To identify licenses, you need to download dependencies to `node_modules` before
|
||||
Trivy supports `Dev` field for `pnpm-lock.yaml` v9 or later. Use the `--include-dev-deps` flag to include the developer's dependencies in the result.
|
||||
|
||||
### Bun
|
||||
Trivy supports scanning `yarn.lock` files generated by [Bun](https://bun.sh/docs/install/lockfile#how-do-i-inspect-bun-s-lockfile). You can use the command `bun install -y` to generate a Yarn-compatible `yarn.lock`.
|
||||
Trivy also supports scanning `bun.lock` file generated by [Bun](https://bun.sh/blog/bun-lock-text-lockfile).
|
||||
You can use Bun v1.2 which uses this file as default or use `bun install --save-text-lockfile` in Bun v1.1.39 to generate it.
|
||||
|
||||
For previous Bun versions you can use the command `bun install -y` to generate a Yarn-compatible `yarn.lock` and then scan it with Trivy.
|
||||
|
||||
#### Development dependencies
|
||||
`bun.lock` contains information about package groups, such as production and development dependencies. By default, Trivy doesn't report development dependencies. Use the `--include-dev-deps` flag to include them.
|
||||
|
||||
!!! note
|
||||
`bun.lockb` is not supported.
|
||||
|
||||
@@ -145,6 +145,15 @@ func TestRepository(t *testing.T) {
|
||||
},
|
||||
golden: "testdata/pnpm.json.golden",
|
||||
},
|
||||
{
|
||||
name: "bun",
|
||||
args: args{
|
||||
scanner: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/repo/bun",
|
||||
listAllPkgs: true,
|
||||
},
|
||||
golden: "testdata/bun.json.golden",
|
||||
},
|
||||
{
|
||||
name: "pip",
|
||||
args: args{
|
||||
|
||||
196
integration/testdata/bun.json.golden
vendored
Normal file
196
integration/testdata/bun.json.golden
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"SchemaVersion": 2,
|
||||
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
|
||||
"ArtifactName": "testdata/fixtures/repo/bun",
|
||||
"ArtifactType": "repository",
|
||||
"Metadata": {
|
||||
"ImageConfig": {
|
||||
"architecture": "",
|
||||
"created": "0001-01-01T00:00:00Z",
|
||||
"os": "",
|
||||
"rootfs": {
|
||||
"type": "",
|
||||
"diff_ids": null
|
||||
},
|
||||
"config": {}
|
||||
}
|
||||
},
|
||||
"Results": [
|
||||
{
|
||||
"Target": "bun.lock",
|
||||
"Class": "lang-pkgs",
|
||||
"Type": "bun",
|
||||
"Packages": [
|
||||
{
|
||||
"ID": "jquery@3.3.1",
|
||||
"Name": "jquery",
|
||||
"Identifier": {
|
||||
"PURL": "pkg:npm/jquery@3.3.1",
|
||||
"UID": "996607b7a767641"
|
||||
},
|
||||
"Version": "3.3.1",
|
||||
"Relationship": "direct",
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 24,
|
||||
"EndLine": 24
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"ID": "typescript@5.8.3",
|
||||
"Name": "typescript",
|
||||
"Identifier": {
|
||||
"PURL": "pkg:npm/typescript@5.8.3",
|
||||
"UID": "dc420153a1d93546"
|
||||
},
|
||||
"Version": "5.8.3",
|
||||
"Relationship": "direct",
|
||||
"Layer": {},
|
||||
"Locations": [
|
||||
{
|
||||
"StartLine": 26,
|
||||
"EndLine": 26
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"VulnerabilityID": "CVE-2019-11358",
|
||||
"PkgID": "jquery@3.3.1",
|
||||
"PkgName": "jquery",
|
||||
"PkgIdentifier": {
|
||||
"PURL": "pkg:npm/jquery@3.3.1",
|
||||
"UID": "996607b7a767641"
|
||||
},
|
||||
"InstalledVersion": "3.3.1",
|
||||
"FixedVersion": "3.4.0",
|
||||
"Status": "fixed",
|
||||
"Layer": {},
|
||||
"SeveritySource": "ghsa",
|
||||
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-11358",
|
||||
"DataSource": {
|
||||
"ID": "ghsa",
|
||||
"Name": "GitHub Security Advisory Npm",
|
||||
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm"
|
||||
},
|
||||
"Title": "jquery: Prototype pollution in object's prototype leading to denial of service, remote code execution, or property injection",
|
||||
"Description": "jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.",
|
||||
"Severity": "MEDIUM",
|
||||
"CweIDs": [
|
||||
"CWE-79"
|
||||
],
|
||||
"VendorSeverity": {
|
||||
"alma": 2,
|
||||
"amazon": 2,
|
||||
"arch-linux": 2,
|
||||
"ghsa": 2,
|
||||
"nodejs-security-wg": 2,
|
||||
"nvd": 2,
|
||||
"oracle-oval": 2,
|
||||
"redhat": 2,
|
||||
"ruby-advisory-db": 2,
|
||||
"ubuntu": 1
|
||||
},
|
||||
"CVSS": {
|
||||
"nvd": {
|
||||
"V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N",
|
||||
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
|
||||
"V2Score": 4.3,
|
||||
"V3Score": 6.1
|
||||
},
|
||||
"redhat": {
|
||||
"V3Vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
|
||||
"V3Score": 5.6
|
||||
}
|
||||
},
|
||||
"References": [
|
||||
"http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00006.html",
|
||||
"http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00025.html",
|
||||
"http://packetstormsecurity.com/files/152787/dotCMS-5.1.1-Vulnerable-Dependencies.html",
|
||||
"http://packetstormsecurity.com/files/153237/RetireJS-CORS-Issue-Script-Execution.html",
|
||||
"http://packetstormsecurity.com/files/156743/OctoberCMS-Insecure-Dependencies.html",
|
||||
"http://seclists.org/fulldisclosure/2019/May/10",
|
||||
"http://seclists.org/fulldisclosure/2019/May/11",
|
||||
"http://seclists.org/fulldisclosure/2019/May/13",
|
||||
"http://www.openwall.com/lists/oss-security/2019/06/03/2",
|
||||
"http://www.securityfocus.com/bid/108023",
|
||||
"https://access.redhat.com/errata/RHBA-2019:1570",
|
||||
"https://access.redhat.com/errata/RHSA-2019:1456",
|
||||
"https://access.redhat.com/errata/RHSA-2019:2587",
|
||||
"https://access.redhat.com/errata/RHSA-2019:3023",
|
||||
"https://access.redhat.com/errata/RHSA-2019:3024",
|
||||
"https://access.redhat.com/security/cve/CVE-2019-11358",
|
||||
"https://backdropcms.org/security/backdrop-sa-core-2019-009",
|
||||
"https://blog.jquery.com/2019/04/10/jquery-3-4-0-released/",
|
||||
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358",
|
||||
"https://github.com/DanielRuf/snyk-js-jquery-174006?files=1",
|
||||
"https://github.com/advisories/GHSA-6c3j-c64m-qhgq",
|
||||
"https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b",
|
||||
"https://github.com/jquery/jquery/pull/4333",
|
||||
"https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#434",
|
||||
"https://hackerone.com/reports/454365",
|
||||
"https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44601",
|
||||
"https://linux.oracle.com/cve/CVE-2019-11358.html",
|
||||
"https://linux.oracle.com/errata/ELSA-2020-4847.html",
|
||||
"https://lists.apache.org/thread.html/08720ef215ee7ab3386c05a1a90a7d1c852bf0706f176a7816bf65fc@%3Ccommits.airflow.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/519eb0fd45642dcecd9ff74cb3e71c20a4753f7d82e2f07864b5108f@%3Cdev.drill.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/5928aa293e39d248266472210c50f176cac1535220f2486e6a7fa844@%3Ccommits.airflow.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/6097cdbd6f0a337bedd9bb5cc441b2d525ff002a96531de367e4259f@%3Ccommits.airflow.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/88fb0362fd40e5b605ea8149f63241537b8b6fb5bfa315391fc5cbb7@%3Ccommits.airflow.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/b0656d359c7d40ec9f39c8cc61bca66802ef9a2a12ee199f5b0c1442@%3Cdev.drill.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/b736d0784cf02f5a30fbb4c5902762a15ad6d47e17e2c5a17b7d6205@%3Ccommits.airflow.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/ba79cf1658741e9f146e4c59b50aee56656ea95d841d358d006c18b6@%3Ccommits.roller.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/bcce5a9c532b386c68dab2f6b3ce8b0cc9b950ec551766e76391caa3@%3Ccommits.nifi.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/f9bc3e55f4e28d1dcd1a69aae6d53e609a758e34d2869b4d798e13cc@%3Cissues.drill.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r2041a75d3fc09dec55adfd95d598b38d22715303f65c997c054844c9@%3Cissues.flink.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r2baacab6e0acb5a2092eb46ae04fd6c3e8277b4fd79b1ffb7f3254fa@%3Cissues.flink.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r38f0d1aa3c923c22977fe7376508f030f22e22c1379fbb155bf29766@%3Cdev.syncope.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r41b5bfe009c845f67d4f68948cc9419ac2d62e287804aafd72892b08@%3Cissues.flink.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r7aac081cbddb6baa24b75e74abf0929bf309b176755a53e3ed810355@%3Cdev.flink.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r7d64895cc4dff84d0becfc572b20c0e4bf9bfa7b10c6f5f73e783734@%3Cdev.storm.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/r7e8ebccb7c022e41295f6fdb7b971209b83702339f872ddd8cf8bf73@%3Cissues.flink.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/rac25da84ecdcd36f6de5ad0d255f4e967209bbbebddb285e231da37d@%3Cissues.flink.apache.org%3E",
|
||||
"https://lists.apache.org/thread.html/rca37935d661f4689cb4119f1b3b224413b22be161b678e6e6ce0c69b@%3Ccommits.nifi.apache.org%3E",
|
||||
"https://lists.debian.org/debian-lts-announce/2019/05/msg00006.html",
|
||||
"https://lists.debian.org/debian-lts-announce/2019/05/msg00029.html",
|
||||
"https://lists.debian.org/debian-lts-announce/2020/02/msg00024.html",
|
||||
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4UOAZIFCSZ3ENEFOR5IXX6NFAD3HV7FA/",
|
||||
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/5IABSKTYZ5JUGL735UKGXL5YPRYOPUYI/",
|
||||
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KYH3OAGR2RTCHRA5NOKX2TES7SNQMWGO/",
|
||||
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QV3PKZC3PQCO3273HAT76PAQZFBEO4KP/",
|
||||
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RLXRX23725JL366CNZGJZ7AQQB7LHQ6F/",
|
||||
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WZW27UCJ5CYFL4KFFFMYMIBNMIU2ALG5/",
|
||||
"https://nvd.nist.gov/vuln/detail/CVE-2019-11358",
|
||||
"https://seclists.org/bugtraq/2019/Apr/32",
|
||||
"https://seclists.org/bugtraq/2019/Jun/12",
|
||||
"https://seclists.org/bugtraq/2019/May/18",
|
||||
"https://security.netapp.com/advisory/ntap-20190919-0001/",
|
||||
"https://snyk.io/vuln/SNYK-JS-JQUERY-174006",
|
||||
"https://www.debian.org/security/2019/dsa-4434",
|
||||
"https://www.debian.org/security/2019/dsa-4460",
|
||||
"https://www.drupal.org/sa-core-2019-006",
|
||||
"https://www.oracle.com//security-alerts/cpujul2021.html",
|
||||
"https://www.oracle.com/security-alerts/cpuApr2021.html",
|
||||
"https://www.oracle.com/security-alerts/cpuapr2020.html",
|
||||
"https://www.oracle.com/security-alerts/cpujan2020.html",
|
||||
"https://www.oracle.com/security-alerts/cpujan2021.html",
|
||||
"https://www.oracle.com/security-alerts/cpujul2020.html",
|
||||
"https://www.oracle.com/security-alerts/cpuoct2020.html",
|
||||
"https://www.oracle.com/security-alerts/cpuoct2021.html",
|
||||
"https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html",
|
||||
"https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html",
|
||||
"https://www.privacy-wise.com/mitigating-cve-2019-11358-in-old-versions-of-jquery/",
|
||||
"https://www.synology.com/security/advisory/Synology_SA_19_19",
|
||||
"https://www.tenable.com/security/tns-2019-08",
|
||||
"https://www.tenable.com/security/tns-2020-02"
|
||||
],
|
||||
"PublishedDate": "2019-04-20T00:29:00Z",
|
||||
"LastModifiedDate": "2021-10-20T11:15:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
30
integration/testdata/fixtures/repo/bun/bun.lock
vendored
Normal file
30
integration/testdata/fixtures/repo/bun/bun.lock
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "buntest",
|
||||
"dependencies": {
|
||||
"jquery": "3.3.1",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.2.14", "", { "dependencies": { "bun-types": "1.2.14" } }, "sha512-VsFZKs8oKHzI7zwvECiAJ5oSorWndIWEVhfbYqZd4HI/45kzW7PN2Rr5biAzvGvRuNmYLSANY+H59ubHq8xw7Q=="],
|
||||
|
||||
"@types/node": ["@types/node@22.15.21", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-Kuh4Ub28ucMRWeiUUWMHsT9Wcbr4H3kLIO72RZZElSDxSu7vpetRvxIUDUaW6QtaIeixIpm7OXtNnZPf82EzwA=="],
|
||||
|
||||
"jquery": ["jquery@3.3.1", "", {}, "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="],
|
||||
|
||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func NewDriver(libType ftypes.LangType) (Driver, bool) {
|
||||
case ftypes.Jar, ftypes.Pom, ftypes.Gradle, ftypes.Sbt:
|
||||
ecosystem = vulnerability.Maven
|
||||
comparer = maven.Comparer{}
|
||||
case ftypes.Npm, ftypes.Yarn, ftypes.Pnpm, ftypes.NodePkg, ftypes.JavaScript:
|
||||
case ftypes.Npm, ftypes.Yarn, ftypes.Pnpm, ftypes.Bun, ftypes.NodePkg, ftypes.JavaScript:
|
||||
ecosystem = vulnerability.Npm
|
||||
comparer = npm.Comparer{}
|
||||
case ftypes.NuGet, ftypes.DotNetCore, ftypes.PackagesProps:
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/pom"
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/sbt"
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/julia/pkg"
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/bun"
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/npm"
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/pkg"
|
||||
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/pnpm"
|
||||
|
||||
@@ -66,6 +66,7 @@ const (
|
||||
TypeNodePkg Type = "node-pkg"
|
||||
TypeYarn Type = "yarn"
|
||||
TypePnpm Type = "pnpm"
|
||||
TypeBun Type = "bun"
|
||||
|
||||
// .NET
|
||||
TypeNuget Type = "nuget"
|
||||
@@ -191,6 +192,7 @@ var (
|
||||
TypeNodePkg,
|
||||
TypeYarn,
|
||||
TypePnpm,
|
||||
TypeBun,
|
||||
TypeNuget,
|
||||
TypeDotNetCore,
|
||||
TypePackagesProps,
|
||||
@@ -220,6 +222,7 @@ var (
|
||||
TypeNpmPkgLock,
|
||||
TypeYarn,
|
||||
TypePnpm,
|
||||
TypeBun,
|
||||
TypePip,
|
||||
TypePipenv,
|
||||
TypePoetry,
|
||||
|
||||
158
pkg/fanal/analyzer/language/nodejs/bun/bun.go
Normal file
158
pkg/fanal/analyzer/language/nodejs/bun/bun.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package bun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/dependency/parser/nodejs/bun"
|
||||
"github.com/aquasecurity/trivy/pkg/dependency/parser/nodejs/packagejson"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
|
||||
xio "github.com/aquasecurity/trivy/pkg/x/io"
|
||||
xpath "github.com/aquasecurity/trivy/pkg/x/path"
|
||||
)
|
||||
|
||||
func init() {
|
||||
analyzer.RegisterPostAnalyzer(analyzer.TypeBun, newBunLibraryAnalyzer)
|
||||
}
|
||||
|
||||
const (
|
||||
version = 1
|
||||
)
|
||||
|
||||
type bunLibraryAnalyzer struct {
|
||||
logger *log.Logger
|
||||
lockParser language.Parser
|
||||
packageParser *packagejson.Parser
|
||||
}
|
||||
|
||||
func newBunLibraryAnalyzer(_ analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
|
||||
return &bunLibraryAnalyzer{
|
||||
logger: log.WithPrefix("bun"),
|
||||
lockParser: bun.NewParser(),
|
||||
packageParser: packagejson.NewParser(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a bunLibraryAnalyzer) PostAnalyze(_ context.Context, input analyzer.PostAnalysisInput) (*analyzer.AnalysisResult, error) {
|
||||
// Parse bun.lock
|
||||
required := func(path string, _ fs.DirEntry) bool {
|
||||
return filepath.Base(path) == types.BunLock || input.FilePatterns.Match(path)
|
||||
}
|
||||
|
||||
var apps []types.Application
|
||||
err := fsutils.WalkDir(input.FS, ".", required, func(filePath string, _ fs.DirEntry, _ io.Reader) error {
|
||||
// Find all licenses from package.json files under node_modules dirs
|
||||
licenses, err := a.findLicenses(input.FS, filePath)
|
||||
if err != nil {
|
||||
a.logger.Error("Unable to collect licenses", log.Err(err))
|
||||
licenses = make(map[string][]string)
|
||||
}
|
||||
|
||||
app, err := a.parseBunLock(input.FS, filePath)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parse error: %w", err)
|
||||
} else if app == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fill licenses
|
||||
for i, lib := range app.Packages {
|
||||
if ll, ok := licenses[lib.ID]; ok {
|
||||
app.Packages[i].Licenses = ll
|
||||
}
|
||||
}
|
||||
sort.Sort(app.Packages)
|
||||
apps = append(apps, *app)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("bun.lock/package.json walk error: %w", err)
|
||||
}
|
||||
|
||||
return &analyzer.AnalysisResult{
|
||||
Applications: apps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a bunLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
|
||||
fileName := filepath.Base(filePath)
|
||||
if fileName == types.BunLock {
|
||||
return true
|
||||
}
|
||||
|
||||
// Save package.json files only from the `node_modules` directory.
|
||||
// Required to search for licenses.
|
||||
if fileName == types.NpmPkg && xpath.Contains(filePath, "node_modules") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a bunLibraryAnalyzer) Type() analyzer.Type {
|
||||
return analyzer.TypeBun
|
||||
}
|
||||
|
||||
func (a bunLibraryAnalyzer) Version() int {
|
||||
return version
|
||||
}
|
||||
|
||||
func (a bunLibraryAnalyzer) parseBunLock(fsys fs.FS, filePath string) (*types.Application, error) {
|
||||
f, err := fsys.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("file open error: %w", err)
|
||||
}
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
file, ok := f.(xio.ReadSeekCloserAt)
|
||||
if !ok {
|
||||
return nil, xerrors.New("type assertion error: file does not implement xio.ReadSeekCloserAt")
|
||||
}
|
||||
|
||||
// parse bun.lock
|
||||
return language.Parse(types.Bun, filePath, file, a.lockParser)
|
||||
}
|
||||
|
||||
func (a bunLibraryAnalyzer) findLicenses(fsys fs.FS, lockPath string) (map[string][]string, error) {
|
||||
dir := path.Dir(lockPath)
|
||||
root := path.Join(dir, "node_modules")
|
||||
if _, err := fs.Stat(fsys, root); errors.Is(err, fs.ErrNotExist) {
|
||||
a.logger.Info(`To collect the license information of packages, "bun install" needs to be performed beforehand`,
|
||||
log.String("dir", root))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Parse package.json
|
||||
required := func(path string, _ fs.DirEntry) bool {
|
||||
return filepath.Base(path) == types.NpmPkg
|
||||
}
|
||||
|
||||
// Traverse node_modules dir and find licenses
|
||||
// Note that fs.FS is always slashed regardless of the platform,
|
||||
// and path.Join should be used rather than filepath.Join.
|
||||
licenses := make(map[string][]string)
|
||||
err := fsutils.WalkDir(fsys, root, required, func(filePath string, _ fs.DirEntry, r io.Reader) error {
|
||||
pkg, err := a.packageParser.Parse(r)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("unable to parse %q: %w", filePath, err)
|
||||
}
|
||||
|
||||
licenses[pkg.ID] = pkg.Licenses
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("walk error: %w", err)
|
||||
}
|
||||
return licenses, nil
|
||||
}
|
||||
206
pkg/fanal/analyzer/language/nodejs/bun/bun_test.go
Normal file
206
pkg/fanal/analyzer/language/nodejs/bun/bun_test.go
Normal file
@@ -0,0 +1,206 @@
|
||||
package bun
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
log.InitLogger(false, true)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func Test_bunLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dir string
|
||||
want *analyzer.AnalysisResult
|
||||
}{
|
||||
{
|
||||
name: "with node_modules",
|
||||
dir: "testdata/happy",
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Bun,
|
||||
FilePath: "bun.lock",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
ID: "@types/bun@1.2.13",
|
||||
Name: "@types/bun",
|
||||
Version: "1.2.13",
|
||||
Dev: true,
|
||||
Relationship: types.RelationshipDirect,
|
||||
DependsOn: []string{"bun-types@1.2.13"},
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: types.Locations{types.Location{StartLine: 18, EndLine: 18}},
|
||||
},
|
||||
{
|
||||
ID: "typescript@5.8.3",
|
||||
Name: "typescript",
|
||||
Version: "5.8.3",
|
||||
Relationship: types.RelationshipDirect,
|
||||
Licenses: []string{"Apache-2.0"},
|
||||
Locations: types.Locations{types.Location{StartLine: 24, EndLine: 24}},
|
||||
},
|
||||
{
|
||||
ID: "zod@3.24.4",
|
||||
Name: "zod",
|
||||
Version: "3.24.4",
|
||||
Relationship: types.RelationshipDirect,
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: types.Locations{types.Location{StartLine: 28, EndLine: 28}},
|
||||
},
|
||||
{
|
||||
ID: "@types/node@22.15.18",
|
||||
Name: "@types/node",
|
||||
Version: "22.15.18",
|
||||
Dev: true,
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
DependsOn: []string{"undici-types@6.21.0"},
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: types.Locations{types.Location{StartLine: 20, EndLine: 20}},
|
||||
},
|
||||
{
|
||||
ID: "bun-types@1.2.13",
|
||||
Name: "bun-types",
|
||||
Version: "1.2.13",
|
||||
Dev: true,
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
DependsOn: []string{"@types/node@22.15.18"},
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: types.Locations{types.Location{StartLine: 22, EndLine: 22}},
|
||||
},
|
||||
{
|
||||
ID: "undici-types@6.21.0",
|
||||
Name: "undici-types",
|
||||
Version: "6.21.0",
|
||||
Dev: true,
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
Licenses: []string{"MIT"},
|
||||
Locations: types.Locations{types.Location{StartLine: 26, EndLine: 26}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sad",
|
||||
dir: "testdata/sad",
|
||||
want: &analyzer.AnalysisResult{},
|
||||
},
|
||||
{
|
||||
name: "without node_modules",
|
||||
dir: "testdata/no-node-modules",
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Bun,
|
||||
FilePath: "bun.lock",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
ID: "@types/bun@1.2.14",
|
||||
Name: "@types/bun",
|
||||
Version: "1.2.14",
|
||||
Dev: true,
|
||||
Relationship: types.RelationshipDirect,
|
||||
DependsOn: []string{"bun-types@1.2.14"},
|
||||
Locations: types.Locations{types.Location{StartLine: 15, EndLine: 15}},
|
||||
},
|
||||
{
|
||||
ID: "typescript@5.8.3",
|
||||
Name: "typescript",
|
||||
Version: "5.8.3",
|
||||
Relationship: types.RelationshipDirect,
|
||||
Locations: types.Locations{types.Location{StartLine: 21, EndLine: 21}},
|
||||
},
|
||||
{
|
||||
ID: "@types/node@22.15.21",
|
||||
Name: "@types/node",
|
||||
Version: "22.15.21",
|
||||
Dev: true,
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
DependsOn: []string{"undici-types@6.21.0"},
|
||||
Locations: types.Locations{types.Location{StartLine: 17, EndLine: 17}},
|
||||
},
|
||||
{
|
||||
ID: "bun-types@1.2.14",
|
||||
Name: "bun-types",
|
||||
Version: "1.2.14",
|
||||
Dev: true,
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
DependsOn: []string{"@types/node@22.15.21"},
|
||||
Locations: types.Locations{types.Location{StartLine: 19, EndLine: 19}},
|
||||
},
|
||||
{
|
||||
ID: "undici-types@6.21.0",
|
||||
Name: "undici-types",
|
||||
Version: "6.21.0",
|
||||
Dev: true,
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
Locations: types.Locations{types.Location{StartLine: 23, EndLine: 23}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a, err := newBunLibraryAnalyzer(analyzer.AnalyzerOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := a.PostAnalyze(t.Context(), analyzer.PostAnalysisInput{
|
||||
FS: os.DirFS(tt.dir),
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
if len(got.Applications) > 0 {
|
||||
sort.Sort(got.Applications[0].Packages)
|
||||
}
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_bunLibraryAnalyzer_Required(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filePath string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "lock file",
|
||||
filePath: "bun/bun.lock",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "sad path",
|
||||
filePath: "bun/package-lock.json",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a := bunLibraryAnalyzer{}
|
||||
got := a.Required(tt.filePath, nil)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
30
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/bun.lock
vendored
Normal file
30
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/bun.lock
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "buntest",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"zod": "^3.24.4",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.2.13", "", { "dependencies": { "bun-types": "1.2.13" } }, "sha512-u6vXep/i9VBxoJl3GjZsl/BFIsvML8DfVDO0RYLEwtSZSp981kEO1V5NwRcO1CPJ7AmvpbnDCiMKo3JvbDEjAg=="],
|
||||
|
||||
"@types/node": ["@types/node@22.15.18", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-rRjA1T6n7wto4gxhAO/ErZEtOXyEZEmnIHQfl0Dt1QQSB4QV0iP6BZ9/YB5fZaHFQ2dwHFrmPaRQ9GGMX01k9Q=="],
|
||||
|
||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"zod": ["zod@3.24.4", "", {}, "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg=="],
|
||||
}
|
||||
}
|
||||
63
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/@types/bun/package.json
generated
vendored
Normal file
63
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/@types/bun/package.json
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "@types/bun",
|
||||
"version": "1.2.13",
|
||||
"description": "TypeScript definitions for bun",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/bun",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jarred Sumner",
|
||||
"githubUsername": "Jarred-Sumner",
|
||||
"url": "https://github.com/Jarred-Sumner"
|
||||
},
|
||||
{
|
||||
"name": "Ashcon Partovi",
|
||||
"githubUsername": "electroid",
|
||||
"url": "https://github.com/electroid"
|
||||
},
|
||||
{
|
||||
"name": "Chloe Caruso",
|
||||
"githubUsername": "paperclover",
|
||||
"url": "https://github.com/paperclover"
|
||||
},
|
||||
{
|
||||
"name": "Robobun",
|
||||
"githubUsername": "robobun",
|
||||
"url": "https://github.com/robobun"
|
||||
},
|
||||
{
|
||||
"name": "Dylan Conway",
|
||||
"githubUsername": "dylan-conway",
|
||||
"url": "https://github.com/dylan-conway"
|
||||
},
|
||||
{
|
||||
"name": "Meghan Denny",
|
||||
"githubUsername": "nektro",
|
||||
"url": "https://github.com/nektro"
|
||||
},
|
||||
{
|
||||
"name": "Michael H",
|
||||
"githubUsername": "RiskyMH",
|
||||
"url": "https://github.com/RiskyMH"
|
||||
},
|
||||
{
|
||||
"name": "Alistair Smith",
|
||||
"githubUsername": "alii",
|
||||
"url": "https://github.com/alii"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/bun"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"bun-types": "1.2.13"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"typesPublisherContentHash": "8a6526d76212b81f34802d6687cb606f8cfb541ad90a916f7b17da292e07fbc2",
|
||||
"typeScriptVersion": "5.1"
|
||||
}
|
||||
225
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/@types/node/package.json
generated
vendored
Normal file
225
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/@types/node/package.json
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"name": "@types/node",
|
||||
"version": "22.15.18",
|
||||
"description": "TypeScript definitions for node",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Microsoft TypeScript",
|
||||
"githubUsername": "Microsoft",
|
||||
"url": "https://github.com/Microsoft"
|
||||
},
|
||||
{
|
||||
"name": "Alberto Schiabel",
|
||||
"githubUsername": "jkomyno",
|
||||
"url": "https://github.com/jkomyno"
|
||||
},
|
||||
{
|
||||
"name": "Alvis HT Tang",
|
||||
"githubUsername": "alvis",
|
||||
"url": "https://github.com/alvis"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Makarov",
|
||||
"githubUsername": "r3nya",
|
||||
"url": "https://github.com/r3nya"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Toueg",
|
||||
"githubUsername": "btoueg",
|
||||
"url": "https://github.com/btoueg"
|
||||
},
|
||||
{
|
||||
"name": "Chigozirim C.",
|
||||
"githubUsername": "smac89",
|
||||
"url": "https://github.com/smac89"
|
||||
},
|
||||
{
|
||||
"name": "David Junger",
|
||||
"githubUsername": "touffy",
|
||||
"url": "https://github.com/touffy"
|
||||
},
|
||||
{
|
||||
"name": "Deividas Bakanas",
|
||||
"githubUsername": "DeividasBakanas",
|
||||
"url": "https://github.com/DeividasBakanas"
|
||||
},
|
||||
{
|
||||
"name": "Eugene Y. Q. Shen",
|
||||
"githubUsername": "eyqs",
|
||||
"url": "https://github.com/eyqs"
|
||||
},
|
||||
{
|
||||
"name": "Hannes Magnusson",
|
||||
"githubUsername": "Hannes-Magnusson-CK",
|
||||
"url": "https://github.com/Hannes-Magnusson-CK"
|
||||
},
|
||||
{
|
||||
"name": "Huw",
|
||||
"githubUsername": "hoo29",
|
||||
"url": "https://github.com/hoo29"
|
||||
},
|
||||
{
|
||||
"name": "Kelvin Jin",
|
||||
"githubUsername": "kjin",
|
||||
"url": "https://github.com/kjin"
|
||||
},
|
||||
{
|
||||
"name": "Klaus Meinhardt",
|
||||
"githubUsername": "ajafff",
|
||||
"url": "https://github.com/ajafff"
|
||||
},
|
||||
{
|
||||
"name": "Lishude",
|
||||
"githubUsername": "islishude",
|
||||
"url": "https://github.com/islishude"
|
||||
},
|
||||
{
|
||||
"name": "Mariusz Wiktorczyk",
|
||||
"githubUsername": "mwiktorczyk",
|
||||
"url": "https://github.com/mwiktorczyk"
|
||||
},
|
||||
{
|
||||
"name": "Mohsen Azimi",
|
||||
"githubUsername": "mohsen1",
|
||||
"url": "https://github.com/mohsen1"
|
||||
},
|
||||
{
|
||||
"name": "Nikita Galkin",
|
||||
"githubUsername": "galkin",
|
||||
"url": "https://github.com/galkin"
|
||||
},
|
||||
{
|
||||
"name": "Parambir Singh",
|
||||
"githubUsername": "parambirs",
|
||||
"url": "https://github.com/parambirs"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Silbermann",
|
||||
"githubUsername": "eps1lon",
|
||||
"url": "https://github.com/eps1lon"
|
||||
},
|
||||
{
|
||||
"name": "Thomas den Hollander",
|
||||
"githubUsername": "ThomasdenH",
|
||||
"url": "https://github.com/ThomasdenH"
|
||||
},
|
||||
{
|
||||
"name": "Wilco Bakker",
|
||||
"githubUsername": "WilcoBakker",
|
||||
"url": "https://github.com/WilcoBakker"
|
||||
},
|
||||
{
|
||||
"name": "wwwy3y3",
|
||||
"githubUsername": "wwwy3y3",
|
||||
"url": "https://github.com/wwwy3y3"
|
||||
},
|
||||
{
|
||||
"name": "Samuel Ainsworth",
|
||||
"githubUsername": "samuela",
|
||||
"url": "https://github.com/samuela"
|
||||
},
|
||||
{
|
||||
"name": "Kyle Uehlein",
|
||||
"githubUsername": "kuehlein",
|
||||
"url": "https://github.com/kuehlein"
|
||||
},
|
||||
{
|
||||
"name": "Thanik Bhongbhibhat",
|
||||
"githubUsername": "bhongy",
|
||||
"url": "https://github.com/bhongy"
|
||||
},
|
||||
{
|
||||
"name": "Marcin Kopacz",
|
||||
"githubUsername": "chyzwar",
|
||||
"url": "https://github.com/chyzwar"
|
||||
},
|
||||
{
|
||||
"name": "Trivikram Kamat",
|
||||
"githubUsername": "trivikr",
|
||||
"url": "https://github.com/trivikr"
|
||||
},
|
||||
{
|
||||
"name": "Junxiao Shi",
|
||||
"githubUsername": "yoursunny",
|
||||
"url": "https://github.com/yoursunny"
|
||||
},
|
||||
{
|
||||
"name": "Ilia Baryshnikov",
|
||||
"githubUsername": "qwelias",
|
||||
"url": "https://github.com/qwelias"
|
||||
},
|
||||
{
|
||||
"name": "ExE Boss",
|
||||
"githubUsername": "ExE-Boss",
|
||||
"url": "https://github.com/ExE-Boss"
|
||||
},
|
||||
{
|
||||
"name": "Piotr Błażejewicz",
|
||||
"githubUsername": "peterblazejewicz",
|
||||
"url": "https://github.com/peterblazejewicz"
|
||||
},
|
||||
{
|
||||
"name": "Anna Henningsen",
|
||||
"githubUsername": "addaleax",
|
||||
"url": "https://github.com/addaleax"
|
||||
},
|
||||
{
|
||||
"name": "Victor Perin",
|
||||
"githubUsername": "victorperin",
|
||||
"url": "https://github.com/victorperin"
|
||||
},
|
||||
{
|
||||
"name": "NodeJS Contributors",
|
||||
"githubUsername": "NodeJS",
|
||||
"url": "https://github.com/NodeJS"
|
||||
},
|
||||
{
|
||||
"name": "Linus Unnebäck",
|
||||
"githubUsername": "LinusU",
|
||||
"url": "https://github.com/LinusU"
|
||||
},
|
||||
{
|
||||
"name": "wafuwafu13",
|
||||
"githubUsername": "wafuwafu13",
|
||||
"url": "https://github.com/wafuwafu13"
|
||||
},
|
||||
{
|
||||
"name": "Matteo Collina",
|
||||
"githubUsername": "mcollina",
|
||||
"url": "https://github.com/mcollina"
|
||||
},
|
||||
{
|
||||
"name": "Dmitry Semigradsky",
|
||||
"githubUsername": "Semigradsky",
|
||||
"url": "https://github.com/Semigradsky"
|
||||
},
|
||||
{
|
||||
"name": "René",
|
||||
"githubUsername": "Renegade334",
|
||||
"url": "https://github.com/Renegade334"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"typesVersions": {
|
||||
"<=5.6": {
|
||||
"*": [
|
||||
"ts5.6/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/node"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"typesPublisherContentHash": "2b90948f1fb3116c8907f2beaa3f3e5508eb0101dc27013c967a068001011e3e",
|
||||
"typeScriptVersion": "5.1"
|
||||
}
|
||||
39
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/bun-types/package.json
generated
vendored
Normal file
39
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/bun-types/package.json
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"version": "1.2.13",
|
||||
"name": "bun-types",
|
||||
"license": "MIT",
|
||||
"types": "./index.d.ts",
|
||||
"description": "Type definitions and documentation for Bun, an incredibly fast JavaScript runtime",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oven-sh/bun",
|
||||
"directory": "packages/bun-types"
|
||||
},
|
||||
"files": [
|
||||
"./*.d.ts",
|
||||
"docs/**/*.md",
|
||||
"docs/*.md"
|
||||
],
|
||||
"homepage": "https://bun.sh",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.5.3",
|
||||
"@definitelytyped/dtslint": "^0.0.199",
|
||||
"@definitelytyped/eslint-plugin": "^0.0.197",
|
||||
"typescript": "^5.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "echo $(pwd)",
|
||||
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v}\"'/g' {} +",
|
||||
"build": "bun run copy-docs && bun scripts/build.ts",
|
||||
"test": "tsc",
|
||||
"fmt": "echo $(which biome) && biome format --write ."
|
||||
},
|
||||
"keywords": [
|
||||
"bun",
|
||||
"bun.js",
|
||||
"types"
|
||||
]
|
||||
}
|
||||
120
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/typescript/package.json
generated
vendored
Normal file
120
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/typescript/package.json
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "https://www.typescriptlang.org/",
|
||||
"version": "5.8.3",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
"TypeScript",
|
||||
"Microsoft",
|
||||
"compiler",
|
||||
"language",
|
||||
"javascript"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/microsoft/TypeScript/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microsoft/TypeScript.git"
|
||||
},
|
||||
"main": "./lib/typescript.js",
|
||||
"typings": "./lib/typescript.d.ts",
|
||||
"bin": {
|
||||
"tsc": "./bin/tsc",
|
||||
"tsserver": "./bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"lib",
|
||||
"!lib/enu",
|
||||
"LICENSE.txt",
|
||||
"README.md",
|
||||
"SECURITY.md",
|
||||
"ThirdPartyNoticeText.txt",
|
||||
"!**/.gitattributes"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@dprint/formatter": "^0.4.1",
|
||||
"@dprint/typescript": "0.93.3",
|
||||
"@esfx/canceltoken": "^1.0.0",
|
||||
"@eslint/js": "^9.17.0",
|
||||
"@octokit/rest": "^21.0.2",
|
||||
"@types/chai": "^4.3.20",
|
||||
"@types/diff": "^5.2.3",
|
||||
"@types/minimist": "^1.2.5",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/ms": "^0.7.34",
|
||||
"@types/node": "latest",
|
||||
"@types/source-map-support": "^0.5.10",
|
||||
"@types/which": "^3.0.4",
|
||||
"@typescript-eslint/rule-tester": "^8.18.1",
|
||||
"@typescript-eslint/type-utils": "^8.18.1",
|
||||
"@typescript-eslint/utils": "^8.18.1",
|
||||
"azure-devops-node-api": "^14.1.0",
|
||||
"c8": "^10.1.3",
|
||||
"chai": "^4.5.0",
|
||||
"chalk": "^4.1.2",
|
||||
"chokidar": "^3.6.0",
|
||||
"diff": "^5.2.0",
|
||||
"dprint": "^0.47.6",
|
||||
"esbuild": "^0.24.0",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-formatter-autolinkable-stylish": "^1.4.0",
|
||||
"eslint-plugin-regexp": "^2.7.0",
|
||||
"fast-xml-parser": "^4.5.1",
|
||||
"glob": "^10.4.5",
|
||||
"globals": "^15.13.0",
|
||||
"hereby": "^1.10.0",
|
||||
"jsonc-parser": "^3.3.1",
|
||||
"knip": "^5.41.0",
|
||||
"minimist": "^1.2.8",
|
||||
"mocha": "^10.8.2",
|
||||
"mocha-fivemat-progress-reporter": "^0.1.0",
|
||||
"monocart-coverage-reports": "^2.11.4",
|
||||
"ms": "^2.1.3",
|
||||
"playwright": "^1.49.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.7.2",
|
||||
"typescript-eslint": "^8.18.1",
|
||||
"which": "^3.0.1"
|
||||
},
|
||||
"overrides": {
|
||||
"typescript@*": "$typescript"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "hereby runtests-parallel --light=false",
|
||||
"test:eslint-rules": "hereby run-eslint-rules-tests",
|
||||
"build": "npm run build:compiler && npm run build:tests",
|
||||
"build:compiler": "hereby local",
|
||||
"build:tests": "hereby tests",
|
||||
"build:tests:notypecheck": "hereby tests --no-typecheck",
|
||||
"clean": "hereby clean",
|
||||
"gulp": "hereby",
|
||||
"lint": "hereby lint",
|
||||
"knip": "hereby knip",
|
||||
"format": "dprint fmt",
|
||||
"setup-hooks": "node scripts/link-hooks.mjs"
|
||||
},
|
||||
"browser": {
|
||||
"fs": false,
|
||||
"os": false,
|
||||
"path": false,
|
||||
"crypto": false,
|
||||
"buffer": false,
|
||||
"source-map-support": false,
|
||||
"inspector": false,
|
||||
"perf_hooks": false
|
||||
},
|
||||
"packageManager": "npm@8.19.4",
|
||||
"volta": {
|
||||
"node": "20.1.0",
|
||||
"npm": "8.19.4"
|
||||
},
|
||||
"gitHead": "68cead182cc24afdc3f1ce7c8ff5853aba14b65a"
|
||||
}
|
||||
55
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/undici-types/package.json
generated
vendored
Normal file
55
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/undici-types/package.json
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "undici-types",
|
||||
"version": "6.21.0",
|
||||
"description": "A stand-alone types package for Undici",
|
||||
"homepage": "https://undici.nodejs.org",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nodejs/undici/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nodejs/undici.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"*.d.ts"
|
||||
],
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Daniele Belardi",
|
||||
"url": "https://github.com/dnlup",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Ethan Arrowood",
|
||||
"url": "https://github.com/ethan-arrowood",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Matteo Collina",
|
||||
"url": "https://github.com/mcollina",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Matthew Aitken",
|
||||
"url": "https://github.com/KhafraDev",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Robert Nagy",
|
||||
"url": "https://github.com/ronag",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Szymon Marczak",
|
||||
"url": "https://github.com/szmarczak",
|
||||
"author": true
|
||||
},
|
||||
{
|
||||
"name": "Tomas Della Vedova",
|
||||
"url": "https://github.com/delvedor",
|
||||
"author": true
|
||||
}
|
||||
]
|
||||
}
|
||||
122
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/zod/package.json
generated
vendored
Normal file
122
pkg/fanal/analyzer/language/nodejs/bun/testdata/happy/node_modules/zod/package.json
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"name": "zod",
|
||||
"version": "3.24.4",
|
||||
"author": "Colin McDonnell <colin@colinhacks.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/colinhacks/zod.git"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"module": "./lib/index.mjs",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@jest/globals": "^29.4.3",
|
||||
"@rollup/plugin-typescript": "^8.2.0",
|
||||
"@standard-schema/spec": "^1.0.0-beta.4",
|
||||
"@swc/core": "^1.3.66",
|
||||
"@swc/jest": "^0.2.26",
|
||||
"@types/benchmark": "^2.1.0",
|
||||
"@types/jest": "^29.2.2",
|
||||
"@types/node": "14",
|
||||
"@typescript-eslint/eslint-plugin": "^5.15.0",
|
||||
"@typescript-eslint/parser": "^5.15.0",
|
||||
"babel-jest": "^29.5.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"dependency-cruiser": "^9.19.0",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-ban": "^1.6.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^29.3.1",
|
||||
"lint-staged": "^12.3.7",
|
||||
"netlify-cli": "^17.26.2",
|
||||
"nodemon": "^2.0.15",
|
||||
"prettier": "^2.6.0",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"rollup": "^2.70.1",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-morph": "^14.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.3.1",
|
||||
"tsx": "^4.19.4",
|
||||
"typescript": "^5.0.0",
|
||||
"vitest": "^0.32.2"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.mjs"
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
"./locales/*": "./lib/locales/*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/colinhacks/zod/issues"
|
||||
},
|
||||
"description": "TypeScript-first schema declaration and validation library with static type inference",
|
||||
"files": [
|
||||
"/lib",
|
||||
"/index.d.ts"
|
||||
],
|
||||
"funding": "https://github.com/sponsors/colinhacks",
|
||||
"homepage": "https://zod.dev",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"schema",
|
||||
"validation",
|
||||
"type",
|
||||
"inference"
|
||||
],
|
||||
"license": "MIT",
|
||||
"lint-staged": {
|
||||
"src/*.ts": [
|
||||
"eslint --cache --fix",
|
||||
"prettier --ignore-unknown --write"
|
||||
],
|
||||
"*.md": [
|
||||
"prettier --ignore-unknown --write"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"prettier:check": "prettier --check src/**/*.ts deno/lib/**/*.ts *.md --no-error-on-unmatched-pattern",
|
||||
"prettier:fix": "prettier --write src/**/*.ts deno/lib/**/*.ts *.md --ignore-unknown --no-error-on-unmatched-pattern",
|
||||
"lint:check": "eslint --cache --ext .ts ./src",
|
||||
"lint:fix": "eslint --cache --fix --ext .ts ./src",
|
||||
"check": "yarn lint:check && yarn prettier:check",
|
||||
"fix": "yarn lint:fix && yarn prettier:fix",
|
||||
"clean": "rm -rf lib/* deno/lib/*",
|
||||
"build": "yarn run clean && npm run build:cjs && npm run build:esm && npm run build:deno",
|
||||
"build:deno": "node ./deno-build.mjs && cp ./README.md ./deno/lib",
|
||||
"build:esm": "rollup --config ./configs/rollup.config.js",
|
||||
"build:cjs": "tsc -p ./configs/tsconfig.cjs.json",
|
||||
"build:types": "tsc -p ./configs/tsconfig.types.json",
|
||||
"build:test": "tsc -p ./configs/tsconfig.test.json",
|
||||
"test:watch": "yarn test:ts-jest --watch",
|
||||
"test": "yarn test:ts-jest",
|
||||
"test:babel": "jest --coverage --config ./configs/babel-jest.config.json",
|
||||
"test:bun": "bun test src/",
|
||||
"test:vitest": "npx vitest --config ./configs/vitest.config.ts",
|
||||
"test:ts-jest": "npx jest --config ./configs/ts-jest.config.json",
|
||||
"test:swc": "npx jest --config ./configs/swc-jest.config.json",
|
||||
"test:deno": "cd deno && deno test",
|
||||
"prepublishOnly": "npm run test && npm run build && npm run build:deno",
|
||||
"play": "nodemon -e ts -w . -x tsx playground.ts",
|
||||
"depcruise": "depcruise -c .dependency-cruiser.js src",
|
||||
"benchmark": "tsx src/benchmarks/index.ts",
|
||||
"prepare": "husky install",
|
||||
"docs": "netlify dev"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"support": {
|
||||
"backing": {
|
||||
"npm-funding": true
|
||||
}
|
||||
},
|
||||
"types": "./index.d.ts"
|
||||
}
|
||||
25
pkg/fanal/analyzer/language/nodejs/bun/testdata/no-node-modules/bun.lock
vendored
Normal file
25
pkg/fanal/analyzer/language/nodejs/bun/testdata/no-node-modules/bun.lock
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "no-node-modules",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.2.14", "", { "dependencies": { "bun-types": "1.2.14" } }, "sha512-VsFZKs8oKHzI7zwvECiAJ5oSorWndIWEVhfbYqZd4HI/45kzW7PN2Rr5biAzvGvRuNmYLSANY+H59ubHq8xw7Q=="],
|
||||
|
||||
"@types/node": ["@types/node@22.15.21", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-Kuh4Ub28ucMRWeiUUWMHsT9Wcbr4H3kLIO72RZZElSDxSu7vpetRvxIUDUaW6QtaIeixIpm7OXtNnZPf82EzwA=="],
|
||||
|
||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
}
|
||||
}
|
||||
5
pkg/fanal/analyzer/language/nodejs/bun/testdata/sad/bun.lock
vendored
Normal file
5
pkg/fanal/analyzer/language/nodejs/bun/testdata/sad/bun.lock
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"lockfileVersion": "broken",
|
||||
"workspaces": {},
|
||||
"packages": {}
|
||||
}
|
||||
@@ -165,6 +165,7 @@ const (
|
||||
NpmPkgLock = "package-lock.json"
|
||||
YarnLock = "yarn.lock"
|
||||
PnpmLock = "pnpm-lock.yaml"
|
||||
BunLock = "bun.lock"
|
||||
|
||||
ComposerLock = "composer.lock"
|
||||
ComposerJson = "composer.json"
|
||||
|
||||
@@ -466,7 +466,7 @@ func purlType(t ftypes.TargetType) string {
|
||||
return packageurl.TypePyPi
|
||||
case ftypes.GoBinary, ftypes.GoModule:
|
||||
return packageurl.TypeGolang
|
||||
case ftypes.Npm, ftypes.NodePkg, ftypes.Yarn, ftypes.Pnpm:
|
||||
case ftypes.Npm, ftypes.NodePkg, ftypes.Yarn, ftypes.Pnpm, ftypes.Bun:
|
||||
return packageurl.TypeNPM
|
||||
case ftypes.Cocoapods:
|
||||
return packageurl.TypeCocoapods
|
||||
|
||||
@@ -65,6 +65,19 @@ func TestNewPackageURL(t *testing.T) {
|
||||
Version: "2.9.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bun package",
|
||||
typ: ftypes.Bun,
|
||||
pkg: ftypes.Package{
|
||||
Name: "bun-types@1.2.14",
|
||||
Version: "1.2.14",
|
||||
},
|
||||
want: &purl.PackageURL{
|
||||
Type: packageurl.TypeNPM,
|
||||
Name: "bun-types@1.2.14",
|
||||
Version: "1.2.14",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "yarn package",
|
||||
typ: ftypes.Yarn,
|
||||
|
||||
Reference in New Issue
Block a user