@pnpm/deps.compliance.sbom 1100.4.0 → 1100.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/lib/collectComponents.d.ts +2 -1
- package/lib/collectComponents.js +37 -1
- package/package.json +10 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @pnpm/deps.compliance.sbom
|
|
2
2
|
|
|
3
|
+
## 1100.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- An `integrity` recorded on a git dependency's resolution (`resolution: {type: git, repo, commit, integrity: sha512-…}`) is no longer treated as a checksum. pnpm never verifies a git checkout against such a hash — the commit pins the content — so it is now dropped when the lockfile is rewritten, and `pnpm sbom` no longer republishes it as a CycloneDX/SPDX checksum. Lockfiles carrying one also load again instead of failing with `ERR_PNPM_BROKEN_LOCKFILE` [#13042](https://github.com/pnpm/pnpm/issues/13042).
|
|
8
|
+
|
|
9
|
+
`pnpm sbom` now also publishes the checksum of a `type: binary` runtime archive, which pnpm does verify.
|
|
10
|
+
|
|
11
|
+
- `pnpm sbom` no longer emits components for optional platform-specific dependencies that cannot be installed on the current platform (for example, the native `@rolldown/binding-*` variants for other operating systems). Such packages are present in the lockfile but are never downloaded, so their license (and other metadata) could not be resolved and they appeared in the SBOM without one. `pnpm sbom --lockfile-only` still describes the whole lockfile graph, which is platform-independent by design.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies:
|
|
14
|
+
- @pnpm/config.package-is-installable@1100.1.3
|
|
15
|
+
- @pnpm/error@1100.1.2
|
|
16
|
+
- @pnpm/lockfile.utils@1101.1.0
|
|
17
|
+
- @pnpm/pkg-manifest.reader@1100.0.16
|
|
18
|
+
- @pnpm/store.index@1100.2.4
|
|
19
|
+
- @pnpm/store.pkg-finder@1100.0.29
|
|
20
|
+
|
|
3
21
|
## 1100.4.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LockfileObject } from '@pnpm/lockfile.types';
|
|
2
2
|
import type { Resolution } from '@pnpm/resolving.resolver-base';
|
|
3
|
-
import type { DependenciesField, ProjectId, Registries } from '@pnpm/types';
|
|
3
|
+
import type { DependenciesField, ProjectId, Registries, SupportedArchitectures } from '@pnpm/types';
|
|
4
4
|
import type { SbomComponentType, SbomResult } from './types.js';
|
|
5
5
|
export interface WorkspacePackageInfo {
|
|
6
6
|
name: string;
|
|
@@ -27,6 +27,7 @@ export interface CollectSbomComponentsOptions {
|
|
|
27
27
|
namedRegistries?: Record<string, string>;
|
|
28
28
|
lockfileDir: string;
|
|
29
29
|
includedImporterIds?: ProjectId[];
|
|
30
|
+
supportedArchitectures?: SupportedArchitectures;
|
|
30
31
|
lockfileOnly?: boolean;
|
|
31
32
|
storeDir?: string;
|
|
32
33
|
virtualStoreDirMaxLength?: number;
|
package/lib/collectComponents.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { normalizeNamedRegistries } from '@pnpm/config.normalize-registries';
|
|
3
|
+
import { checkPackageInstallability } from '@pnpm/config.package-is-installable';
|
|
3
4
|
import { PnpmError } from '@pnpm/error';
|
|
4
5
|
import { DepType, detectDepTypes } from '@pnpm/lockfile.detect-dep-types';
|
|
5
6
|
import { nameVerFromPkgSnapshot, pkgSnapshotToResolution } from '@pnpm/lockfile.utils';
|
|
@@ -132,6 +133,23 @@ async function walkStep(step, parentPurl, depTypes, componentsMap, relationships
|
|
|
132
133
|
const { name, version, nonSemverVersion, registryName } = nameVerFromPkgSnapshot(depPath, pkgSnapshot);
|
|
133
134
|
if (!name || !version)
|
|
134
135
|
return;
|
|
136
|
+
// An optional dependency for another platform is in the lockfile but was
|
|
137
|
+
// never fetched, so the store holds no metadata to describe it with.
|
|
138
|
+
// `checkPackageInstallability`, not `packageIsInstallable`: the latter
|
|
139
|
+
// reports every skip through the install loggers, which reading a
|
|
140
|
+
// lockfile must not do.
|
|
141
|
+
if (!opts.lockfileOnly && pkgSnapshot.optional === true && checkPackageInstallability(pkgSnapshot.id ?? depPath, {
|
|
142
|
+
name,
|
|
143
|
+
version,
|
|
144
|
+
cpu: pkgSnapshot.cpu,
|
|
145
|
+
os: pkgSnapshot.os,
|
|
146
|
+
libc: pkgSnapshot.libc,
|
|
147
|
+
}, {
|
|
148
|
+
optional: true,
|
|
149
|
+
supportedArchitectures: opts.supportedArchitectures,
|
|
150
|
+
}) != null) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
135
153
|
// Resolve the alias before the purl is built. An unknown alias would
|
|
136
154
|
// otherwise yield an unqualified purl that collides with the same
|
|
137
155
|
// package from the default registry, and the `componentsMap.has(purl)`
|
|
@@ -153,7 +171,7 @@ async function walkStep(step, parentPurl, depTypes, componentsMap, relationships
|
|
|
153
171
|
relationships.push({ from: parentPurl, to: purl });
|
|
154
172
|
if (componentsMap.has(purl))
|
|
155
173
|
return;
|
|
156
|
-
const integrity = pkgSnapshot.resolution
|
|
174
|
+
const integrity = verifiedIntegrity(pkgSnapshot.resolution);
|
|
157
175
|
const resolution = pkgSnapshotToResolution(depPath, pkgSnapshot, { registries: opts.registries, namedRegistries: opts.namedRegistries });
|
|
158
176
|
const tarballUrl = resolution.tarball ?? gitDownloadUrl(resolution);
|
|
159
177
|
let metadata = {};
|
|
@@ -225,4 +243,22 @@ export function resolveWorkspaceDeps(lockfile, importerIds, include) {
|
|
|
225
243
|
}
|
|
226
244
|
return { links, additionalImporterIds };
|
|
227
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* The resolution's integrity, but only where pnpm verifies the downloaded
|
|
248
|
+
* bytes against it: the tarball/registry hash and a `type: binary` runtime
|
|
249
|
+
* archive's. Nothing checks a git checkout against a hash, so an `integrity`
|
|
250
|
+
* recorded on one is not a checksum and is never published as one.
|
|
251
|
+
*
|
|
252
|
+
* Read from an untyped lockfile, so the shape is probed rather than trusted:
|
|
253
|
+
* reading a checksum out of a malformed resolution yields nothing instead of
|
|
254
|
+
* throwing, and a non-string integrity never reaches `ssri.parse` downstream.
|
|
255
|
+
* (A malformed resolution still fails the walk further along, in
|
|
256
|
+
* `pkgSnapshotToResolution` — this only keeps the checksum lookup total.)
|
|
257
|
+
*/
|
|
258
|
+
function verifiedIntegrity(resolution) {
|
|
259
|
+
const { type, integrity } = (resolution ?? {});
|
|
260
|
+
if (typeof integrity !== 'string')
|
|
261
|
+
return undefined;
|
|
262
|
+
return (type === undefined || type === 'binary') ? integrity : undefined;
|
|
263
|
+
}
|
|
228
264
|
//# sourceMappingURL=collectComponents.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/deps.compliance.sbom",
|
|
3
|
-
"version": "1100.4.
|
|
3
|
+
"version": "1100.4.1",
|
|
4
4
|
"description": "Generate SBOM from pnpm lockfile",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -30,19 +30,20 @@
|
|
|
30
30
|
"!*.map"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@cyclonedx/cyclonedx-library": "10.1.
|
|
33
|
+
"@cyclonedx/cyclonedx-library": "10.1.1",
|
|
34
34
|
"@pnpm/config.normalize-registries": "1100.1.0",
|
|
35
|
+
"@pnpm/config.package-is-installable": "1100.1.3",
|
|
35
36
|
"@pnpm/constants": "1101.0.0",
|
|
36
37
|
"@pnpm/deps.compliance.license-resolver": "1100.0.1",
|
|
37
|
-
"@pnpm/error": "1100.1.
|
|
38
|
+
"@pnpm/error": "1100.1.2",
|
|
38
39
|
"@pnpm/lockfile.detect-dep-types": "1100.0.19",
|
|
39
40
|
"@pnpm/lockfile.types": "1100.0.19",
|
|
40
|
-
"@pnpm/lockfile.utils": "1101.
|
|
41
|
+
"@pnpm/lockfile.utils": "1101.1.0",
|
|
41
42
|
"@pnpm/lockfile.walker": "1100.0.19",
|
|
42
|
-
"@pnpm/pkg-manifest.reader": "1100.0.
|
|
43
|
+
"@pnpm/pkg-manifest.reader": "1100.0.16",
|
|
43
44
|
"@pnpm/resolving.resolver-base": "1101.1.0",
|
|
44
|
-
"@pnpm/store.index": "1100.2.
|
|
45
|
-
"@pnpm/store.pkg-finder": "1100.0.
|
|
45
|
+
"@pnpm/store.index": "1100.2.4",
|
|
46
|
+
"@pnpm/store.pkg-finder": "1100.0.29",
|
|
46
47
|
"@pnpm/types": "1101.9.0",
|
|
47
48
|
"p-limit": "^7.3.1",
|
|
48
49
|
"ssri": "13.0.1"
|
|
@@ -52,9 +53,9 @@
|
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@jest/globals": "30.4.1",
|
|
55
|
-
"@pnpm/deps.compliance.sbom": "1100.4.
|
|
56
|
+
"@pnpm/deps.compliance.sbom": "1100.4.1",
|
|
56
57
|
"@pnpm/logger": "1100.0.0",
|
|
57
|
-
"@pnpm/store.cafs": "1100.1.
|
|
58
|
+
"@pnpm/store.cafs": "1100.1.19",
|
|
58
59
|
"@types/ssri": "^7.1.5"
|
|
59
60
|
},
|
|
60
61
|
"engines": {
|