Files
pnpm/cspell.json
Allan Kimmer Jensen f92ac24c1b feat(sbom): add pnpm sbom command (#10592)
* feat(sbom): add `pnpm sbom` command (#9088)

new command that generates SBOMs from the lockfile + store metadata.
supports CycloneDX 1.6 JSON and SPDX 2.3 JSON via `--sbom-format`.

two new packages following the existing `pnpm licenses` architecture:
- `@pnpm/sbom` — core library (lockfile walking, store reading, serializers)
- `@pnpm/plugin-commands-sbom` — CLI plugin wiring

uses the lockfile walker for dependency traversal and reads package.json
from the CAFS store for license/author/description metadata. `--lockfile-only`
skips the store entirely for faster CI runs where metadata isn't needed.

validated against official CycloneDX 1.6 and SPDX 2.3 JSON schemas.

* chore: add sbom-related words to cspell dictionary

* fix(sbom): address CycloneDX review feedback and bump to 1.7

Implements all 5 items from the CycloneDX maintainer review:
split scoped names into group/name, move hashes to
externalReferences distribution, use license.id for known SPDX
identifiers, switch to modern tools.components structure with
pnpm version, and bump specVersion to 1.7.

Also adds spdx-license-ids for proper license classification and
improves SPDX serializer test coverage.

* fix(sbom): fix CI bundle failure for spdx-license-ids

createRequire doesn't work in the esbuild bundle since it's a runtime
resolve, switched back to regular import which esbuild can inline.

* fix(sbom): use tarball URL for distribution externalReferences

Use actual tarball download URL instead of PURL for CycloneDX
distribution externalReferences, per review feedback.

* feat(sbom): add CycloneDX metadata and improve SBOM quality scores

adds $schema, timestamp, lifecycles (build/pre-build) to CycloneDX output
to match what npm does. also enriches both CycloneDX and SPDX with
metadata.authors, metadata.supplier, component supplier from author,
vcs externalReferences from repository, and root component details
(purl, license, description, author, vcs). SPDX now uses tarball URL
for downloadLocation instead of NOASSERTION.

renames CycloneDxToolInfo to CycloneDxOptions, passes lockfileOnly
through to the serializer for lifecycle phase selection. adds store-dir
to accepted CLI options.

* fix(sbom): address CycloneDX review feedback round 2

switches license classification from spdx-license-ids to
@cyclonedx/cyclonedx-library (SPDX.isSupportedSpdxId) for accurate
CycloneDX license ID validation per jkowalleck's feedback.

removes hardcoded metadata.authors and metadata.supplier — these are
not appropriate for a tool to set. adds --sbom-authors and
--sbom-supplier CLI flags so the SBOM consumer (e.g. ACME Corp) can
declare who they are.

removes supplier from components — supplier is the registry/distributor,
not the package author. also fixes distribution externalReference to
only emit when a real tarball URL exists, no PURL fallback.

* fix(sbom): use sub-path import for CycloneDX library to fix bundle

top-level import from @cyclonedx/cyclonedx-library drags in
validation/serialize layers with optional deps (ajv-formats, libxmljs2,
xmlbuilder2) that esbuild can't resolve during pnpm CLI bundling.

switch to @cyclonedx/cyclonedx-library/SPDX which only pulls in the
SPDX module we actually use — pure JS, no optional deps.

* chore: update manifests

* refactor: extract shared store-reading logic into @pnpm/store.pkg-finder

Both @pnpm/license-scanner and @pnpm/sbom independently implemented
nearly identical logic to read a package's file index from the
content-addressable store. This extracts that into a new shared package
that returns a uniform Map<string, string> (filename → absolute path),
simplifying both consumers.

Close #9088

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-02-25 08:45:21 +01:00

335 lines
5.1 KiB
JSON

{
"words": [
"adduser",
"adipiscing",
"amet",
"andreineculau",
"appdata",
"applyq",
"archy",
"argumentless",
"armv",
"autocompleting",
"autofix",
"autofixed",
"autoinstalled",
"autozoom",
"babek",
"badheaders",
"behaviour",
"blabla",
"Bluesky",
"brasileiro",
"bryntum",
"cafile",
"cafs",
"camelcase",
"canonicalizer",
"canva",
"cerbos",
"certfile",
"clonedeep",
"cmds",
"codeload",
"codenames",
"codesign",
"colorterm",
"comver",
"copyfiles",
"corejs",
"corepack",
"corge",
"cowsay",
"cves",
"cwsay",
"cyclonedx",
"deburr",
"dedup",
"denoland",
"denolib",
"deptype",
"devextreme",
"devowl",
"dgimuvys",
"didyoumean",
"dirtyforms",
"diskusage",
"dislink",
"dpkg",
"drivelist",
"duplexify",
"eagain",
"ebadplatform",
"ebusy",
"eexist",
"ehrkoext",
"eintegrity",
"eisdir",
"elifecycle",
"elit",
"emfile",
"enametoolong",
"endregion",
"eneedauth",
"enoent",
"enotempty",
"enten",
"eperm",
"epipe",
"etamponi",
"exdev",
"execa",
"exploitability",
"fellback",
"fetchings",
"filenamify",
"filesystem",
"filesystems",
"fnumber",
"foobarqar",
"foofoo",
"forgejo",
"fsevents",
"gabor",
"garply",
"gcttmf",
"getattr",
"ghsa",
"ghsas",
"gitea",
"globalconfig",
"globstar",
"grault",
"gruntfile",
"gwhitney",
"haptics",
"hardlink",
"hardlinked",
"hardlinking",
"hardlinks",
"hashbang",
"highmaps",
"hikljmi",
"hoistable",
"homepath",
"hosters",
"hyperdrive",
"idempotency",
"imurmurhash",
"ionicons",
"isexe",
"istvan",
"italiano",
"jega",
"jhcg",
"jnbpamcxayl",
"kebabcase",
"kevva",
"keyfile",
"killcb",
"kochan",
"koorchik",
"ldid",
"ldni",
"leniolabs",
"libc",
"libnpmpublish",
"libnpx",
"libzip",
"licence",
"licences",
"lifecycles",
"linuxstatic",
"localappdata",
"lockfiles",
"loglevel",
"logstream",
"longlink",
"longpaths",
"luca",
"martensson",
"maxtimeout",
"mdast",
"metafile",
"millis",
"mintimeout",
"monorepolint",
"moonrepo",
"mountpoint",
"msgpack",
"msgpackr",
"msvc",
"msys",
"mycomp",
"mycompany",
"myorg",
"mypackage",
"mytoken",
"ndjson",
"nerfed",
"NOASSERTION",
"nodetouch",
"noent",
"nonexec",
"noninjected",
"nopadding",
"noproxy",
"nosystem",
"nothrow",
"npmcli",
"npmignore",
"npmjs",
"nushell",
"ofjergrg",
"onclickoutside",
"oomol",
"ossl",
"outfile",
"overrider",
"packlist",
"packr",
"packument",
"paralleljs",
"parallelly",
"parseable",
"partialmatch",
"pathext",
"pegjs",
"pidtree",
"pify",
"pkgname",
"pkgs",
"plotly",
"plugh",
"pnpmfile",
"pnpmfiles",
"pnpmjs",
"pnpmrc",
"pnpmtest",
"polyfilling",
"português",
"posix",
"postbuild",
"postfoo",
"postpack",
"postprepare",
"postpublish",
"postrestart",
"postshrinkwrap",
"poststart",
"poststop",
"posttest",
"postuninstall",
"postversion",
"preact",
"prefoo",
"prefs",
"preinstall",
"prepublish",
"prereleases",
"prerestart",
"preshrinkwrap",
"prestart",
"prestop",
"preuninstall",
"preversion",
"prioritizer",
"promisified",
"proxied",
"pwsh",
"quux",
"rcompare",
"redownload",
"refclone",
"reflattened",
"reflink",
"reflinked",
"reflinks",
"rehoist",
"reka",
"relinks",
"renderable",
"reqheaders",
"rimrafed",
"rmgr",
"rpmdevtools",
"rpmlint",
"rstacruz",
"rushstack",
"safecrlf",
"scopeless",
"sdiff",
"searchexclude",
"searchlimit",
"searchopts",
"searchstaleness",
"sels",
"semistrict",
"serp",
"serverjs",
"shasums",
"sheetjs",
"shlex",
"sigstore",
"sindresorhus",
"sirv",
"soporan",
"sopts",
"spdxdocs",
"SPDXID",
"srcset",
"ssri",
"stackblitz",
"stacktracey",
"stdtype",
"subdep",
"subdependencies",
"subdependency",
"subdeps",
"subdir",
"subdirs",
"subpkg",
"subresource",
"supercede",
"syml",
"syncer",
"szia",
"tabtab",
"taffydb",
"teambit",
"tempy",
"testcase",
"TLSV",
"todomvc",
"toplevel",
"tsgo",
"tsparticles",
"typecheck",
"unallowed",
"underperformance",
"undollar",
"uninstallation",
"unnest",
"unreviewed",
"unskip",
"unstar",
"usecase",
"userconfig",
"ustar",
"uuidv",
"valign",
"vuln",
"webcontainer",
"winst",
"workleap",
"worktree",
"worktrees",
"wrappy",
"xmarw",
"yazl",
"zkochan",
"zoli",
"zoltan"
]
}