@pnpm/resolving.npm-resolver 1101.2.0 → 1101.3.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/index.d.ts +5 -1
- package/lib/index.js +58 -3
- package/lib/pickPackage.js +12 -4
- package/lib/pickPackageFromMeta.js +6 -2
- package/package.json +13 -13
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PnpmError } from '@pnpm/error';
|
|
2
2
|
import type { FetchFromRegistry, GetAuthHeader, RetryTimeoutOptions } from '@pnpm/fetching.types';
|
|
3
3
|
import type { PackageMeta } from '@pnpm/resolving.registry.types';
|
|
4
|
-
import type { DirectoryResolution, PkgResolutionId, PreferredVersions, ResolveResult, TarballResolution, WantedDependency, WorkspacePackages } from '@pnpm/resolving.resolver-base';
|
|
4
|
+
import type { DirectoryResolution, LatestInfo, LatestQuery, PkgResolutionId, PreferredVersions, ResolveOptions, ResolveResult, TarballResolution, WantedDependency, WorkspacePackages } from '@pnpm/resolving.resolver-base';
|
|
5
5
|
import type { DependencyManifest, PackageVersionPolicy, PinnedVersion, Registries, TrustPolicy } from '@pnpm/types';
|
|
6
6
|
import { fetchMetadataFromFromRegistry, type FetchMetadataFromFromRegistryOptions, RegistryResponseError } from './fetch.js';
|
|
7
7
|
import { BUILTIN_NAMED_REGISTRIES, parseBareSpecifier, type RegistryPackageSpec } from './parseBareSpecifier.js';
|
|
@@ -70,10 +70,14 @@ export interface WorkspaceResolveResult extends ResolveResult {
|
|
|
70
70
|
export type NpmResolver = (wantedDependency: WantedDependency & {
|
|
71
71
|
optional?: boolean;
|
|
72
72
|
}, opts: ResolveFromNpmOptions) => Promise<NpmResolveResult | JsrResolveResult | NamedRegistryResolveResult | WorkspaceResolveResult | null>;
|
|
73
|
+
export type ResolveLatestFromNpmStyle = (query: LatestQuery, opts: ResolveOptions) => Promise<LatestInfo | undefined>;
|
|
73
74
|
export declare function createNpmResolver(fetchFromRegistry: FetchFromRegistry, getAuthHeader: GetAuthHeader, opts: ResolverFactoryOptions): {
|
|
74
75
|
resolveFromNpm: NpmResolver;
|
|
75
76
|
resolveFromJsr: NpmResolver;
|
|
76
77
|
resolveFromNamedRegistry: NpmResolver;
|
|
78
|
+
resolveLatestFromNpm: ResolveLatestFromNpmStyle;
|
|
79
|
+
resolveLatestFromJsr: ResolveLatestFromNpmStyle;
|
|
80
|
+
resolveLatestFromNamedRegistry: ResolveLatestFromNpmStyle;
|
|
77
81
|
clearCache: () => void;
|
|
78
82
|
};
|
|
79
83
|
export interface ResolveFromNpmContext {
|
package/lib/index.js
CHANGED
|
@@ -125,10 +125,17 @@ export function createNpmResolver(fetchFromRegistry, getAuthHeader, opts) {
|
|
|
125
125
|
saveWorkspaceProtocol: opts.saveWorkspaceProtocol,
|
|
126
126
|
peekManifestFromStore,
|
|
127
127
|
};
|
|
128
|
+
const boundResolveFromNpm = resolveNpm.bind(null, ctx);
|
|
129
|
+
const boundResolveFromJsr = resolveJsr.bind(null, ctx);
|
|
130
|
+
const boundResolveFromNamedRegistry = resolveFromNamedRegistry.bind(null, ctx);
|
|
131
|
+
const defaultRegistry = opts.registries.default;
|
|
128
132
|
return {
|
|
129
|
-
resolveFromNpm:
|
|
130
|
-
resolveFromJsr:
|
|
131
|
-
resolveFromNamedRegistry:
|
|
133
|
+
resolveFromNpm: boundResolveFromNpm,
|
|
134
|
+
resolveFromJsr: boundResolveFromJsr,
|
|
135
|
+
resolveFromNamedRegistry: boundResolveFromNamedRegistry,
|
|
136
|
+
resolveLatestFromNpm: createResolveLatest(boundResolveFromNpm, (query) => isNpmSpec(query, defaultRegistry)),
|
|
137
|
+
resolveLatestFromJsr: createResolveLatest(boundResolveFromJsr, isJsrSpec),
|
|
138
|
+
resolveLatestFromNamedRegistry: createResolveLatest(boundResolveFromNamedRegistry, (query) => isNamedRegistrySpec(query, ctx.namedRegistryNames)),
|
|
132
139
|
clearCache: () => {
|
|
133
140
|
if ('clear' in metaCache && typeof metaCache.clear === 'function') {
|
|
134
141
|
metaCache.clear();
|
|
@@ -137,6 +144,54 @@ export function createNpmResolver(fetchFromRegistry, getAuthHeader, opts) {
|
|
|
137
144
|
},
|
|
138
145
|
};
|
|
139
146
|
}
|
|
147
|
+
function isNpmSpec(query, defaultRegistry) {
|
|
148
|
+
const { alias, bareSpecifier } = query.wantedDependency;
|
|
149
|
+
if (!bareSpecifier)
|
|
150
|
+
return alias != null;
|
|
151
|
+
return parseBareSpecifier(bareSpecifier, alias, 'latest', defaultRegistry) != null;
|
|
152
|
+
}
|
|
153
|
+
function isJsrSpec(query) {
|
|
154
|
+
if (!query.wantedDependency.bareSpecifier?.startsWith('jsr:'))
|
|
155
|
+
return false;
|
|
156
|
+
return parseJsrSpecifierToRegistryPackageSpec(query.wantedDependency.bareSpecifier, query.wantedDependency.alias, 'latest') != null;
|
|
157
|
+
}
|
|
158
|
+
function isNamedRegistrySpec(query, knownRegistryNames) {
|
|
159
|
+
if (!query.wantedDependency.bareSpecifier)
|
|
160
|
+
return false;
|
|
161
|
+
try {
|
|
162
|
+
return parseNamedRegistrySpecifierToRegistryPackageSpec(query.wantedDependency.bareSpecifier, knownRegistryNames, query.wantedDependency.alias, 'latest') != null;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function createResolveLatest(resolve, matches) {
|
|
169
|
+
return async (query, opts) => {
|
|
170
|
+
if (!matches(query))
|
|
171
|
+
return undefined;
|
|
172
|
+
// Always pass the manifest's bareSpecifier so protocol-prefixed specs
|
|
173
|
+
// (`jsr:@scope/pkg@^1.0.0`, `gh:owner/repo@^1.0.0`) still match their
|
|
174
|
+
// resolver. In --compatible mode that range drives the pick; otherwise
|
|
175
|
+
// `update: 'latest'` tells the resolver to ignore the range and take
|
|
176
|
+
// the absolute newest.
|
|
177
|
+
const bareSpecifier = query.wantedDependency.bareSpecifier ?? 'latest';
|
|
178
|
+
const resolveOpts = query.compatible ? opts : { ...opts, update: 'latest' };
|
|
179
|
+
try {
|
|
180
|
+
const result = await resolve({ alias: query.wantedDependency.alias, bareSpecifier }, resolveOpts);
|
|
181
|
+
// Policy-blocked: handled but no latest to surface.
|
|
182
|
+
if (result?.policyViolation?.code === MINIMUM_RELEASE_AGE_VIOLATION_CODE) {
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
return { latestManifest: result?.manifest };
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
if (opts.publishedBy && err.code === 'ERR_PNPM_NO_MATCHING_VERSION') {
|
|
189
|
+
return {};
|
|
190
|
+
}
|
|
191
|
+
throw err;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
140
195
|
async function resolveNpm(ctx, wantedDependency, opts) {
|
|
141
196
|
const defaultTag = opts.defaultTag ?? 'latest';
|
|
142
197
|
const registry = wantedDependency.alias
|
package/lib/pickPackage.js
CHANGED
|
@@ -277,7 +277,12 @@ export async function pickPackage(ctx, spec, opts) {
|
|
|
277
277
|
opts.publishedByExclude?.(spec.name) !== true) {
|
|
278
278
|
const modifiedDate = meta.modified ? new Date(meta.modified) : null;
|
|
279
279
|
const isModifiedValid = modifiedDate != null && !Number.isNaN(modifiedDate.getTime());
|
|
280
|
-
|
|
280
|
+
// Strict `>` (not `>=`) so the boundary case `modified == publishedBy`
|
|
281
|
+
// takes the abbreviated fast path: `modified` is an upper bound on
|
|
282
|
+
// every version's publish time, so when it equals the cutoff every
|
|
283
|
+
// version passes the per-version `<=` filter in
|
|
284
|
+
// `filterPkgMetadataByPublishDate` and a full re-fetch isn't needed.
|
|
285
|
+
if (!isModifiedValid || modifiedDate > opts.publishedBy) {
|
|
281
286
|
// Save the abbreviated metadata to the abbreviated cache before re-fetching full.
|
|
282
287
|
if (!opts.dryRun) {
|
|
283
288
|
const abbreviatedJson = prepareJsonForDisk(fetchResult.meta, fetchResult.etag, fetchResult.jsonText);
|
|
@@ -361,9 +366,12 @@ async function maybeUpgradeAbbreviatedMetaForReleaseAge(ctx, spec, opts, meta) {
|
|
|
361
366
|
}
|
|
362
367
|
const modifiedDate = meta.modified ? new Date(meta.modified) : null;
|
|
363
368
|
const isModifiedValid = modifiedDate != null && !Number.isNaN(modifiedDate.getTime());
|
|
364
|
-
if (isModifiedValid && modifiedDate
|
|
365
|
-
// The package was last modified before the maturity cutoff.
|
|
366
|
-
//
|
|
369
|
+
if (isModifiedValid && modifiedDate <= opts.publishedBy) {
|
|
370
|
+
// The package was last modified at or before the maturity cutoff. Since
|
|
371
|
+
// `modified` is an upper bound on every version's publish time, no version
|
|
372
|
+
// can be newer than the cutoff, so the abbreviated form is fine.
|
|
373
|
+
// Inclusive at the boundary on purpose: matches the per-version `<=` filter
|
|
374
|
+
// in `filterPkgMetadataByPublishDate`.
|
|
367
375
|
return { meta };
|
|
368
376
|
}
|
|
369
377
|
// When `modified` is missing or malformed we fall through to the upgrade
|
|
@@ -14,13 +14,17 @@ export function pickPackageFromMeta(pickVersionByVersionRangeFn, { preferredVers
|
|
|
14
14
|
}
|
|
15
15
|
else {
|
|
16
16
|
const modifiedDate = parseModifiedDate(meta.modified);
|
|
17
|
-
if (modifiedDate == null || modifiedDate
|
|
17
|
+
if (modifiedDate == null || modifiedDate > publishedBy) {
|
|
18
18
|
// Abbreviated metadata without per-version timestamps, and the package
|
|
19
19
|
// was recently modified (or has no/invalid modified field). We cannot determine
|
|
20
20
|
// which individual versions are mature enough — need full metadata.
|
|
21
21
|
assertMetaHasTime(meta);
|
|
22
22
|
}
|
|
23
|
-
// else: meta.modified
|
|
23
|
+
// else: meta.modified <= publishedBy — every version was published at or
|
|
24
|
+
// before the cutoff (modified is an upper bound on per-version time), so
|
|
25
|
+
// they all pass the per-version `<=` maturity filter and no filtering is
|
|
26
|
+
// needed. Inclusive at the boundary on purpose so this branch matches the
|
|
27
|
+
// per-version filter in `filterPkgMetadataByPublishDate`.
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/resolving.npm-resolver",
|
|
3
|
-
"version": "1101.
|
|
3
|
+
"version": "1101.3.0",
|
|
4
4
|
"description": "Resolver for npm-hosted packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -40,27 +40,27 @@
|
|
|
40
40
|
"semver-utils": "^1.1.4",
|
|
41
41
|
"ssri": "13.0.1",
|
|
42
42
|
"version-selector-type": "^3.0.0",
|
|
43
|
-
"@pnpm/config.pick-registry-for-package": "1100.0.
|
|
44
|
-
"@pnpm/
|
|
43
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.4",
|
|
44
|
+
"@pnpm/core-loggers": "1100.1.1",
|
|
45
45
|
"@pnpm/constants": "1100.0.0",
|
|
46
|
-
"@pnpm/
|
|
46
|
+
"@pnpm/config.version-policy": "1100.1.1",
|
|
47
47
|
"@pnpm/crypto.hash": "1100.0.1",
|
|
48
48
|
"@pnpm/error": "1100.0.0",
|
|
49
49
|
"@pnpm/fetching.types": "1100.0.1",
|
|
50
50
|
"@pnpm/fs.graceful-fs": "1100.1.0",
|
|
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",
|
|
51
54
|
"@pnpm/resolving.jsr-specifier-parser": "1100.0.0",
|
|
52
|
-
"@pnpm/
|
|
53
|
-
"@pnpm/resolving.registry.types": "1100.0.3",
|
|
54
|
-
"@pnpm/resolving.resolver-base": "1100.2.0",
|
|
55
|
-
"@pnpm/store.cafs": "1100.1.5",
|
|
55
|
+
"@pnpm/store.cafs": "1100.1.6",
|
|
56
56
|
"@pnpm/store.index": "1100.1.0",
|
|
57
|
-
"@pnpm/types": "1101.1.
|
|
57
|
+
"@pnpm/types": "1101.1.1",
|
|
58
58
|
"@pnpm/workspace.range-resolver": "1100.0.1",
|
|
59
59
|
"@pnpm/workspace.spec-parser": "1100.0.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@pnpm/logger": ">=1001.0.0 <1002.0.0",
|
|
63
|
-
"@pnpm/worker": "^1100.1.
|
|
63
|
+
"@pnpm/worker": "^1100.1.7"
|
|
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/
|
|
75
|
-
"@pnpm/network.fetch": "1100.0.5",
|
|
74
|
+
"@pnpm/network.fetch": "1100.0.6",
|
|
76
75
|
"@pnpm/test-fixtures": "1100.0.0",
|
|
77
|
-
"@pnpm/
|
|
76
|
+
"@pnpm/resolving.npm-resolver": "1101.3.0",
|
|
77
|
+
"@pnpm/testing.mock-agent": "1100.0.6"
|
|
78
78
|
},
|
|
79
79
|
"engines": {
|
|
80
80
|
"node": ">=22.13"
|