feat(nodejs): add a bun.lock analyzer (#8897)

Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
This commit is contained in:
Ashwani Kumar Kamal
2025-05-28 12:44:54 +05:30
committed by GitHub
parent 8939451174
commit 7ca656d54b
22 changed files with 1312 additions and 4 deletions

View File

@@ -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 | ✅ | ✅ | ✅ | ✅ |

View File

@@ -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.

View File

@@ -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
View 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"
}
]
}
]
}

View 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=="],
}
}

View File

@@ -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:

View File

@@ -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"

View File

@@ -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,

View 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
}

View 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)
})
}
}

View 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=="],
}
}

View 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"
}

View 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"
}

View 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"
]
}

View 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"
}

View 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
}
]
}

View 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"
}

View 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=="],
}
}

View File

@@ -0,0 +1,5 @@
{
"lockfileVersion": "broken",
"workspaces": {},
"packages": {}
}

View File

@@ -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"

View File

@@ -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

View File

@@ -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,