@pnpm/resolving.npm-resolver 1102.1.3 → 1102.1.4

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.
@@ -1,37 +0,0 @@
1
- /**
2
- * Memoizes metadata fetches for the whole resolution phase (cleared via
3
- * `clear`, see `clearResolutionCache`), deduplicating concurrent and repeat
4
- * requests for the same package.
5
- *
6
- * Unlike plain memoization, the cache holds a body-less clone of each result:
7
- * `jsonText` — the raw registry response body, up to tens of MB for a popular
8
- * package — reaches only the caller that initiated the fetch, which is the
9
- * caller that writes the disk mirror. A phase-long cache that kept the bodies
10
- * would pin hundreds of MB on large cold-cache graphs. A cache-hit caller
11
- * that also writes the mirror falls back to `JSON.stringify(meta)` in
12
- * `prepareJsonForDisk`, which is equivalent on read: `loadMeta` re-derives
13
- * `etag` from the headers line.
14
- *
15
- * A rejected fetch is evicted so a transient network failure is retried by
16
- * the next request instead of being cached for the rest of the phase.
17
- */
18
- export function memoizeFetchMetadata(fetch) {
19
- const cache = new Map();
20
- return {
21
- fetch: (pkgName, opts) => {
22
- const key = JSON.stringify([pkgName, opts]);
23
- const cached = cache.get(key);
24
- if (cached != null)
25
- return cached;
26
- const pending = fetch(pkgName, opts);
27
- const bodiless = pending.then((result) => result.notModified ? result : { ...result, jsonText: undefined });
28
- bodiless.catch(() => cache.delete(key));
29
- cache.set(key, bodiless);
30
- return pending;
31
- },
32
- clear: () => {
33
- cache.clear();
34
- },
35
- };
36
- }
37
- //# sourceMappingURL=memoizeFetchMetadata.js.map
@@ -1,4 +0,0 @@
1
- /**
2
- * Remove default ports (80 for HTTP, 443 for HTTPS) to ensure consistency
3
- */
4
- export declare function normalizeRegistryUrl(urlString: string): string;
@@ -1,12 +0,0 @@
1
- /**
2
- * Remove default ports (80 for HTTP, 443 for HTTPS) to ensure consistency
3
- */
4
- export function normalizeRegistryUrl(urlString) {
5
- try {
6
- return new URL(urlString).toString();
7
- }
8
- catch {
9
- return urlString;
10
- }
11
- }
12
- //# sourceMappingURL=normalizeRegistryUrl.js.map
@@ -1,16 +0,0 @@
1
- export interface RegistryPackageSpec {
2
- type: 'tag' | 'version' | 'range';
3
- name: string;
4
- fetchSpec: string;
5
- normalizedBareSpecifier?: string;
6
- }
7
- export declare function parseBareSpecifier(bareSpecifier: string, alias: string | undefined, defaultTag: string, registry: string): RegistryPackageSpec | null;
8
- export interface JsrRegistryPackageSpec extends RegistryPackageSpec {
9
- jsrPkgName: string;
10
- }
11
- export declare function parseJsrSpecifierToRegistryPackageSpec(rawSpecifier: string, alias: string | undefined, defaultTag: string): JsrRegistryPackageSpec | null;
12
- export declare const BUILTIN_NAMED_REGISTRIES: Readonly<Record<string, string>>;
13
- export interface NamedRegistryPackageSpec extends RegistryPackageSpec {
14
- registryName: string;
15
- }
16
- export declare function parseNamedRegistrySpecifierToRegistryPackageSpec(rawSpecifier: string, knownRegistryNames: ReadonlySet<string>, packageAlias: string | undefined, defaultTag: string): NamedRegistryPackageSpec | null;
@@ -1,143 +0,0 @@
1
- import { PnpmError } from '@pnpm/error';
2
- import { parseJsrSpecifier } from '@pnpm/resolving.jsr-specifier-parser';
3
- import { parseNpmTarballUrl } from 'parse-npm-tarball-url';
4
- import semver from 'semver';
5
- import validateNpmPackageName from 'validate-npm-package-name';
6
- import getVersionSelectorType from 'version-selector-type';
7
- export function parseBareSpecifier(bareSpecifier, alias, defaultTag, registry) {
8
- let name = alias;
9
- if (bareSpecifier.startsWith('npm:')) {
10
- bareSpecifier = bareSpecifier.slice(4);
11
- // `npm:<version_selector>` — fall back to the outer dependency alias as
12
- // the package name, mirroring the named-registry shape (e.g. `gh:^1.0.0`).
13
- // Restricted to semver ranges/versions so unscoped package names like
14
- // `npm:is-positive` keep their npm package-aliasing meaning.
15
- if (alias && semver.validRange(bareSpecifier) != null) {
16
- name = alias;
17
- }
18
- else {
19
- const index = bareSpecifier.lastIndexOf('@');
20
- if (index < 1) {
21
- name = bareSpecifier;
22
- bareSpecifier = defaultTag;
23
- }
24
- else {
25
- name = bareSpecifier.slice(0, index);
26
- bareSpecifier = bareSpecifier.slice(index + 1);
27
- }
28
- }
29
- }
30
- if (name) {
31
- const selector = getVersionSelectorType(bareSpecifier);
32
- if (selector != null) {
33
- return {
34
- fetchSpec: selector.normalized,
35
- name,
36
- type: selector.type,
37
- };
38
- }
39
- }
40
- if (bareSpecifier.startsWith(registry)) {
41
- const pkg = parseNpmTarballUrl(bareSpecifier);
42
- if (pkg != null) {
43
- return {
44
- fetchSpec: pkg.version,
45
- name: pkg.name,
46
- normalizedBareSpecifier: bareSpecifier,
47
- type: 'version',
48
- };
49
- }
50
- }
51
- return null;
52
- }
53
- export function parseJsrSpecifierToRegistryPackageSpec(rawSpecifier, alias, defaultTag) {
54
- const spec = parseJsrSpecifier(rawSpecifier, alias);
55
- if (!spec?.npmPkgName)
56
- return null;
57
- const selector = getVersionSelectorType(spec.versionSelector ?? defaultTag);
58
- if (selector == null)
59
- return null;
60
- return {
61
- fetchSpec: selector.normalized,
62
- name: spec.npmPkgName,
63
- type: selector.type,
64
- jsrPkgName: spec.jsrPkgName,
65
- };
66
- }
67
- export const BUILTIN_NAMED_REGISTRIES = Object.freeze({
68
- gh: 'https://npm.pkg.github.com/',
69
- });
70
- // Parses a named-registry specifier of the shape `<alias>:<body>` into a
71
- // RegistryPackageSpec. Returns `null` when the specifier does not use one of
72
- // the configured aliases, so the caller can fall through to other resolvers.
73
- // Throws INVALID_NAMED_REGISTRY_PACKAGE_NAME when the alias matches but the
74
- // package name is malformed (missing or empty scope/name segments, path
75
- // separators inside the name).
76
- // Supported shapes:
77
- // - `<alias>:[@<owner>/]<name>[@<version_selector>]`
78
- // - `<alias>:<version_selector>` paired with a package alias
79
- export function parseNamedRegistrySpecifierToRegistryPackageSpec(rawSpecifier, knownRegistryNames, packageAlias, defaultTag) {
80
- const colon = rawSpecifier.indexOf(':');
81
- if (colon <= 0)
82
- return null;
83
- const registryName = rawSpecifier.substring(0, colon);
84
- if (!knownRegistryNames.has(registryName))
85
- return null;
86
- const body = rawSpecifier.substring(colon + 1);
87
- let pkgName;
88
- let versionSelector;
89
- if (semver.validRange(body) != null) {
90
- // `<alias>:<version_selector>` — fall back to the dependency alias as
91
- // the package name. Unresolvable without one.
92
- if (!packageAlias)
93
- return null;
94
- pkgName = packageAlias;
95
- versionSelector = body;
96
- }
97
- else if (body[0] === '@') {
98
- // `<alias>:@<owner>/<name>[@<version_selector>]` — scoped package.
99
- const index = body.lastIndexOf('@');
100
- if (index === 0) {
101
- pkgName = body;
102
- }
103
- else {
104
- pkgName = body.substring(0, index);
105
- versionSelector = body.substring(index + '@'.length);
106
- }
107
- }
108
- else if (packageAlias?.startsWith('@')) {
109
- // `<alias>:<tag>` paired with a scoped alias — body is a version
110
- // selector (tag/dist-tag). Mirrors GitHub Packages, where the package
111
- // is always scoped and a bare body is a tag.
112
- pkgName = packageAlias;
113
- versionSelector = body;
114
- }
115
- else {
116
- // `<alias>:<name>[@<version_selector>]` — unscoped package in body.
117
- const index = body.lastIndexOf('@');
118
- if (index < 1) {
119
- pkgName = body;
120
- }
121
- else {
122
- pkgName = body.substring(0, index);
123
- versionSelector = body.substring(index + '@'.length);
124
- }
125
- if (!pkgName)
126
- return null;
127
- }
128
- // The name is used in registry URLs and metadata cache file paths, so
129
- // anything that is not a valid npm package name must never make it through.
130
- if (!validateNpmPackageName(pkgName).validForOldPackages) {
131
- throw new PnpmError('INVALID_NAMED_REGISTRY_PACKAGE_NAME', `The package name '${pkgName}' in named registry '${registryName}:' is invalid`);
132
- }
133
- const selector = getVersionSelectorType(versionSelector ?? defaultTag);
134
- if (selector == null)
135
- return null;
136
- return {
137
- fetchSpec: selector.normalized,
138
- name: pkgName,
139
- type: selector.type,
140
- registryName,
141
- };
142
- }
143
- //# sourceMappingURL=parseBareSpecifier.js.map
@@ -1,109 +0,0 @@
1
- import type { PackageInRegistry, PackageMeta } from '@pnpm/resolving.registry.types';
2
- import type { FetchMetadataNotModifiedResult, FetchMetadataResult } from './fetch.js';
3
- import type { RegistryPackageSpec } from './parseBareSpecifier.js';
4
- import { type PickPackageFromMetaOptions } from './pickPackageFromMeta.js';
5
- export interface PackageMetaCache {
6
- /**
7
- * Must return the same object reference that `set` stored for the key: the
8
- * resolver tracks whether a cached packument was validated against the
9
- * registry by object identity (see `unverifiedDiskPackuments`). In a cache
10
- * that clones or deserializes on read, that provenance is lost and recovery
11
- * degrades — a stale disk-promoted entry that can't satisfy a spec fails
12
- * the pick instead of falling through to the registry.
13
- */
14
- get: (key: string) => PackageMeta | undefined;
15
- set: (key: string, meta: PackageMeta) => void;
16
- has: (key: string) => boolean;
17
- }
18
- export interface PickPackageOptions extends PickPackageFromMetaOptions {
19
- authHeaderValue?: string;
20
- pickLowestVersion?: boolean;
21
- registry: string;
22
- dryRun: boolean;
23
- includeLatestTag?: boolean;
24
- optional?: boolean;
25
- /**
26
- * When true, force a conditional registry request so a stale on-disk
27
- * packument can't satisfy the call: the on-disk exact-version fast
28
- * path is skipped, and the in-memory cache is bypassed too. The fast
29
- * path now promotes disk-loaded packuments into the in-memory cache,
30
- * so an entry there can no longer be assumed to come from this
31
- * install's own fresh network fetch — on a shared or long-lived
32
- * resolver it might be disk-sourced, which would short-circuit the
33
- * revalidation updateChecksums exists to force.
34
- */
35
- updateChecksums?: boolean;
36
- }
37
- export declare function pickPackage(ctx: {
38
- fetch: (pkgName: string, opts: {
39
- registry: string;
40
- authHeaderValue?: string;
41
- fullMetadata?: boolean;
42
- etag?: string;
43
- modified?: string;
44
- }) => Promise<FetchMetadataResult | FetchMetadataNotModifiedResult>;
45
- fullMetadata?: boolean;
46
- metaCache: PackageMetaCache;
47
- cacheDir: string;
48
- offline?: boolean;
49
- preferOffline?: boolean;
50
- filterMetadata?: boolean;
51
- ignoreMissingTimeField?: boolean;
52
- }, spec: RegistryPackageSpec, opts: PickPackageOptions): Promise<{
53
- meta: PackageMeta;
54
- pickedPackage: PackageInRegistry | null;
55
- }>;
56
- export declare function encodePkgName(pkgName: string): string;
57
- /**
58
- * Key for the in-memory `metaCache` holding a package's registry metadata. The
59
- * registry is part of the key so that a package of the same name served by two
60
- * registries in one install can't collide on a single slot (which would resolve
61
- * the wrong tarball/integrity). `fullMetadata` and `filterMetadata` keep the
62
- * abbreviated, full, and filtered-full documents in distinct slots, mirroring
63
- * the on-disk `metaDir` split: a `filterMetadata` resolver stores a `clearMeta`-
64
- * stripped packument, so it must not share a slot with an unfiltered full one
65
- * (reachable only when a `metaCache` is shared across resolvers with different
66
- * settings). `filterMetadata` only narrows the full slot — abbreviated metadata
67
- * shares one on-disk mirror regardless, so its key carries no filtered variant.
68
- * `\x00` can't appear in a registry URL or a package name, so it's an
69
- * unambiguous separator. The verifier reads this same cache and must build the
70
- * key with this function.
71
- *
72
- * The registry is canonicalized to its origin plus a trailing-slashed path, so
73
- * the resolver (which may pass a configured named-registry URL verbatim) and
74
- * the verifier (which routes through trailing-slashed prefixes) converge on one
75
- * key for the same logical registry instead of creating duplicate slots. Origin
76
- * and path are preserved, so two registries that genuinely differ never collapse.
77
- */
78
- export declare function getPkgMetaCacheKey(registry: string, pkgName: string, fullMetadata: boolean, filterMetadata: boolean): string;
79
- /**
80
- * Path of the on-disk JSONL document where pnpm mirrors a package's registry
81
- * metadata. `metaDir` selects between abbreviated and full caches.
82
- */
83
- export declare function getPkgMirrorPath(cacheDir: string, metaDir: string, registry: string, pkgName: string): string;
84
- /**
85
- * Formats metadata for disk storage as two-line NDJSON:
86
- * Line 1: cache headers (etag, modified) — small, fast to read
87
- * Line 2: the full registry metadata JSON — unchanged from the registry response
88
- */
89
- export declare function prepareJsonForDisk(meta: PackageMeta, etag: string | undefined, jsonText?: string): string;
90
- export declare function warnMissingTimeFieldOnce(pkgName: string): void;
91
- interface MetaHeaders {
92
- etag?: string;
93
- modified?: string;
94
- }
95
- /**
96
- * Reads only the first line of the cached NDJSON metadata file to extract
97
- * the cache headers (etag, modified). This avoids reading and
98
- * parsing the full metadata (which can be megabytes for popular packages)
99
- * when we only need conditional-request headers.
100
- */
101
- export declare function loadMetaHeaders(pkgMirror: string): Promise<MetaHeaders | null>;
102
- /**
103
- * Reads the full metadata from the cached NDJSON file.
104
- * Line 1: cache headers (etag, modified)
105
- * Line 2: registry metadata JSON
106
- */
107
- export declare function loadMeta(pkgMirror: string): Promise<PackageMeta | null>;
108
- export declare function saveMeta(pkgMirror: string, json: string): Promise<void>;
109
- export {};