@pnpm/resolving.npm-resolver 1101.3.2 → 1101.4.0
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/lib/createNpmResolutionVerifier.js +16 -5
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/pickPackage.d.ts +9 -0
- package/lib/pickPackage.js +2 -2
- package/lib/trustChecks.d.ts +1 -1
- package/lib/trustChecks.js +11 -4
- package/package.json +21 -21
|
@@ -233,8 +233,8 @@ async function runAgeCheck(context, registry, name, version, cutoff, ignoreMissi
|
|
|
233
233
|
* attestation endpoint is cheaper than the packument: presence of
|
|
234
234
|
* provenance on the current version is not sufficient to clear a
|
|
235
235
|
* downgrade. A package could have shipped earlier versions under a
|
|
236
|
-
* `trustedPublisher` (the higher-rank evidence) and
|
|
237
|
-
* back to plain provenance for the version we're verifying —
|
|
236
|
+
* `trustedPublisher` with provenance (the higher-rank evidence) and
|
|
237
|
+
* then dropped back to plain provenance for the version we're verifying —
|
|
238
238
|
* `failIfTrustDowngraded` correctly flags that, and a "has any
|
|
239
239
|
* attestation → pass" shortcut would silently miss it.
|
|
240
240
|
*/
|
|
@@ -341,12 +341,23 @@ function projectTrustManifest(manifest) {
|
|
|
341
341
|
// reads them; cast away the unsoundness so callers see the same nominal
|
|
342
342
|
// shape without the per-version dependency graph / scripts / README bulk
|
|
343
343
|
// carrying through. `_npmUser` is similarly narrowed to just
|
|
344
|
-
// `trustedPublisher` — the only sub-
|
|
345
|
-
// we don't keep maintainer name/email PII resident in the
|
|
344
|
+
// `trustedPublisher` and `approver` — the only sub-fields the trust check
|
|
345
|
+
// inspects — so we don't keep maintainer name/email PII resident in the
|
|
346
|
+
// cache.
|
|
347
|
+
const approver = manifest._npmUser?.approver;
|
|
346
348
|
const trustedPublisher = manifest._npmUser?.trustedPublisher;
|
|
347
349
|
const provenance = manifest.dist?.attestations?.provenance;
|
|
350
|
+
let npmUser = undefined;
|
|
351
|
+
if (approver) {
|
|
352
|
+
npmUser ||= {};
|
|
353
|
+
npmUser.approver = {};
|
|
354
|
+
}
|
|
355
|
+
if (trustedPublisher) {
|
|
356
|
+
npmUser ||= {};
|
|
357
|
+
npmUser.trustedPublisher = trustedPublisher;
|
|
358
|
+
}
|
|
348
359
|
return {
|
|
349
|
-
_npmUser:
|
|
360
|
+
_npmUser: npmUser,
|
|
350
361
|
dist: provenance != null
|
|
351
362
|
? { attestations: { provenance } }
|
|
352
363
|
: undefined,
|
package/lib/index.d.ts
CHANGED
|
@@ -108,6 +108,7 @@ export type ResolveFromNpmOptions = {
|
|
|
108
108
|
preferredVersions?: PreferredVersions;
|
|
109
109
|
preferWorkspacePackages?: boolean;
|
|
110
110
|
update?: false | 'compatible' | 'latest';
|
|
111
|
+
updateChecksums?: boolean;
|
|
111
112
|
injectWorkspacePackages?: boolean;
|
|
112
113
|
calcSpecifier?: boolean;
|
|
113
114
|
pinnedVersion?: PinnedVersion;
|
package/lib/index.js
CHANGED
|
@@ -287,6 +287,7 @@ async function resolveNpm(ctx, wantedDependency, opts) {
|
|
|
287
287
|
preferredVersionSelectors: opts.preferredVersions?.[spec.name],
|
|
288
288
|
registry,
|
|
289
289
|
includeLatestTag: opts.update === 'latest',
|
|
290
|
+
updateChecksums: opts.updateChecksums,
|
|
290
291
|
optional: wantedDependency.optional,
|
|
291
292
|
});
|
|
292
293
|
}
|
|
@@ -490,6 +491,7 @@ async function pickFromSimpleRegistry(ctx, wantedDependency, opts, spec, registr
|
|
|
490
491
|
preferredVersionSelectors: opts.preferredVersions?.[spec.name],
|
|
491
492
|
registry,
|
|
492
493
|
includeLatestTag: opts.update === 'latest',
|
|
494
|
+
updateChecksums: opts.updateChecksums,
|
|
493
495
|
optional: wantedDependency.optional,
|
|
494
496
|
});
|
|
495
497
|
if (pickedPackage == null) {
|
package/lib/pickPackage.d.ts
CHANGED
|
@@ -14,6 +14,15 @@ export interface PickPackageOptions extends PickPackageFromMetaOptions {
|
|
|
14
14
|
dryRun: boolean;
|
|
15
15
|
includeLatestTag?: boolean;
|
|
16
16
|
optional?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* When true, skip the on-disk exact-version cache fast path so a
|
|
19
|
+
* stale on-disk packument can't satisfy the call without a
|
|
20
|
+
* conditional registry request. The in-memory cache is left alone:
|
|
21
|
+
* its entries can only be populated by this install's own fresh
|
|
22
|
+
* network fetches, so they're authoritative for second-and-onward
|
|
23
|
+
* lookups within the same install.
|
|
24
|
+
*/
|
|
25
|
+
updateChecksums?: boolean;
|
|
17
26
|
}
|
|
18
27
|
export declare function pickPackage(ctx: {
|
|
19
28
|
fetch: (pkgName: string, opts: {
|
package/lib/pickPackage.js
CHANGED
|
@@ -179,7 +179,7 @@ export async function pickPackage(ctx, spec, opts) {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
if (!opts.includeLatestTag && spec.type === 'version') {
|
|
182
|
+
if (!opts.includeLatestTag && !opts.updateChecksums && spec.type === 'version') {
|
|
183
183
|
metaCachedInStore = metaCachedInStore ?? await limit(async () => loadMeta(pkgMirror));
|
|
184
184
|
// use the cached meta only if it has the required package version
|
|
185
185
|
// otherwise it is probably out of date
|
|
@@ -201,7 +201,7 @@ export async function pickPackage(ctx, spec, opts) {
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
-
if (opts.publishedBy) {
|
|
204
|
+
if (opts.publishedBy && opts.publishedByExclude?.(spec.name) !== true) {
|
|
205
205
|
const mtime = await limit(async () => getFileMtime(pkgMirror));
|
|
206
206
|
if (mtime != null && mtime >= opts.publishedBy) {
|
|
207
207
|
metaCachedInStore = metaCachedInStore ?? await limit(async () => loadMeta(pkgMirror));
|
package/lib/trustChecks.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PackageInRegistry, PackageMeta } from '@pnpm/resolving.registry.types';
|
|
2
2
|
import type { PackageVersionPolicy } from '@pnpm/types';
|
|
3
|
-
type TrustEvidence = 'provenance' | 'trustedPublisher';
|
|
3
|
+
type TrustEvidence = 'provenance' | 'trustedPublisher' | 'stagedPublish';
|
|
4
4
|
export declare function failIfTrustDowngraded(meta: PackageMeta, version: string, opts?: {
|
|
5
5
|
trustPolicyExclude?: PackageVersionPolicy;
|
|
6
6
|
trustPolicyIgnoreAfter?: number;
|
package/lib/trustChecks.js
CHANGED
|
@@ -2,6 +2,7 @@ import { PnpmError } from '@pnpm/error';
|
|
|
2
2
|
import semver from 'semver';
|
|
3
3
|
import { assertMetaHasTime } from './pickPackageFromMeta.js';
|
|
4
4
|
const TRUST_RANK = {
|
|
5
|
+
stagedPublish: 3,
|
|
5
6
|
trustedPublisher: 2,
|
|
6
7
|
provenance: 1,
|
|
7
8
|
};
|
|
@@ -51,6 +52,7 @@ export function failIfTrustDowngraded(meta, version, opts) {
|
|
|
51
52
|
}
|
|
52
53
|
function prettyPrintTrustEvidence(trustEvidence) {
|
|
53
54
|
switch (trustEvidence) {
|
|
55
|
+
case 'stagedPublish': return 'staged publish';
|
|
54
56
|
case 'trustedPublisher': return 'trusted publisher';
|
|
55
57
|
case 'provenance': return 'provenance attestation';
|
|
56
58
|
default: return 'no trust evidence';
|
|
@@ -70,15 +72,20 @@ function detectStrongestTrustEvidenceBeforeDate(meta, beforeDate, options) {
|
|
|
70
72
|
const trustEvidence = getTrustEvidence(manifest);
|
|
71
73
|
if (!trustEvidence)
|
|
72
74
|
continue;
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
+
if (best === undefined || TRUST_RANK[trustEvidence] > TRUST_RANK[best]) {
|
|
76
|
+
best = trustEvidence;
|
|
77
|
+
if (best === 'stagedPublish') {
|
|
78
|
+
return best;
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
|
-
best ||= 'provenance';
|
|
77
81
|
}
|
|
78
82
|
return best;
|
|
79
83
|
}
|
|
80
84
|
export function getTrustEvidence(manifest) {
|
|
81
|
-
if (manifest._npmUser?.
|
|
85
|
+
if (manifest._npmUser?.approver) {
|
|
86
|
+
return 'stagedPublish';
|
|
87
|
+
}
|
|
88
|
+
if (manifest._npmUser?.trustedPublisher && manifest.dist?.attestations?.provenance) {
|
|
82
89
|
return 'trustedPublisher';
|
|
83
90
|
}
|
|
84
91
|
if (manifest.dist?.attestations?.provenance) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/resolving.npm-resolver",
|
|
3
|
-
"version": "1101.
|
|
3
|
+
"version": "1101.4.0",
|
|
4
4
|
"description": "Resolver for npm-hosted packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,39 +28,39 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@zkochan/retry": "^0.2.0",
|
|
30
30
|
"encode-registry": "^3.0.1",
|
|
31
|
-
"lru-cache": "^11.
|
|
31
|
+
"lru-cache": "^11.5.0",
|
|
32
32
|
"normalize-path": "^3.0.0",
|
|
33
|
-
"p-limit": "^7.
|
|
33
|
+
"p-limit": "^7.3.0",
|
|
34
34
|
"p-memoize": "8.0.0",
|
|
35
35
|
"parse-npm-tarball-url": "^5.0.0",
|
|
36
36
|
"path-temp": "^3.0.0",
|
|
37
37
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
38
38
|
"rename-overwrite": "^7.0.1",
|
|
39
|
-
"semver": "^7.
|
|
39
|
+
"semver": "^7.8.1",
|
|
40
40
|
"semver-utils": "^1.1.4",
|
|
41
41
|
"ssri": "13.0.1",
|
|
42
42
|
"version-selector-type": "^3.0.0",
|
|
43
|
-
"@pnpm/config.
|
|
44
|
-
"@pnpm/
|
|
43
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.6",
|
|
44
|
+
"@pnpm/constants": "1100.0.0",
|
|
45
|
+
"@pnpm/error": "1100.0.0",
|
|
45
46
|
"@pnpm/crypto.hash": "1100.0.1",
|
|
46
47
|
"@pnpm/fetching.types": "1100.0.1",
|
|
47
|
-
"@pnpm/constants": "1100.0.0",
|
|
48
48
|
"@pnpm/fs.graceful-fs": "1100.1.0",
|
|
49
|
-
"@pnpm/
|
|
50
|
-
"@pnpm/
|
|
51
|
-
"@pnpm/resolving.registry.pkg-metadata-filter": "1100.0.4",
|
|
52
|
-
"@pnpm/resolving.registry.types": "1100.0.4",
|
|
53
|
-
"@pnpm/resolving.resolver-base": "1100.3.0",
|
|
49
|
+
"@pnpm/resolving.registry.pkg-metadata-filter": "1100.0.6",
|
|
50
|
+
"@pnpm/resolving.registry.types": "1100.1.0",
|
|
54
51
|
"@pnpm/resolving.jsr-specifier-parser": "1100.0.0",
|
|
55
|
-
"@pnpm/store.cafs": "1100.1.
|
|
56
|
-
"@pnpm/
|
|
52
|
+
"@pnpm/store.cafs": "1100.1.7",
|
|
53
|
+
"@pnpm/store.index": "1100.1.0",
|
|
54
|
+
"@pnpm/types": "1101.2.0",
|
|
57
55
|
"@pnpm/workspace.spec-parser": "1100.0.0",
|
|
58
|
-
"@pnpm/
|
|
59
|
-
"@pnpm/
|
|
56
|
+
"@pnpm/resolving.resolver-base": "1100.3.1",
|
|
57
|
+
"@pnpm/workspace.range-resolver": "1100.0.1",
|
|
58
|
+
"@pnpm/config.version-policy": "1100.1.2",
|
|
59
|
+
"@pnpm/core-loggers": "1100.1.2"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@pnpm/logger": "
|
|
63
|
-
"@pnpm/worker": "^1100.1.
|
|
62
|
+
"@pnpm/logger": "^1001.0.1",
|
|
63
|
+
"@pnpm/worker": "^1100.1.8"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@jest/globals": "30.3.0",
|
|
@@ -71,10 +71,10 @@
|
|
|
71
71
|
"load-json-file": "^7.0.1",
|
|
72
72
|
"tempy": "3.0.0",
|
|
73
73
|
"@pnpm/logger": "1100.0.0",
|
|
74
|
-
"@pnpm/network.fetch": "1100.0.
|
|
75
|
-
"@pnpm/resolving.npm-resolver": "1101.3.2",
|
|
74
|
+
"@pnpm/network.fetch": "1100.0.8",
|
|
76
75
|
"@pnpm/test-fixtures": "1100.0.0",
|
|
77
|
-
"@pnpm/
|
|
76
|
+
"@pnpm/resolving.npm-resolver": "1101.4.0",
|
|
77
|
+
"@pnpm/testing.mock-agent": "1100.0.8"
|
|
78
78
|
},
|
|
79
79
|
"engines": {
|
|
80
80
|
"node": ">=22.13"
|