@pnpm/lockfile.utils 1100.0.13 → 1100.1.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 CHANGED
@@ -4,6 +4,7 @@ export { packageIdFromSnapshot } from './packageIdFromSnapshot.js';
4
4
  export { packageIsIndependent } from './packageIsIndependent.js';
5
5
  export { pkgSnapshotToResolution } from './pkgSnapshotToResolution.js';
6
6
  export { refIsLocalDirectory, refIsLocalTarball } from './refIsLocalTarball.js';
7
- export { isGitHostedTarballUrl, toLockfileResolution } from './toLockfileResolution.js';
7
+ export { toLockfileResolution } from './toLockfileResolution.js';
8
8
  export * from '@pnpm/lockfile.types';
9
+ export { isGitHostedTarballUrl } from '@pnpm/resolving.resolver-base';
9
10
  export declare const getPkgShortId: typeof refToRelative;
package/lib/index.js CHANGED
@@ -4,8 +4,9 @@ export { packageIdFromSnapshot } from './packageIdFromSnapshot.js';
4
4
  export { packageIsIndependent } from './packageIsIndependent.js';
5
5
  export { pkgSnapshotToResolution } from './pkgSnapshotToResolution.js';
6
6
  export { refIsLocalDirectory, refIsLocalTarball } from './refIsLocalTarball.js';
7
- export { isGitHostedTarballUrl, toLockfileResolution } from './toLockfileResolution.js';
7
+ export { toLockfileResolution } from './toLockfileResolution.js';
8
8
  export * from '@pnpm/lockfile.types';
9
+ export { isGitHostedTarballUrl } from '@pnpm/resolving.resolver-base';
9
10
  // for backward compatibility
10
11
  export const getPkgShortId = refToRelative;
11
12
  //# sourceMappingURL=index.js.map
@@ -1,38 +1,21 @@
1
1
  import url from 'node:url';
2
2
  import * as dp from '@pnpm/deps.path';
3
3
  import { PnpmError } from '@pnpm/error';
4
- import getNpmTarballUrl from 'get-npm-tarball-url';
4
+ import { getNpmTarballUrl } from '@pnpm/resolving.tarball-url';
5
5
  import { nameVerFromPkgSnapshot } from './nameVerFromPkgSnapshot.js';
6
- import { isGitHostedTarballUrl } from './toLockfileResolution.js';
7
6
  export function pkgSnapshotToResolution(depPath, pkgSnapshot, registries) {
8
7
  const resolution = pkgSnapshot.resolution;
9
- // Tarball-shaped resolutions (no `type` field) must carry `integrity`,
10
- // except where the URL itself anchors the bytes:
11
- // - `file:` tarballs (local file on the user's machine; integrity
12
- // adds nothing the user doesn't already control).
13
- // - Git-hosted tarballs (URL contains the commit SHA; git's content-
14
- // addressed model binds the bytes to the commit). The `gitHosted`
15
- // flag may be absent on legacy lockfiles, so fall back to a URL
16
- // match — same logic as `toLockfileResolution`.
17
- // For any other tarball entry a missing integrity is what a tampered
18
- // lockfile looks like: the worker would mint a fresh integrity from
19
- // whatever bytes the URL returned, so we fail closed here. Pacquet
20
- // enforces the same invariant via
21
- // `pacquet_package_manager::missing_tarball_integrity`.
22
- if (resolution.type == null &&
23
- resolution.integrity == null &&
24
- !resolution.tarball?.startsWith('file:') &&
25
- !(resolution.gitHosted === true || (resolution.tarball != null && isGitHostedTarballUrl(resolution.tarball)))) {
26
- throw new PnpmError('MISSING_TARBALL_INTEGRITY', `Cannot install package "${depPath}": its lockfile entry has no "integrity" field, so pnpm cannot verify the downloaded tarball.`, { hint: 'The lockfile may be corrupted or have been tampered with. Restore it from a trusted source, or delete it and re-run installation without --frozen-lockfile to regenerate.' });
8
+ if (resolution.tarball != null && typeof resolution.tarball !== 'string') {
9
+ // Avoid URL string-coercion from malformed YAML lockfile values.
10
+ throw new PnpmError('INVALID_TARBALL_RESOLUTION', `Cannot install package "${depPath}": its lockfile entry has a non-string "tarball" field.`);
27
11
  }
28
12
  if (Boolean(resolution.type) ||
29
13
  resolution.tarball?.startsWith('file:') ||
30
14
  resolution.gitHosted === true) {
31
15
  return pkgSnapshot.resolution;
32
16
  }
33
- // Recover the tarball field for `file:` snapshots whose resolution lost
34
- // its tarball (e.g. lockfiles written by an earlier pnpm 11 version that
35
- // dropped the tarball under `lockfile-include-tarball-url=false`).
17
+ // Recover the tarball field for `file:` snapshots whose depPath is the only
18
+ // source of the local tarball reference.
36
19
  const nonSemverVersion = dp.parse(depPath).nonSemverVersion;
37
20
  if (nonSemverVersion?.startsWith('file:')) {
38
21
  return {
@@ -51,11 +34,11 @@ export function pkgSnapshotToResolution(depPath, pkgSnapshot, registries) {
51
34
  registry = registries.default;
52
35
  }
53
36
  let tarball;
54
- if (!pkgSnapshot.resolution.tarball) {
37
+ if (!resolution.tarball) {
55
38
  tarball = getTarball(registry);
56
39
  }
57
40
  else {
58
- tarball = new url.URL(pkgSnapshot.resolution.tarball, registry.endsWith('/') ? registry : `${registry}/`).toString();
41
+ tarball = new url.URL(resolution.tarball, registry.endsWith('/') ? registry : `${registry}/`).toString();
59
42
  }
60
43
  return {
61
44
  ...pkgSnapshot.resolution,
@@ -1,7 +1,6 @@
1
1
  import type { LockfileResolution } from '@pnpm/lockfile.types';
2
- import type { Resolution } from '@pnpm/resolving.resolver-base';
2
+ import { type Resolution } from '@pnpm/resolving.resolver-base';
3
3
  export declare function toLockfileResolution(pkg: {
4
4
  name: string;
5
5
  version: string;
6
6
  }, resolution: Resolution, registry: string, lockfileIncludeTarballUrl?: boolean): LockfileResolution;
7
- export declare function isGitHostedTarballUrl(url: string): boolean;
@@ -1,4 +1,5 @@
1
- import getNpmTarballUrl from 'get-npm-tarball-url';
1
+ import { isGitHostedTarballUrl } from '@pnpm/resolving.resolver-base';
2
+ import { isCanonicalRegistryTarballUrl } from '@pnpm/resolving.tarball-url';
2
3
  export function toLockfileResolution(pkg, resolution, registry, lockfileIncludeTarballUrl) {
3
4
  if (resolution.type !== undefined || !resolution['integrity']) {
4
5
  return resolution;
@@ -40,29 +41,4 @@ export function toLockfileResolution(pkg, resolution, registry, lockfileIncludeT
40
41
  ...(path == null ? {} : { path }),
41
42
  };
42
43
  }
43
- // Whether `tarball` is the canonical npm registry URL derived from the package
44
- // name, version, and registry — i.e. it can be dropped from the lockfile and
45
- // rebuilt on demand. The `%2f` unescape matches the URLs npm produces for
46
- // scoped packages.
47
- function isCanonicalRegistryTarballUrl(tarball, pkg, registry) {
48
- const expectedTarball = getNpmTarballUrl(pkg.name, pkg.version, { registry });
49
- const actualTarball = tarball.replaceAll('%2f', '/');
50
- return removeProtocol(expectedTarball) === removeProtocol(actualTarball);
51
- }
52
- // Inlined to avoid pulling @pnpm/fetching.pick-fetcher into the lockfile-utils
53
- // dep graph. Used as a fallback when callers haven't pre-set the
54
- // `gitHosted` field on TarballResolution.
55
- export function isGitHostedTarballUrl(url) {
56
- // Schemes and hostnames are case-insensitive, so match against a lowercased
57
- // copy: a tampered `https://CODELOAD.GITHUB.COM/...` must not slip past as a
58
- // non-git-hosted (and therefore registry-trusted) tarball. Only the
59
- // lowercased copy is inspected; the original URL is never rewritten.
60
- const lowerUrl = url.toLowerCase();
61
- return (lowerUrl.startsWith('https://codeload.github.com/') ||
62
- lowerUrl.startsWith('https://bitbucket.org/') ||
63
- lowerUrl.startsWith('https://gitlab.com/')) && lowerUrl.includes('tar.gz');
64
- }
65
- function removeProtocol(url) {
66
- return url.split('://')[1];
67
- }
68
44
  //# sourceMappingURL=toLockfileResolution.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/lockfile.utils",
3
- "version": "1100.0.13",
3
+ "version": "1100.1.0",
4
4
  "description": "Utils for dealing with pnpm-lock.yaml",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -12,9 +12,9 @@
12
12
  "funding": "https://opencollective.com/pnpm",
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "https://github.com/pnpm/pnpm/tree/main/lockfile/utils"
15
+ "url": "https://github.com/pnpm/pnpm/tree/main/pnpm11/lockfile/utils"
16
16
  },
17
- "homepage": "https://github.com/pnpm/pnpm/tree/main/lockfile/utils#readme",
17
+ "homepage": "https://github.com/pnpm/pnpm/tree/main/pnpm11/lockfile/utils#readme",
18
18
  "bugs": {
19
19
  "url": "https://github.com/pnpm/pnpm/issues"
20
20
  },
@@ -29,14 +29,14 @@
29
29
  "!*.map"
30
30
  ],
31
31
  "dependencies": {
32
- "get-npm-tarball-url": "^2.1.0",
33
32
  "ramda": "npm:@pnpm/ramda@0.28.1",
34
- "@pnpm/lockfile.types": "1100.0.11",
35
- "@pnpm/types": "1101.3.2",
36
- "@pnpm/resolving.resolver-base": "1100.4.2",
37
- "@pnpm/hooks.types": "1100.0.12",
38
- "@pnpm/error": "1100.0.0",
39
- "@pnpm/deps.path": "1100.0.8"
33
+ "@pnpm/error": "1100.0.1",
34
+ "@pnpm/hooks.types": "1100.1.0",
35
+ "@pnpm/resolving.resolver-base": "1100.5.0",
36
+ "@pnpm/lockfile.types": "1100.0.12",
37
+ "@pnpm/resolving.tarball-url": "1100.0.0",
38
+ "@pnpm/deps.path": "1100.0.8",
39
+ "@pnpm/types": "1101.3.2"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@jest/globals": "30.4.1",
@@ -44,7 +44,7 @@
44
44
  "tempy": "3.0.0",
45
45
  "write-yaml-file": "^6.0.0",
46
46
  "yaml-tag": "1.1.0",
47
- "@pnpm/lockfile.utils": "1100.0.13"
47
+ "@pnpm/lockfile.utils": "1100.1.0"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=22.13"